环境: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循环动态更新绘图。
答案 0 :(得分:94)
使用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)
答案 1 :(得分:26)
您可以通过将wait=True
添加到clear_output
:
display.clear_output(wait=True)
display.display(pl.gcf())
答案 2 :(得分:24)
HYRY's answer上的一些改进:
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
答案 3 :(得分:4)
我尝试了很多方法,但我发现这是最简单和最简单的方法->例如添加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()
这会覆盖同一个情节,并给人一种情节动画的错觉
答案 4 :(得分:2)
尝试在show()
功能后添加gcf().show()
或plot()
。这些将强制更新当前数字(gcf()返回当前数字的引用)。
答案 5 :(得分:0)
在此处发布的其他解决方案中添加标签将在每个循环中继续添加新标签。为了解决这个问题,请使用clf
for t in range(100)
if t % refresh_rate == 0:
plt.clf()
plt.plot(history['val_loss'], 'r-', lw=2, label='val')
plt.plot(history['training_loss'], 'b-', lw=1, label='training')
plt.legend()
display.clear_output(wait=True)
display.display(plt.gcf())
答案 6 :(得分:0)
您可以这样做。它接受x,y作为列表,并在同一图上输出散点图和线性趋势。
from IPython.display import clear_output
from matplotlib import pyplot as plt
%matplotlib inline
def live_plot(x, y, figsize=(7,5), title=''):
clear_output(wait=True)
plt.figure(figsize=figsize)
plt.xlim(0, training_steps)
plt.ylim(0, 100)
x= [float(i) for i in x]
y= [float(i) for i in y]
if len(x) > 1:
plt.scatter(x,y, label='axis y', color='k')
m, b = np.polyfit(x, y, 1)
plt.plot(x, [x * m for x in x] + b)
plt.title(title)
plt.grid(True)
plt.xlabel('axis x')
plt.ylabel('axis y')
plt.show();