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

2024-04-19 23:04:27 发布

您现在位置:Python中文网/ 问答频道 /正文

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

我想使用IPython笔记本和pandas来消耗一个流,并每5秒动态更新一个绘图。

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

然后我做了一个简单的测试:

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循环动态更新绘图。


Tags: 数据绘图dataplotipythonnp绘制动态
3条回答

使用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)

HYRY's answer上有一些改进:

  • clear_output之前调用display,这样当单元格中断时,您将得到一个图,而不是两个图。
  • 捕获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

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

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

相关问题 更多 >