如何清除Jupyter中显示Matplotlib动画后残留的绘图?
我帮你分析下这个问题,你遇到的残留绘图本质是因为每次运行代码时,之前创建的Matplotlib图形对象没有被彻底清理,新的图形会和旧的叠加显示在单元格里,尤其是强制用%matplotlib inline后端时,这个问题会更明显。结合你的环境(Anaconda Python 3.6.4、Jupyter 5.4.0),给你几个实用的解决方案:
方法1:每次运行前清理所有图形资源
最简单直接的办法就是在代码开头加上plt.close('all'),它会关闭所有已存在的Matplotlib图形窗口/对象,确保每次运行都是从零开始创建新的动画:
import numpy as np import matplotlib.pyplot as plt import matplotlib.animation as animation # 关键:清理所有旧图形,避免残留 plt.close('all') fig, ax = plt.subplots() line, = ax.plot(np.random.rand(10)) ax.set_ylim(0, 1) def update(data): line.set_ydata(data) return line, def data_gen(): while True: yield np.random.rand(10) ani = animation.FuncAnimation(fig, update, data_gen, interval=100); from IPython.display import HTML HTML(ani.to_jshtml())
方法2:合理管理Matplotlib后端,避免强制用inline
你提到的%matplotlib魔法命令默认值是%matplotlib auto,它会根据当前环境自动选择最合适的后端——在Jupyter Notebook里默认是交互式的notebook后端,这个后端的动画展示更友好,也不容易出现残留问题。
如果之前手动加了%matplotlib inline,可以把它删掉,换成%matplotlib notebook(如果需要交互式操作),或者直接用默认的auto。配合方法1的清理操作,就能彻底解决重复运行的残留问题。
方法3:清除单元格输出后再显示动画
另外,你也可以用IPython的clear_output函数,在每次运行代码前清空当前单元格的所有输出,再渲染新的动画:
import numpy as np import matplotlib.pyplot as plt import matplotlib.animation as animation from IPython.display import HTML, clear_output # 清空当前单元格之前的输出 clear_output(wait=True) fig, ax = plt.subplots() line, = ax.plot(np.random.rand(10)) ax.set_ylim(0, 1) def update(data): line.set_ydata(data) return line, def data_gen(): while True: yield np.random.rand(10) ani = animation.FuncAnimation(fig, update, data_gen, interval=100); HTML(ani.to_jshtml())
补充说明
为什么会出现这个问题?因为Jupyter的inline后端会把每次运行生成的图形都静态嵌入到单元格输出里,重复运行时旧的图形不会自动消失,就会出现左下角的残留。而清理图形对象或者清空输出,都是从根源上避免旧资源干扰新的动画渲染。
内容的提问来源于stack exchange,提问作者Fallen Apart

