Matplotlib FuncAnimation提示动画未渲染即被删除警告如何解决
matplotlib FuncAnimation 动画未渲染警告修复
问题场景
运行环境为Windows系统下的Jupyter,仅最后一段代码块触发警告,前置代码为目标动画实现上下文:
- 实现目标:基于matplotlib pyplot绘制两条线段,蓝色线段标注为
wrong、红色线段标注为right;动画初始状态两条线均与蓝色wrong线位置重合,后续红色线段逐步移动到right线的正确位置。其中wrong线起止坐标为(x,y)=(-1.25,9.1)到(0.75,8.0),right线起止坐标为(-1.25,9.7)到(0.75,7.5)。 - 静态对比实现代码:
import matplotlib.pyplot as plt import numpy as np from matplotlib.animation import FuncAnimation boring_fig = plt.figure() blue = plt.plot([-1.25,.75], [9.1,8], color = 'b', label = 'wrong') red = plt.plot([-1.25,.75], [9.7,7.5], color = 'r', label = 'right') plt.show()
- 动画预实现代码(提前定义红色线段y坐标渐变数组、绘制固定蓝色线段):
y_left = np.array([9.1, 9.16, 9.22, 9.28, 9.34, 9.4, 9.46, 9.52, 9.58, 9.64, 9.7]) y_right = np.array([8.0, 7.95, 7.9, 7.85, 7.8, 7.75, 7.7, 7.65, 7.6, 7.55, 7.5]) fig = plt.figure() blue = plt.plot([-1.25,.75], [9.1,8], color = 'b', label = 'wrong') plt.show()
- 动画逻辑代码(触发警告部分):
def animate_1(i): return plt.plot([-1.25,.75], [y_left[i],y_right[i]], color = 'r'), anim = FuncAnimation(fig = fig, func = animate_1, interval = 100, frames = 10) plt.show(anim)
触发警告内容:
UserWarning: Animation was deleted without rendering anything. This is most likely unintended. To prevent deletion, assign the Animation to a variable that exists for as long as you need the Animation.
动画未正常渲染。
问题原因
代码存在3个核心问题导致动画失效:
- 分段运行时提前调用
plt.show()渲染了仅含蓝色线段的静态画布,后续创建FuncAnimation绑定的fig对象已经被渲染输出,动画无法附着到已生成的静态图上。 - 动画更新逻辑每次都调用
plt.plot()绘制新的红色线段,没有复用初始红线对象,会导致帧内容叠加混乱;同时Jupyter默认的静态图后端不会自动保留动画对象引用,直接触发对象被回收的警告。 - 定义的y坐标渐变数组长度为11,
frames参数设为10会漏掉最后一帧,动画无法停在right线的正确位置。
修复方案
- 不要在创建动画前提前调用
plt.show(),所有画布元素、动画逻辑初始化完成后再统一渲染。 - 提前初始化红色线段对象,更新函数里仅修改线段的y轴坐标,不要重复执行绘图操作。
- Jupyter环境可选择两种渲染方式:一是开启交互式后端魔法命令支持实时动画,二是将动画转成HTML内嵌输出,避免对象被回收;将
frames参数设置为和渐变数组长度一致,保证动画落点正确,补充图例显示。
修复后的完整可运行代码(优先用HTML渲染方式,兼容性最好):
import matplotlib.pyplot as plt import numpy as np from matplotlib.animation import FuncAnimation from IPython.display import HTML # 定义坐标渐变数组 y_left = np.array([9.1, 9.16, 9.22, 9.28, 9.34, 9.4, 9.46, 9.52, 9.58, 9.64, 9.7]) y_right = np.array([8.0, 7.95, 7.9, 7.85, 7.8, 7.75, 7.7, 7.65, 7.6, 7.55, 7.5]) x_coords = [-1.25, 0.75] # 创建画布、绘制固定蓝色线段 fig, ax = plt.subplots() ax.plot(x_coords, [9.1, 8], color='b', label='wrong') # 初始化红色线段,初始位置和蓝色线重合 red_line, = ax.plot(x_coords, [y_left[0], y_right[0]], color='r', label='right') ax.legend() # 动画更新函数:仅修改红色线的y坐标 def animate_1(i): red_line.set_ydata([y_left[i], y_right[i]]) return red_line, # 创建动画,frames匹配数组长度 anim = FuncAnimation(fig=fig, func=animate_1, interval=100, frames=len(y_left), blit=True) # 内嵌HTML渲染动画,无需额外插件 HTML(anim.to_jshtml())
如果需要交互式可缩放的动画窗口,可以在单元格最开头添加魔法命令%matplotlib notebook(新版Jupyter可换成%matplotlib ipympl,需提前安装ipympl库),最后用plt.show()替换HTML渲染代码即可。
内容的提问来源于stack exchange,提问作者Matt Birch
相关产品推荐
相关产品推荐

