I'm plotting a simple image and like to get the x,y value, where I click with the mouse.
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
image = Image.open('points.jpg')
data = np.array(image)
plt.imshow(data)
plt.show()
So, I can navigate the mouse towards each point, click and at the end obtain a list with 4 x,y values.
First off, for images to click on, 'png' is usually a more suitable format than 'jpg'. The compression used for 'jpg' colors can smear colors out.
mplcursors
is a small package that supports clicking (or hovering) on a plot. Standard it displays an annotation tooltip with coordinates. In your application showing an annotation tooltip seems useful. If not, you can suppress that behavior with sel.annotation.set_visible(False)
and still receive the event with the coordinates.
The coordinates come in two flavors: x
and y
using the coordinate system of the axes, or an index (i,j)
to indicate the pixel. With imshow
's extent=
parameter you can flexibly set the desired ranges (default x
and y
go from 0 to the width and height of the image). The x,y
at the center of each pixel are integer values. So, you can either append the (i,j)
indices or the (x,y)
to your list.
Some code to experiment:
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
import mplcursors
image = Image.open('points.png')
data = np.array(image)
img = plt.imshow(data)
points = []
cursor = mplcursors.cursor(img, hover=False)
@cursor.connect("add")
def cursor_clicked(sel):
# sel.annotation.set_visible(False)
sel.annotation.set_text(
f'Clicked on\nx: {sel.target[0]:.2f} y: {sel.target[1]:.2f}\nindex: {sel.target.index}')
points.append(sel.target.index)
print("Current list of points:", points)
plt.show()
print("Selected points:", points)