"यदि कोई कर्मचारी अपना काम अच्छी तरह से करना चाहता है, तो उसे पहले अपने औजारों को तेज करना होगा।" - कन्फ्यूशियस, "द एनालेक्ट्स ऑफ कन्फ्यूशियस। लू लिंगगोंग"
मुखपृष्ठ > प्रोग्रामिंग > पिप्लॉट के साथ रीयल-टाइम प्लॉटिंग

पिप्लॉट के साथ रीयल-टाइम प्लॉटिंग

2024-11-08 को प्रकाशित
ब्राउज़ करें:248

Real-time plotting with pyplot

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

मैंने एक खोज की और समय के साथ ग्राफ़ को अपडेट करने से संबंधित इस SO उत्तर से शुरुआत की।

import matplotlib.pyplot as plt
import numpy as np

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

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

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

यह कोड साइन तरंग परिवर्तन चरण को एनिमेट करता है।

पहली दो पंक्तियाँ उन पुस्तकालयों को आयात करती हैं जिनका मैं उपयोग करना चाहता हूँ: matplotlib.pyplot GUI की प्लॉटिंग और प्रबंधन करता है।

आयन() विधि, अगर मैं समझता हूं (हालाँकि मैं नहीं समझ सकता), पाइप्लॉट को जीयूआई चलाता है। आप इसे टिंकर प्रोग्राम के अंदर भी उपयोग कर सकते हैं, या स्थिर छवियां उत्पन्न करने के लिए इसका उपयोग कर सकते हैं, लेकिन हमारे मामले में यह समझ में आता है कि इसे हमारे लिए प्लॉट के जीयूआई को संभालने दें। (फ्लश_इवेंट्स() कॉल बाद में यही कर रही है: फिगर विंडो के साथ इंटरैक्टिविटी की अनुमति देना।)

यह उदाहरण x मान बनाने के लिए numpy विधि linspace() का उपयोग करता है। यह एक सुस्पष्ट सरणी लौटाता है, जो एक फैंसी पायथन सूची है।

math.sin के बजाय np.sin का उपयोग करने का कारण प्रसारण है। किसी सूची में प्रत्येक आइटम पर फ़ंक्शन लागू करने के लिए यह एक अजीब शब्द है। वास्तव में, मेरे साथ ऐसा हुआ है कि मानचित्र का उपयोग करके बिना सुन्न हुए भी यही चीज़ हासिल की जा सकती है:

map(lambda n: math.sin(n), x)

लेकिन सुन्न प्रसारण सुविधाजनक और उपयोग में सरल है।

अब पाइलप्लॉट सेटअप आता है। सबसे पहले, एक नया "आकृति" (अंजीर) बनाएं। इस आकृति में, एक सबप्लॉट (कुल्हाड़ी) जोड़ें - कई हो सकते हैं। 111 की गूढ़ व्याख्या है, "एक 1x1 ग्रिड बनाएं, और इस सबप्लॉट को पहले सेल में रखें।"

इस सबप्लॉट (या अक्षों के सेट) में, पारित x और y मानों का उपयोग करके एक रेखा प्लॉट की जाती है। (बिंदु सीधी रेखाओं से जुड़े होते हैं और लगातार प्लॉट किए जाते हैं।) "आर-" एक ठोस, लाल रेखा को निर्दिष्ट करने का संक्षिप्त तरीका है। हम कई पंक्तियाँ निर्दिष्ट कर सकते हैं, इसलिए प्लॉट() एक टपल लौटाता है; उपरोक्त कोड हमारे इच्छित मान को निकालने के लिए टुपल अनपैकिंग का उपयोग करता है।

यह एक अच्छी शुरुआत है, लेकिन मुझे समय के साथ एक्स-अक्ष का विस्तार करने की आवश्यकता है। यदि आवश्यक हो तो यह कोड y-अक्ष की सीमाओं को भी अपडेट नहीं करता है - यह पहले प्लॉट के लिए गणना की गई किसी भी सीमा में बंद है। थोड़ी और खोज मुझे इस SO उत्तर तक ले गई। उन्हें उद्धृत करने के लिए:

आपको एक्सिस के डेटालिम को अपडेट करना होगा, फिर बाद में डेटालिम के आधार पर एक्सिस के व्यूलिम को अपडेट करना होगा। उपयुक्त विधियाँ axes.relim() और ax.autoscale_view() विधि हैं।

ज़रूर, अच्छा लगता है। उनके उदाहरण के आधार पर, मैंने एक डेमो ग्राफ़ बनाया जो x और y दोनों में बढ़ता है।

import matplotlib.pyplot as plt
import numpy as np
from threading import Thread
from time import sleep

x = list(map(lambda x: x / 10, range(-100, 100)))
x_next_max = 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-')[0] # Returns a tuple of line objects

growth = 0

while True:
    x.append(x_next_max / 10)
    x_next_max  = 1
    line1.set_xdata(x)
    line1.set_ydata(np.sin(x)   np.sin(np.divide(x, 100))   np.divide(x, 100))
    ax.relim()
    ax.autoscale()
    fig.canvas.draw()
    fig.canvas.flush_events()

    sleep(0.1)

अब मैं कहीं जा रहा हूं। लेकिन, यह एक अवरोधक लूप है, और मुझे अपने डेटा को समय-समय पर अद्यतन करने की आवश्यकता है। यदि मेरे पास एकाधिक थ्रेड हैं, तो मुझे अपने वेरिएबल्स को अपडेट करने के साथ थ्रेड-सुरक्षित होने के बारे में चिंता करनी होगी। इस मामले में, मैं आलसी हो सकता हूं क्योंकि मुझे पता है कि वेरिएबल हर 5 मिनट में केवल एक बार अपडेट होता है (या फिर पोलिंग फ़ंक्शन कितनी बार चलता है); कोड की एक पंक्ति के बीच में वेरिएबल के अधिलेखित हो जाने का कोई खतरा नहीं है।

import matplotlib.pyplot as plt
import numpy as np
from threading import Timer
from time import sleep

x = list(map(lambda x: x / 10, range(-100, 100)))
x_next_max = 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-')[0] # Plot returns a tuple of line objects

growth = 0
new_x = None

dT = 1

def grow():
    global new_x, x_next_max
    while True:
        new_x = x   [x_next_max / 10]
        x_next_max  = 1
        sleep(dT) # grow every dT seconds

t = Thread(target=grow)
t.start()

while True:

    if new_x:
        x = new_x
        new_x = None
        line1.set_xdata(x)
        line1.set_ydata(np.sin(x)   np.sin(np.divide(x, 100))   np.divide(x, 100))
        ax.relim()
        ax.autoscale()
        fig.canvas.draw()

    fig.canvas.flush_events()

    sleep(0.1)

ग्राफ़ केवल तभी अपडेट किया जाता है जब ग्रो थ्रेड new_x को मान निर्दिष्ट करता है। ध्यान दें कि flush_events() कॉल "if" स्टेटमेंट के बाहर है, इसलिए इसे बार-बार कॉल किया जा रहा है।

विज्ञप्ति वक्तव्य इस लेख को पुन: प्रस्तुत किया गया है: https://dev.to/paxfeline/real-bime-to-totting-with-pyplot-2b3g?1 यदि कोई उल्लंघन है, तो कृपया इसे हटाने के लिए [email protected] से संपर्क करें।
नवीनतम ट्यूटोरियल अधिक>

चीनी भाषा का अध्ययन करें

अस्वीकरण: उपलब्ध कराए गए सभी संसाधन आंशिक रूप से इंटरनेट से हैं। यदि आपके कॉपीराइट या अन्य अधिकारों और हितों का कोई उल्लंघन होता है, तो कृपया विस्तृत कारण बताएं और कॉपीराइट या अधिकारों और हितों का प्रमाण प्रदान करें और फिर इसे ईमेल पर भेजें: [email protected] हम इसे आपके लिए यथाशीघ्र संभालेंगे।

Copyright© 2022 湘ICP备2022001581号-3