2015-07-20 121 views
0

目標

嗨, 我想動畫一個複雜圖形與幾個次要情節,並已開始與artist animationfunction animation方法測試。Matplotlib動畫自定義藝術家類

現在,我的目標是讓左側的子圖顯示移動的彩色線(而不是問題),右側的子圖顯示腦掃描(問題)的更新表示。靜態,這看起來像這樣。

# Imports 
import nilearn as nil 
from nilearn import plotting as nlp 
from matplotlib import pyplot as plt 

window = np.arange(0,200-50) 

fig = plt.figure(figsize=(7,4)) 
ax = fig.add_subplot(121) 
ax.set_xlim([0, 200]) 
a = ax.axvspan(window[0], window[0]+50, color='blue', alpha=0.5) 

ay = fig.add_subplot(122) 
b = nlp.plot_stat_map(nil.image.index_img(s_img, 0), axes=ay, colorbar=False, display_mode='x', cut_coords=(0,)) 

Static version of what I'd like to display

問題

正如你所看到的,我使用nilearn用於繪製大腦圖像。出於某種原因,來自plot_stat_map的nilearn對象不具有與來自axvspan的matplotlib對象不同的屬性set_visible

所以,當我嘗試一個簡單的動畫,像這樣:

fig = plt.figure(figsize=(7,4)) 
ax = fig.add_subplot(121) 
ax.set_xlim([0, 200]) 
ay = fig.add_subplot(122) 
iml = list() 

for i in np.arange(50): 
    a = ax.axvspan(window[i], window[i]+50, color='blue', alpha=0.5) 
    b = nlp.plot_stat_map(nil.image.index_img(s_img, i), axes=ay) 
    iml.append((a,b)) 

ani = animation.ArtistAniTruemation(fig, iml, interval=50, blit=False, 
    repeat_delay=1000) 

它與下面的錯誤崩潰:

/home/surchs/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/matplotlib/animation.pyc in _init_draw(self) 
    974   for f in self.new_frame_seq(): 
    975    for artist in f: 
--> 976     artist.set_visible(False) 
    977     # Assemble a list of unique axes that need flushing 
    978     if artist.axes not in axes: 

AttributeError: 'OrthoSlicer' object has no attribute 'set_visible' 

有道理,nilearn也可能不符合matplotlibs預期。所以,我嘗試動畫功能的方法,像這樣:

def show_things(i, window, ax, ay): 
    ax.axvspan(window[i], window[i]+50, color='blue', alpha=0.5) 
    nlp.plot_stat_map(nil.image.index_img(s_img, i), axes=ay, colorbar=False, display_mode='x', cut_coords=(0,)) 

fig = plt.figure(figsize=(7,4)) 
ax = fig.add_subplot(121) 
ax.set_xlim([0, 200]) 
ay = fig.add_subplot(122) 

ani = animation.FuncAnimation(fig, show_things, interval=10, blit=False, fargs=(window, ax, ay)) 

雖然我不知道如果我用正確的事情,這給了我右邊的動畫情節的大腦。然而,左側的情節現在沒有更新,只是畫了一遍。所以,而不是一個滑動條,我得到一個擴大的顏色表面。事情是這樣的:

enter image description here

問題

如何

  • 獲得在圖上留下來更新使用功能動畫製作方法時,在每次迭代(而不是覆蓋) ? 我已經嘗試過matplotlib中的ax.cla()函數,但是因爲這也清除了所有的軸屬性(如xlim),所以對我來說這不是一個解決方案。有沒有優點?
  • 獲得與藝術家動畫方法一起工作的情節,即使自定義繪圖類明顯缺少關鍵屬性。

此外,我不知道如果我正在做整個實施部分權利,所以任何意見,在這方面也非常讚賞。

回答

1

我懷疑你可能需要清除axvspan軸與ax.cla()之間的座標軸以獲得正確的左側繪圖(N.B.可能應該也清除右側繪圖)。爲了解決缺失屬性的問題,我建議從nlp.plot_stat_map中提取返回的句柄中的數據,並使用matplotlib pcolormesh(或imshow)進行繪圖。另一種可能性是創建一個子類並自己添加此方法。如果這應該存在,那麼向nilearn提交錯誤/功能請求也是值得的。

順便說一句,如果你只有在一個快速簡便的情節的時候,你可以做一個窮人的版本使用交互式繪圖動畫,作爲一個小例子,

import matplotlib.pyplot as plt 
import numpy as np 
import time 

#Interactive plot 
plt.ion() 

#Setup figures 
fig = plt.figure(figsize=(7,4)) 
ax = fig.add_subplot(121) 
ay = fig.add_subplot(122) 
plt.show() 


x = np.linspace(0,2*np.pi) 
for i in range(10000): 
    print(i) 
    #Clear axes 
    ax.cla(); ay.cla() 

    #Update data 
    yx = np.sin(x+i*0.1) 
    yy = np.sin(2.*(x+i*0.1)) 

    #Replot 
    ax.plot(x,yx) 
    ay.plot(x,yy) 

    #Pause to allow redraw 
    plt.draw() 
    plt.pause(0.01) 
+0

感謝。我應該澄清ax.cla不是我們所希望的,因爲它也會重新設置每次重繪時的軸屬性(例如xlim),從而弄亂了圖形。我相信我的問題可以重新表述爲:如何在不放鬆軸屬性的情況下清除繪圖? – surchs

+0

你不能簡單地重新設置動畫循環內的軸限制嗎?如果沒有清除所有其他屬性,我認爲您不能清除軸。如果軸必須保持不變,則需要更新/清除顯示的數據對象。繪圖句柄('a'和'b')應該有'set_data'方法,可以在不觸碰軸的情況下改變繪圖。例如'ax.patches.remove(a)'會移除當前的'axvspan'實例。對於其他原始藝術家對象將會有類似的刪除。 –

相關問題