如何创建绘图简易动画?解决Jupyter绘图刷新闪烁问题
解决Jupyter Notebook绘图刷新闪烁问题的优化方案
核心优化思路
复用同一个绘图对象,在循环中仅更新数据而不重建整个绘图,彻底避免clear_output()带来的单元格刷新和滚动问题。
优化后的代码
import numpy as np import matplotlib.pyplot as plt L = 100 x_positions = np.linspace(0, L, 1001) # 仅初始化一次绘图对象 plt.ion() # 开启交互模式 fig, ax = plt.subplots() # 创建初始散点图,保留对象用于后续更新 scatter = ax.scatter([], []) # 提前固定坐标轴范围,避免自动缩放导致的画面跳动 ax.set_xlim(0, 1) # 根据你的mass数据范围调整,示例值为1 ax.set_ylim(0, L) ax.set_xlabel('Mass') ax.set_ylabel('X Position') for t in range(1, 100): mass = np.zeros(1001) # 改用numpy数组运算替代列表推导,提升效率 for n in range(-5, 5): mass += np.exp(-(x_positions + 2 * n * L) ** 2 / (4 * t)) # 仅更新散点数据,不重建整个绘图 scatter.set_offsets(np.column_stack((mass, x_positions))) # 刷新画布内容 fig.canvas.draw() fig.canvas.flush_events() plt.pause(0.1) plt.ioff() # 关闭交互模式 plt.show()
关键优化点说明
- 复用绘图对象:提前创建
fig和ax,循环中只更新散点数据,避免每次创建新图触发的单元格刷新。 - 使用
set_offsets()更新数据:针对散点图,直接修改已有散点对象的坐标数据,是效率最高的更新方式。 - 固定坐标轴范围:提前设置
xlim和ylim,避免每次绘图自动缩放导致的画面跳动。 - numpy数组运算替代列表推导:原代码的列表推导可直接用numpy数组运算,大幅提升计算速度。
更规范的动画方案(可选)
如果需要更稳定流畅的动画效果,可以使用matplotlib.animation模块的FuncAnimation,这是Jupyter中制作动画的标准方式:
import numpy as np import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation L = 100 x_positions = np.linspace(0, L, 1001) fig, ax = plt.subplots() ax.set_xlim(0, 1) ax.set_ylim(0, L) ax.set_xlabel('Mass') ax.set_ylabel('X Position') scatter = ax.scatter([], []) def update(frame): t = frame + 1 # frame从0开始,对应t的取值1到99 mass = np.zeros(1001) for n in range(-5, 5): mass += np.exp(-(x_positions + 2 * n * L) ** 2 / (4 * t)) scatter.set_offsets(np.column_stack((mass, x_positions))) return scatter, # 创建动画:frames为循环次数,interval为帧间隔(毫秒),blit=True提升渲染效率 ani = FuncAnimation(fig, update, frames=99, interval=100, blit=True) plt.show()
这种方式无需手动处理循环和刷新逻辑,动画稳定性更强,还支持导出为视频文件。
内容的提问来源于stack exchange,提问作者SorenJ
相关产品推荐
相关产品推荐

