Search code examples
pythonmatplotlibclickmousecoordinate

Want to get the mouse coordinate in a while loop


I would like to get the mouse click coordinate for several images. This is my code:

import matplotlib.pyplot as plt

j = 0
while j < nb_images:
    plt.ion()
    fig = plt.figure()
    coords = []
    #Affichage
    plt.imshow(img[j], cmap="gray")
    plt.draw()

    while len(coords) <1:
        cid = fig.canvas.mpl_connect('button_press_event', onclick)

    print(coords[0][0], coords[0][1])
j = j + 1

def onclick(event):
    global ix, iy
    ix, iy = event.xdata, event.ydata
    global coords
    coords.append((ix, iy))
    if len(coords) == 1:
        fig.canvas.mpl_disconnect(cid)
        plt.close()
    return coords

The problem is that I cannot click on the figure to get the coordinate. The figure is busy. How I can fix it? Thank you


Solution

  • I'm trying to answer, although I cannot test, being unable to get hold of mathplotlib on windows, so I'm sure it does not work as is but at least it corrects the way to create things & callbacks.

    The posted code had many flaws:

    • it relied on an interactive way of doing things. Mathplotlib defines callback and has a mainloop (plt.show() that need to be called
    • there is an infinite loop because j increase was outside the while loop. I simplified the loop with a for
    • all actions shall be performed in the onclick callback.

    Feel free to edit

    import matplotlib.pyplot as plt
    i = 0
    
    def onclick(event):
        global ix, iy, i
        ix, iy = event.xdata, event.ydata
        global coords
        coords.append((ix, iy))
        print("clicked "+str(coords))
        i+=1
        if i == nb_images:
             plt.close()
             fig.canvas.mpl_disconnect(cid)
             # then do something with the coords array
        else:
             # show next image and go one
             plt.imshow(img[i], cmap="gray")
    
    plt.ion()
    fig = plt.figure()
    
    plt.imshow(img[0], cmap="gray")
    
    
    fig.canvas.mpl_connect('button_press_event', onclick)
    plt.draw()
    plt.show()