matplotlib 在Python/iPython中动态更新图的当前正确方法是什么?

j2qf4p5b  于 2023-10-24  发布在  Python
关注(0)|答案(5)|浏览(124)

在对how to dynamically update a plot in a loop in ipython notebook (within one cell)的回答中,给出了一个如何在Python循环中动态更新Python笔记本中的图表的例子。然而,这是通过在每次迭代中销毁和重新创建图表来实现的,其中一个线程中的评论指出,这种情况可以通过使用新的%matplotlib nbagg魔术来改善,它提供了一个嵌入笔记本中的交互式图形,而不是静态图像。
然而,这个奇妙的新nbagg功能似乎完全没有文档记录,我无法找到如何使用它来动态更新绘图的示例。因此我的问题是,**如何使用nbagg后端有效地更新Python/Python Notebook中的现有绘图?**由于在matplotlib中动态更新图通常是一个棘手的问题,一个简单的工作示例将是一个巨大的帮助。指向任何相关文档的指针也将非常有帮助。
先说清楚我的要求:我想做的是运行一些模拟代码几次迭代,然后绘制其当前状态的图,然后再运行几次迭代,然后更新图以反映当前状态,等等。所以想法是绘制一个图,然后,没有用户的任何交互,更新图中的数据,而不破坏和重新创建整个东西。
下面是从上面链接的问题的答案中稍微修改的代码,它通过每次重新绘制整个图来实现这一点。我想实现相同的结果,但使用nbagg更有效。

  1. %matplotlib inline
  2. import time
  3. import pylab as pl
  4. from IPython import display
  5. for i in range(10):
  6. pl.clf()
  7. pl.plot(pl.randn(100))
  8. display.display(pl.gcf())
  9. display.clear_output(wait=True)
  10. time.sleep(1.0)
t40tm48m

t40tm48m1#

这里有一个循环更新图的例子。它更新图中的数据,而不是每次都重新绘制整个图。它确实会阻止执行,但如果你有兴趣运行一组有限的模拟并将结果保存在某个地方,这对你来说可能不是问题。
%matplotlib widget魔术需要ipympl Matplotlib扩展包。

  1. %matplotlib widget
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. import time
  5. def pltsin(ax, colors=['b']):
  6. x = np.linspace(0,1,100)
  7. if ax.lines:
  8. for line in ax.lines:
  9. line.set_xdata(x)
  10. y = np.random.random(size=(100,1))
  11. line.set_ydata(y)
  12. else:
  13. for color in colors:
  14. y = np.random.random(size=(100,1))
  15. ax.plot(x, y, color)
  16. fig.canvas.draw()
  17. fig,ax = plt.subplots(1,1)
  18. ax.set_xlabel('X')
  19. ax.set_ylabel('Y')
  20. ax.set_xlim(0,1)
  21. ax.set_ylim(0,1)
  22. plt.show()
  23. # run this cell to dynamically update plot
  24. for f in range(5):
  25. pltsin(ax, ['b', 'r'])
  26. time.sleep(1)

我把这个up on nbviewer here,这里是a direct link to the gist

展开查看全部
jgzswidk

jgzswidk2#

我正在使用jupyter-lab,这对我很有效(根据您的情况进行调整):

  1. from IPython.display import clear_output
  2. from matplotlib import pyplot as plt
  3. import numpy as np
  4. import collections
  5. %matplotlib inline
  6. def live_plot(data_dict, figsize=(7,5), title=''):
  7. clear_output(wait=True)
  8. plt.figure(figsize=figsize)
  9. for label,data in data_dict.items():
  10. plt.plot(data, label=label)
  11. plt.title(title)
  12. plt.grid(True)
  13. plt.xlabel('epoch')
  14. plt.legend(loc='center left') # the plot evolves to the right
  15. plt.show();

然后在一个循环中填充一个字典,并将其传递给live_plot()

  1. data = collections.defaultdict(list)
  2. for i in range(100):
  3. data['foo'].append(np.random.random())
  4. data['bar'].append(np.random.random())
  5. data['baz'].append(np.random.random())
  6. live_plot(data)

请确保在图的下方有几个单元格,否则每次重绘图时视图都会捕捉到位。

展开查看全部
jtjikinw

jtjikinw3#

如果你不想清除所有的输出,你可以使用display_id=True来获取一个句柄,然后在上面使用.update()

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. import time
  4. from IPython import display
  5. def pltsin(ax, *,hdisplay, colors=['b']):
  6. x = np.linspace(0,1,100)
  7. if ax.lines:
  8. for line in ax.lines:
  9. line.set_xdata(x)
  10. y = np.random.random(size=(100,1))
  11. line.set_ydata(y)
  12. else:
  13. for color in colors:
  14. y = np.random.random(size=(100,1))
  15. ax.plot(x, y, color)
  16. hdisplay.update(fig)
  17. fig,ax = plt.subplots(1,1)
  18. hdisplay = display.display("", display_id=True)
  19. ax.set_xlabel('X')
  20. ax.set_ylabel('Y')
  21. ax.set_xlim(0,1)
  22. ax.set_ylim(0,1)
  23. for f in range(5):
  24. pltsin(ax, colors=['b', 'r'], hdisplay=hdisplay)
  25. time.sleep(1)
  26. plt.close(fig)

(改编自@ martematics)

展开查看全部
0aydgbwb

0aydgbwb4#

我已经调整了@Ziofil的答案,并将其修改为接受x,y作为列表,并在同一图上输出散点图和线性趋势。

  1. from IPython.display import clear_output
  2. from matplotlib import pyplot as plt
  3. %matplotlib inline
  4. def live_plot(x, y, figsize=(7,5), title=''):
  5. clear_output(wait=True)
  6. plt.figure(figsize=figsize)
  7. plt.xlim(0, training_steps)
  8. plt.ylim(0, 100)
  9. x= [float(i) for i in x]
  10. y= [float(i) for i in y]
  11. if len(x) > 1:
  12. plt.scatter(x,y, label='axis y', color='k')
  13. m, b = np.polyfit(x, y, 1)
  14. plt.plot(x, [x * m for x in x] + b)
  15. plt.title(title)
  16. plt.grid(True)
  17. plt.xlabel('axis x')
  18. plt.ylabel('axis y')
  19. plt.show();

你只需要在一个循环中调用live_plot(x, y).它是这样的:x1c 0d1x

展开查看全部
lh80um4z

lh80um4z5#

图中的canvas.draw方法动态更新其图形,对于当前图:

  1. from matplotlib import pyplot as plt
  2. plt.gcf().canvas.draw()

相关问题