Keep a figure "on hold" after running a script


Question

I have this Python code:

from pylab import *
from numpy import *

time=linspace(-pi,pi,10000)
ycos=cos(time)
ysin=sin(time)

plot(time,ycos)
plot(time,ysin)

show()

If I do all these steps via an Ipython terminal, I can keep the figure open and interact with it. However, if I run the script via $python script.py the figure opens and closes instantly.

How could I have the same behavior as the Ipython terminal but when run as a script?

1
14
3/27/2016 8:41:21 PM

Accepted Answer

Here is a more sensible answer after taking a quick look into the problem.

First, let us suppose that

from matplotlib import pylab
pylab.plot(range(10), range(10))
pylab.show()

does not "hold on" the plot, i.e., it is barely shown before the program ends. If that happens, then the call pylab.show() assumed you were running in interactive mode, so there is some other process going on that will continue executing after this function is called. Since this is not the case, Python exits and so does the plot display. Now, the first approach to solve this is forcing pylab.show to block by doing:

pylab.show(block=True)

Still, we don't know why pylab.show assumed you were running in interactive mode. To confirm its assumption, experiment running the following code

import matplotlib
print matplotlib.is_interactive()

if this prints True, then that means your default configuration is set to interactive: True. To check which configuration is that, do print matplotlib.matplotlib_fname() to find out the path to it. Open it and check the value for the interactive parameter.

Now, if you prefer to not modify the configuration I would suggest a different solution:

import matplotlib
from matplotlib import pylab

if matplotlib.is_interactive():
    pylab.ioff()
pylab.plot(range(10), range(10))
pylab.show()

so there is no situation where matplotlib thinks it has to render stuff before calling the show method. Lastly, the most horrible of these solutions would be the use of pylab.pause or equivalents:

from matplotlib import pylab
pylab.ion()  # Force interactive    
pylab.plot(range(10), range(10))
pylab.show() # This does not block
pylab.pause(2**31-1)
18
12/21/2012 4:58:41 PM

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon