In interactive mode in matplotlib (i.e. pylab), the draw() command gets called after each call to a top-level plotting function. This can really slow a script down if it has a lot of things to plot. The best way around this problem is to use the object-oriented syntax whenever possible, and then call pylab.draw() at the end of the procedure. However, if you prefer to work with the pylab interface, or if there are functions written for that interface that you need to call a lot, it can speed things up a LOT to drop out of interactive mode while generating the plots. However, if you're running the script from the command line, you won't be in interactive mode, so you need to check this and restore the state after making the plot. This is somewhat tedious, so I use this function wrapper to automate the process. The additional wrapping layer using functools.wraps isn't strictly necessary, but it will make the docstring of the wrapped function behave correctly.
import functools
def drawoffscreen(f):
from pylab import isinteractive, ion, ioff, draw
@functools.wraps(f)
def wrapper(*args, **kwargs):
retio = isinteractive()
ioff()
try:
y = f(*args, **kwargs)
finally:
if retio: ion()
draw()
return y
return wrapper
If you're using Python >=2.4 you can use this as a function decorator as below. If you're not, you'll have to call drawoffscreen() on the function after you define it (and adjust the code above, which also uses the decorator syntax).
@drawoffscreen
def plot_stuff(data):
...