使用matplotlib在python中制作多个动画
我想使用matplotlib的动画功能来显示和保存多个动画。以前,我只是使用pyplot在每一步都有一个短暂的停顿来伪造动画,但我没有找到将这些“动画”保存为视频的方法,所以我改用真实动画。以下是我启动时代码的虚拟版本(将运行):使用matplotlib在python中制作多个动画,python,matplotlib,animation,Python,Matplotlib,Animation,我想使用matplotlib的动画功能来显示和保存多个动画。以前,我只是使用pyplot在每一步都有一个短暂的停顿来伪造动画,但我没有找到将这些“动画”保存为视频的方法,所以我改用真实动画。以下是我启动时代码的虚拟版本(将运行): 从matplotlib导入pyplot作为plt 将numpy作为np导入 班级走廊: 定义初始化(自): self.end_pos=5 self.cur\u pos=0 def设置(自): self.cur\u pos=0 def go(自我决定): 如果decis
从matplotlib导入pyplot作为plt
将numpy作为np导入
班级走廊:
定义初始化(自):
self.end_pos=5
self.cur\u pos=0
def设置(自):
self.cur\u pos=0
def go(自我决定):
如果decision==0且self.cur\u pos>0:
self.cur_pos-=1
elif决策==1:
self.cur_pos+=1
完成=self.cur\u pos>=self.end\u pos
返回完成
def绘图(自身,图):
图clear()
ax=图gca()
ax.set(xlim=(-0.5,5.5),ylim=(-0.5,0.5))
最大散射(自电流位置,0,s=350)
plt.draw()
plt.暂停(0.01)
sim=走廊()
对于范围(5)内的num_sim:
打印(“运行模拟{}”。格式(num_sim))
sim.setup()
模拟绘图(plt.gcf())
尽管如此:
done=sim.go(np.random.randint(0,2))
模拟绘图(plt.gcf())
如果这样做:
打破
#在此处保存动画
此处需要注意的关键事项:
go
draw
从matplotlib导入pyplot作为plt
从matplotlib.animation导入FuncAnimation
将numpy作为np导入
班级走廊:
定义初始化(自):
self.end_pos=5
self.cur\u pos=0
def设置(自):
self.cur\u pos=0
def go(自我决定):
如果decision==0且self.cur\u pos>0:
self.cur_pos-=1
elif决策==1:
self.cur_pos+=1
完成=self.cur\u pos>=self.end\u pos
返回完成
def绘图(自身,图):
图clear()
ax=图gca()
ax.set(xlim=(-0.5,5.5),ylim=(-0.5,0.5))
最大散射(自电流位置,0,s=350)
plt.draw()
plt.暂停(0.01)
sim=走廊()
对于范围(5)内的num_sim:
打印(“运行模拟{}”。格式(num_sim))
sim.setup()
全部完成=错误
图=plt.图()
def gen_frame_until_done():#使用生成器生成帧,只要没有全部完成
全球一切就绪
i=0
虽然并非所有工作都已完成:
i+=1
产量一
def animate(i):#animate函数代替while循环
模拟绘图(图)
done=sim.go(np.random.randint(0,2))
如果这样做:
全球一切就绪
全部完成=正确
模拟绘图(图)
anim=FuncAnimation(图,动画,帧=gen\u frame\u,直到完成,重复=False)
plt.show()
#动画保存(…)
这将运行,但它不会给我我想要的。它将只显示一个动画,终端将显示运行模拟0的。当触发all_done
且模拟结束时,程序将等待我退出绘图窗口。一旦退出,程序将继续进行下一次模拟并重复
我不喜欢这样,我必须手动退出窗口。通过将阻塞plt.show()
替换为
plt.show(block=False)
plt.暂停(3)
plt.close()
这将允许程序继续,而无需手动退出窗口。但是,在继续下一个动画之前,只允许显示3秒钟的动画
我想要的是:
- 我希望能够显示模拟,直到模拟结束。当它结束时,我希望窗口自动关闭
- 我希望下一个模拟在上一个动画窗口之后运行一个新的动画窗口
同样,我使用动画对象是因为我需要能够将动画保存为视频。但是如果有其他方法可以做到这一点,我肯定会接受。如果在animate
函数的if done
子句中添加plt.close()
调用,绘图窗口将在模拟完成时关闭,下一个窗口将在下一次模拟时打开
为了使下一个动画不需要与鼠标进行任何交互,我们还需要将block=False
添加到plt.show
;我们可以检查all_done
是否为真,如果动画没有完成,plt.pause()
例如:
for num_sim in range(5):
print("running simulation {}".format(num_sim))
sim.setup()
all_done = False
fig = plt.figure()
def gen_frame_until_done(): # Using a generator to give me frames as long as not all_done
global all_done
i = 0
while not all_done:
i += 1
yield i
def animate(i): # Animate function takes the place of the while loop
sim.draw(fig)
done = sim.go(np.random.randint(0,2))
if done:
global all_done
all_done = True
sim.draw(fig)
plt.close(fig)
anim = FuncAnimation(fig, animate, frames=gen_frame_until_done, repeat=False)
plt.show(block=False)
while all_done is False:
plt.pause(1)
谢谢你的回复!这是一个很大的帮助。但这对我来说并不完全有效,因为动画将播放单个模拟,然后窗口将关闭。然后它就会结冰。它不会继续下一个动画,除非我以某种方式与计算机交互,即单击鼠标或移动鼠标。如果我只是坐着看,它会播放动画,关上窗户,然后它似乎在等我做什么。。。在Mac 10.14上运行。6@KindaTechy你是对的。我想我的编辑通过在plt.show()
的末尾设置block=False
,然后对照all_done
来确定是否需要暂停@tmdavison!这解决了我的问题。我希望我能更好地理解plt是如何工作的,这样我就能更好地理解这段代码是如何运行的。。。这里我只需要注意,我必须将anim.save(…)函数放在plt.show(block=False)之上,否则我无法保存和渲染。