2014-02-19 6 views
26

Der folgende Beispielcode generiert ein einfaches Diagramm, speichert es dann in 'fig1.pdf', zeigt es an und speichert es dann erneut in 'fig2.pdf ". Das erste Bild sieht wie erwartet aus, aber das zweite Bild ist leer (enthält ein weißes Quadrat). Was ist hier eigentlich los? Die Zeile plt.show() vermasselt anscheinend etwas, aber ich kann nicht herausfinden, was/wie!Speichern einer Figur nach dem Aufrufen von pyplot.show() führt zu einer leeren Datei

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') 

Antwort

36

Speichern Wenn Sie die Figur nach Beginn der Anzeige speichern möchten, müssen Sie um an der Figureninstanz festzuhalten. Der Grund dafür, dass plt.savefig nach dem Aufruf von show nicht funktioniert, ist, dass die aktuelle Zahl zurückgesetzt wurde.

pyplot verfolgt hinter den Kulissen, welche Figuren, Achsen usw. "aktuell" sind (d. H. Noch nicht mit show angezeigt wurden). gcf und gca erhalten die aktuelle Figur und die aktuellen Achseninstanzen. plt.savefig (und im Wesentlichen jede andere pyplot Methode) tut gerade plt.gcf().savefig(...). Mit anderen Worten, rufen Sie die aktuelle Figureninstanz ab und rufen Sie die Methode savefig auf. Ähnlich funktioniert plt.plot grundsätzlich plt.gca().plot(...).

Nachdem show aufgerufen wurde, ist die Liste der "aktuellen" Figuren und Achsen leer.

Im Allgemeinen ist es besser, direkt die Figuren- und Achseninstanzen zu verwenden, um/plot/save/show/etc anstatt plt.plot usw. zu verwenden, um implizit die aktuelle Zahl/Achse und den Plot zu erhalten. Es ist nichts falsch daran, pyplot für alles zu verwenden (besonders interaktiv), aber es macht es einfacher, sich in den Fuß zu schießen.

Verwenden Sie pyplot für plt.show() und generieren Sie eine Abbildung und ein Achsenobjekt, aber verwenden Sie dann direkt die Zahlen- 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 welchen Objekten Sie zeichnen, und müssen nicht darüber nachdenken, was die pyplot-Zustandsmaschine tut (obwohl es auch nicht so schwer ist, die Zustands-Maschine-Schnittstelle zu verstehen).

Als Beispiel für die „empfohlenen“ Art und Weise, Dinge zu tun, so etwas wie:

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 lieber die pyplot Schnittstelle für alles verwenden würde, dann die Figur Instanz nur greifen, bevor Sie show nennen . 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') 
+0

edit nm, herausgefunden, das ist nicht interaktiv – tacaswell

+1

+1, Joe.Dies, IMO, zeigt, warum die Verwendung der pyplot-Schnittstelle auf ein Minimum beschränkt werden sollte. –

3

pyplot.show blockiert und zerstört das Diagramm beim Schließen. Sie können mit

plt.show(block=False) 

, nach der die zu fig2.pdf speichern funktioniert oder Sie können es wieder plotten vor

plt.plot(x,y) 
plt.savefig('fig2.pdf') 
+0

Das ist nicht was "Block" steuert, für was es wert ist. 'block' steuert, ob oder die Hauptschleife des GUI-Toolkits die weitere Ausführung blockiert oder in einem separaten Thread abläuft. –

1

Ich hatte plt.cla() und plt.clf() vor dem Plotten der zweiten auszuführen. Beseitigen Sie die aktuellen Achsen und löschen Sie das aktuelle Diagramm.

Verwandte Themen