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


93

환경 : 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 루프를 통해 플롯을 동적으로 업데이트하는 방법이 궁금합니다.

답변:


122

사용 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)

4
이 플롯은 세포 사이에 아래로 가서 처음부터 다시하고, 옵션을 부드럽게하지 않습니다
denfromufa

3
추가하면 clear_output(wait=True)이 문제가 해결됩니다. 아래 wabu의 답변을 참조하십시오.
ahwillia 2014 년

3
요즘에는 더 잘할 수 있으므로 함께 %matplotlib nbagg놀 수있는 생생한 모습을 볼 수 있습니다.
타카 스웰

@tcaswell 나는 이것을 nbagg달성하기 위해 어떻게 사용하는지 묻는 새로운 질문을 추가했습니다 . (답변에 관심이있는 경우 핑을합니다.) stackoverflow.com/questions/34486642/…
나다니엘

3
이것은 작동하지만 인쇄 된 측정 값과 같은 셀의 다른 모든 것을 파괴합니다. 플롯을 업데이트하고 다른 모든 것을 제자리에 유지하는 방법이 있습니까?
KIC

31

다음을 추가하여 더 개선 할 수 있습니다. wait=True 하여clear_output .

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

1
+1. 이건 매우 중요합니다. 이 정보로 HYRY의 답변을 업데이트해야한다고 생각합니다.
ahwillia 2014 년

5
이것은 좋지만 인쇄 출력을 지우는 성가신 부작용도 있습니다.
피터

31

몇 가지 개선 사항이 있습니다. 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

7
실제로, 전에display.display(gcf()) 가야합니다 display.clear_output(wait=True)
herrlich10

감사합니다, @csta. 추가했습니다.
Tom Phillips

@ herrlich10 왜 display전에 호출해야 clear_output합니까? 먼저 출력을 지운 다음 새 데이터를 표시해야하지 않습니까?
Jakub Arnold

1
그래프 업데이트로 여전히 화면 깜박임이 발생하지만 항상 그런 것은 아닙니다. 이에 대한 해결 방법이 있습니까?
MasayoMusic

2

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


2
감사. gcf (). show ()도 작동합니다. 같은 그림에 쇼 물건에 HYRY에 의해 제안 clear_output ()를 추가 할 필요가
user3236895

"display.display (pl.gcf ())"에 추가됩니까?
MasayoMusic

2

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


4
감사 plt.clf()합니다. 그러나 어쨌든 업데이트에서 깜박임을 제거하는 방법이 있습니까?
MasayoMusic

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();

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.