Jack replied to me offlist so I am going to paste in his post below.
Perhaps you and Gael can consult on the ideal functionality of ginput
vis-a-vis optional line segment drawing, etc...
From Jack Sankey <jack.sankey@...149...>
to John Hunter <jdh2358@...149...>,
date Feb 5, 2008 4:02 PM
subject Re: [matplotlib-devel] ginput: blocking call for mouse input
mailed-by gmail.com
Woa, it's working on GTKAgg using wx.Yield()? You must have added some voodoo
Also, my version of GaelInput has seemed to stop evolving. This
version has the option to draw lines between clicks, which I use a
lot. Also, the default timeout is 0 now, since you can always
right-click to abort.
-Jack
class GaelInput(object):
"""
Class that create a callable object to retrieve mouse click in a
blocking way, a la MatLab. Based on Gael Varoquaux's almost-working
object. Thanks Gael! I've wanted to get this working for years!
-Jack
"""
debug = False
cid = None # event connection object
clicks = # list of click coordinates
n = 1 # number of clicks we're waiting for
lines = False # if we should draw the lines
def on_click(self, event):
"""
Event handler that will be passed to the current figure to
retrieve clicks.
"""
# write the debug information if we're supposed to
if self.debug: print "button "+str(event.button)+":
"+str(event.xdata)+", "+str(event.ydata)
# if this event's a right click we're done
if event.button == 3:
self.done = True
return
# if it's a valid click (and this isn't an extra event
# in the queue), append the coordinates to the list
if event.inaxes and not self.done:
self.clicks.append([event.xdata, event.ydata])
# now if we're supposed to draw lines, do so
if self.lines and len(self.clicks) > 1:
event.inaxes.plot([self.clicks[-1][0], self.clicks[-2][0]],
[self.clicks[-1][1], self.clicks[-2][1]],
color='w', linewidth=2.0,
scalex=False, scaley=False)
event.inaxes.plot([self.clicks[-1][0], self.clicks[-2][0]],
[self.clicks[-1][1], self.clicks[-2][1]],
color='k', linewidth=1.0,
scalex=False, scaley=False)
_pylab.draw()
# if we have n data points, we're done
if len(self.clicks) >= self.n and self.n is not 0:
self.done = True
return
def __call__(self, n=1, timeout=0, debug=False, lines=False):
"""
Blocking call to retrieve n coordinate pairs through mouse clicks.
n=1 number of clicks to collect. Set n=0 to keep collecting
points until you click with the right mouse button.
timeout=30 maximum number of seconds to wait for clicks
before giving up.
timeout=0 to disable
debug=False show each click event coordinates
lines=False draw lines between clicks
"""
# just for printing the coordinates
self.debug = debug
# for drawing lines
self.lines = lines
# connect the click events to the on_click function call
self.cid = _pylab.connect('button_press_event', self.on_click)
# initialize the list of click coordinates
self.clicks =
# wait for n clicks
self.n = n
self.done = False
t = 0.0
while not self.done:
# key step: yield the processor to other threads
_wx.Yield();
_time.sleep(0.1)
# check for a timeout
t += 0.1
if timeout and t > timeout: print "ginput timeout"; break;
# All done! Disconnect the event and return what we have
_pylab.disconnect(self.cid)
self.cid = None
return _numpy.array(self.clicks)
def ginput(n=1, timeout=0, show=True, lines=False):
"""
Simple functional call for physicists. This will wait for n clicks
from the user and
return a list of the coordinates of each click.
n=1 number of clicks to collect
timeout=30 maximum number of seconds to wait for clicks
before giving up.
timeout=0 to disable
show=True print the clicks as they are received
lines=False draw lines between clicks
"""
x = GaelInput()
return x(n, timeout, show, lines)
···
On Feb 5, 2008 3:58 PM, John Hunter <jdh2358@...149...> wrote:
On Feb 2, 2008 8:48 AM, Gael Varoquaux <gael.varoquaux@...427...> wrote:
> Here is the new patch. I added visual feedback when accumulating points.
> I hope the docstrings are clear.
Great -- thanks again. I applied this patch and created a new example
ginput_demo.py