how to dynamically update a plot in a loop in ipython notebook (within one cell)
环境:Python 2.7,matplotlib 1.3,IPython笔记本1.1,linux,chrome。代码在一个输入单元格中,使用
我想使用IPython笔记本和pandas来消耗流并每5秒动态更新一次。
当我只使用print语句以文本格式打印数据时,它完全正常:输出单元格只保留打印数据并添加新行。但是当我尝试绘制数据(然后在循环中更新它)时,绘图永远不会出现在输出单元格中。但如果我删除循环,只需绘制一次。它工作正常。
然后我做了一些简单的测试:
1 2 3 4 5 | i = pd.date_range('2013-1-1',periods=100,freq='s') while True: plot(pd.Series(data=np.random.randn(100), index=i)) #pd.Series(data=np.random.randn(100), index=i).plot() also tried this one time.sleep(5) |
在手动中断进程(ctrl + m + i)之前,输出不会显示任何内容。在我打断它之后,该图正确地显示为多个重叠的行。但我真正想要的是一个每5秒显示并更新一次的情节(或者每当调用
我甚至尝试在每个
使用
1 2 3 4 5 6 7 8 9 | %matplotlib inline import time import pylab as pl from IPython import display for i in range(10): pl.plot(pl.randn(100)) display.clear_output(wait=True) display.display(pl.gcf()) time.sleep(1.0) |
您可以通过将
1 2 | display.clear_output(wait=True) display.display(pl.gcf()) |
关于HYRY的答案有几点改进:
-
在
clear_output 之前调用display ,以便在单元格中断时最终得到一个图,而不是两个图。 -
捕获
KeyboardInterrupt ,以便单元格输出不会跟踪回溯。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import matplotlib.pylab as plt import pandas as pd import numpy as np import time from IPython import display %matplotlib inline i = pd.date_range('2013-1-1',periods=100,freq='s') while True: try: plt.plot(pd.Series(data=np.random.randn(100), index=i)) display.display(plt.gcf()) display.clear_output(wait=True) time.sleep(1) except KeyboardInterrupt: break |
尝试在
将标签添加到此处发布的其他解决方案将继续在每个循环中添加新标签。 要解决这个问题,请使用
1 2 3 4 5 6 7 8 9 | for t in range(100) if t % refresh_rate == 0: plt.clf() plt.plot(history['val_loss'], 'r-', lw=2, label='val') plt.plot(history['training_loss'], 'b-', lw=1, label='training') plt.legend() display.clear_output(wait=True) display.display(plt.gcf()) |