Pregunta Guarde el diagrama en el archivo de imagen en lugar de mostrarlo usando Matplotlib


Estoy escribiendo un guión rápido y sucio para generar tramas sobre la marcha. Estoy usando el siguiente código (desde Matplotlib documentación) 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 la trama en una GUI, en cambio, quiero guardar la trama en un archivo (digamos foo.png), para que, por ejemplo, se pueda usar en secuencias de comandos por lotes. ¿Cómo puedo hacer eso?


734
2018-03-08 17:38


origen


Respuestas:


Si bien la pregunta ha sido respondida, me gustaría agregar algunos consejos útiles al usar savefig. El formato de archivo puede ser especificado por la extensión:

savefig('foo.png')
savefig('foo.pdf')

Proporcionará una salida rasterizada o vectorizada respectivamente, ambas que podrían ser útiles. Además, encontrarás que pylab deja un espacio en blanco generoso, a menudo indeseable, alrededor de la imagen. Eliminarlo con:

savefig('foo.png', bbox_inches='tight')

897
2018-03-27 13:35



La solucion es:

pylab.savefig('foo.png')

125
2018-03-27 11:36



Como otros han dicho, plt.savefig() o fig1.savefig() de hecho es la forma 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. Trabajo alrededor de esto forzando el cierre de la ventana de figura en mi bucle gigante, así que no tengo un millón de figuras abiertas durante el ciclo:

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

110
2018-04-28 22:35



Acabo 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 back-end no interactivo (por ejemplo, Agg), a través de matplotib.use(<backend>), p.ej:

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
plt.plot([1,2,3])
plt.savefig('myfig')

Yo personalmente todavía prefiero usar plt.close( fig ), desde entonces tiene la opción de ocultar ciertas cifras (durante un ciclo), pero aún así mostrar las cifras para el procesamiento de datos post-loop. Sin embargo, es probablemente más lento que elegir un back-end no interactivo; sería interesante si alguien lo probara.


58
2018-01-04 00:35



Si no te gusta el concepto de la figura "actual", hazlo:

import matplotlib.image as mpimg

img = mpimg.imread("src.png")
mpimg.imsave("out.png", img)

32
2018-01-30 18:30



Las otras respuestas son correctas. Sin embargo, a veces me parece que quiero abrir la figura objeto luego. Por ejemplo, podría querer cambiar los tamaños de etiqueta, agregar una cuadrícula o hacer otro procesamiento. En un mundo perfecto, simplemente volvería a ejecutar el código que genera la trama y adaptaré la configuración. Por desgracia, 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)

De esta manera, más tarde puedo cargar el objeto figura y manipular la configuración como me plazca.

También escribo la pila con el código fuente y locals() diccionario para cada función / método en la pila, para que luego pueda decir exactamente qué generó la figura.

NB: Tenga cuidado, ya que a veces este método genera archivos enormes.


22
2018-05-26 11:48



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

21
2018-06-30 08:38



Después de usar el diagrama () y otras funciones para crear el contenido que desea, puede usar una cláusula como esta para seleccionar entre trazar en la pantalla o en 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()

17
2017-10-11 22:12



Usé 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á.figura exportada en png


15
2018-04-05 13:34



Si, como yo, utilizas Spyder IDE, debes inhabilitar el modo interactivo con:

plt.ioff()

(este comando se inicia automáticamente con el inicio científico)

Si quiere habilitarlo de nuevo, use:

plt.ion()


10
2017-08-29 14:50