python - example - Guarde la trama en el archivo de imagen en lugar de mostrarla utilizando Matplotlib
subplot python (14)
Estoy escribiendo un guión rápido y sucio para generar gráficos sobre la marcha. Estoy utilizando el siguiente código (de la documentación de Matplotlib ) como punto de partida:
from pylab import figure, axes, pie, title, show
# Make a square figure and axes
figure(1, figsize=(6, 6))
ax = axes([0.1, 0.1, 0.8, 0.8])
labels = ''Frogs'', ''Hogs'', ''Dogs'', ''Logs''
fracs = [15, 30, 45, 10]
explode = (0, 0.05, 0, 0)
pie(fracs, explode=explode, labels=labels, autopct=''%1.1f%%'', shadow=True)
title(''Raining Hogs and Dogs'', bbox={''facecolor'': ''0.8'', ''pad'': 5})
show() # Actually, don''t show, just save to foo.png
No quiero mostrar el gráfico en una GUI, en cambio, quiero guardar el gráfico en un archivo (por ejemplo, foo.png), para que, por ejemplo, se pueda usar en scripts por lotes. ¿Cómo puedo hacer eso?
Acaba de encontrar este enlace en la documentación de MatPlotLib que aborda exactamente este problema: http://matplotlib.org/faq/howto_faq.html#generate-images-without-having-a-window-appear
Dicen que la forma más fácil de evitar que la figura aparezca es utilizar un backend no interactivo (por ejemplo, Agg), a través de matplotib.use(<backend>)
, por ejemplo:
import matplotlib
matplotlib.use(''Agg'')
import matplotlib.pyplot as plt
plt.plot([1,2,3])
plt.savefig(''myfig'')
Personalmente prefiero usar plt.close( fig )
, ya que entonces tiene la opción de ocultar ciertas cifras (durante un bucle), pero todavía muestra las cifras para el procesamiento de datos posterior al bucle. Sin embargo, probablemente sea más lento que elegir un backend no interactivo, sería interesante si alguien lo probara.
Como han dicho otros, plt.savefig()
o fig1.savefig()
es la manera de guardar una imagen.
Sin embargo, he encontrado que en ciertos casos (por ejemplo, con Spyder teniendo plt.ion()
: modo interactivo = Activado), la figura siempre se muestra. Para evitar esto, forzo el cierre de la ventana de figuras en mi bucle gigante, por lo que no tengo un millón de figuras abiertas durante el bucle:
import matplotlib.pyplot as plt
fig, ax = plt.subplots( nrows=1, ncols=1 ) # create figure & 1 axis
ax.plot([0,1,2], [10,20,3])
fig.savefig(''path/to/save/image/to.png'') # save the figure to file
plt.close(fig) # close the figure
De acuerdo con la pregunta Matplotlib (pyplot) savefig muestra una imagen en blanco .
Una cosa debe tener en cuenta: si usa plt.show
y debería después de plt.savefig
, o dará una imagen en blanco.
Un ejemplo detallado:
import numpy as np
import matplotlib.pyplot as plt
def draw_result(lst_iter, lst_loss, lst_acc, title):
plt.plot(lst_iter, lst_loss, ''-b'', label=''loss'')
plt.plot(lst_iter, lst_acc, ''-r'', label=''accuracy'')
plt.xlabel("n iteration")
plt.legend(loc=''upper left'')
plt.title(title)
plt.savefig(title+".png") # should before plt.show method
plt.show()
def test_draw():
lst_iter = range(100)
lst_loss = [0.01 * i + 0.01 * i ** 2 for i in xrange(100)]
# lst_loss = np.random.randn(1, 100).reshape((100, ))
lst_acc = [0.01 * i - 0.01 * i ** 2 for i in xrange(100)]
# lst_acc = np.random.randn(1, 100).reshape((100, ))
draw_result(lst_iter, lst_loss, lst_acc, "sgd_method")
if __name__ == ''__main__'':
test_draw()
Después de usar el gráfico () y otras funciones para crear el contenido que desea, puede usar una cláusula como esta para seleccionar entre el trazado en la pantalla o el archivo:
import matplotlib.pyplot as plt
fig = plt.figure(figuresize=4, 5)
# use plot(), etc. to create your plot.
# Pick one of the following lines to uncomment
# save_file = None
# save_file = os.path.join(your_directory, your_file_name)
if save_file:
plt.savefig(save_file)
plt.close(fig)
else:
plt.show()
La solución :
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
matplotlib.style.use(''ggplot'')
ts = pd.Series(np.random.randn(1000), index=pd.date_range(''1/1/2000'', periods=1000))
ts = ts.cumsum()
plt.figure()
ts.plot()
plt.savefig("foo.png", bbox_inches=''tight'')
Si desea visualizar la imagen y guardarla, utilice:
%matplotlib inline
despues de import matplotlib
La solucion es:
pylab.savefig(''foo.png'')
Las otras respuestas son correctas. Sin embargo, a veces encuentro que quiero abrir el objeto figura más tarde. Por ejemplo, es posible que desee cambiar el tamaño de las etiquetas, agregar una cuadrícula o realizar otro procesamiento. En un mundo perfecto, simplemente ejecutaría el código que genera la trama y adaptaría la configuración. Ay, el mundo no es perfecto. Por lo tanto, además de guardar en PDF o PNG, agrego:
with open(''some_file.pkl'', "wb") as fp:
pickle.dump(fig, fp, protocol=4)
Así, más tarde puedo cargar el objeto figura y manipular la configuración como me plazca.
También escribo la pila con el diccionario de código fuente y locals()
para cada función / método en la pila, para que luego pueda decir exactamente qué generó la figura.
NB: Ten cuidado, ya que a veces este método genera archivos enormes.
Mientras que la pregunta ha sido respondida, me gustaría agregar algunos consejos útiles al usar savefig . El formato del archivo puede ser especificado por la extensión:
savefig(''foo.png'')
savefig(''foo.pdf'')
Dará una salida rasterizada o vectorizada respectivamente, ambas que podrían ser útiles. Además, encontrará que pylab
deja un espacio en blanco generoso, a menudo indeseable, alrededor de la imagen. Eliminar con:
savefig(''foo.png'', bbox_inches=''tight'')
Si no te gusta el concepto de la figura "actual", haz:
import matplotlib.image as mpimg
img = mpimg.imread("src.png")
mpimg.imsave("out.png", img)
Si, como yo, utilizas el IDE de Spyder, debes desactivar el modo interactivo con:
plt.ioff()
(este comando se inicia automáticamente con el inicio científico)
Si quieres habilitarlo de nuevo, usa:
plt.ion()
Usted puede hacer:
plt.show(hold=False)
plt.savefig(''name.pdf'')
y recuerde dejar que finalice savefig antes de cerrar el gráfico de GUI. De esta manera podrás ver la imagen de antemano.
Alternativamente, puede verlo con plt.show()
Luego cierre la GUI y ejecute el script nuevamente, pero esta vez reemplace plt.show()
con plt.savefig()
.
Alternativamente, puedes usar
fig, ax = plt.figure(nrows=1, ncols=1)
plt.plot(...)
plt.show()
fig.savefig(''out.pdf'')
Utilicé lo siguiente:
import matplotlib.pyplot as plt
p1 = plt.plot(dates, temp, ''r-'', label="Temperature (celsius)")
p2 = plt.plot(dates, psal, ''b-'', label="Salinity (psu)")
plt.legend(loc=''upper center'', numpoints=1, bbox_to_anchor=(0.5, -0.05), ncol=2, fancybox=True, shadow=True)
plt.savefig(''data.png'')
plt.show()
f.close()
plt.close()
Me pareció muy importante usar plt.show después de guardar la figura, de lo contrario no funcionará. cifra exportada en png
#write the code for the plot
plt.savefig("filename.png")
El archivo se guardará en el mismo directorio que el archivo python / Jupyter en ejecución
import datetime
import numpy as np
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt
# Create the PdfPages object to which we will save the pages:
# The with statement makes sure that the PdfPages object is closed properly at
# the end of the block, even if an Exception occurs.
with PdfPages(''multipage_pdf.pdf'') as pdf:
plt.figure(figsize=(3, 3))
plt.plot(range(7), [3, 1, 4, 1, 5, 9, 2], ''r-o'')
plt.title(''Page One'')
pdf.savefig() # saves the current figure into a pdf page
plt.close()
plt.rc(''text'', usetex=True)
plt.figure(figsize=(8, 6))
x = np.arange(0, 5, 0.1)
plt.plot(x, np.sin(x), ''b-'')
plt.title(''Page Two'')
pdf.savefig()
plt.close()
plt.rc(''text'', usetex=False)
fig = plt.figure(figsize=(4, 5))
plt.plot(x, x*x, ''ko'')
plt.title(''Page Three'')
pdf.savefig(fig) # or you can pass a Figure object to pdf.savefig
plt.close()
# We can also set the file''s metadata via the PdfPages object:
d = pdf.infodict()
d[''Title''] = ''Multipage PDF Example''
d[''Author''] = u''Jouni K. Sepp/xe4nen''
d[''Subject''] = ''How to create a multipage pdf file and set its metadata''
d[''Keywords''] = ''PdfPages multipage keywords author title subject''
d[''CreationDate''] = datetime.datetime(2009, 11, 13)
d[''ModDate''] = datetime.datetime.today()