Ich habe in den letzten Tagen mit Numpy und Matplotlib gespielt. Ich habe Probleme beim Versuch, matplotlib plot zu einer Funktion zu machen, ohne die Ausführung zu blockieren. Ich weiß, dass es hier auf SO bereits viele Threads gibt, die ähnliche Fragen stellen, und ich habe ziemlich viel gegoogelt, aber es nicht geschafft, dass dies funktioniert.
Ich habe versucht, show (block = False) zu verwenden, wie einige Leute vorschlagen, aber alles, was ich bekomme, ist ein eingefrorenes Fenster. Wenn ich einfach show () aufrufe, wird das Ergebnis korrekt dargestellt, aber die Ausführung wird blockiert, bis das Fenster geschlossen wird. Von anderen Threads, die ich gelesen habe, vermute ich, dass es vom Backend abhängt, ob show (block = False) funktioniert oder nicht. Ist das richtig? Mein Backend ist Qt4Agg. Könnten Sie sich meinen Code ansehen und mir sagen, wenn Sie etwas falsch sehen? Hier ist mein Code. Vielen Dank für jede Hilfe.
from math import *
from matplotlib import pyplot as plt
print plt.get_backend()
def main():
x = range(-50, 51, 1)
for pow in range(1,5): # plot x^1, x^2, ..., x^4
y = [Xi**pow for Xi in x]
print y
plt.plot(x, y)
plt.draw()
#plt.show() #this plots correctly, but blocks execution.
plt.show(block=False) #this creates an empty frozen window.
_ = raw_input("Press [enter] to continue.")
if __name__ == '__main__':
main()
PS. Ich habe vergessen zu sagen, dass ich das vorhandene Fenster jedes Mal aktualisieren möchte, wenn ich etwas zeichne, anstatt ein neues zu erstellen.
quelle
plt.ion()
vorplt.show()
? Es sollte dann nicht blockierend sein, da jeder Plot in einem untergeordneten Thread erzeugt wird.matplotlib
.Antworten:
Ich habe lange nach Lösungen gesucht und diese Antwort gefunden .
Es sieht aus wie, um zu bekommen , was Sie (und ich) wollen, müssen Sie die Kombination
plt.ion()
,plt.show()
(nichtblock=False
) und, was am wichtigsten ist ,plt.pause(.001)
(oder was auch immer Zeit , die Sie wollen). Die Pause wird benötigt, da die GUI-Ereignisse auftreten, während der Hauptcode im Ruhezustand ist, einschließlich Zeichnen. Es ist möglich, dass dies implementiert wird, indem Zeit von einem schlafenden Thread abgeholt wird. Vielleicht spielen IDEs damit herum - ich weiß es nicht.Hier ist eine Implementierung, die für mich unter Python 3.5 funktioniert:
quelle
plt.draw
gefolgt,plt.show(block = False)
aber dann funktionierte es nicht mehr: Abbildung reagierte nicht, beim Schließen stürzte iPython ab. Meine Lösung bestand darin, jede Instanz zu entfernenplt.draw()
und durch zu ersetzenplt.pause(0.001)
. Anstatt esplt.show(block = False)
wieplt.draw
zuvor folgen zu lassen , wurde es vonplt.ion()
und vorangestelltplt.show()
. Ich habe jetzt eine,MatplotlibDeprecationWarning
aber damit kann ich meine Zahlen zeichnen, also bin ich mit dieser Lösung zufrieden.raw_input
nicht verwenden müsseninput
. Siehe hierEin einfacher Trick, der für mich funktioniert, ist der folgende:
Beispiel :
Hinweis :
plt.show()
ist die letzte Zeile meines Skripts.quelle
Sie können das Blockieren der Ausführung vermeiden, indem Sie den Plot in ein Array schreiben und das Array dann in einem anderen Thread anzeigen. Hier ist ein Beispiel für das gleichzeitige Generieren und Anzeigen von Plots mit pf.screen aus pyformulas 0.2.8 :
Ergebnis:
Haftungsausschluss: Ich bin der Betreuer für Pyformeln.
Referenz: Matplotlib: Plot im Numpy-Array speichern
quelle
Viele dieser Antworten sind sehr aufgeblasen und nach allem, was ich finden kann, ist die Antwort gar nicht so schwer zu verstehen.
Sie können verwenden,
plt.ion()
wenn Sie möchten, aber ich fand die Verwendungplt.draw()
genauso effektivFür mein spezielles Projekt zeichne ich Bilder, aber Sie können
plot()
oderscatter()
oder was auch immer verwendenfigimage()
, es spielt keine Rolle.Oder
Wenn Sie eine tatsächliche Zahl verwenden.
Ich habe @ krs013 und die Antworten von @Default Picture verwendet, um dies herauszufinden.
Hoffentlich erspart dies jemandem, jede einzelne Figur in einem separaten Thread zu starten oder diese Romane lesen zu müssen, um dies herauszufinden
quelle
Live-Plotten
Wenn die Datenmenge zu groß ist, können Sie die Aktualisierungsrate mit einem einfachen Zähler senken
Halten des Plots nach dem Beenden des Programms
Dies war mein eigentliches Problem, für das keine zufriedenstellende Antwort gefunden werden konnte. Ich wollte ein Plotten, das nach Abschluss des Skripts nicht geschlossen wurde (wie MATLAB).
Wenn Sie darüber nachdenken, wird das Programm nach Abschluss des Skripts beendet und es gibt keine logische Möglichkeit, den Plot auf diese Weise zu halten. Daher gibt es zwei Optionen
Das war für mich nicht zufriedenstellend, also fand ich eine andere Lösung außerhalb des Rahmens
SaveToFile und View im externen Viewer
Zu diesem Zweck sollte das Speichern und Anzeigen schnell erfolgen und der Betrachter sollte die Datei nicht sperren und den Inhalt automatisch aktualisieren
Format zum Speichern auswählen
Vektorbasierte Formate sind sowohl klein als auch schnell
Schneller Lightweight Viewer mit Live Update
Für PDF gibt es mehrere gute Optionen
Unter Windows verwende ich SumatraPDF, das kostenlos, schnell und leicht ist (verwendet für meinen Fall nur 1,8 MB RAM).
Unter Linux gibt es verschiedene Optionen wie Evince (GNOME) und Ocular (KDE).
Beispielcode & Ergebnisse
Beispielcode für die Ausgabe eines Plots in eine Datei
Öffnen Sie nach dem ersten Start die Ausgabedatei in einem der oben genannten Viewer und genießen Sie.
Hier ist ein Screenshot von VSCode neben SumatraPDF. Außerdem ist der Vorgang schnell genug, um eine Semi-Live-Aktualisierungsrate zu erhalten (ich kann bei meinem Setup fast 10 Hz erreichen, wenn ich es nur
time.sleep()
zwischen den Intervallen verwende).quelle
Iggys Antwort war für mich am einfachsten zu befolgen, aber ich bekam den folgenden Fehler, als ich einen nachfolgenden
subplot
Befehl ausführte, der nicht da war, als ich gerade ausführteshow
:Um diesen Fehler zu vermeiden, ist es hilfreich, das Diagramm zu schließen (oder zu löschen ), nachdem der Benutzer die Eingabetaste gedrückt hat.
Hier ist der Code, der für mich funktioniert hat:
quelle
Mit dem gezeichneten Python-Paket können Sie einen Plot in Echtzeit auf nicht blockierende Weise aktualisieren.
Es funktioniert auch mit einer Webcam und OpenCV, um beispielsweise Kennzahlen für jeden Frame zu zeichnen.
Siehe den Originalbeitrag .
quelle