pylab vs. embedding in wx

I have a problem that probably highlights a problem with how I
normally use mpl vs. how I should use it. I have some utility scripts
that do various data processing tasks and also have convenience
functions for plotting data using pylab. Almost all of my scripts
have a line like this near the top:
from pylab import figure, cla, clf, plot, subplot, show, ylabel,
xlabel, xlim, ylim, semilogx, legend, title, savefig

I am now trying to import some of my data processing functions into a
script that is embedding matplotib in a wxPython application following
the embedding_in_wx#.py examples. I am getting this error:

ryan@...1519...:~/siue/Research/PythonSimulationEnvironment$ python SystemID_gui.py
Traceback (most recent call last):
  File "SystemID_gui.py", line 18, in ?
    import rwkbode
  File "/home/ryan/pythonutil/rwkbode/__init__.py", line 3, in ?
    import pylab
  File "/usr/lib/python2.4/site-packages/pylab.py", line 1, in ?
    from matplotlib.pylab import *
  File "/usr/lib/python2.4/site-packages/matplotlib/pylab.py", line 216, in ?
    from backends import new_figure_manager, draw_if_interactive, show
ImportError: cannot import name new_figure_manager

which seems to say that pylab cannot be imported after my wx mpl panel
has done this:
import matplotlib
import wx
from scipy import sin, cos, pi, atleast_1d, shape, log10
#from wxPython.wx import *
matplotlib.use('WXAgg')
import matplotlib.cm as cm
from matplotlib.backends.backend_wxagg import Toolbar, FigureCanvasWxAgg
from matplotlib.figure import Figure
import matplotlib.numerix as numerix
import matplotlib.numerix.mlab as mlab
from matplotlib.mlab import meshgrid

How should I be using matplotlib/pylab in my utility scripts so that
they are compatible with embedding in wx?

Thanks,

Ryan

A good rule of thumb is to never import pylab at the top level for
modules that need to be imported. In my own code, I often do
something like

  def somefunc(figfunc):
      fig = figfunc()
      ax = fig.add_subplot(111)
      ax.plot([1,2,3])

and then I can call it with

  somefunc(pylab.figure)

or a custom func that generates a GUI embedded figure instance. Eg,
in my GTKApps, I have a functor like gtk_figure that returns a
function that creates a figure embedded in a GTK window.

In basemap, Jeffrey Whitaker does something like the following

  def somefunc(ax=None):
      if ax is None:
          import pylab
          ax = pylab.gca()

Here the pylab import is triggered only when the function is called
with default arguments. That way you can use it from GUI code without
triggering a pylab import like

  somefunc(ax)

and from other code where you want pylab do do everything with

  somefunc()

I'm afraid you have some cleanup to do..... Mixing pylab with
embedded GUI code is a recipe for pain and misery.

JDH

···

On 3/15/07, Ryan Krauss <ryanlists@...287...> wrote:

How should I be using matplotlib/pylab in my utility scripts so that
they are compatible with embedding in wx?

Thanks John. I know I have some clean up to do, I just want to do it
right so it isn't an annual (or more often) thing....

···

On 3/15/07, John Hunter <jdh2358@...287...> wrote:

On 3/15/07, Ryan Krauss <ryanlists@...287...> wrote:

> How should I be using matplotlib/pylab in my utility scripts so that
> they are compatible with embedding in wx?

A good rule of thumb is to never import pylab at the top level for
modules that need to be imported. In my own code, I often do
something like

  def somefunc(figfunc):
      fig = figfunc()
      ax = fig.add_subplot(111)
      ax.plot([1,2,3])

and then I can call it with

  somefunc(pylab.figure)

or a custom func that generates a GUI embedded figure instance. Eg,
in my GTKApps, I have a functor like gtk_figure that returns a
function that creates a figure embedded in a GTK window.

In basemap, Jeffrey Whitaker does something like the following

  def somefunc(ax=None):
      if ax is None:
          import pylab
          ax = pylab.gca()

