Pregunta Guardar una figura después de invocar a pyplot.show () da como resultado un archivo vacío


El siguiente código de ejemplo genera un gráfico simple, luego lo guarda en 'fig1.pdf', luego lo muestra y luego lo guarda de nuevo en 'fig2.pdf'. La primera imagen se ve como se esperaba, pero la segunda está en blanco (contiene un cuadrado blanco). ¿Qué está pasando realmente aquí? La línea plt.show()  aparentemente arruina algo, ¡pero no puedo entender qué / cómo!

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

32
2018-02-19 08:53


origen


Respuestas:


Si desea guardar la figura después de mostrarla, necesitará aferrarse a la instancia de figura. La razón que plt.savefig no funciona después de llamar show es que la cifra actual se ha restablecido.

pyplot realiza un seguimiento de qué figuras, ejes, etc. son "actuales" (es decir, aún no se han mostrado con show) detrás de las escenas. gcf y gca obtener la figura actual y las instancias de los ejes actuales, respectivamente. plt.savefig (y esencialmente cualquier otro pyplot método) simplemente lo hace plt.gcf().savefig(...). En otras palabras, obtenga la instancia de la figura actual y llame a su savefig método. similar plt.plot básicamente hace plt.gca().plot(...).

Después show se llama, la lista de figuras y ejes "actuales" está vacía.

En general, es mejor usar directamente las instancias de figuras y ejes para trazar / guardar / mostrar / etc, en lugar de utilizar plt.plot, etc., para obtener implícitamente la figura / ejes actuales y trazar sobre ella. No hay nada malo con el uso pyplot para todo (especialmente interactivamente), pero hace que sea más fácil pegarse un tiro en el pie.

Utilizar pyplot para plt.show() y para generar una figura y un objeto (s) de eje, pero luego usa los métodos de figura o eje directamente. (p.ej. ax.plot(x, y) en lugar de plt.plot(x, y), etc.) La principal ventaja de esto es que es explícito. Usted sabe en qué objetos está trazando y no tiene que razonar sobre lo que hace la máquina de estado pyplot (aunque tampoco es tan difícil de entender la interfaz estado-máquina).

Como ejemplo de la forma "recomendada" de hacer las cosas, haga algo como:

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

Si prefieres usar el pyplot interfaz para todo, luego solo toma la instancia de figura antes de llamar show. Por ejemplo:

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

40
2018-02-19 14:58



pyplot.show bloquea y destruye la trama al cerrar. Puedes usar

plt.show(block=False)

después de lo cual funcionará guardar en fig2.pdf o puede trazarlo de nuevo antes de guardarlo

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

3
2018-02-19 09:21



Tuve que correr plt.cla() y plt.clf() antes de trazar el segundo. Borrar los ejes actuales y borrar el gráfico actual, respectivamente.


1
2017-08-30 18:11