আমি কীভাবে ম্যাটপ্ল্লোব ব্যবহার করে কিছুক্ষণ লুপে রিয়েল-টাইমে প্লট করব?


233

আমি ওপেনসিভি ব্যবহার করে রিয়েল টাইমে ক্যামেরা থেকে কিছু ডেটা প্লট করার চেষ্টা করছি। তবে, রিয়েল-টাইম প্লট করা (ম্যাটপ্ল্লোব ব্যবহার করে) কাজ করছে বলে মনে হচ্ছে না।

আমি এই সাধারণ উদাহরণটিতে সমস্যাটি বিচ্ছিন্ন করেছি:

fig = plt.figure()
plt.axis([0, 1000, 0, 1])

i = 0
x = list()
y = list()

while i < 1000:
    temp_y = np.random.random()
    x.append(i)
    y.append(temp_y)
    plt.scatter(i, temp_y)
    i += 1
    plt.show()

আমি এই উদাহরণটি পৃথকভাবে 1000 পয়েন্ট প্লট করার আশা করব। আসলে যা ঘটে তা হ'ল উইন্ডোটি প্রথম পয়েন্ট দেখানোর সাথে পপ আপ করে (ঠিক আছে এর সাথে), তারপরে লুপটি শেষ হওয়ার জন্য অপেক্ষা করে এটি গ্রাফের বাকি অংশগুলিকে পপুলেট করার আগে।

কোনও চিন্তা কেন আমি একবারে পপুলিটি দেখছি না?

উত্তর:


312

এখানে প্রশ্নে থাকা কোডটির কার্যকারী সংস্করণ এখানে রয়েছে (২০১১-১১-১৪ থেকে কমপক্ষে সংস্করণ ম্যাটপ্লটলিব ১.১.০ প্রয়োজন):

import numpy as np
import matplotlib.pyplot as plt

plt.axis([0, 10, 0, 1])

for i in range(10):
    y = np.random.random()
    plt.scatter(i, y)
    plt.pause(0.05)

plt.show()

কিছু পরিবর্তন লক্ষ্য করুন:

  1. plt.pause(0.05)উভয়কেই নতুন ডেটা আঁকার জন্য কল করুন এবং এটি জিইউআইয়ের ইভেন্ট লুপটি চালায় (মাউস ইন্টারঅ্যাকশনের অনুমতি দেয়)।

3
পাইথন 2 এ এটি আমার জন্য কাজ করেছিল। পাইথন 3 এ এটি হয়নি। প্লটের উইন্ডোটি রেন্ডার করার পরে এটি লুপটি বিরতি দেয়। তবে plt.show () পদ্ধতিটি লুপের পরে নিয়ে যাওয়ার পরে ... এটি পাইথন 3 এর জন্য সমাধান করেছে, আমার জন্য।
ধারাবাহিকতা

1
অদ্ভুত, পাইথন 3 (ভার্স 3.4.0) ম্যাটপ্ল্লোলিব (ভের 1.3.1) নম্পি (ভের 1.8.1) উবুন্টু লিনাক্স 3.13.0 64-বিট
ভেলিমির ম্লেকার

37
plt.show () এবং plt.draw () এর পরিবর্তে plt.draw () এর পরিবর্তে plt.pause (0.1)
denfromufa

4
উইন 64 / অ্যানাকোন্ডা ম্যাটপ্ল্লিটব .__ সংস্করণ__ 1.5.0 এ কাজ করেনি। প্রাথমিক চিত্রের উইন্ডোটি খোলা হয়েছে, তবে কিছুই প্রদর্শন করা হয়নি, এটি বন্ধ না করা পর্যন্ত এটি অবরুদ্ধ অবস্থায় থেকে গেছে
isti_spl

5
এই উত্তরের জন্য এক্স / ওয়াই ডেটার পূর্ব-পূর্ব জ্ঞান প্রয়োজন ... যা প্রয়োজন নেই: আমি পছন্দ করি ১. কল না করে plt.axis()তার পরিবর্তে দুটি তালিকা x এবং y এবং plt.plot(x,y)2 কল করুন আপনার লুপে, নতুন ডেটা মানগুলিকে যুক্ত করুন দুটি তালিকা 3. কল করুনplt.gca().lines[0].set_xdata(x); plt.gca().lines[0].set_ydata(y); plt.gca().relim(); plt.gca().autoscale_view(); plt.pause(0.05);
ট্রেভর বয়ড স্মিথ

76

আপনি যদি রিয়েলটাইম প্লট করতে আগ্রহী হন, আমি ম্যাটপ্ল্লোলিবের অ্যানিমেশন এপিআই সন্ধান করার পরামর্শ দেব । বিশেষত, blitপ্রতিটি ফ্রেমের পটভূমি পুনরায় আঁকতে এড়ানোর জন্য আপনাকে যথেষ্ট গতি লাভ (10 ডলার) দিতে পারে:

#!/usr/bin/env python

import numpy as np
import time
import matplotlib
matplotlib.use('GTKAgg')
from matplotlib import pyplot as plt


