Appel de pylab.savefig sans affichage dans ipython

111

J'ai besoin de créer une figure dans un fichier sans l'afficher dans le bloc-notes IPython. Je ne suis pas clair sur l'interaction entre IPythonet matplotlib.pylabà cet égard. Mais, lorsque j'appelle, pylab.savefig("test.png")le chiffre actuel s'affiche en plus d'être enregistré dans test.png. Lors de l'automatisation de la création d'un grand ensemble de fichiers de tracé, cela n'est souvent pas souhaitable. Ou dans le cas où un fichier intermédiaire pour un traitement externe par une autre application est souhaité.

Je ne sais pas s'il s'agit d'une question matplotlibou d' un IPythoncahier.

tnt
la source
La réponse de @staticfloat a fonctionné pour moi même lorsque je ne suis pas dans un cahier et lorsque vous utilisez matplotlib via JuliaLang; en utilisantioff
Vass

Réponses:

173

Ceci est une question matplotlib, et vous pouvez contourner cela en utilisant un backend qui ne s'affiche pas pour l'utilisateur, par exemple 'Agg':

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

plt.plot([1,2,3])
plt.savefig('/tmp/test.png')

MODIFIER: Si vous ne voulez pas perdre la possibilité d'afficher les tracés, désactivez le mode interactif et n'appelez que plt.show()lorsque vous êtes prêt à afficher les tracés:

import matplotlib.pyplot as plt

# Turn interactive plotting off
plt.ioff()

# Create a new figure, plot into it, then close it so it never gets displayed
fig = plt.figure()
plt.plot([1,2,3])
plt.savefig('/tmp/test0.png')
plt.close(fig)

# Create a new figure, plot into it, then don't close it so it does get displayed
plt.figure()
plt.plot([1,3,2])
plt.savefig('/tmp/test1.png')

# Display all "open" (non-closed) figures
plt.show()
flotteur statique
la source
2
Ok - mais, je veux généralement conserver le traçage en ligne dans iPython. Ce que vous suggérez fonctionne bien si vous effectuez un changement complet sur le backend. La question est de savoir comment tenir compte de la situation générale du traçage en ligne avec le cas exceptionnel de la sauvegarde des chiffres (sans affichage en ligne). Avec votre suggestion, j'ai tenté de recharger les modules et de changer le backend temporairement mais sans succès. Des idées sur la façon de modifier temporairement le backend dans une session de bloc-notes iPython?
tnt
1
J'ai mis à jour la question pour parler du traçage interactif et des commandes close()et show(), ce qui devrait résoudre votre problème. le changement de backends à la volée n'est pas pris en charge, comme vous l'avez découvert.
staticfloat
3
Merci pour les excellents commentaires. Il semble que le plt.close (fig) soit la commande clé pour mon besoin. Je ne suis toujours pas clair sur l'ioff car il ne semble pas avoir d'impact sur l'opération; mais, je manque probablement quelque chose. Merci encore.
tnt
1
La recette que j'ai donnée est générale; si vous ne travaillez pas dans le notebook ipython, plt.ioff () est important pour empêcher les chiffres de scintiller sur et en dehors de l'écran, car en ligne de commande, les chiffres ipython sont tracés dès que vous appelez plt.plot()si le mode interactif est activé. La désactivation du mode interactif retarde l'affichage de tous les tracés jusqu'à plt.show(). Étant donné que vous utilisez le bloc-notes ipython, le mode interactif est traité différemment.
staticfloat
Pour moi, matplotlib.use('Agg')seul a fait l'affaire. Je n'en avais pas besoin plt.show()ni plt.ioff()dans mon code du tout.
Zhanwen Chen
67

Nous n'avons pas besoin de plt.ioff()ou plt.show()(si nous utilisons %matplotlib inline). Vous pouvez tester le code ci-dessus sans plt.ioff(). plt.close()a le rôle essentiel. Essaye celui-là:

%matplotlib inline
import pylab as plt

# It doesn't matter you add line below. You can even replace it by 'plt.ion()', but you will see no changes.
## plt.ioff()

# Create a new figure, plot into it, then close it so it never gets displayed
fig = plt.figure()
plt.plot([1,2,3])
plt.savefig('test0.png')
plt.close(fig)

# Create a new figure, plot into it, then don't close it so it does get displayed
fig2 = plt.figure()
plt.plot([1,3,2])
plt.savefig('test1.png')

Si vous exécutez ce code dans iPython, il affichera un deuxième tracé, et si vous ajoutez plt.close(fig2)à la fin de celui-ci, vous ne verrez rien.

En conclusion, si vous fermez la figure plt.close(fig), elle ne sera pas affichée.

Mojtaba Khodadadi
la source
5
Meilleure solution en effet! Je génère et enregistre de nombreux tracés dans une boucle. Avec plt.ioffje reçois RuntimeWarning: More than 20 figures have been opened.... plt.closerésolu.
Nagasaki45