3

I have a scatter plot, over an imshow (map). I want a click event to add a new scatter point, which I have done by scater(newx,newy)). The trouble is, I then want to add the ability to remove points using a pick event. As there is no remove(pickX,PickY) function, I must get the picked Index and remove them from the list, which means I can't create my scatter as above, I must scatter(allx, ally).

So the bottom line is I need a method of removing the scatter plot and redrawing it with new data, without changing the presence of my imshow. I have tried and tried: just one attempt.

 fig = Figure()
 axes = fig.add_subplot(111)
 axes2 = fig.add_subplot(111)
 axes.imshow(map)
 axes2.scatter(allx,ally)
 # and the redraw
 fig.delaxes(axes2)
 axes2 = fig.add_subplot(111)
 axes2.scatter(NewscatterpointsX,NewscatterpointsY,picker=5)
 canvas.draw()

much to my suprise, this dispensed with my imshow and axes too :(. Any methods of achieving my dream is much appreciated. Andrew

Andrewb
  • 63
  • 1
  • 5

1 Answers1

3

Firstly, you should have a good read of the events docs here.

You can attach a function which gets called whenever the mouse is clicked. If you maintain a list of artists (points in this case) which can be picked, then you can ask if the mouse click event was inside the artists, and call the artist's remove method. If not, you can create a new artist, and add it to the list of clickable points:

import matplotlib.pyplot as plt

fig = plt.figure()
ax = plt.axes()

ax.set_xlim(0, 1)
ax.set_ylim(0, 1)

pickable_artists = []
pt, = ax.plot(0.5, 0.5, 'o')  # 5 points tolerance
pickable_artists.append(pt)


def onclick(event):
    if event.inaxes is not None and not hasattr(event, 'already_picked'):
        ax = event.inaxes

        remove = [artist for artist in pickable_artists if artist.contains(event)[0]]

        if not remove:
            # add a pt
            x, y = ax.transData.inverted().transform_point([event.x, event.y])
            pt, = ax.plot(x, y, 'o', picker=5)
            pickable_artists.append(pt)
        else:
            for artist in remove:
                artist.remove()
        plt.draw()


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

plt.show()

enter image description here

Hope this helps you achieve your dream. :-)

pelson
  • 21,252
  • 4
  • 92
  • 99