首页 文章

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

提问于
浏览
61

环境: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() 函数时,就像我上面提到的打印语句输出一样,效果很好) . 仅在单元格完成后才显示最终图表不是我想要的 .

我甚至尝试在每个 plot() 之后显式添加draw()函数,等等 . 它们都不起作用 . 想知道如何通过IPython笔记本中一个单元格内的for / while循环动态更新绘图 .

4 回答

  • 88

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

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

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

    关于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
    
  • 21

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

相关问题