Guarde el gráfico en el archivo de imagen en lugar de mostrarlo usando Matplotlib
Frecuentes
Visto 2,130 equipos
1443
Estoy escribiendo un script rápido y sucio para generar gráficos sobre la marcha. Estoy usando el siguiente código (de 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 el gráfico en una GUI, en su lugar, quiero guardar el gráfico en un archivo (digamos foo.png), para que, por ejemplo, se pueda usar en scripts por lotes. ¿Cómo puedo hacer eso?
23 Respuestas
1817
Si bien la pregunta ha sido respondida, me gustaría agregar algunos consejos útiles al usar matplotlib.pyplot.savefig
. El formato de archivo se puede especificar mediante 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 que 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 plt.savefig()
, de lo contrario, la imagen del archivo estará en blanco.
Respondido el 28 de Septiembre de 21 a las 21:09
255
Como han dicho otros, plt.savefig()
or fig1.savefig()
es de hecho la forma de guardar una imagen.
Sin embargo, he descubierto que en ciertos casos la figura siempre se muestra. (por ejemplo, con Spyder teniendo plt.ion()
: modo interactivo = Activado.) Soluciono esto forzando el cierre de la ventana de la figura en mi bucle gigante con plt.close(figure_object)
(consulta: documentación), por lo que no tengo 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 me probé).
Respondido el 30 de Septiembre de 19 a las 18:09
plt
es solo un alias para matplotlib.pyplot
, para facilitar la escritura. Busca el help(plt.subplots)
para ver qué devuelve, que también se menciona en los comentarios de mi código, uno Figure
objeto y uno Axis
objeto. - Demis
Tenga en cuenta que los nombres ax
/fig
/plt
están formados por nombres de variables, llámelos como desee. De cualquier manera, contienen Objetos. Puedes ver que objetos subplots
vuelve aquí: matplotlib.org/3.2.1/api/_as_gen/… y que pyplot
el módulo está aquí: matplotlib.org/tutorials/introductory/pyplot.html . - Demis
172
La solucion es:
pylab.savefig('foo.png')
Respondido 19 Oct 14, 08:10
pylab no está definido - user14349917
103
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 aparezca la figura es utilizar un backend 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 sigo prefiriendo usar plt.close( fig )
, desde entonces tiene la opción de ocultar ciertas cifras (durante un bucle), pero aún mostrar 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.
ACTUALIZACIÓN: para Spyder, generalmente no puede configurar el backend de esta manera (debido a que Spyder generalmente carga matplotlib temprano, lo que le impide usar matplotlib.use()
).
En su lugar, use plt.switch_backend('Agg')
, o apagar "habilitar soporte"en las preferencias de Spyder y ejecute el matplotlib.use('Agg')
mandarte a ti mismo.
Respondido el 09 de diciembre de 18 a las 02:12
Esto funciona muy bien para situaciones en las que no tienes una pantalla configurada. Usando otro backend con .plot()
arrojará un error si os.environ['DISPLAY']
no está configurado correctamente. - la estrategia de precio "economy".
Gracias. esto funciona y es muy útil para los servidores de producción donde no hay conexión a Internet y se necesita un administrador del sistema para instalar los paquetes. - milon sarker
Me gusta el tutorial que tiene el sitio matplotlib para la descripción / definición de "backends": matplotlib.org/tutorials/introductory/… - curtidor golpeado
56
Si no le gusta el concepto de figura "actual", haga lo siguiente:
import matplotlib.image as mpimg
img = mpimg.imread("src.png")
mpimg.imsave("out.png", img)
Respondido 19 Oct 14, 08:10
¿No es esto solo una copia? src.png
a out.png
? - Gerrit
Eso es solo un ejemplo, que muestra si tiene un objeto de imagen (img
), luego puede guardarlo en un archivo con .imsave()
método. - maravilla.mice
@ wonder.mice ayudaría a mostrar cómo crear una imagen sin usar la figura actual. - adivinar
@ wonder.mice Gracias por este ejemplo, es el primero que me mostró cómo guardar un objeto de imagen en .png. - Arthur Dent
@scry No siempre necesitas crear una imagen, a veces pruebas algún código y quieres una salida visual, es útil en tales ocasiones. - Sagitario
37
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()
Respondido el 30 de junio de 15 a las 09:06
plt.close()
es exactamente lo que estaba buscando! - Eenoku
33
Las otras respuestas son correctas. Sin embargo, a veces encuentro que quiero abrir la figura objeto 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 eso, 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, luego puedo cargar el objeto de 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, de modo que luego pueda decir exactamente qué generó la figura.
NB: tenga cuidado, ya que a veces este método genera archivos enormes.
Respondido 22 Feb 17, 14:02
¿No sería más fácil hacer el desarrollo en un portátil jupyter, con las cifras en línea? De esta manera, puede realizar un seguimiento exacto del historial e incluso volver a ejecutarlo. - Ciprian Tomoiaga
@CiprianTomoiaga Nunca genero gráficos de producción desde un shell interactivo de Python (Jupyter o de otro tipo). Trazo todo a partir de guiones. - Gerrit
30
Después de usar plot () y otras funciones para crear el contenido que desea, puede usar una cláusula como esta para seleccionar entre trazar en la pantalla o archivar:
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()
Respondido el 14 de enero de 19 a las 16:01
Algunos dicen fig = plt.figure(figuresize=4, 5)
podría ser fig = plt.figure(figsize=(4, 5)) #figure sizes in inches
- usuario
25
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
Respondido 05 Abr '16, 14:04
lo siento, ¿qué hay en esto? archivo de imagen trazado? f= plt.savefig('data.png')
- Morse
14
Si, como yo, usa Spyder IDE, debe desactivar el modo interactivo con:
plt.ioff()
(este comando se inicia automáticamente con el inicio científico)
Si desea habilitarlo nuevamente, use:
plt.ion()
Respondido 29 ago 15, 15:08
14
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 forma puedes ver la imagen de antemano.
Alternativamente, puede mirarlo con plt.show()
Luego cierre la GUI y ejecute el script nuevamente, pero esta vez reemplace plt.show()
a plt.savefig()
.
Alternativamente, puede utilizar
fig, ax = plt.figure(nrows=1, ncols=1)
plt.plot(...)
plt.show()
fig.savefig('out.pdf')
Respondido el 24 de Septiembre de 17 a las 00:09
obtuvo un argumento de palabra clave inesperado 'hold' - amitdatta
13
Según pregunta Matplotlib (pyplot) savefig genera una imagen en blanco.
Una cosa debe tener en cuenta: si usa plt.show
y debería después 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()
Respondido 20 Jul 18, 10:07
12
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 además de guardarla, utilice:
%matplotlib inline
después de
import matplotlib
respondido 27 mar '16, 09:03
10
Cuando usas 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 window
contestado el 11 de mayo de 20 a las 09:05
7
import matplotlib.pyplot as plt
plt.savefig("image.png")
En Jupyter Notebook tienes que eliminar plt.show()
y añade plt.savefig()
, junto con el resto del código plt en una celda. La imagen seguirá apareciendo en su cuaderno.
Respondido el 07 de enero de 19 a las 11:01
6
Además de los anteriores, agregué __file__
para el nombre para que la imagen y el archivo Python obtengan 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'
respondido 12 mar '20, 12:03
4
Dado que hoy (no estaba disponible cuando se hizo esta pregunta) mucha gente usa Jupyter Notebook como consola de Python, existe una manera extremadamente fácil de guardar los gráficos como .png
, solo llama al matplotlib
's pylab
class de Jupyter Notebook, trace la figura de las celdas jupyter 'en línea' y luego arrastre esa figura / imagen a un directorio local. No olvides
%matplotlib inline
en la primera linea!
Respondido el 01 de enero de 19 a las 17:01
esa es una buena idea, solo necesita tomar nota del impacto en si la imagen se deja incrustada en el cuaderno .. - Prusswan
4
Solo una nota extra porque todavía no puedo comentar las publicaciones.
Si está utilizando plt.savefig('myfig')
o algo por el estilo, asegúrese de agregar un plt.clf()
después de que se guarde su imagen. Esto se debe a que savefig no cierra el gráfico y si agrega al gráfico después sin un plt.clf()
estará agregando a la trama 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.
Respondido el 29 de junio de 21 a las 16:06
2
Como se sugirió anteriormente, puede usar:
import matplotlib.pyplot as plt
plt.savefig("myfig.png")
Para guardar cualquier imagen de IPhython que esté mostrando. O en una nota diferente (mirando desde un ángulo diferente), si alguna vez se pone a trabajar con un CV abierto, o si ha importado un CV abierto, puede optar por:
import cv2
cv2.imwrite("myfig.png",image)
Pero esto es solo por si necesita trabajar con Open CV. De lo contrario plt.savefig()
debería ser suficiente
respondido 29 mar '21, 09:03
2
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 utilizo mucho este decorador para publicar artículos académicos en varias revistas de la American Chemical Society, American Physics Society, Opticcal Society American, Elsivier, etc.
Se puede encontrar un ejemplo en la siguiente imagen (https://github.com/MarkMa1990/gradientDescent):
Respondido 06 ago 21, 17:08
0
Puedes guardar tu imagen con cualquier extensión (png, jpg, etc.) Y con la resolución que desees. Aquí tienes una función para guardar tu 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:)
Respondido el 25 de junio de 19 a las 18:06
0
Puedes hacerlo así:
def plotAFig():
plt.figure()
plt.plot(x,y,'b-')
plt.savefig("figurename.png")
plt.close()
Respondido 20 ago 19, 15:08
0
Nada funcionaba 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 ayude a alguien.
Respondido el 22 de junio de 21 a las 09:06
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas python matplotlib plot or haz tu propia pregunta.
Muchas de las respuestas en la parte inferior de la página mencionan
plt.close(fig)
que es especialmente importante en bucles grandes. De lo contrario, las figuras permanecen abiertas y esperando en la memoria y todas las figuras abiertas se mostrarán al ejecutarplt.show()
- timctranpylab
ya no debe usarse: ¿Cuál es la forma recomendada de graficar: matplotlib o pylab? - Trenton McKinney