Events not registering in FigureCanvasWxAgg

I am using Python 2.7 and Matplotlib 1.0.0 and I am having problems getting events triggering in this example below. I have taken the draggable rectangle example (with blit) code from the event handling documentation (http://matplotlib.sourceforge.net/users/event_handling.html) and tried to put it in a wxPython frame. The problem I have is that I can’t get any events to register. When I click in the figure nothing happens, the on_press section in the code is never reached.

Any suggestions how I can make this work?

I have a vague recollection of this working in matplotlib < 1.0.0 and python < 2.7, but I am not 100% sure as it was a long time ago I last worked with matplotlib.

The code:

import numpy as np

import wx

from matplotlib.figure import Figure

from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas

class DraggableRectangle:

lock = None  # only one can be animated at a time

def __init__(self, rect):

	self.rect = rect

	self.press = None

	self.background = None

def connect(self):

	'connect to all the events we need'

	self.cidpress = self.rect.figure.canvas.mpl_connect('button_press_event', self.on_press)

	self.cidrelease = self.rect.figure.canvas.mpl_connect('button_release_event', self.on_release)

	self.cidmotion = self.rect.figure.canvas.mpl_connect('motion_notify_event', self.on_motion)

def on_press(self, event):

	'on button press we will see if the mouse is over us and store some data'

	if event.inaxes != self.rect.axes: return

	if DraggableRectangle.lock is not None: return

	contains, attrd = self.rect.contains(event)

	if not contains: return

	print 'event contains', self.rect.xy

	x0, y0 = self.rect.xy

	self.press = x0, y0, event.xdata, event.ydata

	DraggableRectangle.lock = self

	# draw everything but the selected rectangle and store the pixel buffer

	canvas = self.rect.figure.canvas

	axes = self.rect.axes

	self.rect.set_animated(True)

	canvas.draw()

	self.background = canvas.copy_from_bbox(self.rect.axes.bbox)

	# now redraw just the rectangle

	axes.draw_artist(self.rect)

	# and blit just the redrawn area

	canvas.blit(axes.bbox)

def on_motion(self, event):

	'on motion we will move the rect if the mouse is over us'

	if DraggableRectangle.lock is not self:

		return

	if event.inaxes != self.rect.axes: return

	x0, y0, xpress, ypress = self.press

	dx = event.xdata - xpress

	dy = event.ydata - ypress

	self.rect.set_x(x0+dx)

	self.rect.set_y(y0+dy)

	canvas = self.rect.figure.canvas

	axes = self.rect.axes

	# restore the background region

	canvas.restore_region(self.background)

	# redraw just the current rectangle

	axes.draw_artist(self.rect)

	# blit just the redrawn area

	canvas.blit(axes.bbox)

def on_release(self, event):

	'on release we reset the press data'

	if DraggableRectangle.lock is not self:

		return

	self.press = None

	DraggableRectangle.lock = None

	# turn off the rect animation property and reset the background

	self.rect.set_animated(False)

	self.background = None

	# redraw the full figure

	self.rect.figure.canvas.draw()

def disconnect(self):

	'disconnect all the stored connection ids'

	self.rect.figure.canvas.mpl_disconnect(self.cidpress)

	self.rect.figure.canvas.mpl_disconnect(self.cidrelease)

	self.rect.figure.canvas.mpl_disconnect(self.cidmotion)

class TestFrame(wx.Frame):

def __init__(self):

	wx.Frame.__init__(self, None, title="Event Test", size=(640,480))

	panel = wx.Panel(self,-1)

	fig = Figure()

	canvas = FigureCanvas(panel, -1, fig)

	ax = fig.add_subplot(111)

	rects = ax.bar(range(10), 20*np.random.rand(10))

	drs = []

	for rect in rects:

		dr = DraggableRectangle(rect)

		dr.connect()

		drs.append(dr)

	fig.canvas.draw()

if name == “main”:

app = wx.App()

theFrame = TestFrame()

theFrame.Show()

app.MainLoop()

I am using Python 2.7 and Matplotlib 1.0.0 and I am having problems
getting events triggering in this example below. I have taken the
draggable rectangle example (with blit) code from the event handling
documentation
(http://matplotlib.sourceforge.net/users/event_handling.html) and tried
to put it in a wxPython frame. The problem I have is that I can't get
any events to register. When I click in the figure nothing happens, the
on_press section in the code is never reached.

Any suggestions how I can make this work?

Keep references to your DraggableRectangle objects. As it is you are putting them in a list, but the list and its contents are being garbage-collected as soon as TestFrame.__init__() finishes.

This was discussed recently on the list; I think you are the third person in the last week or two who has run into this consequence of a change that was made (for good reasons) in mpl 1.0.

Eric

···

On 10/07/2010 07:11 PM, Åke Kullenberg wrote:

I have a vague recollection of this working in matplotlib < 1.0.0 and
python < 2.7, but I am not 100% sure as it was a long time ago I last
worked with matplotlib.

The code:

import numpy as np
import wx
from matplotlib.figure import Figure
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as
FigureCanvas

class DraggableRectangle:
lock = None # only one can be animated at a time
def __init__(self, rect):
self.rect = rect
self.press = None
self.background = None

def connect(self):
'connect to all the events we need'
self.cidpress =
self.rect.figure.canvas.mpl_connect('button_press_event', self.on_press)
self.cidrelease =
self.rect.figure.canvas.mpl_connect('button_release_event', self.on_release)
self.cidmotion =
self.rect.figure.canvas.mpl_connect('motion_notify_event', self.on_motion)

def on_press(self, event):
'on button press we will see if the mouse is over us and store some data'
if event.inaxes != self.rect.axes: return
if DraggableRectangle.lock is not None: return
contains, attrd = self.rect.contains(event)
if not contains: return
print 'event contains', self.rect.xy
x0, y0 = self.rect.xy
self.press = x0, y0, event.xdata, event.ydata
DraggableRectangle.lock = self

# draw everything but the selected rectangle and store the pixel buffer
canvas = self.rect.figure.canvas
axes = self.rect.axes
self.rect.set_animated(True)
canvas.draw()
self.background = canvas.copy_from_bbox(self.rect.axes.bbox)

# now redraw just the rectangle
axes.draw_artist(self.rect)

# and blit just the redrawn area
canvas.blit(axes.bbox)

def on_motion(self, event):
'on motion we will move the rect if the mouse is over us'
if DraggableRectangle.lock is not self:
return
if event.inaxes != self.rect.axes: return
x0, y0, xpress, ypress = self.press
dx = event.xdata - xpress
dy = event.ydata - ypress
self.rect.set_x(x0+dx)
self.rect.set_y(y0+dy)

canvas = self.rect.figure.canvas
axes = self.rect.axes
# restore the background region
canvas.restore_region(self.background)

# redraw just the current rectangle
axes.draw_artist(self.rect)

# blit just the redrawn area
canvas.blit(axes.bbox)

def on_release(self, event):
'on release we reset the press data'
if DraggableRectangle.lock is not self:
return

self.press = None
DraggableRectangle.lock = None

# turn off the rect animation property and reset the background
self.rect.set_animated(False)
self.background = None

# redraw the full figure
self.rect.figure.canvas.draw()

def disconnect(self):
'disconnect all the stored connection ids'
self.rect.figure.canvas.mpl_disconnect(self.cidpress)
self.rect.figure.canvas.mpl_disconnect(self.cidrelease)
self.rect.figure.canvas.mpl_disconnect(self.cidmotion)

class TestFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, title="Event Test", size=(640,480))
panel = wx.Panel(self,-1)
fig = Figure()
canvas = FigureCanvas(panel, -1, fig)
ax = fig.add_subplot(111)
rects = ax.bar(range(10), 20*np.random.rand(10))
drs = []
for rect in rects:
dr = DraggableRectangle(rect)
dr.connect()
drs.append(dr)
fig.canvas.draw()

if __name__ == "__main__":
app = wx.App()
theFrame = TestFrame()
theFrame.Show()
app.MainLoop()

------------------------------------------------------------------------------
Beautiful is writing same markup. Internet Explorer 9 supports
standards for HTML5, CSS3, SVG 1.1, ECMAScript5, and DOM L2& L3.
Spend less time writing and rewriting code and more time creating great
experiences on the web. Be a part of the beta today.
http://p.sf.net/sfu/beautyoftheweb

_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users