2017-10-06 36 views
0

在FuncAnimation中使用imshow藝術家時。第一幀不能丟失。它會始終保持第一幀不變,但其他藝術家的行爲是正確的。我們如何解決這個問題? 下面是代碼:當blit = True時,FuncAnimation無法消除第一幀imshow內容?

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() 

我知道有一個hack solution設置藝術家無形之中init_func。但這是一個黑客攻擊,我不想使用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

anima = animation.FuncAnimation(fig, 
         updater, 
         nframe, 
         init_func=init, 
         interval=20, 
         blit=blit, 
         repeat=False 
         ) 
+0

這是一個破解。因爲你創建了一個空的'imart'。如果沒有'init_func','_init_draw'就會調用updater(0)。如果您查看代碼,'_init_draw'所做的只是將'init_func'返回的所有藝術家註冊爲'set_animated(True)'。理論上,它不應該在那裏留下任何框架。正如我所說,這隻能通過imshow失敗。其他藝術家不需要空的初始藝術家。 – Wang

+0

不知道問題是什麼問。如果您覺得這是一個錯誤,那麼SO不適合報告它,請轉到[matplotlib問題跟蹤器](https://github.com/matplotlib/matplotlib/issues)。但是,如果你考慮一下,可能有一個很好的理由沒有_animated屬性翻譯成可見性,上述是一個明智的解決方案。或者,也許你只是重申你想要問的問題。 – ImportanceOfBeingErnest

相關問題