OK, I spent some time looking at this morning and think I have a fix
that works for matplotlib wx API users as well as pylab users. For
the record, a little background.
The module matplotlib.backends.backend_wx contains all the classes to
enable matplotlib to be embedded in a wx application. There are two
modes this module is used in: application developers who want to
control the wx windows, panels, frames, etc, themselves, and pylab
users who want a matlab like environment in which all the figure
window, creation, etc, is managed for them.
To support the latter, all the matplotlib GUI backends are required to
define two functions
new_figure_manager - creates a new wxFrame
show - realizes/shows all frames
Jeremy O'Donoghue, who wrote the wx backend, and latter Matt Newville
who has been helping maintain it of late, tried putting the wxapp
instantiation in the show function, but this caused a segfault on some
platforms with some versions of wxpython (win32 with 2.4.x). We never
figured out the root cause of this since often times the person
developing/maintaining wx didn't have access to the buggy combination
of platform + version. So we left wxapp creation at the module level
which was ugly, hacky, and buggy, but at least it didn't seg fault.
Today I spent some time tracking down where and why the segfault was
occurring, and it was
new_figure_manager -> FigureFrameWx -> wxPanel.__init__
The call to wxPanel.__init__ trigged the segfault.
It appears the cause of this problem is that the wxapp must be created
before the wxPanel is init'ed. The solution is to put the wxapp
creation in new_figure_manager, not show, so that the app will be
created before the wxpanel. This appears to work. Here is what I am
currently doing
wxapp = None # module level
def new_figure_manager(num, *args, **kwargs):
global wxapp
if wxapp is None:
wxapp = wx.PySimpleApp()
wxapp.SetExitOnFrameDelete(True)
...snipsnip...
def show():
...snipsnip...
if show._needmain and not matplotlib.is_interactive():
if wxapp is not None: wxapp.MainLoop()
show._needmain = False
And this seems to work for pylab and wx apps. Since apps will never
call new_figure_manager or show, there should be no problem
If there is a better / more elegant / more wxlike way to do this, let
me know.
Thanks,
JDH