Introduction
As I am coming from matlab, I am used to an interactive interface where a script can update figures while it is running. During the processing each figure can be re-sized or even closed. This probably means that each figure is running in its own thread which is obviously not the case with matplotlib.
IPython can imitate the Matlab behavior using the magic command %pylab
or %matplotlib
which does something that I don't understand yet and which is the very point of my question.
My goal is then to allow standalone Python scripts to work as Matlab does (or as IPython with %matplotlib
does). In other words, I would like this script to be executed from the command line. I am expecting a new figure that pop-up every 3 seconds. During the execution I would be able to zoom, resize or even close the figure.
#!/usr/bin/python
import matplotlib.pyplot as plt
import time
def do_some_work():
time.sleep(3)
for i in range(10):
plt.plot([1,2,3,4])
plt.show() # this is way too boilerplate, I'd like to avoid it too.
do_some_work()
What alternative to
%matplotlib
I can use to manipulate figures while a script is running in Python (not IPython)?
What solutions I've already investigated?
I currently found 3 way to get a plot show.
1. %pylab
/ %matplotlib
As tom said, the use of %pylab
should be avoided to prevent the namespace to be polluted.
>>> %pylab
>>> plot([1,2,3,4])
This solution is sweet, the plot is non-blocking, there is no need for an additionnal show()
, I can still add a grid with grid()
afterwards and I can close, resize or zoom on my figure with no additional issues.
Unfortunately the %matplotlib
command is only available on IPython.
2. from pylab import *
or from matplotlib.pyplot import plt
>>> from pylab import *
>>> plot([1,2,3,4])
Things are quite different here. I need to add the command show()
to display my figure which is blocking. I cannot do anything but closing the figure to execute the next command such as grid()
which will have no effect since the figure is now closed...
** 3. from pylab import *
or from matplotlib.pyplot import plt
+ ion()
**
Some suggestions recommend to use the ion()
command as follow:
>>> from pylab import *
>>> ion()
>>> plot([1,2,3,4])
>>> draw()
>>> pause(0.0001)
Unfortunately, even if the plot shows, I cannot close the figure manually. I will need to execute close()
on the terminal which is not very convenient. Moreover the need for two additional commands such as draw(); pause(0.0001)
is not what I am expecting.
Summary
With %pylab
, everything is wonderful, but I cannot use it outside of IPython
With from pylab import *
followed by a plot
, I get a blocking behavior and all the power of IPython is wasted.
from pylab import *
followed by ion
offers a nice alternative to the previous one, but I have to use the weird pause(0.0001)
command that leads to a window that I cannot close manually (I know that the pause
is not needed with some backends. I am using WxAgg
which is the only one that works well on Cygwin x64
.
This question advices to use matplotlib.interactive(True)
. Unfortunately it does not work and gives the same behavior as ion()
does.