Due to repeated emails by Eric Firing about how something like this would be nice to have, I finally got around to packaging a little utility I wrote. I uploaded it to the MPL source repository. The basic idea is to create a layout engine for matplotlib. Not wanting to (re-)invent an API, I decided simply to imitate the layout engine I knew best, which is wxPython. Disclaimer: This isn't bug-free, complete, or well-documented and this announcement should merely be taken as a call to "commence hacking now". That being said, I've used mplsizer for several figures for publication, so I don't consider it that bad or incomplete, either. Anyhow, the source code, licensed under the MIT license, is available at: https://svn.sourceforge.net/svnroot/matplotlib/trunk/toolkits/mplsizer One note: aside from depending on matplotlib, this requires setuptools. Sorry to those of you who hate setuptools, but it simply gives me tools that make my life easier. If you want to change mplsizer to not require setuptools, that's fine by me, but we should keep it setuptools compatible. Here's the last part of the demo_basic.py script. "fig" is a matplotlib Figure instance, "a","b","b2", and "lowest" are matplotlib Axes instances. # Now perform the mplsizer stuff import matplotlib.toolkits.mplsizer as mplsizer frame = mplsizer.MplSizerFrame( fig ) sizer = mplsizer.MplBoxSizer() frame.SetSizer(sizer) sizer.Add(a,name='a',expand=1) sizer.Add(b,name='b',all=0,left=1,border=0.2) sizer.Add(b2,name='b2') if more_plots: hsizer = mplsizer.MplBoxSizer(orientation='horizontal') hsizer.Add(c,name='c',option=1,align_bottom=1) hsizer.Add(d,name='d',align_centre=1) sizer.Add(hsizer,all=0,bottom=1,border=0.5,expand=1,option=1) frame.Layout() # triggers layout # It's naughty to use the private attribute, but, hey, this is for # debugging only, so it's OK, right? lowest.set_position(hsizer._rect) pylab.show()
On 7/30/06, Andrew Straw <str...@as...> wrote: > The basic > idea is to create a layout engine for matplotlib. Not wanting to > (re-)invent an API, I decided simply to imitate the layout engine I knew > best, which is wxPython. Very cool!
Andrew, This looks very cool, and I'm looking forward to playing around with it. Thanks for the hard work! Shooting from the hip, here are some initial comments. I may be able to submit patches for some of the more innocuous items later in the week. 1. It appears that as_sizer_element() uses the _axes_sizer_elements dictionary to cache MplAxesSizerElement instances. Using a WeakKeyDictionary from the "weakref" module instead of a regular dictionary may be necessary to allow the garbage collection of the MplAxesSizerElements when their associated Axes gets GC'd. 2. Convenience MplBoxSizer subclasses that let you omit the "orient" keyword might be nice: class MplHBoxSizer(MplBoxSizer): def __init__(self): MplBoxSizer.__init__(self, orientation='vertical') 3. Couldn't you just drop mplsizer.py into the "matplotlib.toolkits" virtual package? Maybe you can't -- I'm pretty new to applied python- eggery. 4. I feel we should avoid the whole European/American spelling problem that WX has. Why not make both 'align_centre' and 'align_center' do the same thing? 5. Why not use shorter names, with less redundancy? (e.g. "matplotlib.toolkits.sizer", FigureSizer, Box, HBox, Grid, etc) Ken
Hi Ken, Thanks for your comments. Ken McIvor wrote: >1. It appears that as_sizer_element() uses the _axes_sizer_elements >dictionary to cache MplAxesSizerElement instances. Using a >WeakKeyDictionary from the "weakref" module instead of a regular >dictionary may be necessary to allow the garbage collection of the >MplAxesSizerElements when their associated Axes gets GC'd. > > I'll check into this. >2. Convenience MplBoxSizer subclasses that let you omit the "orient" >keyword might be nice: > > class MplHBoxSizer(MplBoxSizer): > def __init__(self): > MplBoxSizer.__init__(self, orientation='vertical') > > I was thinking I want an exact a replica of the wx API as possible, simply so my feeble mind doesn't get (more) confused. Is there anything like this in stock wx? I think it's a decent enough idea, but I'd rather not cause namespace bloat. But, if you're really into it, let's do it. >3. Couldn't you just drop mplsizer.py into the "matplotlib.toolkits" >virtual package? Maybe you can't -- I'm pretty new to applied python- >eggery. > > I think this is possible, and I hope for not too much effort. This is the result of historic accident and personal time-allocation issues. Mplsizer started life as a private setuptools-ized package, and I'm not spending my time to de-setuptools-ize software -- I see setuptools as the way forward, not something (I will spend my time) to remove. I understand that some people aren't too fond of setuptools, and to them, I say, "patches welcome". >4. I feel we should avoid the whole European/American spelling >problem that WX has. Why not make both 'align_centre' and >'align_center' do the same thing? > > Same answer as to point 2... >5. Why not use shorter names, with less redundancy? (e.g. >"matplotlib.toolkits.sizer", FigureSizer, Box, HBox, Grid, etc) > > Same answer as to point 2... (I'd be happy to drop the "Mpl" prefix, though.)
Andrew Straw wrote: > I was thinking I want an exact a replica of the wx API as possible, well, I'm a big fan of wx.Sizers, but we all know that they confuses folks. Given that grid-like layouts are likely to be the most common with MPL, maybe just make a GridBagSizer, and forget the rest? All the other sizers are just a simplification of that anyway. just my 0ドル.2 Despite that small suggestion -- very nice work! -Chris -- Christopher Barker, Ph.D. Oceanographer NOAA/OR&R/HAZMAT (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chr...@no...