def randomwalk(dims=(256, 256), n=20, sigma=5, alpha=0.95, seed=1):
    """ A simple random walk with memory """

    r, c = dims
    gen = np.random.RandomState(seed)
    pos = gen.rand(2, n) * ((r,), (c,))
    old_delta = gen.randn(2, n) * sigma

    while True:
        delta = (1. - alpha) * gen.randn(2, n) * sigma + alpha * old_delta
        pos += delta
        for ii in xrange(n):
            if not (0. <= pos[0, ii] < r):
                pos[0, ii] = abs(pos[0, ii] % r)
            if not (0. <= pos[1, ii] < c):
                pos[1, ii] = abs(pos[1, ii] % c)
        old_delta = delta
        yield pos


def run(niter=1000, doblit=True):
    """
    Display the simulation using matplotlib, optionally using blit for speed
    """

    fig, ax = plt.subplots(1, 1)
    ax.set_aspect('equal')
    ax.set_xlim(0, 255)
    ax.set_ylim(0, 255)
    ax.hold(True)
    rw = randomwalk()
    x, y = rw.next()

    plt.show(False)
    plt.draw()

    if doblit:
        # cache the background
        background = fig.canvas.copy_from_bbox(ax.bbox)

    points = ax.plot(x, y, 'o')[0]
    tic = time.time()

    for ii in xrange(niter):

        # update the xy data
        x, y = rw.next()
        points.set_data(x, y)

        if doblit:
            # restore background
            fig.canvas.restore_region(background)

            # redraw just the points
            ax.draw_artist(points)

            # fill in the axes rectangle
            fig.canvas.blit(ax.bbox)

        else:
            # redraw everything
            fig.canvas.draw()

    plt.close(fig)
    print "Blit = %s, average FPS: %.2f" % (
        str(doblit), niter / (time.time() - tic))

if __name__ == '__main__':
    run(doblit=False)
    run(doblit=True)

আউটপুট:

Blit = False, average FPS: 54.37
Blit = True, average FPS: 438.27

1
@ বেজোটা মূল সংস্করণটি ইন্টারেক্টিভ ম্যাটপ্ল্লিটিব সেশনের মধ্যে কাজ করার জন্য তৈরি করা হয়েছিল। এটা একটি স্বতন্ত্র স্ক্রিপ্ট হিসেবে কাজ করতে, এটা 1 প্রয়োজনীয়) স্পষ্টভাবে matplotlib জন্য একটি ব্যাক নির্বাচন করুন, এবং 2) জোর করে ব্যবহার অ্যানিমেশন লুপ প্রবেশের আগে চিত্রে প্রদর্শিত ও আকৃষ্ট হবে plt.show()এবং plt.draw()। আমি উপরের কোডে এই পরিবর্তনগুলি যুক্ত করেছি।
ali_m

2
অভিপ্রায়টির উদ্দেশ্য / অনুপ্রেরণা blit()কি "রিয়েল-টাইম প্লটিংয়ের উন্নতি" বলে মনে হচ্ছে? আপনার যদি ম্যাটপ্ল্লোব বিকাশকারী / ব্লগ থাকে তবে কেন / উদ্দেশ্য / অভিপ্রায় / অনুপ্রেরণা নিয়ে আলোচনা করে যা দুর্দান্ত। (মনে হচ্ছে এই নতুন ব্লিট অপারেশনটি ম্যাটপ্লটলিবকে কেবল অফলাইনে বা অতি ধীরে ধীরে ডেটা পরিবর্তনের জন্য ব্যবহার থেকে রূপান্তরিত করবে এখন আপনি খুব দ্রুত আপডেটিং ডেটা দিয়ে ম্যাটপ্ল্লোলিব ব্যবহার করতে পারবেন ... প্রায় একটি অসিস্কলকের মতো)।
ট্রেভর বয়েড স্মিথ

1
আমি দেখতে পেয়েছি যে এই পদ্ধতির ফলে প্লট উইন্ডোটি প্রতিক্রিয়াহীন করে তুলেছে: আমি এটির সাথে ইন্টারঅ্যাক্ট করতে পারি না এবং এটি করা এটি ক্র্যাশ হতে পারে।
নিনজাকাননন

1
"Gtk পাওয়া যায় না" ইস্যু পেতে তাদের পক্ষে এটি আলাদা ব্যাক-এন্ডে ভাল কাজ করে (আমি 'TKAgg' ব্যবহার করেছি)। সমর্থিত সমর্থিত সন্ধানের জন্য
জেমস নেলসন

1
এই উত্তরের লিঙ্কটি আর কাজ করবে বলে মনে হচ্ছে না। এটি একটি আপ-টু-ডেট লিঙ্ক হতে পারে: scipy-cookbook.readthedocs.io/items/…
awelkie

35

আমি জানি এই প্রশ্নের উত্তর দিতে আমি কিছুটা দেরি করছি। তবুও, আমি লাইভ গ্রাফগুলি প্লট করতে কিছুক্ষণ আগে কিছু কোড তৈরি করেছি, যা আমি ভাগ করে নিতে চাই:

পাইকিউটি 4 এর জন্য কোড:

###################################################################
#                                                                 #
#                    PLOT A LIVE GRAPH (PyQt4)                    #
#                  -----------------------------                  #
#            EMBED A MATPLOTLIB ANIMATION INSIDE YOUR             #
#            OWN GUI!                                             #
#                                                                 #
###################################################################


