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

use*_*895 77 python matplotlib ipython pandas ipython-notebook

环境: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)
Run Code Online (Sandbox Code Playgroud)

在手动中断进程(ctrl + m + i)之前,输出不会显示任何内容.在我打断它之后,该图正确显示为多个重叠的行.但我真正想要的是一个每5秒显示并更新一次的情节(或者每当plot()函数被调用时,就像我上面提到的print语句输出一样,效果很好).仅在单元格完成后才显示最终图表不是我想要的.

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

HYR*_*YRY 102

使用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)
Run Code Online (Sandbox Code Playgroud)

  • 这不是平滑的选项,图表是从头开始重新创建的,单元格在两者之间上下移动 (4认同)
  • 添加`clear_output(wait = True)`解决了这个问题.请参阅下面的wabu答案. (3认同)
  • 这些天你可以用`%matplotlib nbagg`做得更好,它可以为你提供一个真人形象. (3认同)
  • 这行之有效,但也像打印的度量一样破坏单元格中的其他任何内容。是否真的有办法只是更新情节并保持其他所有内容不变? (3认同)

小智 28

您可以通过添加以下内容wait=True来进一步改进clear_output:

display.clear_output(wait=True)
display.display(pl.gcf())
Run Code Online (Sandbox Code Playgroud)

  • 这很好,但也有清除打印输出的恼人的副作用. (5认同)

Tom*_*ips 25

关于HYRY的答案有几点改进:

  • display之前调用,clear_output以便在单元格中断时最终得到一个图而不是两个图.
  • 捕获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
Run Code Online (Sandbox Code Playgroud)

  • 的确,`display.display(gcf())`应该****之前**`display.clear_output(wait = True)` (4认同)
  • 随着图表更新,我仍然会出现屏幕闪烁的情况,但并非总是如此。有解决方法吗? (4认同)

小智 7

我尝试了很多方法,但我发现这是最简单、最简单的方法 -> 添加clear_output(wait=True),例如,

from IPython.display import clear_output

for i in range(n_iterations):
     clear_output(wait=True)
     x = some value
     y = some value
     plt.plot(x, y, '-r')
     plt.show()
Run Code Online (Sandbox Code Playgroud)

这会覆盖相同的情节,并给出情节动画的错觉