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

Reply via email to