I figured it out, I think. I read the docs (
http://matplotlib.sourceforge.net/api/figure_api.html#matplotlib.figure.Figure.add_axes)
on add_axes and found the part about adding a label to a new axes to force
matplotlib to add a new axes.
So I changed this line from:
subplot = self.figure.add_subplot(n_before + 1, 1, n_before + 1)
to
subplot = self.figure.add_subplot(n_before + 1, 1, n_before + 1, label='%s'
% self.c)
and everything works as advertised.
On Thu, Dec 16, 2010 at 10:48 AM, Åke Kullenberg
<ake.kullenb...@gmail.com>wrote:
> I am using matplotlib in wxpython to dynamically add subplots to a figure
> and I am using the geometry_change() method to manage how they are shown.
> Basically I want all subplot to share the space evenly in one column. With
> the simple test code I have pasted in below I have run into some weird
> behavior though.
>
> Two cases, one good and one weird. (launch the wxpython app and do as
> follows to replicate)
>
> Good behavior:
> 1. Right-click in an empty frame.
> 2. Click the 'add subplot' menu item to add a subplot.
> 3. Repeat 1 & 2 to add a second subplot.
> 4. Right-click on top of the LOWER subplot, and click the 'delete' menu
> item to delete that particular subplot.
> 5. Right-click and click the 'add subplot' menu item to add a second
> subplot again.
>
> You will have some debug stuff in the console, but this run does exactly
> what you would expect it to. You first end up with two subplots sharing the
> column 50-50, you delete the LOWER one, and you add a second one again to
> end up in the same situation, i.e., two subplots sharing the colum 50-50.
>
> Weird behavior:
> 1. Right-click in an empty frame.
> 2. Click the 'add subplot' menu item to add a subplot.
> 3. Repeat 1 & 2 to add a second subplot.
> 4. Right-click on top of the UPPER subplot, and click the 'delete' menu
> item to delete that particular subplot.
> 5. Right-click and click the 'add subplot' menu item to add a second
> subplot again.
>
> This time you would of course expect the same behavior as above, but after
> 5 you won't end up with two subplots sharing the column 50-50. Instead you
> have one subplot (which is the most recent one you added) in upper half, and
> the lower half is blank.
>
> Looking at the console after 5 it says this:
>
> add ----------------------------------------
> changing geometry for subplot 0 to (211)
> adding subplot(212)
> count=2 c=3 n_before=1 n_after=1
> --------------------------------------------
>
> So it has changed the geometry as you would expect. It has also added the
> new second subplot as you would expect too. But somehow the axes count
> before and after is the same (n_before and n_after). In other words it looks
> like it hasn't added the subplot with 212, it looks like 211 has been used
> instead.
>
> Am I doing something stupid, or is this a bug os some sort?
>
>
> Comment regarding the code. The Frame class has two attributes outside of
> the usual figures etc, count & c. Both are simple counters. But while count
> is increased/decreased as subplots are added/subtracted, c is only increased
> as subplots are added it is never decreased. I then use c for making a
> simple plot in every subplot. I made it that way so I could tell the
> subplots apart.
>
> Code starts here:
>
> import wx
> import matplotlib
> matplotlib.use('wxagg')
> from matplotlib.figure import Figure
> from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as
> FigureCanvas
>
> class Frame(wx.Frame):
> def __init__(self, title):
> wx.Frame.__init__(self, None, title=title, pos=(150,150), size=(800,800))
> self.panel = wx.Panel(self)
> self.figure = Figure()
> self.canvas = FigureCanvas(self, -1, self.figure)
> self.figure.canvas.mpl_connect('button_press_event', self.OnEvent)
> self.figure.canvas.draw()
> self.Bind(wx.EVT_SIZE, self.OnSize)
> self.count = 0
> self.c = 0
> def OnEvent(self, event):
> self.clicked_axes = event.inaxes
> if event.button == 3:
> id_add_subplot = wx.NewId()
> id_reset = wx.NewId()
> self.Bind(wx.EVT_MENU, self.OnAddSubplot, id=id_add_subplot)
> self.Bind(wx.EVT_MENU, self.OnReset, id=id_reset)
> self.menu = wx.Menu()
> self.menu.Append(id_add_subplot, "Add subplot")
> self.menu.Append(id_reset, "Reset")
> if self.clicked_axes is not None:
> id_delete_subplot = wx.NewId()
> self.Bind(wx.EVT_MENU, self.OnDeleteSubplot, id=id_delete_subplot)
> self.menu.Append(id_delete_subplot, "Delete")
> self.PopupMenu(self.menu)
> self.menu.Destroy()
> def OnDeleteSubplot(self, event):
> self.count -= 1
> self.figure.delaxes(self.clicked_axes)
> n = len(self.figure.axes)
> print ''
> print 'delete -------------------------------------'
> for i in xrange(n):
> print 'changing geometry for subplot %s to (%s%s%s)' % (i, n, 1, i + 1)
> self.figure.axes[i].change_geometry(n, 1, i + 1)
> self.figure.axes[i].update_params()
> self.figure.subplots_adjust()
> self.figure.canvas.draw()
> print 'count=%s c=%s n=%s' % (self.count, self.c, n)
> print '--------------------------------------------'
> def OnAddSubplot(self, event):
> self.count += 1
> self.c += 1
> n_before = len(self.figure.axes)
> print ''
> print 'add ----------------------------------------'
> for i in xrange(n_before):
> print 'changing geometry for subplot %s to (%s%s%s)' % (i, n_before + 1, 1,
> i + 1)
> self.figure.axes[i].change_geometry(n_before + 1, 1, i + 1)
> self.figure.axes[i].update_params()
> print 'adding subplot(%s%s%s)' % (n_before + 1, 1, n_before + 1)
> subplot = self.figure.add_subplot(n_before + 1, 1, n_before + 1)
> n_after = len(self.figure.axes)
> subplot.plot([self.c,self.c,self.c])
> self.figure.subplots_adjust()
> self.figure.canvas.draw()
> print 'count=%s c=%s n_before=%s n_after=%s' % (self.count, self.c,
> n_before, n_after)
> print '--------------------------------------------'
> def OnReset(self, event):
> self.count = 0
> self.figure.clear()
> self.figure.canvas.draw()
> def OnSize(self, event):
> pixels = tuple(event.GetSize())
> self.canvas.SetSize(pixels)
> self.figure.set_size_inches(float(pixels[0])/self.figure.get_dpi(),
> float(pixels[1])/self.figure.get_dpi())
> if __name__ == "__main__":
> app = wx.PySimpleApp()
> frame = Frame('Hello')
> frame.Show()
> app.MainLoop()
>
>
------------------------------------------------------------------------------
Lotusphere 2011
Register now for Lotusphere 2011 and learn how
to connect the dots, take your collaborative environment
to the next level, and enter the era of Social Business.
http://p.sf.net/sfu/lotusphere-d2d
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users