Estoy escribiendo un guión rápido y sucio para generar tramas sobre la marcha. Estoy usando 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.pngNo 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, pueda usarse en secuencias de comandos por lotes. ¿Cómo puedo hacer eso?
La solucion es:
pylab.savefig('foo.png')Si bien se respondió la pregunta, me gustaría agregar algunos consejos útiles al usarmatplotlib.pyplot.savefig . El formato de archivo puede ser especificado por la extensión:
from matplotlib import pyplot as plt plt.savefig('foo.png') plt.savefig('foo.pdf')Dará una salida rasterizada o vectorizada respectivamente, ambas podrían ser útiles. Además, a menudo hay un espacio en blanco no deseado alrededor de la imagen, que se puede eliminar con:
plt.savefig('foo.png', bbox_inches='tight') Tenga en cuenta que si muestra la trama, plt.show() debe seguir a plt.savefig() , de lo contrario, la imagen del archivo estará en blanco.
Si no le gusta el concepto de la figura "actual", haga lo siguiente:
import matplotlib.image as mpimg img = mpimg.imread("src.png") mpimg.imsave("out.png", img)Como han dicho otros, plt.savefig() o fig1.savefig() es de hecho la forma de guardar una imagen.
Sin embargo, descubrí que, en ciertos casos, la figura siempre se muestra . (por ejemplo, con Spyder teniendo plt.ion() : modo interactivo = Activado). Resuelvo esto forzando el cierre de la ventana de la figura en mi bucle gigante con plt.close(figure_object) (ver documentación ), así que no t tener un millón de cifras 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 window Debería poder volver a abrir la figura más tarde si es necesario con fig.show() (no lo probé).
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()Si, como yo, usa Spyder IDE, debe desactivar el modo interactivo con:
plt.ioff()
(este comando se lanza automáticamente con el inicio científico)
Si desea habilitarlo nuevamente, use:
plt.ion()
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-have-a-window-appear
Dicen que la forma más fácil de evitar que aparezca la figura es usar 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') Todavía personalmente prefiero usar plt.close( fig ) , ya que entonces tiene la opción de ocultar ciertas cifras (durante un bucle), pero aún muestra 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 probara eso.
ACTUALIZACIÓN : para Spyder, generalmente no puede configurar el backend de esta manera (porque Spyder generalmente carga matplotlib temprano, lo que le impide usar matplotlib.use() ).
En su lugar, use plt.switch_backend('Agg') o desactive " habilitar soporte " en las preferencias de Spyder y ejecute el matplotlib.use('Agg') usted mismo.
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 mostrar la imagen y guardar la imagen, use:
%matplotlib inline después de import matplotlib
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()Encontré muy importante usar plt.show después de guardar la figura, de lo contrario no funcionará. figura exportada en png
Las otras respuestas son correctas. Sin embargo, a veces encuentro que quiero abrir el objeto de figura más tarde. Por ejemplo, es posible que desee cambiar los tamaños de las etiquetas, agregar una cuadrícula o realizar otro procesamiento. En un mundo perfecto, simplemente volvería a ejecutar el código que genera la trama y adaptaría 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)Así, más tarde puedo cargar el objeto de la figura y manipular la configuración a mi antojo.
También escribo la pila con el código fuente y el diccionario locals() para cada función/método en la pila, de modo que luego pueda decir exactamente qué generó la figura.
NB: Tenga cuidado, ya que a veces este método genera archivos de gran tamaño.
Después de usar plot() y otras funciones para crear el contenido que desea, puede usar una cláusula como esta para seleccionar entre dibujar en la pantalla o en un archivo:
import matplotlib.pyplot as plt fig = plt.figure(figsize=(4, 5)) # size in inches # 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()Puedes hacer:
plt.show(hold=False) plt.savefig('name.pdf')y recuerde dejar que savefig finalice antes de cerrar el gráfico de la GUI. De esta manera se puede 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() .
Como alternativa, puede utilizar
fig, ax = plt.figure(nrows=1, ncols=1) plt.plot(...) plt.show() fig.savefig('out.pdf')De acuerdo con la pregunta, Matplotlib (pyplot) savefig genera una imagen en blanco .
Una cosa debe tener en cuenta: si usa plt.show y debería hacerlo después de plt.savefig , o le 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()import matplotlib.pyplot as plt plt.savefig("image.png") En Jupyter Notebook, debe eliminar plt.show() y agregar plt.savefig() , junto con el resto del código plt en una celda. La imagen seguirá apareciendo en su cuaderno.
Dado que hoy (no estaba disponible cuando se hizo esta pregunta) mucha gente usa Jupyter Notebook como consola de Python, hay una manera extremadamente fácil de guardar los gráficos como .png , simplemente llame a la clase pylab de matplotlib desde Jupyter Notebook, trace la figura 'en línea' celdas jupyter, y luego arrastre esa figura/imagen a un directorio local. ¡No olvide %matplotlib inline en la primera línea!
Puede guardar su imagen con cualquier extensión (png, jpg, etc.) y con la resolución que desee. Aquí hay una función para guardar su figura.
import os def save_fig(fig_id, tight_layout=True, fig_extension="png", resolution=300): path = os.path.join(IMAGES_PATH, fig_id + "." + fig_extension) print("Saving figure", fig_id) if tight_layout: plt.tight_layout() plt.savefig(path, format=fig_extension, dpi=resolution)'fig_id' es el nombre con el que desea guardar su figura. Espero eso ayude:)
Además de los anteriores, agregué __file__ como nombre para que la imagen y el archivo de Python tengan los mismos nombres. También agregué algunos argumentos para que se vea mejor:
# Saves a PNG file of the current graph to the folder and updates it every time # (nameOfimage, dpi=(sizeOfimage),Keeps_Labels_From_Disappearing) plt.savefig(__file__+".png",dpi=(250), bbox_inches='tight') # Hard coded name: './test.png'Puedes hacerlo así:
def plotAFig(): plt.figure() plt.plot(x,y,'b-') plt.savefig("figurename.png") plt.close()Como se sugirió antes, puede usar:
import matplotlib.pyplot as plt plt.savefig("myfig.png")Para guardar cualquier imagen de IPhython que estés mostrando. O en una nota diferente (mirando desde un ángulo diferente), si alguna vez trabaja con un CV abierto, o si ha importado un CV abierto, puede optar por:
import cv2 cv2.imwrite("myfig.png",image) Pero esto es por si acaso si necesita trabajar con Open CV. De lo contrario plt.savefig() debería ser suficiente.
Cuando use matplotlib.pyplot , primero debe guardar su gráfico y luego cerrarlo usando estas 2 líneas:
fig.savefig('plot.png') # save the plot, place the path you want to save the figure in quotation plt.close(fig) # close the figure windowNada estaba funcionando para mí. El problema es que la imagen guardada era muy pequeña y no pude encontrar cómo diablos hacerla más grande.
Esto parece hacerlo más grande, pero aún no a pantalla completa.
https://matplotlib.org/stable/api/figure_api.html#matplotlib.figure.Figure.set_size_inches
fig.set_size_inches((ancho, alto))
Espero que eso ayude a alguien.
Solo una nota adicional porque todavía no puedo comentar en las publicaciones.
Si está utilizando plt.savefig('myfig') o algo similar, asegúrese de agregar un plt.clf() después de guardar su imagen. Esto se debe a que savefig no cierra la gráfica y si agrega a la gráfica después sin plt.clf() , estará agregando a la gráfica anterior.
Es posible que no note si sus tramas son similares, ya que se trazarán sobre la trama anterior, pero si está en un bucle guardando sus figuras, la trama se volverá masiva lentamente y hará que su guión sea muy lento.
bueno, recomiendo usar envoltorios para renderizar o controlar el trazado. los ejemplos pueden ser mpltex ( https://github.com/liuyxpp/mpltex ) o prettyplotlib ( https://github.com/olgabot/prettyplotlib ).
import mpltex @mpltex.acs_decorator def myplot(): plt.figure() plt.plot(x,y,'b-',lable='xxx') plt.tight_layout(pad=0.5) plt.savefig('xxxx') # the figure format was controlled by the decorator, it can be either eps, or pdf or png.... plt.close()Básicamente, uso mucho este decorador para publicar artículos académicos en varias revistas de la American Chemical Society, la American Physics Society, la Opticcal Society American, Elsivier, etc.
Se puede encontrar un ejemplo en la siguiente imagen ( https://github.com/MarkMa1990/gradientDescent ): 
usando 'agg' debido a que no hay interfaz gráfica de usuario en el servidor. Depuración en ubuntu 21.10 con gui y VSC. En la depuración, intento mostrar un gráfico y luego guardarlo en un archivo para la interfaz de usuario web.
Descubrí que se requiere guardar antes de mostrar, de lo contrario, la trama guardada está en blanco. Supongo que mostrarlo aclarará la trama por alguna razón. Hacer esto:
plt.savefig(imagePath) plt.show() plt.close(fig)En lugar de esto:
plt.show() plt.savefig(imagePath) plt.close(fig)