如何dynamic更新ipython笔记本中的一个循环(在一个单元格内)

环境:Python 2.7,matplotlib 1.3,IPython笔记本1.1,linux,chrome。 代码位于一个单独的input单元格中,使用--pylab=inline

我想使用IPython笔记本和pandas来消耗一个stream,并dynamic更新每5秒的情节。

当我使用print语句以文本格式打印数据时,它工作得很好:输出单元只是保持打印数据和添加新行。 但是,当我试图绘制数据(然后在一个循环中更新它),该图不会显示在输出单元格中。 但是,如果我删除循环,只需绘制一次。 它工作正常。

然后我做了一些简单的testing:

 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秒显示并更新一次(或每当plot()函数被调用,就像我上面提到的print语句输出一样,这很好)。 只在细胞完成后显示最终的图表是不是我想要的。

我甚至试图在每个plot()之后明确添加draw()函数,等等。 不知道如何通过IPython笔记本中的一个单元格内的for / while循环来dynamic更新图表。

使用IPython.display模块:

 %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) 

您可以通过将wait=True添加到clear_output来进一步改进:

 display.clear_output(wait=True) display.display(pl.gcf()) 

对HYRY的回答有一些改进:

  • clear_output之后调用display ,这样当单元格被中断时,最终得到一个graphics,而不是两个graphics。
  • 赶上KeyboardInterrupt ,使单元格输出不跟踪回溯。
 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 

尝试在plot()函数之后添加show()gcf().show() 。 这些将强制当前数字更新(gcf()返回当前数字的参考)。