matplotlib에서 플롯을 업데이트하는 방법은 무엇입니까?


156

여기 그림을 다시 그리는 데 문제가 있습니다. 사용자가 시간 단위 (x 축)로 단위를 지정한 다음 다시 계산 하고이 함수를 호출 할 수 있습니다 plots(). 그림에 다른 그림을 추가하지 않고 그림을 간단하게 업데이트하고 싶습니다.

def plots():
    global vlgaBuffSorted
    cntr()

    result = collections.defaultdict(list)
    for d in vlgaBuffSorted:
        result[d['event']].append(d)

    result_list = result.values()

    f = Figure()
    graph1 = f.add_subplot(211)
    graph2 = f.add_subplot(212,sharex=graph1)

    for item in result_list:
        tL = []
        vgsL = []
        vdsL = []
        isubL = []
        for dict in item:
            tL.append(dict['time'])
            vgsL.append(dict['vgs'])
            vdsL.append(dict['vds'])
            isubL.append(dict['isub'])
        graph1.plot(tL,vdsL,'bo',label='a')
        graph1.plot(tL,vgsL,'rp',label='b')
        graph2.plot(tL,isubL,'b-',label='c')

    plotCanvas = FigureCanvasTkAgg(f, pltFrame)
    toolbar = NavigationToolbar2TkAgg(plotCanvas, pltFrame)
    toolbar.pack(side=BOTTOM)
    plotCanvas.get_tk_widget().pack(side=TOP)

답변:


178

본질적으로 두 가지 옵션이 있습니다.

  1. 당신은 무슨 일을하는지 정확히 모르지만, 전화 graph1.clear()graph2.clear()데이터를 replotting 전에. 가장 느리지 만 가장 단순하고 강력한 옵션입니다.

  2. 플로팅 대신 플롯 객체의 데이터를 업데이트 할 수 있습니다. 코드를 약간 변경해야하지만 매번 반복하는 것보다 훨씬 빠릅니다. 그러나 플로팅하는 데이터의 모양을 변경할 수 없으며 데이터 범위가 변경되는 경우 x 및 y 축 제한을 수동으로 재설정해야합니다.

두 번째 옵션의 예를 제공하려면

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 6*np.pi, 100)
y = np.sin(x)

# You probably won't need this if you're embedding things in a tkinter plot...
plt.ion()

fig = plt.figure()
ax = fig.add_subplot(111)
line1, = ax.plot(x, y, 'r-') # Returns a tuple of line objects, thus the comma

for phase in np.linspace(0, 10*np.pi, 500):
    line1.set_ydata(np.sin(x + phase))
    fig.canvas.draw()
    fig.canvas.flush_events()

"1"테스트를 시도했습니다. 결과는 데이터를 replotted 한 후 GUI에 다른 플롯 세트가 그려 졌으므로 이제는 이전과 마찬가지로 재 계산 후 4 개의 플롯이있었습니다.
thenickname

@thenickname-코드에서 정확히 어디로 전화 clear합니까? 당신은 호출해야 graph1.clear(); graph2.clear()당신 안에 for당신이 전화를 바로 전에, 루프 graph1.plot(...), graph2.plot(...)등 ...
조 킹톤

for 루프는 graphx.plot (...)을 N 번 호출하고 명확한 문장을 거기에 넣으면 마지막 문장 만 플롯합니다. 실제로 캔버스 코드를 꺼내서 그림 코드와 함께 기본 프로그램 루프에 넣었고 이제 버튼으로 함수를 호출했습니다. 어떤 이유로 방금 함수를 호출하면 플롯이 업데이트되지만 버튼을 누르면 플롯이 업데이트되지 않습니다. 꽤 흥미로운 행동입니다. Tkinter의 버그 여야한다고 생각합니다.
thenickname

직감 ... 전화가 fig.canvas.draw()없거나 plt.draw()각 프레임을 플로팅 한 후? (즉 당신의 순서를해야한다 clear, plot, draw때마다 프레임을 보여주고 싶은) 내가 추측하고있어,하지만 난 그게 정확히 동작이 설명하고 ... 행운을 빕니다, 어떤 속도가 발생할 것 같아!
Joe Kington

3
그것은 2k14이고 나는 이와 같은 것을 달성하기 위해 우연히 발견되었습니다 ... 예상대로 작동하지만 플로팅 창이 "응답하지 않습니다".. 어떤 제안 ??
DevC

39

다음과 같이 수행 할 수도 있습니다. 이렇게하면 for 루프의 50주기 동안 플롯에 10x1 랜덤 매트릭스 데이터가 그려집니다.

import matplotlib.pyplot as plt
import numpy as np

plt.ion()
for i in range(50):
    y = np.random.random([10,1])
    plt.plot(y)
    plt.draw()
    plt.pause(0.0001)
    plt.clf()

이것은 그래프를 출력하지 않는 것 같습니다. 뭔가 빠졌습니까? 나는이 %matplotlib inline뿐만 아니라 Jupyter 노트북에.
MasayoMusic

하하, 내가 제거했을 때 나를 위해 일했다 plt.clf(). 오 matplotlib, 당신은
rascal

15

이것은 나를 위해 일했습니다. 매번 그래프를 업데이트하는 함수를 반복해서 호출합니다.

import matplotlib.pyplot as plt
import matplotlib.animation as anim