import sys
import os
from PyQt4 import QtGui
from PyQt4 import QtCore
import functools
import numpy as np
import random as rd
import matplotlib
matplotlib.use("Qt4Agg")
from matplotlib.figure import Figure
from matplotlib.animation import TimedAnimation
from matplotlib.lines import Line2D
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
import time
import threading


def setCustomSize(x, width, height):
    sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
    sizePolicy.setHorizontalStretch(0)
    sizePolicy.setVerticalStretch(0)
    sizePolicy.setHeightForWidth(x.sizePolicy().hasHeightForWidth())
    x.setSizePolicy(sizePolicy)
    x.setMinimumSize(QtCore.QSize(width, height))
    x.setMaximumSize(QtCore.QSize(width, height))

''''''

class CustomMainWindow(QtGui.QMainWindow):

    def __init__(self):

        super(CustomMainWindow, self).__init__()

        # Define the geometry of the main window
        self.setGeometry(300, 300, 800, 400)
        self.setWindowTitle("my first window")

        # Create FRAME_A
        self.FRAME_A = QtGui.QFrame(self)
        self.FRAME_A.setStyleSheet("QWidget { background-color: %s }" % QtGui.QColor(210,210,235,255).name())
        self.LAYOUT_A = QtGui.QGridLayout()
        self.FRAME_A.setLayout(self.LAYOUT_A)
        self.setCentralWidget(self.FRAME_A)

        # Place the zoom button
        self.zoomBtn = QtGui.QPushButton(text = 'zoom')
        setCustomSize(self.zoomBtn, 100, 50)
        self.zoomBtn.clicked.connect(self.zoomBtnAction)
        self.LAYOUT_A.addWidget(self.zoomBtn, *(0,0))

        # Place the matplotlib figure
        self.myFig = CustomFigCanvas()
        self.LAYOUT_A.addWidget(self.myFig, *(0,1))

        # Add the callbackfunc to ..
        myDataLoop = threading.Thread(name = 'myDataLoop', target = dataSendLoop, daemon = True, args = (self.addData_callbackFunc,))
        myDataLoop.start()

        self.show()

    ''''''


    def zoomBtnAction(self):
        print("zoom in")
        self.myFig.zoomIn(5)

    ''''''

    def addData_callbackFunc(self, value):
        # print("Add data: " + str(value))
        self.myFig.addData(value)



''' End Class '''


class CustomFigCanvas(FigureCanvas, TimedAnimation):

    def __init__(self):

        self.addedData = []
        print(matplotlib.__version__)

        # The data
        self.xlim = 200
        self.n = np.linspace(0, self.xlim - 1, self.xlim)
        a = []
        b = []
        a.append(2.0)
        a.append(4.0)
        a.append(2.0)
        b.append(4.0)
        b.append(3.0)
        b.append(4.0)
        self.y = (self.n * 0.0) + 50

        # The window
        self.fig = Figure(figsize=(5,5), dpi=100)
        self.ax1 = self.fig.add_subplot(111)


        # self.ax1 settings
        self.ax1.set_xlabel('time')
        self.ax1.set_ylabel('raw data')
        self.line1 = Line2D([], [], color='blue')
        self.line1_tail = Line2D([], [], color='red', linewidth=2)
        self.line1_head = Line2D([], [], color='red', marker='o', markeredgecolor='r')
        self.ax1.add_line(self.line1)
        self.ax1.add_line(self.line1_tail)
        self.ax1.add_line(self.line1_head)
        self.ax1.set_xlim(0, self.xlim - 1)
        self.ax1.set_ylim(0, 100)


        FigureCanvas.__init__(self, self.fig)
        TimedAnimation.__init__(self, self.fig, interval = 50, blit = True)

    def new_frame_seq(self):
        return iter(range(self.n.size))

    def _init_draw(self):
        lines = [self.line1, self.line1_tail, self.line1_head]
        for l in lines:
            l.set_data([], [])

    def addData(self, value):
        self.addedData.append(value)

    def zoomIn(self, value):
        bottom = self.ax1.get_ylim()[0]
        top = self.ax1.get_ylim()[1]
        bottom += value
        top -= value
        self.ax1.set_ylim(bottom,top)
        self.draw()


    def _step(self, *args):
        # Extends the _step() method for the TimedAnimation class.
        try:
            TimedAnimation._step(self, *args)
        except Exception as e:
            self.abc += 1
            print(str(self.abc))
            TimedAnimation._stop(self)
            pass

    def _draw_frame(self, framedata):
        margin = 2
        while(len(self.addedData) > 0):
            self.y = np.roll(self.y, -1)
            self.y[-1] = self.addedData[0]
            del(self.addedData[0])


        self.line1.set_data(self.n[ 0 : self.n.size - margin ], self.y[ 0 : self.n.size - margin ])
        self.line1_tail.set_data(np.append(self.n[-10:-1 - margin], self.n[-1 - margin]), np.append(self.y[-10:-1 - margin], self.y[-1 - margin]))
        self.line1_head.set_data(self.n[-1 - margin], self.y[-1 - margin])
        self._drawn_artists = [self.line1, self.line1_tail, self.line1_head]

''' End Class '''

