Wie zeige ich Echtzeit-Grafiken in einer einfachen Benutzeroberfläche für ein Python-Programm?
-
29-09-2019 - |
Frage
Ich habe einen komplizierten Algorithmus, der 3 Histogramme aktualisiert, die in Arrays gespeichert sind. Ich mag meinen Algorithmus debuggen, so wurde ich in einer Benutzeroberfläche zeigt die Arrays als Histogramm zu denken. Was ist der einfachste Weg, dies zu tun. (Rapid Application Development ist wichtiger als optimierten Code.)
Ich habe einige Erfahrung mit Qt (in C ++) und einige Erfahrung mit matplotlib.
(Ich werde diese Frage offen für einen Tag verlassen, oder zwei, weil es ist schwer für mich, die Lösungen ohne viel mehr Erfahrung zu bewerten, dass ich nicht haben. Ich hoffe, dass die Stimmen der Community die beste Antwort helfen wählen ).
Lösung
Edit: Heutzutage ist es einfacher und besser zu Einsatz matplotlib.animation
:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
def animate(frameno):
x = mu + sigma * np.random.randn(10000)
n, _ = np.histogram(x, bins, normed=True)
for rect, h in zip(patches, n):
rect.set_height(h)
return patches
mu, sigma = 100, 15
fig, ax = plt.subplots()
x = mu + sigma * np.random.randn(10000)
n, bins, patches = plt.hist(x, 50, normed=1, facecolor='green', alpha=0.75)
ani = animation.FuncAnimation(fig, animate, blit=True, interval=10,
repeat=True)
plt.show()
Es ist ein Beispiel zur Herstellung eines animierten Graphen hier . Aufbauend auf diesem Beispiel können Sie versuchen, so etwas wie:
import numpy as np
import matplotlib.pyplot as plt
plt.ion()
mu, sigma = 100, 15
fig = plt.figure()
x = mu + sigma*np.random.randn(10000)
n, bins, patches = plt.hist(x, 50, normed=1, facecolor='green', alpha=0.75)
for i in range(50):
x = mu + sigma*np.random.randn(10000)
n, bins = np.histogram(x, bins, normed=True)
for rect,h in zip(patches,n):
rect.set_height(h)
fig.canvas.draw()
kann ich über 14 Frames pro Sekunde erhalten diese Weise im Vergleich zu 4 Bildern pro Sekunde mit dem Code I zuerst geschrieben . Der Trick besteht darin, zu vermeiden matplotlib fragte vollständige Zahlen zu zeichnen. Statt einmal Anruf plt.hist
, manipulieren dann die vorhandenen matplotlib.patches.Rectangle
s in patches
das Histogramm zu aktualisieren, und Aufruf
fig.canvas.draw()
um das Updates sichtbar zu machen.
Andere Tipps
Für Echtzeit-Plotten, empfehle ich versuchen, Chaco, pyqtgraph, oder eine der OpenGL-basierten Bibliotheken wie glumpy oder visvis. Matplotlib, wunderbar, wie es ist, ist für diese Art der Anwendung der Regel nicht geeignet.
Edit: die Entwickler von glumpy, visvis, galry und pyqtgraph sind alle gemeinsam an einer Visualisierung Bibliothek mit dem Namen
Ich empfehle, mit matplotlib im interaktiven Modus, wenn Sie .show
rufen einmal, dann wird es in einem eigenen Fenster geöffnet, wenn Sie nicht dann tun es existiert nur im Speicher und kann in eine Datei geschrieben werden, wenn Sie fertig sind mit es.
Ouh, jetzt sehen, wenn Sie Echtzeit sagen Sie meinen, Sie wollen eine Bildwiederholfrequenz von mehr als 5 Hz matplotlib wird den Job nicht machen. Ich hatte dieses Problem vor, ging ich für PyQwt , die mit PyQt funktioniert.