Ich evaluiere derzeit verschiedene Python-Plot-Bibliotheken. Im Moment versuche ich Matplotlib und bin ziemlich enttäuscht von der Leistung. Das folgende Beispiel wurde von SciPy-Beispielen modifiziert und gibt mir nur ~ 8 Bilder pro Sekunde!
Gibt es Möglichkeiten, dies zu beschleunigen, oder sollte ich eine andere Plotbibliothek auswählen?
from pylab import *
import time
ion()
fig = figure()
ax1 = fig.add_subplot(611)
ax2 = fig.add_subplot(612)
ax3 = fig.add_subplot(613)
ax4 = fig.add_subplot(614)
ax5 = fig.add_subplot(615)
ax6 = fig.add_subplot(616)
x = arange(0,2*pi,0.01)
y = sin(x)
line1, = ax1.plot(x, y, 'r-')
line2, = ax2.plot(x, y, 'g-')
line3, = ax3.plot(x, y, 'y-')
line4, = ax4.plot(x, y, 'm-')
line5, = ax5.plot(x, y, 'k-')
line6, = ax6.plot(x, y, 'p-')
# turn off interactive plotting - speeds things up by 1 Frame / second
plt.ioff()
tstart = time.time() # for profiling
for i in arange(1, 200):
line1.set_ydata(sin(x+i/10.0)) # update the data
line2.set_ydata(sin(2*x+i/10.0))
line3.set_ydata(sin(3*x+i/10.0))
line4.set_ydata(sin(4*x+i/10.0))
line5.set_ydata(sin(5*x+i/10.0))
line6.set_ydata(sin(6*x+i/10.0))
draw() # redraw the canvas
print 'FPS:' , 200/(time.time()-tstart)
python
matplotlib
ich mich
quelle
quelle
Antworten:
Zunächst einmal (obwohl dies die Leistung überhaupt nicht ändert) sollten Sie Ihren Code bereinigen, ähnlich wie folgt:
Mit dem obigen Beispiel erhalte ich ungefähr 10 fps.
Nur eine kurze Anmerkung: Abhängig von Ihrem genauen Anwendungsfall ist matplotlib möglicherweise keine gute Wahl. Es ist auf Zahlen in Publikationsqualität ausgerichtet, nicht auf Echtzeitanzeigen.
Es gibt jedoch eine Menge Dinge, die Sie tun können, um dieses Beispiel zu beschleunigen.
Es gibt zwei Hauptgründe, warum dies so langsam ist wie es ist.
1) Beim Aufrufen
fig.canvas.draw()
wird alles neu gezeichnet . Es ist dein Engpass. In Ihrem Fall müssen Sie Dinge wie Achsengrenzen, Häkchen usw. nicht neu zeichnen.2) In Ihrem Fall gibt es viele Nebenhandlungen mit vielen Häkchen. Das Zeichnen dauert lange.
Beide können durch Blitting behoben werden.
Um das Blitting effizient durchzuführen, müssen Sie Backend-spezifischen Code verwenden. Wenn Sie sich in der Praxis wirklich Sorgen um flüssige Animationen machen, binden Sie in der Regel ohnehin Matplotlib-Plots in eine Art GUI-Toolkit ein, sodass dies kein großes Problem darstellt.
Ohne ein bisschen mehr darüber zu wissen, was Sie tun, kann ich Ihnen dort nicht helfen.
Trotzdem gibt es eine gui-neutrale Methode, die immer noch recht schnell ist.
Das gibt mir ~ 200fps.
Um dies ein wenig bequemer zu machen, gibt es
animations
in neueren Versionen von matplotlib ein Modul.Als Beispiel:
quelle
animation
scheint den Plot nachinterval
Zeitraum zu aktualisieren. Was ist, wenn ich ihn nur aktualisieren möchte, wenn neue Daten verfügbar sind?Matplotlib liefert großartige Grafiken in Publikationsqualität, ist jedoch nicht sehr schnell optimiert. Es gibt eine Vielzahl von Python-Plot-Paketen, die auf Geschwindigkeit ausgelegt sind:
[edit: pyqwt wird nicht mehr gepflegt; der vorherige Betreuer empfiehlt pyqtgraph]
quelle
Zu Beginn liefert die Antwort von Joe Kington sehr gute Ratschläge mit einem gui-neutralen Ansatz, und Sie sollten auf jeden Fall seinen Rat (insbesondere in Bezug auf Blitting) befolgen und in die Praxis umsetzen. Weitere Informationen zu diesem Ansatz finden Sie im Matplotlib-Kochbuch
Der nicht GUI-neutrale (GUI-voreingenommene?) Ansatz ist jedoch der Schlüssel zur Beschleunigung des Plots. Mit anderen Worten, das Backend ist äußerst wichtig, um die Geschwindigkeit zu zeichnen.
Setzen Sie diese beiden Zeilen, bevor Sie etwas anderes aus matplotlib importieren:
Natürlich gibt es verschiedene Optionen anstelle von
GTKAgg
, aber laut dem zuvor erwähnten Kochbuch war dies die schnellste. Weitere Optionen finden Sie unter dem Link zu Backends.quelle
Für die erste von Joe Kington vorgeschlagene Lösung (.copy_from_bbox & .draw_artist & canvas.blit) musste ich die Hintergründe nach der Zeile fig.canvas.draw () erfassen , andernfalls hatte der Hintergrund keine Auswirkung und ich erhielt das gleiche Ergebnis wie du hast erwähnt. Wenn Sie es nach fig.show () setzen, funktioniert es immer noch nicht wie von Michael Browne vorgeschlagen.
Setzen Sie also einfach die Hintergrundzeile nach canvas.draw ():
quelle
Dies gilt möglicherweise nicht für viele von Ihnen, aber ich betreibe meine Computer normalerweise unter Linux. Daher speichere ich meine Matplotlib-Diagramme standardmäßig als PNG und SVG. Dies funktioniert unter Linux einwandfrei, ist aber in meinen Windows 7-Installationen [MiKTeX unter Python (x, y) oder Anaconda] unerträglich langsam. Daher habe ich diesen Code hinzugefügt, und dort funktioniert es wieder einwandfrei:
quelle