[python] Ipython 노트북의 루프에서 플롯을 동적으로 업데이트하는 방법 (한 셀 내에서)

환경 : Python 2.7, matplotlib 1.3, IPython 노트북 1.1, linux, chrome. 코드는 하나의 단일 입력 셀에 있습니다.--pylab=inline

IPython 노트북과 팬더를 사용하여 스트림을 소비하고 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 문 출력과 마찬가지로 함수가 호출 될 때마다 잘 작동 함). 셀이 완전히 완료된 후에 만 ​​최종 차트를 보여주는 것은 내가 원하는 것이 아닙니다.

나는 각각의 뒤에 draw () 함수를 명시 적으로 추가하려고 시도했다 plot(). 그들 중 어느 것도 작동하지 않는다. IPython 노트북의 한 셀 내에서 for / while 루프를 통해 플롯을 동적으로 업데이트하는 방법이 궁금합니다.



답변

사용 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의 답변 :

  • 요구 displayclear_output셀이 중단 될 때 두 개가 아닌 하나의 플롯으로 끝나도록 before를 .
  • 를 잡아서 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


답변

함수 를 추가 show()하거나 gcf().show()뒤에 시도하십시오 plot(). 이렇게하면 현재 Figure가 업데이트됩니다 (gcf ()는 현재 Figure에 대한 참조를 반환합니다).


답변

여기에 게시 된 다른 솔루션에 레이블을 추가하면 모든 루프에서 새 레이블이 계속 추가됩니다. 이를 처리하려면 다음을 사용하여 플롯을 지 웁니다.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())


답변

이렇게 할 수 있습니다. 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();

live_plot(x, y)루프 내부 에서 호출 하면됩니다. 어떻게 보이는지 :
여기에 이미지 설명 입력


답변