Drawing lines between clicks on image with Matplotlib
Question: I am trying to allow for a user to right click on an image once, and then
again, and then the program will draw a line from the first click to the
second.

However, what I have now, inserts lines into my image seemingly randomly. They
pop up and they are nowhere near my clicks, and are of random lengths and
angles.

I'm sort of a beginner to python and definitely to `matplotlib`, so any help
would be appreciated. Below is my code, with the relevant area marked with a
line of #s:

    
    
    from pymouse import PyMouse
    import matplotlib.pyplot as plt
    import matplotlib.lines as lines
    import numpy
    
    
    im1 = plt.imread('xexample1.PNG')
    im2 = plt.imread('xexample2.PNG')
    im3 = plt.imread('xexample3.PNG')
    data_images = [im1,im2,im3]
    
    
    index = 0
    ax = plt.gca()
    fig = plt.gcf()
    plt.imshow(data_images[index])
    
    
    linepoints = numpy.array([])
    print linepoints
    
    
    
    
    #on click event- print x,y coords
    def onclick(event):
       # if event.xdata != None and event.ydata != None:
        plot = numpy.asarray(data_images[index])
    
        if event.button == 1:            
            print("IMAGE: %d" %index, event.xdata, event.ydata,(plot[event.xdata][event.ydata])*255)
    ######################################################################
        if event.button == 3:
            global linepoints
    
            x = event.xdata
            y = event.ydata
            tup1 = [(x, y)]
    
            linepoints = numpy.append(linepoints, x)
            linepoints = numpy.append(linepoints, y)
    
            if numpy.size(linepoints) == 4:
               # print "full"
                #l1 = lines.Line2D([linepoints[0], linepoints[1]], [linepoints[2],linepoints[3]], transform=fig.transFigure, figure=plt)
                #fig.canvas.draw()
                plt.plot((linepoints[0], linepoints[1]), (linepoints[2], linepoints[3]), '-')
    
                print linepoints
                linepoints = numpy.array([])
    
    
            print linepoints
           # plt.show()
    ######################################################################
    def toggle_images(event):
        global index
    
    
        if event.key == 'x':
            index += 1
    
            if index < len(data_images) and index >= 0:
                plt.imshow(data_images[index])
                plt.draw()
    
            else:
                #plt.close()
                print 'out of range'
                index -= 1
    
    
        if event.key == 'z':
            index -= 1
    
            if index < len(data_images) and index >= 0:
                plt.imshow(data_images[index])
                plt.draw()
    
            else:
                #plt.close()
                print 'out of range'
                index += 1
    
    plt.imshow(data_images[index])
    plt.connect('key_press_event',toggle_images)
    cid = fig.canvas.mpl_connect('button_press_event', onclick)
    plt.show()
    


Answer: I created a dressed-down version attached below, but in the end there was only
a very minor mistake in your code:

    
    
    plt.plot((linepoints[0], linepoints[1]), (linepoints[2], linepoints[3]), '-')
    

needed to be:

    
    
    plt.plot((linepoints[0], linepoints[2]), (linepoints[1], linepoints[3]), '-')
    

I.e.; your 1st (index `0`) and 3rd (index `2`) values are the `x` values and
2nd (index `1`) and fourth (index `3`) are the `y` values, now you were
actually plotting `(x0,y0),(x1,y1)` instead of `(x0,x1),(y0,y1)`

My minimal example:

    
    
    import matplotlib.pyplot as plt
    import numpy
    
    plt.close('all')
    
    fake_img = numpy.random.random((10,10))
    
    plt.imshow(fake_img, interpolation='none')
    ax  = plt.gca()
    fig = plt.gcf()
    
    linepoints = numpy.array([])
    
    def onclick(event):
        if event.button == 3:
            global linepoints
    
            x = event.xdata
            y = event.ydata
    
            linepoints = numpy.append(linepoints, x)
            linepoints = numpy.append(linepoints, y)
    
            if numpy.size(linepoints) == 4:
                plt.plot((linepoints[0], linepoints[2]), (linepoints[1], linepoints[3]), '-')
                linepoints = numpy.array([])
                plt.show()
    
    cid = fig.canvas.mpl_connect('button_press_event', onclick)
    plt.show()
    