# You need to setup a signal slot mechanism, to 
# send data to your GUI in a thread-safe way.
# Believe me, if you don't do this right, things
# go very very wrong..
class Communicate(QtCore.QObject):
    data_signal = QtCore.pyqtSignal(float)

''' End Class '''


def dataSendLoop(addData_callbackFunc):
    # Setup the signal-slot mechanism.
    mySrc = Communicate()
    mySrc.data_signal.connect(addData_callbackFunc)

    # Simulate some data
    n = np.linspace(0, 499, 500)
    y = 50 + 25*(np.sin(n / 8.3)) + 10*(np.sin(n / 7.5)) - 5*(np.sin(n / 1.5))
    i = 0

    while(True):
        if(i > 499):
            i = 0
        time.sleep(0.1)
        mySrc.data_signal.emit(y[i]) # <- Here you emit a signal!
        i += 1
    ###
###


if __name__== '__main__':
    app = QtGui.QApplication(sys.argv)
    QtGui.QApplication.setStyle(QtGui.QStyleFactory.create('Plastique'))
    myGUI = CustomMainWindow()
    sys.exit(app.exec_())

''''''

 
আমি সম্প্রতি পাইকিউটি 5 এর জন্য কোডটি আবার লিখেছি।
পাইকিউটি 5 এর জন্য কোড:

###################################################################
#                                                                 #
#                    PLOT A LIVE GRAPH (PyQt5)                    #
#                  -----------------------------                  #
#            EMBED A MATPLOTLIB ANIMATION INSIDE YOUR             #
#            OWN GUI!                                             #
#                                                                 #
###################################################################

import sys
import os
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import functools
import numpy as np
import random as rd
import matplotlib
matplotlib.use("Qt5Agg")
from matplotlib.figure import Figure
from matplotlib.animation import TimedAnimation
from matplotlib.lines import Line2D
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import time
import threading

class CustomMainWindow(QMainWindow):
    def __init__(self):
        super(CustomMainWindow, self).__init__()
        # Define the geometry of the main window
        self.setGeometry(300, 300, 800, 400)
        self.setWindowTitle("my first window")
        # Create FRAME_A
        self.FRAME_A = QFrame(self)
        self.FRAME_A.setStyleSheet("QWidget { background-color: %s }" % QColor(210,210,235,255).name())
        self.LAYOUT_A = QGridLayout()
        self.FRAME_A.setLayout(self.LAYOUT_A)
        self.setCentralWidget(self.FRAME_A)
        # Place the zoom button
        self.zoomBtn = QPushButton(text = 'zoom')
        self.zoomBtn.setFixedSize(100, 50)
        self.zoomBtn.clicked.connect(self.zoomBtnAction)
        self.LAYOUT_A.addWidget(self.zoomBtn, *(0,0))
        # Place the matplotlib figure
        self.myFig = CustomFigCanvas()
        self.LAYOUT_A.addWidget(self.myFig, *(0,1))
        # Add the callbackfunc to ..
        myDataLoop = threading.Thread(name = 'myDataLoop', target = dataSendLoop, daemon = True, args = (self.addData_callbackFunc,))
        myDataLoop.start()
        self.show()
        return

    def zoomBtnAction(self):
        print("zoom in")
        self.myFig.zoomIn(5)
        return

    def addData_callbackFunc(self, value):
        # print("Add data: " + str(value))
        self.myFig.addData(value)
        return

''' End Class '''


class CustomFigCanvas(FigureCanvas, TimedAnimation):
    def __init__(self):
        self.addedData = []
        print(matplotlib.__version__)
        # The data
        self.xlim = 200
        self.n = np.linspace(0, self.xlim - 1, self.xlim)
        a = []
        b = []
        a.append(2.0)
        a.append(4.0)
        a.append(2.0)
        b.append(4.0)
        b.append(3.0)
        b.append(4.0)
        self.y = (self.n * 0.0) + 50
        # The window
        self.fig = Figure(figsize=(5,5), dpi=100)
        self.ax1 = self.fig.add_subplot(111)
        # self.ax1 settings
        self.ax1.set_xlabel('time')
        self.ax1.set_ylabel('raw data')
        self.line1 = Line2D([], [], color='blue')
        self.line1_tail = Line2D([], [], color='red', linewidth=2)
        self.line1_head = Line2D([], [], color='red', marker='o', markeredgecolor='r')
        self.ax1.add_line(self.line1)
        self.ax1.add_line(self.line1_tail)
        self.ax1.add_line(self.line1_head)
        self.ax1.set_xlim(0, self.xlim - 1)
        self.ax1.set_ylim(0, 100)
        FigureCanvas.__init__(self, self.fig)
        TimedAnimation.__init__(self, self.fig, interval = 50, blit = True)
        return

    def new_frame_seq(self):
        return iter(range(self.n.size))

    def _init_draw(self):
        lines = [self.line1, self.line1_tail, self.line1_head]
        for l in lines:
            l.set_data([], [])
        return

    def addData(self, value):
        self.addedData.append(value)
        return

    def zoomIn(self, value):
        bottom = self.ax1.get_ylim()[0]
        top = self.ax1.get_ylim()[1]
        bottom += value
        top -= value
        self.ax1.set_ylim(bottom,top)
        self.draw()
        return

    def _step(self, *args):
        # Extends the _step() method for the TimedAnimation class.
        try:
            TimedAnimation._step(self, *args)
        except Exception as e:
            self.abc += 1
            print(str(self.abc))
            TimedAnimation._stop(self)
            pass
        return

    def _draw_frame(self, framedata):
        margin = 2
        while(len(self.addedData) > 0):
            self.y = np.roll(self.y, -1)
            self.y[-1] = self.addedData[0]
            del(self.addedData[0])

        self.line1.set_data(self.n[ 0 : self.n.size - margin ], self.y[ 0 : self.n.size - margin ])
        self.line1_tail.set_data(np.append(self.n[-10:-1 - margin], self.n[-1 - margin]), np.append(self.y[-10:-1 - margin], self.y[-1 - margin]))
        self.line1_head.set_data(self.n[-1 - margin], self.y[-1 - margin])
        self._drawn_artists = [self.line1, self.line1_tail, self.line1_head]
        return

