Schnelles Live-Plotten in Matplotlib / PyPlot

Seit Jahren habe ich Mühe, in Matplotlib ein effizientes Live-Plotten zu erreichen, und bis heute bin ich unzufrieden.

Ich will einredraw_figure -Funktion, die die Zahl "live" aktualisiert (während der Code ausgeführt wird) und die neuesten Diagramme anzeigt, wenn ich an einem Haltepunkt anhalte.

Hier ist ein Demo-Code:

import time
from matplotlib import pyplot as plt
import numpy as np

def live_update_demo():

    plt.subplot(2, 1, 1)
    h1 = plt.imshow(np.random.randn(30, 30))
    redraw_figure()
    plt.subplot(2, 1, 2)
    h2, = plt.plot(np.random.randn(50))
    redraw_figure()

    t_start = time.time()
    for i in xrange(1000):
        h1.set_data(np.random.randn(30, 30))
        redraw_figure()
        h2.set_ydata(np.random.randn(50))
        redraw_figure()
        print 'Mean Frame Rate: %.3gFPS' % ((i+1) / (time.time() - t_start))

def redraw_figure():
    plt.draw()
    plt.pause(0.00001)

live_update_demo()

Plots sollten live aktualisiert werden, wenn der Code ausgeführt wird. Die neuesten Daten sollten angezeigt werden, wenn Sie an einem Haltepunkt nach @ anhalteredraw_figure(). Die Frage ist, wie man @ am besten umsetzredraw_figure()

In der obigen Implementierung plt.draw(); plt.pause(0.00001)) funktioniert, ist aber sehr langsam (~ 3.7FPS)

Ich kann es implementieren als:

def redraw_figure():
    plt.gcf().canvas.flush_events()
    plt.show(block=False)

Und es läuft schneller (~ 11FPS), aber Diagramme sind nicht aktuell, wenn Sie an Haltepunkten anhalten (z. B. wenn ich einen Haltepunkt auf das @ sett_start = ... line, der zweite Plot erscheint nicht.

Seltsamerweise funktioniert es tatsächlich, die Show zweimal aufzurufen:

def redraw_figure():
    plt.gcf().canvas.flush_events()
    plt.show(block=False)
    plt.show(block=False)

Welche ~ 11FPS ergibt und die Diagramme auf dem neuesten Stand hält, wenn Sie in einer Zeile abbrechen.

Jetzt habe ich gehört, dass das Schlüsselwort "block" veraltet ist. Und zweimal dieselbe Funktion aufzurufen, scheint ohnehin ein seltsamer, wahrscheinlich nicht portierbarer Hack zu sein.

So was kann ich in diese Funktion einfügen, die mit einer vernünftigen Framerate plottet, kein Riesenwunder ist und vorzugsweise über Backends und Systeme hinweg funktioniert?

Einige Notizen

Ich bin auf OSX und benutzeTkAgg Backend, aber Lösungen auf jedem Backend / System sind willkommenInteraktiver Modus "Ein" funktioniert nicht, da keine Live-Aktualisierung durchgeführt wird. Es wird nur in der Python-Konsole aktualisiert, wenn der Interpreter auf Benutzereingaben wartet.

A blog schlug die Implementierung vor:

def redraw_figure (): fig = plt.gcf () fig.canvas.draw () fig.canvas.flush_events ()

Aber zumindest auf meinem System werden die Diagramme dadurch überhaupt nicht neu gezeichnet.

Also, wenn jemand eine Antwort hat, würdest du mich und tausende andere direkt sehr glücklich machen. Ihr Glück würde wahrscheinlich zu ihren Freunden und Verwandten, ihren Freunden und Verwandten usw. durchdringen, so dass Sie möglicherweise das Leben von Milliarden verbessern könnte

Schlussfolgerungen

ImportanceOfBeingErnest zeigt, wie Sie Blit zum schnelleren Plotten verwenden können, aber es ist nicht so einfach, wie etwas anderes in das @ zu schreiberedraw_figure -Funktion (Sie müssen nachverfolgen, welche Dinge neu gezeichnet werden sollen).

Antworten auf die Frage(4)

Ihre Antwort auf die Frage