Aufruf von pylab.savefig ohne Anzeige in ipython


110

Ich muss eine Figur in einer Datei erstellen, ohne sie im IPython-Notizbuch anzuzeigen. Die Wechselwirkung zwischen IPythonund matplotlib.pylabin dieser Hinsicht ist mir nicht klar . Aber wenn ich anrufe, wird pylab.savefig("test.png")die aktuelle Zahl angezeigt und zusätzlich gespeichert test.png. Wenn Sie die Erstellung einer großen Anzahl von Plotdateien automatisieren, ist dies häufig unerwünscht. Oder in dem Fall, dass eine Zwischendatei für die externe Verarbeitung durch eine andere App gewünscht wird.

Ich bin mir nicht sicher, ob dies eine matplotliboder eine IPythonNotebook-Frage ist.


Die Antwort von @staticfloat funktionierte für mich auch dann, wenn ich mich nicht in einem Notizbuch befand und wenn ich matplotlib über JuliaLang verwendete. usingioff
Vass

Antworten:


172

Dies ist eine matplotlib-Frage, und Sie können dies umgehen, indem Sie ein Backend verwenden, das dem Benutzer nicht angezeigt wird, z. B. 'Agg':

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

plt.plot([1,2,3])
plt.savefig('/tmp/test.png')

BEARBEITEN: Wenn Sie die Fähigkeit zum Anzeigen von Plots nicht verlieren möchten, deaktivieren Sie den interaktiven Modus und rufen plt.show()Sie nur an, wenn Sie bereit sind, die Plots anzuzeigen:

import matplotlib.pyplot as plt

# Turn interactive plotting off
plt.ioff()

# Create a new figure, plot into it, then close it so it never gets displayed
fig = plt.figure()
plt.plot([1,2,3])
plt.savefig('/tmp/test0.png')
plt.close(fig)

# Create a new figure, plot into it, then don't close it so it does get displayed
plt.figure()
plt.plot([1,3,2])
plt.savefig('/tmp/test1.png')

# Display all "open" (non-closed) figures
plt.show()

2
Ok - aber ich möchte das Inline-Plotten in iPython generell beibehalten. Was Sie vorschlagen, funktioniert einwandfrei, wenn Sie das Backend vollständig umschalten. Die Frage ist, wie Sie die allgemeine Situation des Inline-Plottens mit dem Ausnahmefall des Speicherns von Zahlen (ohne Inline-Anzeige) berücksichtigen. Mit Ihrem Vorschlag habe ich versucht, die Module neu zu laden und das Backend vorübergehend zu ändern, aber ohne Erfolg. Irgendwelche Ideen, wie Sie das Backend innerhalb einer iPython-Notebook-Sitzung vorübergehend ändern können?
tnt

1
Ich habe die Frage aktualisiert, um über interaktives Plotten und die Befehle close()und zu sprechen show(), die Ihr Problem lösen sollen. Das schnelle Auswechseln von Backends wird nicht unterstützt, wie Sie festgestellt haben.
Staticfloat

3
Vielen Dank für das hervorragende Feedback. Es scheint, dass plt.close (fig) der Schlüsselbefehl für meine Bedürfnisse ist. Ich bin mir immer noch nicht sicher, da dies keinen Einfluss auf die Operation zu haben scheint. aber mir fehlt wahrscheinlich etwas. Danke noch einmal.
tnt

1
Das Rezept, das ich gegeben habe, ist ein allgemeines; Wenn Sie nicht im ipython-Notizbuch arbeiten, ist plt.ioff () wichtig, um zu verhindern, dass Zahlen auf dem Bildschirm und außerhalb des Bildschirms flackern, da in der Befehlszeile ipython-Zahlen aufgezeichnet werden, sobald Sie aufrufen, plt.plot()wenn der interaktive Modus aktiviert ist. Durch Deaktivieren des interaktiven Modus wird die Anzeige von Plots bis verzögert plt.show(). Da Sie das ipython-Notizbuch verwenden, wird der interaktive Modus anders behandelt.
staticfloat

Für mich hat matplotlib.use('Agg')allein der Trick getan. Ich brauchte keine plt.show()oder überhaupt keinen plt.ioff()Code.
Zhanwen Chen

67

Wir brauchen nicht plt.ioff()oder plt.show()(wenn wir verwenden %matplotlib inline). Sie können den obigen Code ohne testen plt.ioff(). plt.close()hat die wesentliche Rolle. Probier diese:

%matplotlib inline
import pylab as plt

# It doesn't matter you add line below. You can even replace it by 'plt.ion()', but you will see no changes.
## plt.ioff()

# Create a new figure, plot into it, then close it so it never gets displayed
fig = plt.figure()
plt.plot([1,2,3])
plt.savefig('test0.png')
plt.close(fig)

# Create a new figure, plot into it, then don't close it so it does get displayed
fig2 = plt.figure()
plt.plot([1,3,2])
plt.savefig('test1.png')

Wenn Sie diesen Code in iPython ausführen, wird ein zweiter Plot angezeigt, und wenn Sie ihn plt.close(fig2)am Ende hinzufügen , wird nichts angezeigt .

Abschließend , wenn Sie Abbildung in der Nähe plt.close(fig), wird es nicht angezeigt.


5
Bessere Lösung! Ich generiere und speichere viele Plots in einer Schleife. Mit plt.ioffbekomme ich RuntimeWarning: More than 20 figures have been opened.... plt.closeIch habe es gelöst.
Nagasaki45
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.