如何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()返回当前数字的参考)。