使用matplotlib的FuncAnimation逐帧生成动画时报错如何解决?
问题原因与修改方案
核心错误原因
- 你开启了
blit = True参数:该模式用于优化动画渲染效率,要求animate函数必须返回所有发生了更新的Artist对象序列,你的原animate函数没有返回值,因此触发RuntimeError。 - 动画实例被提前回收:
FuncAnimation生成的动画对象必须被一个生命周期足够长的变量持有,否则会被Python垃圾回收机制自动销毁,就会触发你遇到的UserWarning,因此不能删除返回动画实例的逻辑。
优化后的可运行代码
import numpy as np import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation def create_video(n): X = np.random.binomial(1, 0.3, size = (n,n)) fig = plt.figure() im = plt.imshow(X, cmap = plt.cm.gray) def animate(t): nonlocal X X = np.roll(X, +1, axis = 0) im.set_array(X) # blit模式下必须返回更新后的artist序列,加逗号表示是元组 return (im,) anim = FuncAnimation( fig, animate, frames = 100, interval = 1000 / 30, blit = True ) return anim # 持有动画实例,避免被回收 anim = create_video(10) # 如果需要显示动画,执行下面这行 plt.show() # 如果需要保存为视频,可以调用anim.save方法,比如保存为mp4: # anim.save("roll_array.mp4", fps=30)
关键修改说明
- 移除了全局变量
X,改用nonlocal关键字引用外层函数的变量,代码更易维护。 - 在
animate函数末尾添加了return (im,),返回更新后的图像对象,满足blit模式的要求。 - 保留了动画实例的返回与变量赋值逻辑,避免实例被提前回收。
如果你不需要blit优化,也可以将blit参数设为False,此时animate函数可以不需要返回值,但大规模数组场景下blit模式的渲染效率会更高。
内容的提问来源于stack exchange,提问作者Sam OT
相关产品推荐
相关产品推荐

