By default, matplotlib defers drawing until the end of the script because drawing can be an expensive operation, and you may not want to update the plot every time a single property is changed, only once after all the properties have changed.
But when working from the python shell, you usually do want to update the plot with every command, eg, after changing the :func:`~matplotlib.pyplot.xlabel`, or the marker style of a line. While this is simple in concept, in practice it can be tricky, because matplotlib is a graphical user interface application under the hood, and there are some tricks to make the applications work right in a python shell.
Fortunately, ipython, an enhanced interactive python shell, has figured out all of these tricks, and is matplotlib aware, so when you start ipython in the pylab mode.
johnh@flag:~> ipython -pylab Python 2.4.5 (#4, Apr 12 2008, 09:09:16) IPython 0.9.0 -- An enhanced Interactive Python. Welcome to pylab, a matplotlib-based Python environment. For more information, type 'help(pylab)'. In [1]: x = randn(10000) In [2]: hist(x, 100)
it sets everything up for you so interactive plotting works as you would expect it to. Call :func:`~matplotlib.pyplot.figure` and a figure window pops up, call :func:`~matplotlib.pyplot.plot` and your data appears in the figure window.
Note in the example above that we did not import any matplotlib names because in pylab mode, ipython will import them automatically. ipython also turns on interactive mode for you, which causes every pyplot command to trigger a figure update, and also provides a matplotlib aware run command to run matplotlib scripts efficiently. ipython will turn off interactive mode during a run command, and then restore the interactive state at the end of the run so you can continue tweaking the figure manually.
There has been a lot of recent work to embed ipython, with pylab support, into various GUI applications, so check on the ipython mailing list for the latest status.
If you can't use ipython, and still want to use matplotlib/pylab from an interactive python shell, eg the plain-ol standard python interactive interpreter, or the interpreter in your favorite IDE, you are going to need to understand what a matplotlib backend is :ref:`what-is-a-backend`.
With the TkAgg backend, that uses the Tkinter user interface toolkit, you can use matplotlib from an arbitrary python shell. Just set your backend : TkAgg and interactive : True in your :file:`matplotlibrc` file (see :ref:`customizing-matplotlib`) and fire up python. Then:
>>> from pylab import * >>> plot([1,2,3]) >>> xlabel('hi mom')
should work out of the box. Note, in batch mode, ie when making figures from scripts, interactive mode can be slow since it redraws the figure with each command. So you may want to think carefully before making this the default behavior.
For other user interface toolkits and their corresponding matplotlib backends, the situation is complicated by the GUI mainloop which takes over the entire process. The solution is to run the GUI in a separate thread, and this is the tricky part that ipython solves for all the major toolkits that matplotlib supports. There are reports that upcoming versions of pygtk will place nicely with the standard python shell, so stay tuned.
The interactive property of the pyplot interface controls whether a figure canvas is drawn on every pyplot command. If interactive is False, then the figure state is updated on every plot command, but will only be drawn on explicit calls to :func:`~matplotlib.pyplot.draw`. When interactive is True, then every pyplot command triggers a draw.
The pyplot interface provides 4 commands that are useful for interactive control.
When working with a big figure in which drawing is expensive, you may want to turn matplotlib's interactive setting off temporarily to avoid the performance hit:
>>> #create big-expensive-figure >>> ioff() # turn updates off >>> title('now how much would you pay?') >>> xticklabels(fontsize=20, color='green') >>> draw() # force a draw >>> savefig('alldone', dpi=300) >>> close() >>> ion() # turn updating back on >>> plot(rand(20), mfc='g', mec='r', ms=40, mew=4, ls='--', lw=3)