Nicht blockförmiges Zeichnen und Aktualisieren von Diagrammen mit Bokeh

Bild

Ich habe ein Python-Skript mit Berechnungen. Es gab einen Zyklus von ungefähr 2000 Iterationen, von denen jede als einige Minuten angesehen wurde.

Und ich habe mich entschlossen, dieses Skript geschickt zu debuggen und ein Diagramm einiger Metriken aus der Iterationsnummer anzuzeigen. Und wie die nächste Iteration berechnet wird, so wird dieser Zeitplan und diese Aktualisierung.

Der einfachste Weg, dies zu tun, ist mit Bokeh. Genauer gesagt, Verwenden eines Bokeh-Servers zum Zeichnen von Diagrammen. Wie - jetzt werde ich es dir sagen.

Starten Sie zuerst den Server: Der Server wird zusammen mit Bokeh selbst ausgeliefert. Geben Sie nach der Installation von Bokeh einfach Bokeh Serve in die Konsole ein, und der Server wird gestartet.

Warum wird es benötigt? Und dann die Diagramme zu zeigen

  • hat die Ausführung des restlichen Codes nicht blockiert (da dies im Browser in einem separaten Prozess geschieht),
  • so dass das Diagramm auf die Größenänderung des Fensters (oder auf das Minimieren-Maximieren) reagiert
  • und damit wir diesen Zeitplan jederzeit ändern können, direkt aus unserem Python-Prozess!

Dies geschieht folgendermaßen:

import time import sys from bokeh.plotting import figure from bokeh.client import pull_session from bokeh.models import ColumnDataSource #     --    -,    bokeh serve # Please run "bokeh serve" in console before start! if __name__ == "__main__": #    (  ,     ) session = pull_session() #  .. ,      (    ) fig = figure(title=("Total TBS (in bits)"), plot_height=300, plot_width=800) #         datasource = ColumnDataSource(data={"x": [], "y": []}) line = fig.line(x="x", y="y", source=datasource, line_width=2, legend=("Super dooper line from hell")) #        session.show(fig) #     for i in range(10000): #          .   datasource     #       = ) datasource.stream({"x": [i], "y": [i ** 2]}) #       30-40      ,   session.force_roundtrip() #  ! 

Früher musste ich das auch tun, aber frühere Entscheidungen waren, gelinde gesagt, nicht so gut. Was ich in meinem Leben nicht versucht habe ...

Achtung, Gehirnballast!
Sie können matplotlib im nicht blockierenden Modus verwenden, indem Sie bei jeder Iteration manuell plt.draw () ziehen. Richtig, matplotlib hat keine eigene Verarbeitung von Nachrichten von der GUI im nicht blockierenden Modus. Wenn das Fenster minimiert oder mit einem anderen Fenster geschlossen wird, müssen wir auf die nächste Iteration warten, um es neu zu zeichnen. So lala Krücke, aber zum Debuggen reicht es.

In Negro ist es möglich, ein Bild mit einem Diagramm derselben Matplotlib zu erstellen und auf die Festplatte zu kopieren. Auch eine wilde Krücke, aber eine Fahrt auf den Fischmangel. Oder auf einem Remote-Computer ohne Grafik.

Sie können es auf coole Weise tun: Verwenden Sie PyQt, wickeln Sie den Berechnungscode in ein QObject ein, verschieben Sie ihn in einen separaten Stream, wickeln Sie die Matplotlib-Grafiken in ein QWidget (oder verwenden Sie die Grafiken von Qt Data Visualizaion oder PyQtGraph), verbinden Sie die Mathematik über ein Signal mit einem Slot mit den Grafiken und es wird Glück geben. Es stimmt, dies ist ein bisschen wie eine schnelle Debugging-Lösung, und Qt muss gelehrt werden, aber ich habe es ein paar Mal gemacht.

Sie können eine kleine Serveranwendung zum Zeichnen von Diagrammen in einem separaten Prozess (z. B. mit aiohttp + PyQt + PyQtGraph) aufrufen, die vom Hauptprozess aus über die REST-API geklickt werden kann. Einmal habe ich das getan, aber es hat auch keine schnelle Lösung für das Debuggen gefunden.

Sie können in eine Art Datenbank schreiben (was ist gerade in Mode?) Und dann Grafan in Mode kommen lassen. Richtig, Sie müssen sowohl die Datenbank als auch Grafan speichern, konfigurieren und sich im Allgemeinen die Mühe machen, in die Datenbank zu schreiben. Wahrscheinlich ist es auch durch eine Datei möglich, aber für zwei Graphen für tausend Punkte ist jeder wie ein Waffensperling ...

Oder Sie können plotly.dash verstehen, die Mathematik in einen separaten Stream stellen, sie in eine Dash-Anwendung einbinden und verdammt viel Müll machen. Dies habe ich nicht gemeistert, obwohl es notwendig wäre.

Kurz gesagt, erfolgreiches Debuggen!

Source: https://habr.com/ru/post/de474378/


All Articles