Calling pylab.savefig without display in ipython
Asked Answered
T

4

178

I need to create a figure in a file without displaying it within IPython notebook. I am not clear on the interaction between IPython and matplotlib.pylab in this regard. But, when I call pylab.savefig("test.png") the current figure get's displayed in addition to being saved in test.png. When automating the creation of a large set of plot files, this is often undesirable. Or in the situation that an intermediate file for external processing by another app is desired.

Not sure if this is a matplotlib or IPython notebook question.

Tina answered 30/3, 2013 at 0:0 Comment(1)
The answer by @staticfloat worked for me even when not within a notebook, and when using matplotlib through JuliaLang; using ioffTorquemada
I
254

This is a matplotlib question, and you can get around this by using a backend that doesn't display to the user, e.g. 'Agg':

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

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

EDIT: If you don't want to lose the ability to display plots, turn off Interactive Mode, and only call plt.show() when you are ready to display the plots:

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()
Ilke answered 30/3, 2013 at 0:35 Comment(6)
Ok - but, I want to generally retain the inline plotting within iPython. What you suggest works fine if make a complete switch on the backend. The question is how do you allow for the general situation of inline plotting with the exceptional case of saving figures (without showing inline). With your suggestion, I attempted to reload the modules and change the backend temporarily but without success. Any ideas on how to temporarily change out the backend within an iPython notebook session?Tina
I have updated the question to talk about interactive plotting and the close() and show() commands, which should solve your problem. changing out backends on the fly is not supported, as you have discovered.Ilke
Thank you for the excellent feedback. It seems that the plt.close(fig) is the key command for my need. I am still not clear on the ioff as it does not seem to impact the operation; but, I am probably missing something. Thanks again.Tina
The recipe I have given is a general one; if you are not working in the ipython notebook, plt.ioff() is important to stop figures from flickering on and off the screen, as in command-line ipython figures are plotted as soon as you call plt.plot() if interactive mode is on. Turning interactive mode off delays the display of any plots until plt.show(). Because you are using the ipython notebook, interactive mode is treated differently.Ilke
For me, matplotlib.use('Agg') alone did the trick. I did not need any plt.show() or plt.ioff() in my code at all.Bohaty
how to revert to the standard backend after using 'Agg'?Putamen
E
110

We don't need to plt.ioff() or plt.show() (if we use %matplotlib inline). You can test above code without plt.ioff(). plt.close() has the essential role. Try this one:

%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')

If you run this code in iPython, it will display a second plot, and if you add plt.close(fig2) to the end of it, you will see nothing.

In conclusion, if you close figure by plt.close(fig), it won't be displayed.

Efface answered 6/8, 2015 at 1:23 Comment(2)
Better solution indeed! I generate and save many plots in a loop. With plt.ioff I get RuntimeWarning: More than 20 figures have been opened.... plt.close solved it.Kerch
Simply call plt.close() at the end of each plot instead of plt.show() and they won't be displayed. This is the best solution as it doesn't change any global behaviour and requires just one line.Bilyeu
M
1

Just call plt.close() rather that plt.show()

xs = [1,2,3]
ys = [1,4,9]
plt.plot(xs, ys)
# plt.show() # will show the plot
plt.close() # will close the plot
Materiel answered 17/5, 2023 at 10:33 Comment(0)
S
0

Just an addition to the previous answers: plt.close('all') will close all figures, just in case you not only want to close one figure. Moreover you can also specify specific figures that you want to close https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.close.html This might be helpful if you plot multiple figures in a loop.

Sabadilla answered 4/7, 2023 at 7:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.