''' End Class '''


# You need to setup a signal slot mechanism, to
# send data to your GUI in a thread-safe way.
# Believe me, if you don't do this right, things
# go very very wrong..
class Communicate(QObject):
    data_signal = pyqtSignal(float)

''' End Class '''



def dataSendLoop(addData_callbackFunc):
    # Setup the signal-slot mechanism.
    mySrc = Communicate()
    mySrc.data_signal.connect(addData_callbackFunc)

    # Simulate some data
    n = np.linspace(0, 499, 500)
    y = 50 + 25*(np.sin(n / 8.3)) + 10*(np.sin(n / 7.5)) - 5*(np.sin(n / 1.5))
    i = 0

    while(True):
        if(i > 499):
            i = 0
        time.sleep(0.1)
        mySrc.data_signal.emit(y[i]) # <- Here you emit a signal!
        i += 1
    ###
###

if __name__== '__main__':
    app = QApplication(sys.argv)
    QApplication.setStyle(QStyleFactory.create('Plastique'))
    myGUI = CustomMainWindow()
    sys.exit(app.exec_())

এটি চেষ্টা করে দেখুন। একটি নতুন অজগর-ফাইলটিতে এই কোডটি অনুলিপি করুন এবং এটি চালান। আপনার একটি সুন্দর, সাবলীলভাবে চলমান গ্রাফ পাওয়া উচিত:

এখানে চিত্র বর্ণনা লিখুন


আমি লক্ষ্য করেছি যে dataSendLoopআপনি উইন্ডোটি বন্ধ করার সময় থ্রেডটি পটভূমিতে চলতে থাকবে। সুতরাং আমি daemon = Trueসমস্যাটি সমাধান করার জন্য কীওয়ার্ডটি যুক্ত করেছি ।
কে.মুলিয়ার

1
এর জন্য ভার্চুয়াল পরিবেশটি কিছুটা সময় নিয়েছিল। অবশেষে, conda install pyqt=4কৌশলটি।
রেব কেবিন

1
বেসিক কোডের জন্য অনেক ধন্যবাদ। এটি আপনার কোডের উপর ভিত্তি করে চারপাশে বৈশিষ্ট্যগুলি সংশোধন করে এবং কিছু সাধারণ ইউআই তৈরি করতে আমাকে সহায়তা করেছিল। এটি আমার সময় বাঁচিয়েছে =]
আইজাক সিম

হাই @ আইস্যাকসিম, আপনার সদয় বার্তার জন্য আপনাকে অনেক ধন্যবাদ। আমি খুশি এই কোডটি সহায়ক ছিল :-)
কে.মুলিয়ার

সুতরাং আমি এই স্ক্রিপ্টটি নিয়েছি এবং একটি এনপি.অ্যান্ডারি টাইপ ব্যবহার করার জন্য সিগন্যাল স্লট প্রক্রিয়াটি সংশোধন করে এবং আপেক্ষিক টাইমস্ট্যাম্প এবং সিগন্যালের এনপি.আর্রে নির্গত করে এক্স-অক্ষের সাথে টাইমস্ট্যাম্প যুক্ত করেছি। আমি প্রতিটি ফ্রেমের অঙ্কনে xlim () আপডেট করছি যা নতুন অক্ষের সাহায্যে সিগন্যাল প্রদর্শনের জন্য জরিমানা করে তবে আমি উইন্ডোর আকার পরিবর্তন করলে এক্স-লেবেল / টিকগুলি কেবল সংক্ষেপে আপডেট হয় না। @ কে.মুলিয়ার আমি মূলত ডেটা স্লাইডিং অস্টিক অক্ষের পরে যাচ্ছি এবং ভাবছিলাম যে এরকম কিছুতে আপনার কোনও সাফল্য আছে?
নিমিগ 18

33

showসম্ভবত এটির জন্য সেরা পছন্দ নয়। আমি কি করব তার pyplot.draw()পরিবর্তে ব্যবহার করা। আপনি লুপটিতে একটি অল্প সময়ের বিলম্ব (উদাহরণস্বরূপ time.sleep(0.05)) অন্তর্ভুক্ত করতে চাইতে পারেন যাতে আপনি প্লটগুলি ঘটতে দেখেন। আমি যদি আপনার উদাহরণে এই পরিবর্তনগুলি করি তবে তা আমার পক্ষে কাজ করে এবং আমি প্রতিটি পয়েন্ট একবারে একটি করে উপস্থিত হতে দেখি।


