web-dev-qa-db-de.com

Das Speichern einer Abbildung nach dem Aufruf von pyplot.show () führt zu einer leeren Datei

Der folgende Beispielcode generiert eine einfache Zeichnung, speichert sie in 'fig1.pdf', zeigt sie an und speichert sie erneut in 'fig2.pdf'. Das erste Bild sieht erwartungsgemäß aus, das zweite ist jedoch leer (enthält ein weißes Quadrat). Was ist hier eigentlich los? Die Zeile plt.show() vermisst anscheinend etwas, aber ich kann nicht herausfinden, was/wie!

import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-1, 1, 100)
y = x**2
plt.plot(x,y)
plt.savefig('fig1.pdf')
plt.show()
plt.savefig('fig2.pdf')
41
andreasdr

Wenn Sie die Figur nach dem Anzeigen speichern möchten, müssen Sie die Figurinstanz beibehalten. Der Grund, dass plt.savefig nach dem Aufruf von show nicht funktioniert, ist, dass die aktuelle Zahl zurückgesetzt wurde.

pyplot verfolgt, welche Figuren, Achsen usw. "aktuell" sind (d. h. noch nicht mit show angezeigt wurden) hinter den Kulissen. gcf und gca erhalten jeweils die aktuelle Instanz der Figur und der aktuellen Achse. plt.savefig (und im Wesentlichen jede andere pyplot-Methode) führt einfach plt.gcf().savefig(...) aus. Mit anderen Worten, rufen Sie die aktuelle Figur-Instanz ab und rufen Sie ihre savefig-Methode auf. Ebenso funktioniert plt.plot grundsätzlich plt.gca().plot(...).

Nach dem Aufruf von show ist die Liste der "aktuellen" Zahlen und Achsen leer.

Im Allgemeinen ist es besser, die Figuren- und Achseninstanzen direkt zum Plotten/Speichern/Anzeigen/etc zu verwenden, anstatt plt.plot usw., um implizit die aktuelle Figur/Achsen zu erhalten und darauf zu plotten. Es ist nichts falsch daran, pyplot für alles zu verwenden (vor allem interaktiv), aber es macht es einfacher, sich in den Fuß zu schießen. 

Verwenden Sie pyplot für plt.show() und zum Generieren einer Figur und eines Achsenobjekts, verwenden Sie dann direkt die Figur- oder Achsenmethoden. (z. B. ax.plot(x, y) anstelle von plt.plot(x, y) usw.) Der Hauptvorteil davon ist, dass es explizit ist. Sie wissen, auf welche Objekte Sie plotten, und Sie müssen nicht darüber nachdenken, was der Pyplot-Zustandsautomat tut (obwohl es auch nicht so schwer ist, die Zustandsmaschinen-Schnittstelle zu verstehen).

Als Beispiel für die "empfohlene" Vorgehensweise gehen Sie wie folgt vor:

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(-1, 1, 100)
y = x**2

fig, ax = plt.subplots()
ax.plot(x, y)
fig.savefig('fig1.pdf')
plt.show()
fig.savefig('fig2.pdf')

Wenn Sie die pyplot-Schnittstelle lieber für alles verwenden möchten, greifen Sie einfach zu der Figurinstanz, bevor Sie show aufrufen. Zum Beispiel:

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(-1, 1, 100)
y = x**2

plt.plot(x, y)
fig = plt.gcf()
fig.savefig('fig1.pdf')
plt.show()
fig.savefig('fig2.pdf')
51
Joe Kington

pyplot.show blockiert und zerstört die Zeichnung beim Schließen. Sie können verwenden

plt.show(block=False)

danach funktioniert das Speichern in fig2.pdf oder Sie können es vor dem Speichern erneut zeichnen

plt.plot(x,y)
plt.savefig('fig2.pdf')
3
miles82

Ich musste plt.cla() und plt.clf() ausführen, bevor ich den zweiten plottete. Aktuelle Achsen löschen bzw. aktuelle Darstellung löschen.

1

Wenn Sie die Figur nur vor dem Speichern sehen möchten, können Sie anrufen 

plt.ion()

vor dem Plotten, der den interaktiven Modus startet , und zeigt alle Figuren beim Zeichnen . Dadurch entfällt meist die Notwendigkeit, plt.show() aufzurufen. Sie müssen die Zahlen nicht mehr schließen, um fortzufahren.

Um den interaktiven Modus wieder zu deaktivieren, rufen Sie plt.ioff() auf.

0
serv-inc