मैटप्लोटलिब में प्लॉट कैसे अपडेट करें?


156

मैं यहाँ आंकड़ा redrawing के साथ मुद्दों कर रहा हूँ। मैं उपयोगकर्ता को समय स्केल (एक्स-अक्ष) में इकाइयों को निर्दिष्ट करने की अनुमति देता हूं और फिर मैं इस फ़ंक्शन को पुनर्गणना और कॉल करता हूं 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()डेटा को दोहराने से पहले। यह सबसे धीमा, लेकिन सबसे सरल और सबसे मजबूत विकल्प है।

  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." परीक्षण की कोशिश की और परिणाम यह था कि, जब मैंने डेटा को दोहराया तो प्लॉट का एक और सेट मेरे जीयूआई में खींचा गया था, इसलिए अब मेरे पास पहले की तरह ही पुनर्गणना के बाद 4 प्लॉट थे।
तत्पश्चात

@thenickname - आपके कोड में वास्तव में आप कहां कॉल कर रहे हैं clear? आप graph1.clear(); graph2.clear()अपने forलूप के अंदर बुला रहे हैं , इससे पहले कि आप फोन करें graph1.plot(...), graph2.plot(...)आदि ...
जोई किंग्स्टन

लूप के लिए यह कॉल्स graphx.plot (...) N बार बनाता है और इसमें स्पष्ट कथनों को डालकर केवल अंतिम प्लॉट करता है। मैंने वास्तव में कैनवास कोड निकाला है और इसे फिगर कोड के साथ मुख्य प्रोग्राम लूप में डाल दिया है और मेरे पास अब एक बटन द्वारा अपने फ़ंक्शन को बुलाया जा रहा है। किसी कारणवश अगर मैं फंक्शन को कॉल करता हूं तो प्लॉट अपडेट हो जाते हैं, लेकिन अगर मैं बटन दबाता हूं तो प्लॉट्स नहीं आते हैं। यह काफी दिलचस्प व्यवहार है। मुझे लगता है कि Tkinter में एक बग होना चाहिए।
तत्पश्चात

बस एक कूबड़ ... क्या आप एक कॉल याद कर रहे हैं fig.canvas.draw()या plt.draw()प्रत्येक फ्रेम की साजिश रचने के बाद? (अर्थात, आप का एक अनुक्रम होना चाहिए clear, plot, drawहर बार जब आप एक फ्रेम दिखाना चाहते हैं) मेरा अनुमान है कि है, लेकिन मुझे लगता है कि वास्तव में व्यवहार आप का वर्णन कर रहे हैं ... गुड लक, किसी भी दर पर कारण होगा!
जो किंग्सटन

3
यह 2k14 है और मैं इस तरह से कुछ हासिल करने के लिए लड़खड़ा गया ... यह उम्मीद के मुताबिक काम करता है लेकिन प्लॉटिंग विंडो "मेरे जवाब नहीं" दे रही है .. मेरे सुझाव ??
DevC

39

आप निम्न की तरह भी कर सकते हैं: यह लूप के लिए 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जुपिटर नोटबुक भी है।
MasayoMusic

जब मैंने हटाया तो हाहा, मेरे लिए काम कर गया plt.clf()। ओह matplotlib,
यू रस्कल

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

"मज़ा" एक फ़ंक्शन है जो पूर्णांक देता है। FuncAnimation बार-बार "अपडेट" को कॉल करेगा, यह उस "xmax" बार करेगा।


क्या आप इस बात का उदाहरण दे सकते हैं कि आप इस फ़ंक्शन को कैसे कहते हैं (विशेषकर आप किसी फ़ंक्शन कॉल में फ़ंक्शन कैसे पास करते हैं) और साथ ही मज़ा () फ़ंक्शन कैसा दिखता है?
ब्योर्नमैस

1
ज़रूर। "मज़ा ()" कोई भी फ़ंक्शन है जो पूर्णांक देता है। आप फ़ंक्शन को इस तरह से एक तर्क के रूप में पारित कर सकते हैं: "प्लॉट_ कॉंट (my_function, 123)"। वहाँ आप मुझे 86 पर लाइन में कॉल कर रहे हैं प्लॉट_कंट: github.com/vitobasso/audio-ml/blob/…
Vituel

1
ध्यान दें कि "a =" आवश्यक है या FuncAnimation कचरा एकत्र किया जाएगा और कोड काम नहीं करेगा!
किहुंम

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

मैंने एक पैकेज जारी किया है जिसे पायथन-ड्रॉवन कहा जाता है जो एक आंकड़ा अद्यतन करने के लिए कार्यक्षमता प्रदान करता है, जिसे आमतौर पर मैटलैब के समान लूप के भीतर कहा जाता है 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 आंकड़ा के साथ काम करता है" और "सप्ताहांत परियोजना" के रूप में अस्थिर के रूप में मजबूत था। मैंने अपना उत्तर
स्कॉट

3

उपरोक्त सभी सही हो सकते हैं, हालांकि मेरे लिए आंकड़ों का "ऑनलाइन-अपडेटिंग" केवल कुछ बैकएंड के साथ काम करता है, विशेष रूप से wx। आप बस इसे बदलने की कोशिश कर सकते हैं, जैसे कि ipython / pylab द्वारा शुरू करके ipython --pylab=wx! सौभाग्य!


1
आपके संदेश के लिए धन्यवाद, मैंने कभी भी इंटरएक्टिव मोड का उपयोग नहीं किया क्योंकि मैंने कभी भी डिफ़ॉल्ट बैकएंड के साथ काम नहीं किया। जब आप किसी ग्राफ़ को देखना चाहते हैं, तो निष्पादन को रोकने की तुलना में यह इंटरैक्टिव मोड का उपयोग करने के लिए बहुत अच्छा है!
पियरे

1
अन्य किसी भी उत्तर ने मेरे मामले में मदद नहीं की। मैं pycharm का उपयोग कर रहा हूँ और समस्या कंसोल की साजिश रचने और अन्तरक्रियाशीलता के साथ थी। मुझे कोड बॉडी में पाइलैब इंपोर्ट * और फिर आयन () से इंटरेक्टिव ऑन करने की जरूरत थी। यह मेरे लिए अब आसानी से काम करता है।
शेल्बीपेरेरा

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()
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.