Jupyter / iPython에서 플롯을 동적으로 업데이트하는 현재 올바른 방법은 무엇입니까?


93

ipython notebook (하나의 셀 내)의 루프에서 플롯을 동적으로 업데이트하는 방법에 대한 답변에서 Python 루프 내에서 Jupyter 노트북 내부의 플롯을 동적으로 업데이트하는 방법에 대한 예제가 제공됩니다. 그러나 이것은 매 반복마다 플롯을 파괴하고 다시 생성하는 방식으로 작동하며 스레드 중 하나의 주석은 %matplotlib nbagg노트북에 포함 된 대화 형 그림을 제공하는 새로운 마법 을 사용하여이 상황을 개선 할 수 있다고 언급합니다. 정적 이미지보다.

그러나이 멋진 새 nbagg기능은 내가 말할 수있는 한 완전히 문서화되지 않은 것처럼 보이며이를 사용하여 플롯을 동적으로 업데이트하는 방법에 대한 예를 찾을 수 없습니다. 따라서 내 질문은 nbagg 백엔드를 사용하여 Jupyter / Python 노트북의 기존 플롯을 어떻게 효율적으로 업데이트합니까? matplotlib에서 플롯을 동적으로 업데이트하는 것은 일반적으로 까다로운 문제이므로 간단한 작업 예제가 큰 도움이 될 것입니다. 주제에 대한 문서에 대한 포인터도 매우 유용합니다.

내가 원하는 것은 몇 번의 반복에 대해 시뮬레이션 코드를 실행 한 다음 현재 상태의 플롯을 그린 다음 몇 번 더 반복하여 실행 한 다음 반영하도록 플롯을 업데이트하는 것입니다. 현재 상태 등. 따라서 아이디어는 플롯을 그린 다음 사용자의 상호 작용없이 전체를 파괴하고 다시 생성하지 않고 플롯의 데이터를 업데이트하는 것입니다.

다음은 위의 링크 된 질문에 대한 답변에서 약간 수정 된 코드로, 매번 전체 그림을 다시 그려이를 달성합니다. 동일한 결과를 얻고 싶지만 nbagg.

%matplotlib inline
import time
import pylab as pl
from IPython import display
for i in range(10):
    pl.clf()
    pl.plot(pl.randn(100))
    display.display(pl.gcf())
    display.clear_output(wait=True)
    time.sleep(1.0)

답변:


62

다음은 루프에서 플롯을 업데이트하는 예입니다. 그림의 데이터를 업데이트하고 매번 전체 그림을 다시 그리지 않습니다. 제한된 시뮬레이션 세트를 실행하고 결과를 어딘가에 저장하는 데 관심이 있다면 실행을 차단하지만 문제가되지 않을 수 있습니다.

%matplotlib notebook

import numpy as np
import matplotlib.pyplot as plt
import time

def pltsin(ax, colors=['b']):
    x = np.linspace(0,1,100)
    if ax.lines:
        for line in ax.lines:
            line.set_xdata(x)
            y = np.random.random(size=(100,1))
            line.set_ydata(y)
    else:
        for color in colors:
            y = np.random.random(size=(100,1))
            ax.plot(x, y, color)
    fig.canvas.draw()

fig,ax = plt.subplots(1,1)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_xlim(0,1)
ax.set_ylim(0,1)
for f in range(5):
    pltsin(ax, ['b', 'r'])
    time.sleep(1)

나는 이것을 nbviewer에 올려 놓았습니다.

의 IPython 위젯 버전 nbagg즉,하기 matplotlib 저장소에서 진행중인 작업은 현재됩니다 . 사용 가능한 경우를 사용하는 가장 좋은 방법 일 것입니다 nbagg.

편집 : 여러 플롯을 표시하도록 업데이트 됨


1
좋습니다. 잘 작동하는 것 같습니다. 실행 중 상호 작용이 없다는 것은 저에게 큰 문제가 아닙니다. 약간 이상한 점이 하나 있습니다. while True:를 for 루프로 변경하면 루프가 끝날 때 대화 형 nbagg가 아닌 마지막 플롯의 두 정적 이미지를 얻습니다. 그 이유를 아십니까?
나다니엘

while을 for 루프로 변경하고 tmpnb.org에서 시도했지만 두 번째 이미지가 표시되지 않거나 상호 작용이 손실되지 않습니다. 어둠 속에서 촬영했지만 함수에 루프를 사용하는 대신 함수 호출 주위로 루프를 이동해 볼 수 있습니다. f 범위 (10) : pltsin (ax) time.sleep (1)
pneumatics

3
@pneumatics 불행히도 Retina 디스플레이의 Matplotlib 2.0에는 몇 가지 문제가 있습니다. 루프에서 플롯은 일반적으로 두 배 더 작습니다.
Alexander Rodin

1
그림에 올바르게 크기를 조정할 시간이 주어지지 않은 것 같습니다. 그래서 저는 plt.show()for 루프를 다음 셀로 이동시킬 때 훨씬 더 나은 경험 을했습니다.
ImportanceOfBeingErnest

2
당신이 당신의 줄거리와 같은 jupyter 노트북 셀의 %의하기 matplotlib 노트북을 가지고 수 - 내가 가져 오기 문에서도 함께 첫 번째 셀 %의하기 matplotlib 노트북을했기 때문에 나는이 문제를 해결 2시간 오늘 지출 한
aguazul

14

나는 jupyter-lab을 사용하고 있으며 이것은 나를 위해 작동합니다 (귀하의 경우에 적용하십시오).

from IPython.display import clear_output
from matplotlib import pyplot as plt
import collections
%matplotlib inline

def live_plot(data_dict, figsize=(7,5), title=''):
    clear_output(wait=True)
    plt.figure(figsize=figsize)
    for label,data in data_dict.items():
        plt.plot(data, label=label)
    plt.title(title)
    plt.grid(True)
    plt.xlabel('epoch')
    plt.legend(loc='center left') # the plot evolves to the right
    plt.show();

그런 다음 루프에서 사전을 채우고 다음으로 전달합니다 live_plot().

data = collections.defaultdict(list)
for i in range(100):
    data['foo'].append(np.random.random())
    data['bar'].append(np.random.random())
    data['baz'].append(np.random.random())
    live_plot(data)

플롯 아래에 몇 개의 셀이 있는지 확인하십시오. 그렇지 않으면 플롯을 다시 그릴 때마다 뷰가 제자리에 고정됩니다.


1
이 새로운 플롯마다보다는 기존의 음모를 업데이트 생성
공압

2
옳은. jupyter-lab에서 동적 플롯을 갖는 더 좋은 방법을 찾지 못했습니다.
Ziofil

1
반복 사이에 대기하는 시간을 설정하는 방법이 있습니까? 단지 'wait = True'를 갖는 것보다
Ahmad Moussa

1
플롯을 다시 그릴 때마다 그래프가 깜박입니다. 이 문제를 해결할 방법이 있습니까? 플롯 아래에 빈 셀이 몇 개 있지만 도움이되지 않는 것 같습니다.
MasayoMusic

@MasayoMusic은 buildmedia.readthedocs.org/media/pdf/ipywidgets/latest/에서 "깜빡이는 출력물"을 참조하십시오.
leo

0

@Ziofil 대답을 수정하고 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.