如何用Matplotlib高效实时重绘含100个点的曲线?
优化Matplotlib实时重绘100点曲线的标准实现
你的代码帧率低的核心问题是每次循环都清空坐标轴、重新创建曲线并全局重绘,这会产生大量不必要的开销。Matplotlib中实时更新绘图的标准高效方式是复用已有的曲线对象,只更新数据,再局部重绘,而不是每次从头构建图表。
优化思路
- 提前初始化固定的x轴数据(因为每次都是100个点,x可以固定为0到99)
- 先创建一条空的曲线,获取对应的
Line2D对象 - 循环中仅更新曲线的y值数据
- 使用局部重绘的方式更新画布,避免全局重绘的开销
优化后的代码
import time import matplotlib.pyplot as plt import numpy as np # 初始化画布和坐标轴 fig, ax = plt.subplots() # 固定x轴数据(100个点) x = np.arange(100) # 创建初始曲线,获取Line2D对象 line, = ax.plot(x, np.zeros(100), color='b') # 设置坐标轴范围,避免每次重绘自动调整范围(进一步提速) ax.set_ylim(0, 1) ax.set_xlim(0, 99) # 开启交互模式 plt.ion() fig.show() t0 = time.time() for i in range(10000000): # 生成新的100个点数据 y = np.random.random(100) # 更新曲线的y数据 line.set_ydata(y) # 局部重绘:只重绘坐标轴背景和曲线,比全局重绘快很多 ax.draw_artist(ax.patch) ax.draw_artist(line) # 刷新画布事件 fig.canvas.flush_events() # 输出帧率(减少打印频率避免影响性能) if i % 10 == 0: print(i, i/(time.time()-t0))
关键优化点说明
- 复用Line2D对象:
line, = ax.plot(...)获取曲线对象后,每次只用set_ydata更新数据,避免重复创建曲线元素。 - 固定坐标轴范围:提前设置
ylim和xlim,避免Matplotlib每次重绘时自动计算坐标轴范围,节省计算资源。 - 局部重绘:使用
ax.draw_artist()只重绘必要的部分(坐标轴背景和曲线),替代全局的fig.canvas.draw(),大幅降低重绘开销。 - 交互模式:
plt.ion()开启交互模式,配合fig.canvas.flush_events()处理UI事件,保证绘图实时响应。
这种实现方式能把帧率提升到几十甚至上百FPS,是Matplotlib中处理实时更新绘图的标准高效方案。
内容的提问来源于stack exchange,提问作者Basj
相关产品推荐
相关产品推荐

