2017-10-06 4 views
0

FuncAnimationでimshowアーティストを使用する場合。最初のフレームはblitできません。最初のフレームはそのまま残りますが、他のアーティストは正しく動作します。どうすればこの問題を解決できますか?私はinit_funcに見えないアーティストを設定するhack solutionあり承知していますblit = Trueの場合、FuncAnimationは最初のフレームのimshowコンテンツをblitできませんか?

from matplotlib import pyplot as plt, animation, cm 
def show_imshow_blit_bug(start=0, blit=True): 
    pic = np.zeros((10, 10), dtype=float) 
    x = np.arange(0, 2 * np.pi, 0.01) 
    amp = (x.max() - x.min())/2 

    fig, ax = plt.subplots() 
    extent = [x.min(), x.max(), -amp, amp] 
    _cm = cm.jet 
    picf = pic.flat 
    picf[0] = 1 
    picf[-1] = 0.5 
    imart = ax.imshow(pic, 
         origin='lower', 
         extent=extent, 
         cmap=_cm 
        ) 
    # imart.set_animated(True) # set or not has no effect 
    line, = ax.plot(x, np.sin(x)*amp) 
    line2, = ax.plot(x[[0, -1]], np.array([-amp, amp]), 'r') 
    line2.set_animated(True) # this make line2 disappear, since updater does not return this artist 
    line3, = ax.plot(x[[0, -1]], np.array([amp, -amp]), 'C1') 
    #line3 will be keeped since _animated = False 
    ax.set_xlim(x.min(), x.max()) 
    ax.set_ylim(-amp * 1.1, amp * 1.1) 
    fig.tight_layout() 

    def updater(fn): 
     print(fn) 
     np.random.shuffle(picf) 
     imart.set_data(np.ma.masked_where(pic == 0, pic)) 
     line.set_ydata(np.sin(x + fn/10.0)*amp) 
     return (imart, line,) # Both artist will be in blit list 

    nframe = range(start, 200) 
    anima = animation.FuncAnimation(fig, 
          updater, 
          nframe, 
          interval=20, 
          blit=blit, 
          repeat=False 
          ) 
    plt.show() 

: は、ここでは、コードです。しかし、これはハックで、残りのコードでは互換性がないinit_funcを使用したくありません。

答えて

0

FuncAnimation documentation状態

init_func:明確なフレームの描画に使用する呼び出し可能、

オプション機能。 指定されていない場合は、フレームシーケンスの最初の項目から描画された結果が使用されます。 。この関数は、最初のフレームの前に一度呼び出されます)

のでinit_funcを使用すると、ハッキング、または望ましくないではない - それは実際にインデントの使用です。

あなたは空の画像

imart = ax.imshow([[]], ...) 

を開始するだろうが

def init(): 
    return imart,line, 

と更新機能

def updater(fn): 
    np.random.shuffle(picf) 
    imart.set_data(np.ma.masked_where(pic == 0, pic)) 
    line.set_ydata(np.sin(x + fn/10.0)*amp) 
    return (imart, line,) 

FuncAnimation

をインスタンス化init関数を持っています
+0

これはハックです。空の 'imart'を作成するからです。 'init_func'がなければ、' _init_draw'はupdater(0)を呼び出します。コードを調べると、 '_init_draw'は' init_func'によって返されたすべてのアーティストを 'set_animated(True)'で登録するだけです。理論的には、そこにフレームを残すべきではありません。私が言ったように、これはimshowで失敗しただけです。他のアーティストは空の初期アーティストを必要としません。 – Wang

+0

質問が何を求めているのかよく分かりません。これがバグだと思えば、SOはそれを報告する適切な場所ではありません。[matplotlib issue tracker](https://github.com/matplotlib/matplotlib/issues)にアクセスしてください。しかし、アニメーション化されたプロパティを持たない画像が可視性に変換される正当な理由があるかもしれないと考えている場合は、上記は賢明な解決策です。または、あなたがここで尋ねたいと思っていることをちょうど再記述してください。 – ImportanceOfBeingErnest

関連する問題