Memplot masa nyata dengan pyplot

王林
Lepaskan: 2024-09-03 17:17:02
asal
662 orang telah melayarinya

Real-time plotting with pyplot

Saya ingin membuat graf beberapa data yang saya hasilkan daripada apl tinjauan pendapat mudah. Saya telah bermain-main dengan pyplot pada masa lalu, tetapi saya tidak cuba mencipta apa-apa dari awal. Nasib baik, ia benar-benar popular, dan terdapat banyak contoh yang boleh ditemui di StackOverflow dan di tempat lain.

Saya melakukan carian dan bermula dengan jawapan SO ini berkaitan dengan mengemas kini graf dari semasa ke semasa.

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()
Salin selepas log masuk

Kod ini menghidupkan fasa perubahan gelombang sinus.

Dua baris pertama mengimport perpustakaan yang saya mahu gunakan: matplotlib.pyplot melakukan perancangan dan pengendalian GUI.

Kaedah ion(), jika saya faham (walaupun mungkin tidak), menjadikan pyplot memacu GUI. Anda juga boleh menggunakannya di dalam program tkinter, atau menggunakannya untuk menjana imej statik, tetapi dalam kes kami adalah wajar untuk membiarkannya mengendalikan GUI plot untuk kami. (Itulah yang dilakukan oleh flush_events() kemudiannya: membenarkan interaktiviti dengan tetingkap angka.)

Contoh ini menggunakan kaedah numpy linspace() untuk mencipta nilai x. Ia mengembalikan tatasusunan numpy, iaitu senarai Python yang mewah.

Sebab untuk menggunakan np.sin dan bukannya math.sin adalah penyiaran. Itulah istilah numpy untuk menggunakan fungsi pada setiap item dalam senarai. Malah, saya terfikir bahawa perkara yang sama boleh dicapai tanpa numpy menggunakan peta:

map(lambda n: math.sin(n), x)
Salin selepas log masuk

Tetapi penyiaran numpy adalah mudah dan mudah untuk digunakan.

Kini datang persediaan pyplot. Mula-mula, buat "angka" baharu (rajah). Dalam angka ini, tambahkan subplot (kapak) -- mungkin terdapat banyak. 111 mempunyai tafsiran yang agak esoterik, "buat grid 1x1, dan letakkan subplot ini dalam sel pertama."

Ke dalam subplot ini (atau set paksi), garis diplot menggunakan nilai x dan y yang diluluskan. (Titik disambungkan dengan garis lurus dan diplot secara berterusan.) "r-" ialah cara singkat untuk menentukan garis merah pepejal. Kita boleh menentukan berbilang baris, jadi plot() mengembalikan tuple; kod di atas menggunakan tuple unpacking untuk mengekstrak satu nilai yang kita mahu.

Ini adalah permulaan yang baik, tetapi saya perlu memanjangkan paksi-x dari semasa ke semasa. Kod ini juga tidak mengemas kini sempadan paksi-y jika perlu -- ia dikunci ke dalam sebarang sempadan yang dikira untuk plot pertama. Sedikit lagi carian membawa saya kepada jawapan SO ini. Untuk memetik mereka:

Anda perlu mengemas kini dataLim paksi, kemudian mengemas kini viewLim paksi berdasarkan dataLim. Kaedah yang sesuai ialah kaedah axes.relim() dan ax.autoscale_view().

Sudah tentu, bunyinya bagus. Berdasarkan contoh mereka, saya mencipta graf demo yang tumbuh dalam kedua-dua x dan 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)
Salin selepas log masuk

Sekarang saya sampai ke suatu tempat. Tetapi, ini adalah gelung menyekat, dan saya memerlukan data saya dikemas kini sekali-sekala. Jika saya mempunyai berbilang utas, saya perlu bimbang tentang keselamatan benang dengan mengemas kini pembolehubah saya. Dalam kes ini, saya boleh menjadi malas kerana saya tahu bahawa pembolehubah hanya dikemas kini sekali setiap 5 minit (atau bagaimanapun selalunya fungsi pengundian berjalan); tiada bahaya pembolehubah ditimpa di tengah baris kod.

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)
Salin selepas log masuk

Graf hanya dikemas kini apabila urutan tumbuh memberikan nilai kepada new_x. Perhatikan bahawa panggilan flush_events() berada di luar pernyataan "if", supaya panggilan itu kerap dipanggil.

Atas ialah kandungan terperinci Memplot masa nyata dengan pyplot. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!