10

matplotlibにホライズンチャートを実装しようとしています(http://square.github.com/cubism/を参照)

基本的な考え方は、時系列を狭いアスペクト比で表示し、値が増加すると(y軸の制限を超えて)、下から暗い色で元に戻ります(古いAtariゲームを考えてみてください)。画面の上部を過ぎて、下部に飛び出します)。

私の基本的なアプローチは、yデータをチャックに分割しax.twinx()、制限を適切に使用および設定して、各垂直グループを新しい軸にプロットすることです。

正または負のデータだけの場合、これはうまく機能しているようです。

ポジティブ:

ポジティブホライズンチャート

ネガティブ:

負の棒グラフ

しかし、何らかの理由で、両方のネジを締めます:

# setup the environment
import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, np.pi*4, 137)
y = (2*np.random.normal(size=137) + x**2)

# reflect everything around the origin
xx = np.hstack([-1*x[::-1], x])
yy = np.hstack([-1*y[::-1], y])

# function to do the plot
def horizonPlot(ax, x, y, nfolds=3, inverty=False, color='CornflowerBlue'):
    axes = [ax]
    if inverty:
        ylims = np.linspace(y.min(), y.max(), nfolds + 1)[::-1]
    else:
        ylims = np.linspace(y.min(), y.max(), nfolds + 1)

    for n in range(1, nfolds):
        newax = axes[-1].twinx()
        axes.append(newax)

    for n, ax in enumerate(axes):        
        ax.fill_between(x, y, y2=ylims[n], facecolor=color, alpha=1.0/nfolds, zorder=n)
        ax.set_ylim([ylims[n], ylims[n+1]])
        ax.set_yticklabels([])
        ax.set_yticks([])

        if inverty:
            ax.invert_yaxis()

    ax.set_xlim([x.min(), x.max()])
    return fig

fig, baseax = plt.subplots(figsize=(6.5,1.5))
posax = baseax.twinx()
negax = posax.twinx()
fig = horizonPlot(posax, xx, np.ma.masked_less(yy, 0), inverty=False, color='DarkGreen')
fig = horizonPlot(negax, xx, np.ma.masked_greater(yy, 0), inverty=True,   color='CornflowerBlue')
for ax in fig.get_axes():
    ax.set_yticklabels([])

fig.tight_layout()
plt.show()

悪いチャート(プラス側に複数のレイヤーがないことに注意してください):

両方の地平線チャート

どんな考えでも大歓迎です!

4

1 に答える 1

5

私のコンピュータでは問題なく動作するので、なぜあなたが動作しないのか、私は実際にはわかりません。しかし、私はこのプロットに本当に興味があるので、このような凝っtwinxたものをすべて使わずに、自分でそれを実装しようとしました。

これは実際にはプロットの素晴らしいところなので、私はこれらの領域を互いに重ねてプロットします。したがって、アルファを調整する必要はありません。合計するだけです。

import numpy as np
from matplotlib.pyplot import *

def layer(y,height):
    neg=0.0;pos=0.0
    if y>0:
        if y-height>=0:
            pos=height
            y-= pos
        else : 
            pos = y
    elif y<0:
        if y+height<=0:
            neg=height
            y += neg
        else : 
            neg = -y
    return pos,neg

def horizonPlot(x,y,height=50.0,colors=['CornflowerBlue','DarkGreen']):
    alpha = .10
    vlayer = np.vectorize(layer)
    while (y != 0).any():
        l = vlayer(y,height)
        y -= l[0];y += l[1]
        fill_between(x,0,l[0],color=colors[0], alpha=alpha)
        fill_between(x,height-l[1],height,color=colors[1], alpha=alpha)

def main():
    x = np.linspace(0, np.pi*4, 137)
    y = (2*np.random.normal(size=137) + x**2)
    xx = np.hstack([-1*x[::-1], x])
    yy = np.hstack([-1*y[::-1], y])
    horizonPlot(xx,yy)
    show()

これは私のマシンでは次のようになります。それがあなたのものでうまくいくことを願っていますが、私は基本的なプロット方法を使用しています。

ここに画像の説明を入力してください

于 2013-03-02T01:06:26.087 に答える