10
আমার কোডের খুব মিল রয়েছে, এবং যখন আমি আপনার সমাধানটি চেষ্টা করি (শো এবং সময় বিলম্বের পরিবর্তে আঁকুন) পাইথন কোনও চিত্র উইন্ডোটি একেবারেই খোলেন না, কেবল লুপটি পেরিয়ে যান ...
জর্জ এপ্রিলিস

31

কোনও পদ্ধতিই আমার পক্ষে কাজ করেনি। তবে আমি খুঁজে পেয়েছি যে এই রিয়েল টাইম ম্যাটপ্ল্লিটিব প্লটটি কোনও লুপ থাকা অবস্থায় কাজ করছে না

আপনার যা দরকার তা হল যুক্ত করা

plt.pause(0.0001)

এবং তারপরে আপনি নতুন প্লট দেখতে পেলেন।

সুতরাং আপনার কোডটি দেখতে এমন হওয়া উচিত এবং এটি কার্যকর হবে

import matplotlib.pyplot as plt
import numpy as np
plt.ion() ## Note this correction
fig=plt.figure()
plt.axis([0,1000,0,1])

i=0
x=list()
y=list()

while i <1000:
    temp_y=np.random.random();
    x.append(i);
    y.append(temp_y);
    plt.scatter(i,temp_y);
    i+=1;
    plt.show()
    plt.pause(0.0001) #Note this correction

6
এটি আমার জন্য প্রতিবার একটি নতুন চিত্র / প্লট উইন্ডোটি খোলায় কেবল বিদ্যমান চিত্রটি আপডেট করার কোনও উপায় আছে? সম্ভবত এর ইচ্ছার কারণেই আমি ইমশো ব্যবহার করছি?
ফ্রান্সিসকো ভার্গাস

: @FranciscoVargas আপনি imshow ব্যবহার করছেন কিনা তা, আপনি এখানে set_data, বর্ণন ব্যবহার করতে হবে stackoverflow.com/questions/17835302/...
ওরণ

22

শীর্ষ (এবং অন্যান্য অনেকগুলি) উত্তরগুলি তৈরি করা হয়েছিল plt.pause(), তবে এটি ম্যাটপ্ল্লিটিব-এ প্লটটি অ্যানিমেট করার এক পুরানো উপায় ছিল। এটি কেবল ধীরগতির নয়, প্রতিটি আপডেটের উপরেও মনোযোগ কেন্দ্রীভূত করতে পারে (প্লাইটিংয়ের পাইথন প্রক্রিয়াটি থামাতে আমার খুব কষ্ট হয়েছিল)।

টিএল; ডিআর: আপনি ব্যবহার করতে চাইতে পারেন matplotlib.animation( ডকুমেন্টেশনে উল্লিখিত হিসাবে )

বিভিন্ন উত্তর এবং কোডের টুকরাগুলির চারপাশে খনন করার পরে, এটি প্রকৃতপক্ষে আমার কাছে ইনফিনেটে অন্তর্ভুক্ত ডেটা আঁকার একটি সহজ উপায় হিসাবে প্রমাণিত।

দ্রুত শুরুর জন্য এখানে আমার কোড। এটি প্রতি 200 মিমিগুলিতে অসম্পূর্ণভাবে [0, 100) এ এলোমেলো সংখ্যার সাথে বর্তমান সময়কে প্লট করে, পাশাপাশি দৃশ্যের স্বয়ংক্রিয় পুনরুদ্ধার পরিচালনা করে:

from datetime import datetime
from matplotlib import pyplot
from matplotlib.animation import FuncAnimation
from random import randrange

x_data, y_data = [], []

figure = pyplot.figure()
line, = pyplot.plot_date(x_data, y_data, '-')

def update(frame):
    x_data.append(datetime.now())
    y_data.append(randrange(0, 100))
    line.set_data(x_data, y_data)
    figure.gca().relim()
    figure.gca().autoscale_view()
    return line,

animation = FuncAnimation(figure, update, interval=200)

pyplot.show()

আপনি FuncAnimation ডকুমেন্টেশনের মতোblit আরও ভাল পারফরম্যান্সের জন্যও অন্বেষণ করতে পারেন ।

blitডকুমেন্টেশন থেকে একটি উদাহরণ :

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

fig, ax = plt.subplots()
xdata, ydata = [], []
ln, = plt.plot([], [], 'ro')

def init():
    ax.set_xlim(0, 2*np.pi)
    ax.set_ylim(-1, 1)
    return ln,

def update(frame):
    xdata.append(frame)
    ydata.append(np.sin(frame))
    ln.set_data(xdata, ydata)
    return ln,

ani = FuncAnimation(fig, update, frames=np.linspace(0, 2*np.pi, 128),
                    init_func=init, blit=True)
plt.show()

