কীভাবে ম্যাটপ্লোটিলেব প্লট আপডেট করবেন?


156

এখানে চিত্রটি পুনরায় আঁকানো নিয়ে আমার সমস্যা হচ্ছে। আমি ব্যবহারকারীকে সময় স্কেলে ইউনিটগুলি নির্দিষ্ট করার অনুমতি দিই (এক্স-অক্ষ) এবং তারপরে আমি পুনরায় গণনা করে এই ফাংশনটি কল করি 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()

আমি "১" পরীক্ষা করার চেষ্টা করেছি এবং ফলাফলটি হয়েছিল, আমি তথ্যটি প্রত্যাখ্যান করার পরে আমার জিইউআইতে আরও একটি প্লট আঁকা হয়েছিল, সুতরাং এখন আমার আগের মতো পুনর্ব্যবহারের পরে 4 টি প্লট ছিল।
তারপরে

@ অন্য নাম - আপনার কোডটিতে আপনি ঠিক কোথায় ফোন করছেন clear? আপনি কলিং হবে graph1.clear(); graph2.clear()আপনার ভিতরে forলুপ, ঠিক করার আগে আপনাকে কল graph1.plot(...), graph2.plot(...)ইত্যাদি ...
জো Kington

লুপের জন্য কলগুলি গ্রাফিক্স.প্লাট (...) এন বার তৈরি করে এবং পরিষ্কার বিবৃতি সেখানে রেখে কেবল শেষটিকে প্লট করে। আমি আসলে ক্যানভাস কোডটি টেনে এনে ফিগার কোডের সাথে মূল প্রোগ্রাম লুপে রেখে দিয়েছি এবং এখন আমার বোতামটি আমার বোতামটির দ্বারা ডাকা হচ্ছে। কিছু কারণে যদি আমি কেবল ফাংশনটি কল করি প্লটগুলি আপডেট হয়ে যায়, তবে আমি বোতামটি টিপলে প্লটগুলি না করে। এটি বেশ আকর্ষণীয় আচরণ। আমি মনে করি এটি টিন্টেটারে অবশ্যই একটি বাগ থাকতে হবে।
তারপরে

কেবল একটি কুঁচকী ... আপনি কি কোনও কল মিস করছেন fig.canvas.draw()বা plt.draw()প্রতিটি ফ্রেম প্লট করার পরে? (অর্থাত আপনি একটি ক্রম থাকতে হবে clear, plot, drawপ্রতিটি সময় আপনি একটি ফ্রেম দেখাতে চান) আমি অনুমান করছি, কিন্তু আমি মনে করি যে ঠিক আচরণ আপনি বর্ণনা করছি ... গুড লাক, কোন হারে কারণ হবে!
জো কিংটন

3
এটি 2 কে 14 এবং আমি এরকম কিছু অর্জন করতে হোঁচট খেয়েছি ... এটি প্রত্যাশার মতো কাজ করে তবে প্লটিং উইন্ডোটি "প্রতিক্রিয়া জানায় না" পরিণত হচ্ছে .. কোনও পরামর্শ ??
ডিভিসি

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জুপিটার নোটবুকও আছে ।
মাসায়ো মিউজিক

হাহা, আমি যখন সরিয়েছিলাম তখন আমার জন্য কাজ করেছিল 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
অবশ্যই। "মজা ()" এমন কোনও ফাংশন যা কোনও পূর্ণসংখ্যা ফেরত দেয়। আপনি অন্যটির মতো যুক্তি হিসাবে ফাংশনটি পাস করতে পারেন: "প্লট_কন্ট (আমার_ফানশন, 123)"। সেখানে আপনি আমাকে ৮৮ নং লাইনে প্লট_কন্ট কল করছেন: github.com/vitobasso/audio-ml/blob/…
ভিটুইল

1
নোট করুন যে "a =" প্রয়োজনীয় বা FuncAnimation আবর্জনা সংগ্রহ করা হবে এবং কোড কাজ করবে না!
কিউনম

8

এই নিবন্ধটি জুড়ে যদি কেউ আসে তবে আমি যা খুঁজছিলাম তার সন্ধান করতে আমি উদাহরণ পেয়েছি

কীভাবে ম্যাটপ্লোটিলেব দিয়ে স্কেলার 2 ডি ডেটা ভিজ্যুয়ালাইজ করবেন?

এবং

http://mri.brechmos.org/2009/07/automatic-update-a-figure-in-a-loop (ওয়েব.আরচাইভ.আরগে)

তারপরে ফ্লাইয়ের কনট্যুরগুলি উত্পন্ন এবং ব্যবহারের পরিবর্তে ফ্রেমের ইনপুট স্ট্যাকের সাথে ইমশো ব্যবহারের জন্য তাদের পরিবর্তন করে।


আকৃতির চিত্রগুলির একটি 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)

এই প্যাকেজটি যে কোনও ম্যাটপ্ল্লিটব চিত্রের সাথে কাজ করে এবং প্রতিটি চিত্র আপডেট হওয়ার পরে অপেক্ষা করতে বা ডিবাগারে নেমে যাওয়ার বিকল্প সরবরাহ করে।


2
একই সাথে এটি কীভাবে দৃust় এবং অস্থির?
ব্লুমুন93

2
আমি দৃ any়তার সাথে বোঝাতে চাইছি "কোনও ম্যাটপ্ল্লোব ফিগারের সাথে কাজ করে" এবং "উইকএন্ড প্রজেক্ট" এর মতো অস্থির। আমি আমার উত্তর আপডেট করেছি
স্কট

3

উপরের সমস্ত সত্য হতে পারে, তবে আমার জন্য পরিসংখ্যানগুলির "অনলাইন-আপডেটিং" কেবলমাত্র কিছু ব্যাকেন্ডের সাথে বিশেষভাবে কাজ করে wx। আপনি কেবল এটির জন্য পরিবর্তনের চেষ্টা করতে পারেন, উদাহরণস্বরূপ আইপিথন / পাইলাব দ্বারা শুরু করে ipython --pylab=wx! শুভকামনা!


1
আপনার বার্তার জন্য আপনাকে ধন্যবাদ, আমি কখনই ইন্টারেক্টিভ মোড ব্যবহার করিনি কারণ এটি আমার ব্যবহৃত ডিফল্ট ব্যাকএন্ডের সাথে কখনও কাজ করে না। আপনি যখনই কোনও গ্রাফ দেখতে চান প্রতিবার কার্যকর করা বন্ধ করার চেয়ে ইন্টারেক্টিভ মোডটি ব্যবহার করা অনেক সুন্দর!
পিয়েরি

1
অন্য কোনও উত্তর আমার ক্ষেত্রে সহায়তা করেনি helped আমি পাইচার্ম ব্যবহার করছি এবং কনসোলের প্লট করা এবং ইন্টার্যাকটিভিটি নিয়ে সমস্যা ছিল। ইন্টারেক্টিভ চালু করতে কোড বডিতে আমাকে পাইলব আমদানি * এবং তারপরে আয়ন () যুক্ত করতে হবে। এটি এখন আমার জন্য সুচারুভাবে কাজ করে।
শেলবিপিরের

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.