10

In a matplotlib plot, how can I continuously read the coordinates of the mouse when it is moved, but without waiting for clicks? This is possible in matlab, and there is a mpld3 plugin to do almost exactly what I want, but I can't see how to actually access the coordinates from it. There is also the package mpldatacursor, but this seems to require clicks. Searching for things like "matplotlib mouse coordinates without clicking" did not yield answers.

Answers using additional packages such as mpld3 are fine, but it seems like a pure matplotlib solution should be possible.

Robert D-B
  • 1,067
  • 1
  • 10
  • 16
  • Possible duplicate of [Possible to make labels appear when hovering over a point in matplotlib?](https://stackoverflow.com/questions/7908636/possible-to-make-labels-appear-when-hovering-over-a-point-in-matplotlib) – Gabriel Jablonski Jul 17 '18 at 13:11
  • 1
    I think this is much easier to do using Plotly, personally. Supply a dataframe to the plot you need and specify `hover` as the column of interest. – jbuddy_13 May 13 '20 at 20:03

2 Answers2

13

This can be done by connecting to the motion_notify_event, mentioned briefly here in the matplotlib docs. This event fires whenever the mouse moves, giving the callback function a MouseEvent class to work with. This question has some relevant examples.

The MouseEvent class has attributes x, y, xdata, and ydata. The (x, y) coordinates in terms of your plot are given by xdata and ydata; x and y are in pixels. An example is given at cursor_demo.py in the matplotlib docs.

Here's a fairly small example:

import matplotlib.pyplot as plt
import numpy as np


def plot_unit_circle():
    angs = np.linspace(0, 2 * np.pi, 10**6)
    rs = np.zeros_like(angs) + 1
    xs = rs * np.cos(angs)
    ys = rs * np.sin(angs)
    plt.plot(xs, ys)


def mouse_move(event):
    x, y = event.xdata, event.ydata
    print(x, y)


plt.connect('motion_notify_event', mouse_move)
plot_unit_circle()
plt.axis('equal')
plt.show()
Robert D-B
  • 1,067
  • 1
  • 10
  • 16
7

The solution is very simple! We can ask matplotlib to notify us whenever a mouse event happens on the plot. We need to specify three things to achieve this:

  • Which mouse event we are interested in? ( Here we are interested in mouse move, not click for example) view supported events
  • Where matplotlib should send the event data? ( Here we defined a function to receive the data. The name is arbitrary it could be anything)

  • Pass the name of the event and function to matplotlib (we pass them to .connect method.)

It's as simple as that!

def on_mouse_move(event):
    print('Event received:',event.x,event.y)

image= #your image

plt.imshow(image)
plt.connect('motion_notify_event',on_mouse_move)
plt.show()
Mahmoud
  • 698
  • 1
  • 8
  • 9
  • 1
    I would recommend that you add some explanatory text to your answer, or you risk having it deleted as 'low quality' (even though it may be a correct answer)! – Adrian Mole Nov 16 '19 at 23:57