হাই, এই সমস্ত লুপ মধ্যে থাকলে কি হবে। বলুন for i in range(1000): x,y = some func_func()। এখানে some_func()অনলাইনে x,yডেটা জোড়া তৈরি করা হয় , যা আমি একবারে উপলভ্য করতে চাই they এটি দিয়ে কি এটি সম্ভব FuncAnimation? আমার লক্ষ্যটি প্রতিটি পুনরাবৃত্তির সাথে ধাপে ধাপে ডেটা দ্বারা সংজ্ঞায়িত বক্ররেখা তৈরি করা।
আলেকজান্ডার সিএসকা

@ আলেকজান্ডার সিসকা pyploy.show()ব্লক করা উচিত। আপনি যদি ডেটা যুক্ত করতে চান তবে সেগুলি পুনরুদ্ধার করুন এবং updateফাংশনে আপডেট করুন ।
হাই ঝাং

আমি ভয় করি যে আমি আপনার উত্তরটি সত্যই বুঝতে পারি না। আপনি আপনার পরামর্শ প্রশস্ত করুন দয়া করে।
আলেকজান্ডার সিএসকা

মানে, আপনি pyplot.showযদি কোনও লুপে কল করেন তবে লুপটি এই কল দ্বারা অবরুদ্ধ হয়ে যাবে এবং চালিয়ে যাবে না। আপনি যদি ধাপে ধাপে বক্ররেখায় ডেটা যুক্ত করতে চান তবে আপনার যুক্তিটি প্রবেশ করুন update, যা একে একে বলা হবে intervalতাই এটি ধাপে ধাপে।
হাই ঝাং

ঝাংয়ের কোডটি কনসোল থেকে কাজ করে তবে জুপিটারে নয়। আমি সেখানে একটি ফাঁকা প্লট পেয়েছি। প্রকৃতপক্ষে, আমি যখন জ্যোপিয়রে একটি ক্রমিক লুপে একটি অ্যারেটি তৈরি করি এবং একটি পেট.প্ল্যাট স্টেটমেন্টের সাথে বাড়ার সাথে সাথে অ্যারের মুদ্রণ করি, আমি পৃথকভাবে অ্যারেগুলির একটি মুদ্রণ পেতে পারি তবে কেবল একটি প্লট। এই কোডটি দেখুন: gist.github.com/bwanaaa/12252cf36b35fced0eb3c2f64a76cb8a
অ্যাকাগ্রামলিন

15

আমি জানি এই প্রশ্নটি পুরানো, তবে এখন গিটহাবের উপর "পাইথন-ড্রাউন" নামে একটি প্যাকেজ উপলব্ধ রয়েছে । এটি এমএটিএলবি'র আঁকার মতো একটি ইন্টারফেস সরবরাহ করে - আপনি সহজেই কোনও চিত্র আপডেট করতে পারেন

আপনার ব্যবহারের ক্ষেত্রে একটি উদাহরণ:

import matplotlib.pyplot as plt
from drawnow import drawnow

def make_fig():
    plt.scatter(x, y)  # I think you meant this

plt.ion()  # enable interactivity
fig = plt.figure()  # make a figure

x = list()
y = list()

for i in range(1000):
    temp_y = np.random.random()
    x.append(i)
    y.append(temp_y)  # or any arbitrary update to your figure's data
    i += 1
    drawnow(make_fig)

পাইথন-ড্রোউন চারপাশে একটি পাতলা মোড়ক plt.drawহলেও চিত্র প্রদর্শনের পরে নিশ্চিত করার (বা ডিবাগ) করার ক্ষমতা সরবরাহ করে।


এটি কোথাও কোথাও স্তব্ধ হয়ে যায়
চিবি

যদি তা হয় তবে আরও প্রসঙ্গে github.com/scottsievert/python-drawnow/issues
স্কট

+1 এটি আমার জন্য ওপেনসিভি থেকে ভিডিও ক্যাপচারের ফ্রেম প্রতি লাইভ ডেটা প্লট করার জন্য কাজ করেছে, যখন ম্যাটপ্ল্লোব হিমায়িত হয়েছে।
jj080808

আমি এটি চেষ্টা করেছি এবং এটি অন্যান্য পদ্ধতির চেয়ে ধীর বলে মনে হচ্ছে।
ডেভ সি

ব্যবহার করবেন না, আমার সার্ভার পুনরায় বুট করুন, ম্যাটপ্লোটিব হিমশীতল
বিগ-ভিএল

6

সমস্যাটি মনে হচ্ছে আপনি plt.show()উইন্ডোটি দেখানোর এবং তারপরে ফিরে আসার প্রত্যাশা করছেন। এটা যে না। প্রোগ্রামটি সেই সময়ে থামবে এবং আপনি উইন্ডোটি বন্ধ করার পরে কেবল পুনরায় শুরু হবে। আপনি এটি পরীক্ষা করতে সক্ষম হবেন: আপনি যদি উইন্ডোটি বন্ধ করেন এবং অন্য একটি উইন্ডো পপ আপ করা উচিত।

সমস্যাটি সমাধান করার জন্য plt.show()আপনার লুপের পরে একবার কল করুন । তারপরে আপনি সম্পূর্ণ প্লট পাবেন। (তবে 'রিয়েল-টাইম প্লট' নয়)

আপনি কীওয়ার্ড-যুক্তিটি সেট করার চেষ্টা করতে পারেন block: plt.show(block=False)একবার শুরুতে এবং তারপরে .draw()আপডেট করতে ব্যবহার করুন।


