5

Using Python 3.6+, Jupyter notebooks and matplotlib, I want to find out how to get the x,y position of an image by moving the mouse over it and/or clicking the position

I'm using any image, for example a png sized 966 x 525 pixel.

%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

fig = plt.figure(figsize=(20,30))

img=mpimg.imread('ausgabe.png')
imgplot = plt.imshow(img)
plt.show();

Many suggested solutions on stackoverflow involve connecting an event to matplotlib, like

fig.canvas.mpl_connect('button_press_event', onclick)

(see Store mouse click event coordinates with matplotlib)

But in Jupyter that just doesn't react. Instead clicking on the image sometimes enlarges it.

What is a good way to display a png in Jupyter so that I could collect (=print) the click positions - or rerun the cell with the collected information?

576i
  • 7,579
  • 12
  • 55
  • 92
  • Did you consider using the `%matplotlib notebook` backend instead? This would allow to use the events just as within python scripts. Else you would need to write some JavaScript that is executed in the browser to retrieve the coordinates in the image. – ImportanceOfBeingErnest Sep 08 '18 at 13:25
  • Yes, I tried `%matplotlib notebook` instead of `%matplotlib inline`- this resulted in the image not printing at all. The navigation bar would flash up for a split second and then nothing. The examples I found for that were not using Jupyter, so I assumed they'd just work with regular python. I also tried googling for JavaScript examples that would show the x/y position of an image but couldn't find anything helpful. – 576i Sep 08 '18 at 15:19
  • 1
    I assume when you tried that you did not restart the kernel? – ImportanceOfBeingErnest Sep 08 '18 at 15:23
  • That was a good tip, after restarting the kernel I get an image... Now I only need to research again how to receive the position this way – 576i Sep 08 '18 at 15:29

3 Answers3

6

you can use the native Tk backend and you can retrieve the mouse click position this way. for example

%matplotlib tk
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

fig = plt.figure(figsize=(20,30))

img=mpimg.imread('ausgabe.png')

def onclick(event):
    ix, iy = event.xdata, event.ydata
    print(ix, iy)

cid = fig.canvas.mpl_connect('button_press_event', onclick)

imgplot = plt.imshow(img)
plt.show()

A separate tk window will pop-up and when you click, the x,y position will print in the notebook. if that doesn't work, you might need to use %matplotlib qt5 or even %matplotlib qt4

mark jay
  • 1,256
  • 14
  • 23
0

I agree with the post above about switching to tk. The only thing I would like to add is that in order to get point clicks on an image, one can simply use ginput().

import matplotlib
matplotlib.use('TkAgg')

pil = Image.open("..\img\japan.jpg")
im = array(pil)
imshow(im)

pts = ginput(3) #number of clicks
print(pts)

Result: [(0.052688172043010795, 0.06725720343611918), (1.9451612903225803, 0.8951697538724439), (3.9854838709677414, -0.7310870416274797)]

Illia
  • 301
  • 1
  • 4
  • 16
0

As pointed out by @ImportanceOfBeingErnest.

Add %matplotlib notebook to your program and you would be able to register clicks and interact with the graph like zoom in / out, move and reset. Here's how the result would appear.

Before:

enter image description here

After: enter image description here

Hissaan Ali
  • 2,229
  • 4
  • 25
  • 51