out of curiosity...

From: John Hunter [mailto:jdh2358@…287…]
Sent: Monday, June 11, 2007 9:08 AM
To: Trevis Crane
Cc: matplotlib-users@lists.sourceforge.net
Subject: Re: [Matplotlib-users] out of curiosity…

> Coming from MATLAB, I started using matplotlib in the same fashion

(and was

> very appreciative of the similariry). That is, I would import pylab

and

> call the plotting functions as necessary. However, after seeing

some of how

> others are using matplotlib, it seems most people use axes object

methods to

> take care of plotting needs. I'm now taking this approach as well,

but I

> honestly don't know why I should (or if I should). Will someone

explain to

> me why one approach is better or worse?

[Trevis Crane]

John, your explanation is great. Thanks for taking the time.

trevis

···

-----Original Message-----
On 6/11/07, Trevis Crane <t_crane@...1614...> wrote:

matplotlib supports both because in different contexts one is often
superior to the other.

The main difference is that the pylab interface is stateful and
handles object instantiation when necessary. For example, when you do
"plot", it checks to see if there is a current axes and if so plots
into it, and if not creates a new axes. When the new axes function is
called, it checks to see if there is a current figure and inserts into
it if available, and if not creates one. So it is "stateful" because
under the hood it is tracking the current axes, figure and some other
stuff.

When working interactively from the shell or in short scripts, this is
a nice feature because it saves typing and syntactic overhead. When
working in the shell, eg in ipython -pyab mode, this is usually the
way I work.

In other contexts the convenience that these functions imply become a
liability, because you often want to have explicit control, eg "put
this axes in this figure and put this plot into this axes...". In a
web application server or a user interface application, this is
definitely the way to work. In scripts of moderate complexity it is
advisable.

The basic idea is that "explicit is better than implicit". Working
this way is a little harder at first, but by forcing yourself to
understand who is doing what where, you ultimately write better, more
stable, more maintainable code.

One thing most serious python programmers agree on is that

  from something import *

is bad practice because you usually don't know what names are coming
from where, and it creates the possibility of latent bugs. Eg, pylab
used to have a "set" command which emulates the matlab command of the
same name. It is used to set handle graphics properties. This worked
fine, until python introduced the "set" builtin, which works like the
mathematical set. Then it became impossible do "from pylab import *"
and use the new python builtin "set", so we cleaned up all the old
code and renamed the function. The programmer who do

import pylab
pylab.set

was protected from these often subtle and difficult to detect bugs.

The import * idiom also makes it tricky to combine code from two
scripts or modules into one, because both may be importing different
namespaces with overlapping names.

I have found, however, when talking to science teachers who are trying
to introduce python/numpy/pylab/scipy into the classroom as a matlab
replacement that the 'from pylab import *' idiom is important to them,
because their students want something that "just works" and is about
as easy as matlab. Even though it is probably preferable in the
abstract to teach students good practices from the beginning, it might
raise the barrier to entry sufficiently that they simply use matlab
instead. These teachers are already facing a fair amount of
resistance in trying to get python introduced at all, and we should
make it as easy on them as possible. So I am not a zealot on this
issue.

The other reason it is good practice to use the explicit API calls is
that code which starts out its life as a small script often has a way
of growing into a large script, and then you begin sharing it with
your colleagues and maybe writing a web interface or a GUI application
built on it. Code written using the API can safely be dropped into
larger applications, whereas code written in pylab probably cannot
(imagine lots of different functions competing for the current figure
w/o knowledge of one another).

So the answer of which is better is a question of skill level and
context, but my simple advice is to use the pylab syntax from the
interactive python shell (and "ipython -pylab" is ideal for this) and
the API everywhere else. Most of my scripts are variants of this:

  import numpy as npy
  from pylab import figure, close, show
  fig = figure()
  ax = fig.add_subplot(111)
  x = npy.arange(0,10.)
  ax.plot(x)
  show()

JDH