我的问题是恢复matplotlib ArtistsAnimation
我的代码是:
def PlotFields(self):
fig = plt.figure()
axess = []
for i in range(0,self.number_fields):
axess.append(fig.add_subplot((self.number_fields+1)//2,2,i+1))
#find min and max in time
mins = {}
maxs = {}
for key,field in self.fields.items():
mins[key] = field[:,:,:,self.z_slice].min()
maxs[key] = field[:,:,:,self.z_slice].max()
if mins[key] == maxs[key]:#this fixes bug in imshow when vmin = vmax
mins[key] = mins[key]-0.1
maxs[key] = maxs[key]+0.1
#set up list of images for animation
movie = []
images = []
nt = self.fields[list(self.fields)[0]].shape[0] #number of time slices
print('time slices = {}'.format(nt))
first = 1
for time in range(0,nt):
images.clear()
i = 0
for key,field in self.fields.items():
if self.cut == 'xy':
images.append(axess[i].pcolor(field[time,:,:,self.z_slice].T, vmin = mins[key], vmax = maxs[key]))
axess[i].set_xlabel('x')
axess[i].set_ylabel('y')
elif self.cut == 'xz':
images.append(axess[i].pcolor(field[time,:,:,self.y_slice].T, vmin = mins[key], vmax = maxs[key]))
axess[i].set_xlabel('x')
axess[i].set_ylabel('z')
else:
print('unknown cut --- exiting !!')
quit()
axess[i].set_title(key)
i = i + 1
if first == 1:
for i in range(0,self.number_fields):
fig.colorbar(images[i], ax = axess[i])
first = 0
# time_title.set_text('t={}'.format(t_array[time]))
time_title = axess[0].annotate('t={}'.format(self.t_array[time]),xy = (0.1,1.2))
collected_list = [*images] #apparently a bug in matplotlib forces this solution
collected_list.append(time_title)
movie.append(collected_list)
#for i in range(0,number_fields):
# fig.colorbar(images[i], ax = axess[i])
#run animation
self.ani = anim.ArtistAnimation(fig, movie, interval=500, blit = False, repeat_delay = 1000)
fig.canvas.mpl_connect('button_press_event', self.onClick)
if self.save_movie == True:
try:
ani.save('xy_film.mp4')
#ani.save('film.mp4',writer = FFwriter, fps=30, extra_args=['-vcodec', 'libx264'])
except Exception:
print("Save failed: Check ffmpeg path")
plt.show()
def onClick(self, event):
self.pause == True
if self.pause == False:
self.ani._stop()
self.pause = True
print('self pause = False')
else:
self.ani._start()
self.pause = False
#pause ^= True
print('self pause = True')
动画停止onClick,但是在第二次点击时引发以下错误,该第二次点击应继续播放动画(如果可能):
File "PlotFieldsFieldAligned.py", line 149, in onClick
self.ani._start()
File "/home/yolen/scicomp/anaconda3/lib/python3.5/site- packages/matplotlib/animation.py", line 665, in _start
self.event_source.add_callback(self._step)
AttributeError: 'NoneType' object has no attribute 'add_callback'
任何帮助表示赞赏:-D
最佳答案
尽管在这种情况下,似乎FuncAnimation
比ArtistAnimation
更适合,但两者都可以
停止/开始的方式相同。参见问题stop / start / pause in python matplotlib animation。
要点是,'private'ArtistAnimation._start()
函数没有按照您认为的那样做。因此,使用ArtistAnimation.event_source.stop()
和ArtistAnimation.event_source.start()
函数是明智的。
下面是一个最小的可运行示例,显示了如何通过使用鼠标按钮单击来启动/停止ArtistAnimation
。
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animation
class SomeClass():
def __init__(self):
self.pause = False
self.fig, ax = plt.subplots()
ax.set_aspect("equal")
self.movie = []
nt = 10
X,Y = np.meshgrid(np.arange(16), np.arange(16))
for t in range(nt):
data = np.sin((X+t*1)/3.)**2+ 1.5*np.cos((Y+t*1)/3.)**2
pc = ax.pcolor(data)
self.movie.append([pc])
self.ani = animation.ArtistAnimation(self.fig, self.movie, interval=100)
self.fig.canvas.mpl_connect('button_press_event', self.onClick)
plt.show()
def onClick(self, event):
if self.pause:
self.ani.event_source.stop()
else:
self.ani.event_source.start()
self.pause ^= True
a = SomeClass()