Source code for clickinput

"""
2010-06-30 16:00 IJC: Figuring out how to select a position at a given location.

For an example of how this works:

import clickinput
coords = clickinput.picktest()
print "You finally picked a location, at: ",coords
"""

import matplotlib.pyplot as plt


[docs]def picktest(zoom=10): """ Set up a small, simple test and run PICKLOC on it. """ setuptest() out = pickloc(zoom=zoom) return out
[docs]def setuptest(): """ Set up a small, simple test with which to test PICKLOC. """ import numpy as np f=plt.figure() plt.imshow(np.random.randn(100,100),interpolation=None) plt.plot([23],[66],'*k',ms=15) plt.draw()
[docs]def pickloc(ax=None, zoom=10, resetaxes=False, titstr="click to select location"): """ :INPUTS: ax : (axes instance) axes in which to pick a location zoom : int or 2-tuple zoom radius for target confirmation in x,y or both resetaxes : bool whether to reset axes limits after selection titstr : str String to initially display at title of plot. Press enter/return to exit out, returning -1 :NOTES: Since I updated Matplotlib the "hit enter to exit" functionality doesn't work. Need to fix that.. """ # 2011-04-29 19:26 IJC: # 2011-09-03 20:59 IJMC: Zoom can now be a tuple; x,y not cast as int. # 2011-12-22 13:22 IJMC: On enter, exit out with -1 # 2012-08-18 19:53 IJMC: Cleaned up a bit more, added titstr, # zoom=None works better now. pickedloc = False if ax is None: ax = plt.gca() axlimits = ax.axis() if hasattr(zoom, '__iter__') and len(zoom)>1: xzoom, yzoom = zoom else: xzoom = zoom yzoom = zoom while not pickedloc: if titstr is not None: ax.set_title(titstr) ax.axis(axlimits) x = None while x is None: selectevent = plt.ginput(n=1,show_clicks=False) if len(selectevent)>0: # Prevent user from cancelling out. x,y = selectevent[0] else: return -1 #x = x.astype(int) #y = y.astype(int) if zoom is None: confirmevent = selectevent pickedloc = True else: ax.axis([x-xzoom,x+xzoom,y-yzoom,y+yzoom]) ax.set_title("you selected xy=(%i,%i)\nclick again to confirm, or hit Enter/Return at the prompt to try again." %(x,y) ) plt.draw() confirmevent = plt.ginput(n=1,show_clicks=False) if len(confirmevent)>0: pickedloc = True loc = confirmevent[0] if resetaxes: ax.axis(axlimits) plt.draw() return loc
[docs]def fitparabola(*args, **kw): """Fit a parabola to a data vector. INPUTS: Either y, or x,y -- sequences of data OPTIONS: zoom : float or 2-sequence radii for zoom confirmation. xrange : float +/- range of x values for data to use in fit ax : matplotlib "axes" instance Where to plot: if None, create a new figure plotfit : bool Whether to plot fitted data OUTPUTS: fit : 3-sequence Best-fit parameters of parabola (suitable for :func:`numpy.polyfit`) REQUIREMENTS: :module:`numpy` """ # 2011-09-03 21:20 IJMC: Created import numpy as np # Read options defaults = dict(zoom=None, xrange=None, ax=None, plotfit=False) for key in defaults: if (not kw.has_key(key)): kw[key] = defaults[key] zoom = kw['zoom'] xrange = kw['xrange'] ax = kw['ax'] plotfit = kw['plotfit'] # Initialize data: if len(args)==1: x = np.array(args[0]) nx = x.size y = np.arange(nx, dtype=float) else: x = np.array(args[0]) y = np.array(args[1]) nx = x.size # Plot data if ax is None: f=plt.figure() ax = plt.axes() ax.plot(x, y, '-k') # Select point: x0, y0 = pickloc(zoom=zoom) # Index data and fit: index = (x > (x0 - xrange)) * (x < (x0 + xrange)) fit = np.polyfit(x[index], y[index], 2) if plotfit: ax.plot(x[index], y[index], 'r-') ax.plot(x[index], np.polyval(fit, x[index]), 'og') return fit