Matplotlib循环迭代时图形仅前30次更新后续停止问题求助
问题解决方法
根本原因
迭代后期图形停止更新的核心原因是每次调用update方法时都重复创建plot、imshow绘图对象,迭代次数增加后axes上的绘图实例不断叠加,渲染资源被占满导致重绘卡住。调试模式下运行速度慢、资源释放更及时,因此不会触发该问题。
修改要点
- 初始化阶段提前创建折线、热力图的绘图实例,后续迭代仅更新实例数据,不重复新建绘图对象
- 移除
update方法中重复调用的fig.show(),该方法仅需在窗口初始化时调用一次 - 改用
fig.canvas.draw_idle()刷新画布,配合单次plt.pause即可完成重绘 - 如遇PyCharm SciView内联绘图兼容问题,可手动指定Matplotlib使用独立窗口后端
修改后完整代码
import numpy as np import matplotlib.pyplot as plt # 可选:取消下面注释指定独立窗口后端,解决PyCharm内联绘图兼容问题 # plt.switch_backend('TkAgg') class SimpOutput: fig = None ax_l = None ax_r = None line = None im = None it_container = [] obj_container = [] def __init__(self): self.fig, (self.ax_l, self.ax_r) = plt.subplots(nrows=1, ncols=2, figsize=(8, 4)) self.ax_l.set_title("Flexibility $c$") self.ax_l.set_ylabel("obj. value $c$") self.ax_l.set_xlabel("Iteration") # 初始化折线对象,后续仅更新数据 self.line, = self.ax_l.plot([], [], c="r") self.ax_r.set_title("Shape") # 初始化热力图对象,后续仅更新数据 self.im = self.ax_r.imshow(np.zeros((4,4)), cmap="binary") self.fig.show() def update(self, iteration, obj, x): self.it_container.append(iteration) self.obj_container.append(obj) # 更新折线数据,自动调整坐标轴范围保证新数据可见 self.line.set_data(self.it_container, self.obj_container) self.ax_l.relim() self.ax_l.autoscale_view() x = x.reshape((4, 4)) x = x.T x = np.flip(x, 0) # 更新热力图数据 self.im.set_array(x) # 刷新画布 self.fig.canvas.draw_idle() plt.pause(0.1) if __name__ == "__main__": out = SimpOutput() for i in range(50): out.update(i, 1000 * np.random.rand(), np.random.rand(16))
内容的提问来源于stack exchange,提问作者Klixz
相关产品推荐
相关产品推荐

