Question Enregistrer le graphique dans le fichier image au lieu de l'afficher à l'aide de Matplotlib


J'écris un script rapide et sale pour générer des complots à la volée. J'utilise le code ci-dessous (de Matplotlib documentation) comme point de départ:

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

Je ne veux pas afficher le tracé sur une interface graphique, mais je veux enregistrer le tracé dans un fichier (disons foo.png), de sorte que, par exemple, il puisse être utilisé dans des scripts batch. Comment je fais ça?


734
2018-03-08 17:38


origine


Réponses:


Alors que la question a été répondue, je voudrais ajouter quelques conseils utiles lors de l'utilisation savefig. Le format de fichier peut être spécifié par l'extension:

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

Donnera une sortie pixellisée ou vectorisée respectivement, les deux qui pourraient être utiles. De plus, vous trouverez que pylab laisse un espace généreux, souvent indésirable, autour de l'image. Retirez-le avec:

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

897
2018-03-27 13:35



La solution est:

pylab.savefig('foo.png')

125
2018-03-27 11:36



Comme d'autres l'ont dit, plt.savefig() ou fig1.savefig() est en effet le moyen de sauver une image.

Cependant, j'ai trouvé que dans certains cas (par exemple avec Spyder ayant plt.ion(): mode interactif = On) la figure est toujours affichée. Je contourne cela en forçant la fermeture de la fenêtre de chiffres dans ma boucle géante, donc je n'ai pas un million de chiffres ouverts pendant la boucle:

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



Vous venez de trouver ce lien sur la documentation de MatPlotLib qui résout exactement ce problème: http://matplotlib.org/faq/howto_faq.html#generate-images-without-having-a-window-appear

Ils disent que le moyen le plus simple d'empêcher le chiffre d'apparaître est d'utiliser un backend non-interactif (par exemple Agg), via matplotib.use(<backend>), par exemple:

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

Je préfère toujours utiliser plt.close( fig )Depuis, vous avez la possibilité de masquer certaines figures (pendant une boucle), mais vous pouvez toujours afficher des chiffres pour le traitement des données post-boucle. Il est probablement plus lent que de choisir un backend non-interactif - serait intéressant si quelqu'un a testé cela.


58
2018-01-04 00:35



Si vous n'aimez pas le concept de la figure "actuelle", faites:

import matplotlib.image as mpimg

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

32
2018-01-30 18:30



Les autres réponses sont correctes. Cependant, je trouve parfois que je veux ouvrir la figure objet plus tard. Par exemple, je pourrais vouloir changer la taille des étiquettes, ajouter une grille, ou faire un autre traitement. Dans un monde parfait, je voudrais simplement réexécuter le code générant l'intrigue, et adapter les paramètres. Hélas, le monde n'est pas parfait. Par conséquent, en plus d'enregistrer au format PDF ou PNG, j'ajoute:

with open('some_file.pkl', "wb") as fp:
    pickle.dump(fig, fp, protocol=4)

Comme ça, je peux plus tard charger l'objet figure et manipuler les paramètres à ma guise.

J'écris aussi la pile avec le code source et locals() dictionnaire pour chaque fonction / méthode dans la pile, de sorte que je puisse dire plus tard exactement ce qui a généré la figure.

NB: Attention, cette méthode génère parfois des fichiers volumineux.


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



Après avoir utilisé le plot () et d'autres fonctions pour créer le contenu que vous voulez, vous pouvez utiliser une clause comme celle-ci pour choisir entre le tracé à l'écran ou le fichier:

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



J'ai utilisé ce qui suit:

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

J'ai trouvé très important d'utiliser plt.show après avoir enregistré la figure, sinon ça ne marchera pas.figure exportée en png


15
2018-04-05 13:34



Si, comme moi, vous utilisez l'IDE Spyder, vous devez désactiver le mode interactif avec:

plt.ioff()

(cette commande est automatiquement lancée avec le démarrage scientifique)

Si vous souhaitez l'activer à nouveau, utilisez:

plt.ion()


10
2017-08-29 14:50