1
রিয়েল-টাইম প্লট করা সত্যিই আমি যা যাচ্ছি। আমি কোনও বিষয়ে 5 ঘন্টা পরীক্ষা চালাচ্ছি এবং দেখতে চাই কীভাবে জিনিসগুলি এগিয়ে চলছে।
ক্রিস

@ ক্রিস আপনি কি ২৪ ঘন্টা পরীক্ষা চালাতে পেরেছিলেন? আমিও অনুরূপ কিছু খুঁজছি। প্লট আপডেট করতে আমি প্লাইপ্লট.পজ (সময়_শিক্ষা) ব্যবহার করছি। এটি করার অন্য কোনও উপায় আছে?
প্রখর মোহন শ্রীবাস্তব

4

আমি আমার সিস্টেমে কাজ করতে পেরেছি এমন একটি সংস্করণ এখানে।

import matplotlib.pyplot as plt
from drawnow import drawnow
import numpy as np

def makeFig():
    plt.scatter(xList,yList) # I think you meant this

plt.ion() # enable interactivity
fig=plt.figure() # make a figure

xList=list()
yList=list()

for i in np.arange(50):
    y=np.random.random()
    xList.append(i)
    yList.append(y)
    drawnow(makeFig)
    #makeFig()      The drawnow(makeFig) command can be replaced
    #plt.draw()     with makeFig(); plt.draw()
    plt.pause(0.001)

অঙ্কন (মেকফিগ) লাইনটি একটি মেকফিগ () দিয়ে প্রতিস্থাপন করা যেতে পারে; plt.draw () ক্রম এবং এটি এখনও ঠিক কাজ করে।


1
আপনি কীভাবে জানতে পারবেন কতক্ষণ বিরতি দেবেন? এটি প্লটের উপর নির্ভর করে বলে মনে হচ্ছে।
সিএমসিডিগ্রাগনকাই

1

যদি আপনি আঁকতে চান এবং আপনার থ্রেডটি স্থির না করতে পারেন কারণ আরও পয়েন্ট আঁকা থাকে আপনার প্লট.পজ () সময় নয় ব্যবহার করা উচিত leep ঘুম ()

আমি এক্স কোডের একটি স্থানাঙ্কের সিরিজ প্লট করতে নিম্নলিখিত কোডটি ব্যবহার করছি।

import matplotlib.pyplot as plt 
import math


pi = 3.14159

fig, ax = plt.subplots()

x = []
y = []

def PointsInCircum(r,n=20):
    circle = [(math.cos(2*pi/n*x)*r,math.sin(2*pi/n*x)*r) for x in xrange(0,n+1)]
    return circle

circle_list = PointsInCircum(3, 50)

for t in range(len(circle_list)):
    if t == 0:
        points, = ax.plot(x, y, marker='o', linestyle='--')
        ax.set_xlim(-4, 4) 
        ax.set_ylim(-4, 4) 
    else:
        x_coord, y_coord = circle_list.pop()
        x.append(x_coord)
        y.append(y_coord)
        points.set_data(x, y)
    plt.pause(0.01)

1

আরেকটি বিকল্প বোকেহ সঙ্গে যেতে হয় । আইএমও, এটি অন্তত রিয়েল-টাইম প্লটের জন্য একটি ভাল বিকল্প। প্রশ্নে কোডটির বোকেহ সংস্করণ এখানে রয়েছে:

from bokeh.plotting import curdoc, figure
import random
import time

def update():
    global i
    temp_y = random.random()
    r.data_source.stream({'x': [i], 'y': [temp_y]})
    i += 1

i = 0
p = figure()
r = p.circle([], [])
curdoc().add_root(p)
curdoc().add_periodic_callback(update, 100)

এবং এটি চালানোর জন্য:

pip3 install bokeh
bokeh serve --show test.py

বোকেহ ওয়েব ব্রাউজারের যোগাযোগের মাধ্যমে একটি ওয়েব ব্রাউজারে ফলাফল দেখায়। এটি বিশেষত কার্যকর যখন ডেটা দূরবর্তী হেডলেস সার্ভার প্রক্রিয়াগুলির দ্বারা উত্পন্ন হয়।

বোকেহ নমুনা প্লট


0

রিয়েল-টাইমে সিপিইউ ব্যবহারের প্লট করার জন্য ব্যবহারের একটি উদাহরণ।

import time
import psutil
import matplotlib.pyplot as plt

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

i = 0
x, y = [], []

while True:
    x.append(i)
    y.append(psutil.cpu_percent())

    ax.plot(x, y, color='b')

    fig.canvas.draw()

    ax.set_xlim(left=max(0, i - 50), right=i + 50)
    fig.show()
    plt.pause(0.05)
    i += 1

এটি প্রায় 2 মিনিটের পরে ধীর হতে শুরু করে। এর কারণ কী হতে পারে? সম্ভবত পূর্বের পয়েন্টগুলি, যা বর্তমান দর্শনের বাইরে চলে যায়, বাদ দেওয়া উচিত।
pfabri

এটি সত্যিই দুর্দান্ত দেখাচ্ছে, তবে এটির সাথে বেশ কয়েকটি সমস্যা রয়েছে: ১. এটি 2 নামা অসম্ভব just
pfabri
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.