def plot_cont(fun, xmax):
    y = []
    fig = plt.figure()
    ax = fig.add_subplot(1,1,1)

    def update(i):
        yi = fun()
        y.append(yi)
        x = range(len(y))
        ax.clear()
        ax.plot(x, y)
        print i, ': ', yi

    a = anim.FuncAnimation(fig, update, frames=xmax, repeat=False)
    plt.show()

"fun"은 정수를 반환하는 함수입니다. FuncAnimation은 반복적으로 "update"를 호출하고, "xmax"번 수행합니다.


fun () 함수의 모양뿐만 아니라이 함수를 호출하는 방법 (특히 함수 호출에서 함수를 전달하는 방법)에 대한 예를들 수 있습니까?
bjornasm

1
확실한. "fun ()"은 정수를 반환하는 함수입니다. "plot_cont (my_function, 123)"와 같이 다른 함수에 인수로 함수를 전달할 수 있습니다. 86 번 줄에서 plot_cont으로 전화하십시오 : github.com/vitobasso/audio-ml/blob/…
Vituel

1
"a ="가 필요하거나 FuncAnimation이 가비지 수집되고 코드가 작동하지 않습니다!
Kiuhnm

8

내가 찾고있는 것을 찾는 사람 이이 기사를 발견하면 예제를 찾았습니다.

Matplotlib로 스칼라 2D 데이터를 시각화하는 방법은 무엇입니까?

http://mri.brechmos.org/2009/07/automatically-update-a-figure-in-a-loop(web.archive.org)

그런 다음 즉시 등고선을 생성하고 사용하는 대신 입력 프레임 스택과 함께 imshow를 사용하도록 수정했습니다.


이라고하는 모양의 이미지 (nBins, nBins, nBins)의 3D 배열로 시작 frames합니다.

def animate_frames(frames):
    nBins   = frames.shape[0]
    frame   = frames[0]
    tempCS1 = plt.imshow(frame, cmap=plt.cm.gray)
    for k in range(nBins):
        frame   = frames[k]
        tempCS1 = plt.imshow(frame, cmap=plt.cm.gray)
        del tempCS1
        fig.canvas.draw()
        #time.sleep(1e-2) #unnecessary, but useful
        fig.clf()

fig = plt.figure()
ax  = fig.add_subplot(111)

win = fig.canvas.manager.window
fig.canvas.manager.window.after(100, animate_frames, frames)

또한 강력하지는 않지만이 전체 프로세스를 수행하는 훨씬 간단한 방법을 찾았습니다.

fig = plt.figure()

for k in range(nBins):
    plt.clf()
    plt.imshow(frames[k],cmap=plt.cm.gray)
    fig.canvas.draw()
    time.sleep(1e-6) #unnecessary, but useful

이 두 가지 모두 ipython --pylab=tk일명 일명 작동합니다.backend = TkAgg

모든 도움을 주셔서 감사합니다.


6

python-drawnow 라는 패키지를 출시했습니다.이 패키지는 Matlab과 비슷한 for 루프 내에서 호출되는 그림 업데이트 기능을 제공합니다 drawnow.

사용법 예 :

from pylab import figure, plot, ion, linspace, arange, sin, pi
def draw_fig():
    # can be arbitrarily complex; just to draw a figure
    #figure() # don't call!
    plot(t, x)
    #show() # don't call!

N = 1e3
figure() # call here instead!
ion()    # enable interactivity
t = linspace(0, 2*pi, num=N)
for i in arange(100):
    x = sin(2 * pi * i**2 * t / 100.0)
    drawnow(draw_fig)

이 패키지는 모든 matplotlib 그림과 함께 작동하며 각 그림이 업데이트되거나 디버거로 떨어질 때까지 기다리는 옵션을 제공합니다.


2
동시에 견고하고 불안정합니까?
BlueMoon93

2
나는 "모든 matplotlib 그림과 함께 작동"에서와 같이 강력하고 "주말 프로젝트"에서와 같이 불안정 함을 의미했습니다. 내 답변을 업데이트했습니다
Scott

3

위의 모든 내용이 사실 일 수도 있지만 필자의 경우 "온라인 업데이트"는 일부 백엔드에서만 작동합니다 wx. 예를 들어 ipython / pylab을 ipython --pylab=wx! 행운을 빕니다!


1
귀하의 메시지에 감사드립니다. 대화 형 모드는 사용한 기본 백엔드와 작동하지 않았기 때문에 절대 사용하지 않았습니다. 그래프를보고 싶을 때마다 실행을 중지하는 것보다 대화식 모드를 사용하는 것이 훨씬 좋습니다!
PierreE

1
내 경우에는 다른 답변이 도움이되지 않았습니다. 나는 pycharm을 사용하고 있으며 문제는 콘솔의 음모와 상호 작용에 관한 것입니다. 대화 형을 켜려면 From pylab import *를 추가 한 다음 코드 본문에 ion ()을 추가해야했습니다. 그것은 나를 위해 지금 원활하게 작동합니다.
shelbypereira

2

이것은 나를 위해 일했다 :

from matplotlib import pyplot as plt
from IPython.display import clear_output
import numpy as np
for i in range(50):
    clear_output(wait=True)
    y = np.random.random([10,1])
    plt.plot(y)
    plt.show()
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.