5

I'm created a vertical and a horizontal line in a plot with mouseover event. Those lines intend to help user to select where to click in the plot. My problem is that when the mouse moves over the plot, the lines previous drawn don't disappear. Can someone explain me how to do it?
I used ax.lines.pop() after draw the plot inside the OnOver function but that doesn't worked.

This is the code that I'm using

from matplotlib import pyplot as plt
import numpy as np

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(np.random.rand(10))


def OnClick(event):
    print 'button=%d, x=%d, y=%d, xdata=%f, ydata=%f'%(
        event.button, event.x, event.y, event.xdata, event.ydata)

def OnOver(event):
    x = event.xdata
    y = event.ydata
    ax.axhline(y)
    ax.axvline(x)
    plt.draw()  


did = fig.canvas.mpl_connect('motion_notify_event', OnOver)   
#iii = fig.canvas.mpl_disconnect(did) # get rid of the click-handler
cid = fig.canvas.mpl_connect('button_press_event', OnClick)

plt.show()

Thanks in advance for your help. Ivo

TMoover
  • 620
  • 1
  • 7
  • 22

1 Answers1

12

You need to remove the lines you do not want. For example

def OnOver(event):
   if len(ax.lines) > 1 :
      ax.lines[-1].remove()
      ax.lines[-1].remove()
   ax.axhline(event.ydata)
   ax.axvline(event.xdata)
   plt.draw()

This is neither robust nor efficient.

Instead of constantly creating and destroying lines we can just draw them once and keep updating them.

lhor = ax.axhline (0.5)
lver = ax.axvline (1)
def OnOver2(event):
   lhor.set_ydata(event.ydata)
   lver.set_xdata(event.xdata)
   plt.draw()

Here I have used global variables and drawn the "cross hairs" in the viewing area to begin with. It could instead be drawn outside of it or not made visible, but you get the idea.

I don't know the optimal way for achieving this.

Craig J Copi
  • 1,754
  • 1
  • 15
  • 12
  • This is great. Thank you very much. I will use second function. Can you explain me why do I need to use [event.ydata, event.ydata] and not only event.ydata? Thank you – TMoover Jul 23 '13 at 21:15
  • @TMoover You can only use one value. I have updated the answer to reflect this. Really I was just introducing the general approach of updating an existing object instead of deleting/creating them repeatedly. I didn't try to generalize/optimize the approach too much. – Craig J Copi Jul 23 '13 at 21:28