In R, there is a function locator
which is like Matlab's ginput
where you can click on the figure with a mouse and select any x,y coordinate. In addition, there is a function called identify(x,y)
where if you give it a set of points x,y that you have plotted and then click on the figure, it will return the index of the x,y point which lies nearest (within an adjustable tolerance) to the location you have selected (or multiple indices, if multiple points are selected). Is there such a functionality in Matplotlib?

- 42,883
- 45
- 137
- 231
-
1FWIW: There's also `iselect()` in the `iplots` package (for R). This is a generalization: it involves linking and brushing. The same can be done via the `get(,'BrushData')` function in Matlab. – Iterator Nov 01 '11 at 18:29
-
Right, and Rggobi as well. But I was not aware of Matlab's capability for this -- last time I used it intensively was back in the days of version 6.5. Seems to have gotten fancy since then. – hatmatrix Nov 03 '11 at 10:09
-
3Fancy and pricey. The cost of R has also tripled in the last decade, but it remains a bargain. :) – Iterator Nov 03 '11 at 12:24
4 Answers
You may want to use a pick event :
fig = figure()
ax1 = fig.add_subplot(111)
ax1.set_title('custom picker for line data')
line, = ax1.plot(rand(100), rand(100), 'o', picker=line_picker)
fig.canvas.mpl_connect('pick_event', onpick2)
Tolerance set by picker parameter there:
line, = ax1.plot(rand(100), 'o', picker=5) # 5 points tolerance

- 9,989
- 4
- 38
- 56
-
1Updated tutorial for [pick_event](https://matplotlib.org/stable/gallery/event_handling/pick_event_demo.html) – Dawierha Sep 20 '21 at 14:09
from __future__ import print_function
import matplotlib.pyplot as plt
from matplotlib.lines import Line2D
from matplotlib.patches import Rectangle
from matplotlib.text import Text
from matplotlib.image import AxesImage
import numpy as np
from numpy.random import rand
if 1:
fig, ax = plt.subplots()
ax.set_title('click on points', picker=True)
ax.set_ylabel('ylabel', picker=True, bbox=dict(facecolor='red'))
line, = ax.plot(rand(100), 'o', picker=5)
def onpick1(event):
if isinstance(event.artist, Line2D):
thisline = event.artist
xdata = thisline.get_xdata()
ydata = thisline.get_ydata()
ind = event.ind
print 'X='+str(np.take(xdata, ind)[0]) # Print X point
print 'Y='+str(np.take(ydata, ind)[0]) # Print Y point
fig.canvas.mpl_connect('pick_event', onpick1)

- 1,523
- 12
- 7
-
4If you import print function from future you have to add the brakets: print('X='+str(np.take(xdata, ind)[0])) – G M Apr 22 '16 at 09:38
Wow many years have passed! Now matplotlib
also support the ginput
function which has almost the same API as Matlab. So there is no need to hack by the mpl-connect and so on any more! (https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.ginput.html) For instance,
plt.ginput(4)
will let the user to select 4 points.

- 15,854
- 5
- 53
- 88
-
Is there also an equivalent for `identify(x, y)`? Or better, the ability to call something like `ginput()` on e.g., a `Line2D` object? – James Paul Mason Nov 08 '19 at 19:58
-
@James Paul Mason I am not familiar with that and maybe you can search or open a new question :) – ch271828n Nov 10 '19 at 00:38
The ginput()
is a handy tool to select x, y coordinates of any random point from a plotted window, however that point may not belong to the plotted data. To select x, y coordinates of a point from the plotted data, an efficient tool still is to use 'pick_event'
property with mpl_connect
as the example given in the documentation. For example:
import matplotlib.pyplot as plt
import numpy as np
from numpy.random import rand
fig, ax = plt.subplots()
ax.plot(rand(100), rand(100), picker=3)
# 3, for example, is tolerance for picker i.e, how far a mouse click from
# the plotted point can be registered to select nearby data point/points.
def on_pick(event):
global points
line = event.artist
xdata, ydata = line.get_data()
print('selected point is:',np.array([xdata[ind], ydata[ind]]).T)
cid = fig.canvas.mpl_connect('pick_event', on_pick)
The last line above will connect the plot with the 'pick_event'
and the corrdinates of the nearest plot points will keep printing after each mouse click on plot, to end this process, we need to use mpl_disconnect
as:
fig.canvas.mpl_disconnect(cid)

- 1
- 1