Matplotlib FuncAnimation:如何同时在Jupyter Notebook中显示动画并正常保存GIF文件?
Matplotlib FuncAnimation:如何同时在Jupyter Notebook中显示动画并正常保存GIF文件?
嗨,我之前也碰到过一模一样的问题!这其实是因为ani.save()会把动画的帧序列从头到尾遍历一遍来生成GIF,遍历完之后动画的状态就停在最后一帧了,所以再调用plt.show()的时候,动画没法从初始帧开始播放。不过有几个简单的小技巧可以解决这个问题,不用重复运行两次代码:
首先要确保你在Jupyter里用的是交互式matplotlib后端,先运行这行代码:
%matplotlib notebook
(或者用%matplotlib widget,看你的环境支持哪个,这能保证动画在Notebook里正常交互显示,而不是变成静态图片)
方法一:保存后重置动画状态
这是最直接的解决方案,保存完GIF之后,手动把动画的帧序列重置回初始状态,再调用显示:
from matplotlib.animation import FuncAnimation, PillowWriter import matplotlib.pyplot as plt # 这里替换成你的初始化和更新函数 def init(): # 你的初始化逻辑,比如创建初始图形元素 return [...] def update_plot(frame): # 每一帧的更新逻辑 return [...] fig = plt.figure() # 创建动画实例 ani = FuncAnimation(fig, update_plot, init_func=init, frames=len(t), interval=2, blit=True, repeat=False) # 先保存GIF ani.save('fast.gif', writer=PillowWriter(fps=60)) # 重置动画的帧序列,回到初始状态 ani.frame_seq = ani.new_frame_seq() # 重新调用初始化函数,确保画面回到最开始的状态 ani._init_draw() # 现在显示动画就是从初始帧开始了 plt.show()
方法二:先显示再保存(适合先预览效果再保存)
如果你想先在Notebook里看动画效果,再保存成GIF,可以这样做:
%matplotlib notebook # 同样先定义init和update_plot函数,以及创建动画实例 fig = plt.figure() ani = FuncAnimation(fig, update_plot, init_func=init, frames=len(t), interval=2, blit=True, repeat=False) # 先显示动画 plt.show() # 关闭显示窗口,重置动画状态 plt.close() ani.frame_seq = ani.new_frame_seq() ani._init_draw() # 再保存GIF ani.save('fast.gif', writer=PillowWriter(fps=60))
为什么会出现这个问题?
简单来说,FuncAnimation的帧序列是一个一次性的迭代器,ani.save()会把这个迭代器从头到尾跑一遍来生成每一帧的图像,跑完之后迭代器就空了,动画的当前状态也停在了最后一帧。通过ani.frame_seq = ani.new_frame_seq()我们可以重新生成一个初始的帧迭代器,再加上ani._init_draw()调用初始化函数,就能让动画完全回到最开始的状态,这样不管是保存还是显示,都能从第一帧开始正常运行。
备注:内容来源于stack exchange,提问作者lzzard
相关产品推荐
相关产品推荐

