Hello everyone, I am trying to implement object picking in my
> matplotlib-based plotting application. I found two examples.
> The 'picker_demo.py' demo is very nice and looks a lot simpler
> than the 'object_picker.py' which requires you to use your own
> Canvas object. But since object_picker needs to have the
> event.inaxes object, it seems impossible to catch any events
> outside the axes' bounding box, like 'click on axes title', or
> 'click on ticks' or 'click on xlabel'.
Yes, the object_picker demo is very old and deprecated. It is around
from before the days of GUI neutral picking.
I wrote a little demo showing you how to pick the text (title, xlabel,
ylabel, ticklabels). Press "p" over a text instance outside the axes
bounding box and it will turn blue. If you think this is a reasonable
interface, I can make this the basis of a figure pick function. The
question is, what should such a function return. Eg, if you are
outside the axes and click over a text instance, it should return the
text instance. Clear enough. But if you are over an axes and click
on a line, what should it return? The Axes instance, The Line2D
instance, both in a tuple?
from pylab import subplot, title, connect, text, plot, rand, \
show, gcf, draw
from matplotlib.text import Text
from matplotlib.lines import Line2D
from matplotlib.patches import Patch, Circle
def overtext(t, event):
'return true if event is over text'
bbox = t.get_window_extent()
return bbox.contains(event.x, event.y)
def pick(event):
if event.key!='p': return
if event.inaxes is not None: # axes pick
ax = event.inaxes
a = ax.pick(event.x, event.y)
if isinstance(a, Text):
a.set_color('r')
elif isinstance(a, Line2D):
a.set_markerfacecolor('r')
elif isinstance(a, Patch):
a.set_facecolor('r')
draw()
else: # figure pick
fig = gcf()
texts =
for ax in fig.axes:
texts.extend([ax.xaxis.label, ax.yaxis.label, ax.title])
texts.extend(ax.xaxis.get_ticklabels())
texts.extend(ax.yaxis.get_ticklabels())
for t in texts:
if overtext(t, event):
t.set_color('blue')
draw()
return
connect('key_press_event', pick)
ax = subplot(111)
title('Put mouse over object and press "p" to pick it')
for i in range(20):
x, y = rand(2)
text(x,y,'hi!')
for i in range(5):
x = rand(10)
y = rand(10)
plot(x,y,'go')
for i in range(5):
x = rand()
y = rand()
center = x,y
p = Circle(center, radius=.1)
ax.add_patch(p)
show()