Here the pylab import is triggered only when the function is called
with default arguments. That way you can use it from GUI code without
triggering a pylab import like

  somefunc(ax)

and from other code where you want pylab do do everything with

  somefunc()

I'm afraid you have some cleanup to do..... Mixing pylab with
embedded GUI code is a recipe for pain and misery.

JDH

I am learning the hard way that I don't know as much about matplotlib
as I thought I did except for how to use pylab.

I think I have managed to create a figure, add an axis, and plot
something on it without pylab, but I don't know how to do the
equivalent of show(). draw() needs a renderder and I can't seem to
figure out how to create one. Here is what I have done so far:

myfig = pylab.Figure()
myaxes=myfig.add_axes((0,1,0,1))
t=arange(0,1,0.01)
y=sin(2*pi*t)
myaxes.plot(t,y)

What do I need to do to show the plot from the command line in IPython
(i.e. if I actually want to use pylab instead of OO)?

I may be going about this the wrong way and it may be easier just to
set up some imports of pylab that only trigger inside of functions,
but I would like to have functions that are useful either from the
IPython command line or in OOP situations. Following the examples
for WX, I am doing this at the top of my OOP modules:

from matplotlib.backends.backend_wxagg import Toolbar, FigureCanvasWxAgg
from matplotlib.figure import Figure
.
  
class mplpanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, -1)

        self.fig = Figure((5,5), 75)
        self.canvas = FigureCanvasWxAgg(self, -1, self.fig)

And the my drawing commands operate on self.fig and then the last line
of all plotting functions is self.canvas.draw().

So, it would be nice if my utility functions took a figure instance as
an input and operated on it.

Am I making any sense? Am I going about this revision in a good way?

Thanks,

Ryan

···

On 3/15/07, Ryan Krauss <ryanlists@...287...> wrote:

Thanks John. I know I have some clean up to do, I just want to do it
right so it isn't an annual (or more often) thing....

On 3/15/07, John Hunter <jdh2358@...287...> wrote:
> On 3/15/07, Ryan Krauss <ryanlists@...287...> wrote:
>
> > How should I be using matplotlib/pylab in my utility scripts so that
> > they are compatible with embedding in wx?
>
> A good rule of thumb is to never import pylab at the top level for
> modules that need to be imported. In my own code, I often do
> something like
>
> def somefunc(figfunc):
> fig = figfunc()
> ax = fig.add_subplot(111)
> ax.plot([1,2,3])
>
> and then I can call it with
>
> somefunc(pylab.figure)
>
> or a custom func that generates a GUI embedded figure instance. Eg,
> in my GTKApps, I have a functor like gtk_figure that returns a
> function that creates a figure embedded in a GTK window.
>
> In basemap, Jeffrey Whitaker does something like the following
>
> def somefunc(ax=None):
> if ax is None:
> import pylab
> ax = pylab.gca()
>
> Here the pylab import is triggered only when the function is called
> with default arguments. That way you can use it from GUI code without
> triggering a pylab import like
>
> somefunc(ax)
>
> and from other code where you want pylab do do everything with
>
> somefunc()
>
> I'm afraid you have some cleanup to do..... Mixing pylab with
> embedded GUI code is a recipe for pain and misery.
>
> JDH
>

Ryan,

In my (limited) experience, it's dicey to mix pylab's plotting functionality and the OO API. I guess I'm a little unclear exactly what your use case is for this. It sounds like you're goal is to create a library of functions that operate on Figure instances, perhaps so you can use them both interactively and as part of a wxPython application.

If that's the case, I'd recommend you try using pylab's gcf() and draw() to acquire and redraw the current Figure instance from within IPython. You can also save the return value of pylab's figure(), which returns a Figure that's already been attached to the appropriate renderer. This way you can use the OO API for plotting without having to futz with the drawing machinery directly.

This script might give you some ideas about how to structure your code. It contains several of the MPL examples re-coded as functions that accept a Figure instance and use the OO API for plotting.

  http://svn.csrri.iit.edu/mr-software/wxmpl/trunk/demos/plotting.py

Ken