2013-07-27 218 views
5

我正在嘗試使用matplotlib.ArtistAnimation來動畫兩個子圖。我希望X軸隨着動畫的進展而增加值,這樣動畫的總長度是100,但是在任何時候,子圖都只給我提供0-24的時間值,然後迭代到100。使用matplotlib動畫更新x軸值

一個很好的例子是here。該鏈接使用FuncAnimation,並使用plot().axes.set_xlim()以滾動方式更新x軸標籤並增加x值。該代碼可通過所提供鏈接中YouTube視頻下方的鏈接獲得。

我附加了下面的代碼,顯示了我試圖複製這些結果,但x限制似乎取決於它們的最終值而不是隨着時間增加。我也嘗試通過只畫出在子圖中可見的窗口中的值來增加解決方案(與軸相對),但不會增加x軸值。我也嘗試實現自動縮放,但x軸仍不更新。

我也發現this question這實際上是同樣的問題,但問題從未得到解答。

這裏是我的代碼:

import matplotlib.pylab as plt 
import matplotlib.animation as anim 
import numpy as np 

#create image with format (time,x,y) 
image = np.random.rand(100,10,10) 

#setup figure 
fig = plt.figure() 
ax1=fig.add_subplot(1,2,1) 
ax2=fig.add_subplot(1,2,2) 
#set up viewing window (in this case the 25 most recent values) 
repeat_length = (np.shape(image)[0]+1)/4 
ax2.set_xlim([0,repeat_length]) 
#ax2.autoscale_view() 
ax2.set_ylim([np.amin(image[:,5,5]),np.amax(image[:,5,5])]) 

#set up list of images for animation 

ims=[] 
for time in xrange(np.shape(image)[0]): 

    im = ax1.imshow(image[time,:,:]) 
    im2, = ax2.plot(image[0:time,5,5],color=(0,0,1)) 
    if time>repeat_length: 
     lim = ax2.set_xlim(time-repeat_length,time) 

    ims.append([im, im2]) 


#run animation 
ani = anim.ArtistAnimation(fig,ims, interval=50,blit=False) 
plt.show() 

我只想第二副區(ax2)來更新x軸的值。

任何幫助將不勝感激。

+1

http://stackoverflow.com/questions/17558096/animated-title-in-matplotlib/17562747#17562747 < - 得到blit更新標籤 – tacaswell

+0

http://stackoverflow.com/questions/17888593/display-sequence -of-images-using-matplotlib – tacaswell

+0

動畫在我使用blit時不會運行,不確定爲什麼 – abradd

回答

5

如果需要阻擊器

import matplotlib.pylab as plt 
import matplotlib.animation as animation 
import numpy as np 

#create image with format (time,x,y) 
image = np.random.rand(100,10,10) 

#setup figure 
fig = plt.figure() 
ax1 = fig.add_subplot(1,2,1) 
ax2 = fig.add_subplot(1,2,2) 
#set up viewing window (in this case the 25 most recent values) 
repeat_length = (np.shape(image)[0]+1)/4 
ax2.set_xlim([0,repeat_length]) 
#ax2.autoscale_view() 
ax2.set_ylim([np.amin(image[:,5,5]),np.amax(image[:,5,5])]) 

#set up list of images for animation 


im = ax1.imshow(image[0,:,:]) 
im2, = ax2.plot([], [], color=(0,0,1)) 

def func(n): 
    im.set_data(image[n,:,:]) 

    im2.set_xdata(np.arange(n)) 
    im2.set_ydata(image[0:n, 5, 5]) 
    if n>repeat_length: 
     lim = ax2.set_xlim(n-repeat_length, n) 
    else: 
     # makes it look ok when the animation loops 
     lim = ax2.set_xlim(0, repeat_length) 
    return im, im2 

ani = animation.FuncAnimation(fig, func, frames=image.shape[0], interval=30, blit=False) 

plt.show() 

會工作。

如果您需要跑得更快,您需要使用用於blitting的邊框進行遊戲,以便更新座標軸標籤。

+0

我一直希望能用ArtistAnimation讓它運行,但最終咬住了項目符號並重寫了代碼。它似乎運行順利。 – abradd

0

這會移動您的軸,但速度很慢。

import matplotlib.pylab as plt 
import matplotlib.animation as anim 
import numpy as np 


image = np.random.rand(100,10,10) 
repeat_length = (np.shape(image)[0]+1)/4 

fig = plt.figure() 
ax1 = ax1=fig.add_subplot(1,2,1) 
im = ax1.imshow(image[0,:,:]) 

ax2 = plt.subplot(122) 
ax2.set_xlim([0,repeat_length]) 
ax2.set_ylim([np.amin(image[:,5,5]),np.amax(image[:,5,5])]) 
im2, = ax2.plot(image[0:0,5,5],color=(0,0,1)) 

canvas = ax2.figure.canvas 

def init(): 
    im = ax1.imshow(image[0,:,:]) 
    im2.set_data([], []) 
    return im,im2, 

def animate(time): 
    time = time%len(image) 
    im = ax1.imshow(image[time,:,:]) 
    im2, = ax2.plot(image[0:time,5,5],color=(0,0,1)) 
    if time>repeat_length: 
     print time 
     im2.axes.set_xlim(time-repeat_length,time) 
     plt.draw() 
    return im,im2, 

ax2.get_yaxis().set_animated(True) 

# call the animator. blit=True means only re-draw the parts that have changed. 
animate = anim.FuncAnimation(fig, animate, init_func=init, 
           interval=0, blit=True, repeat=True) 

plt.show() 
+0

您不需要每次都重新創建'imshow'對象,而是使用'set_data'。 – tacaswell

0

如果您正在使用blitting,則可以在每次更改y/x軸時調用pyplot.draw()來重新繪製整個圖形。

這會更新整個圖形,所以速度相對較慢,但如果不將其稱爲多個項目,則可以接受。