問題描述
matplotlib:重繪前清除散點數據 (matplotlib: clearing the scatter data before redrawing)
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
參考解法
方法 1:
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()
Hope this helps you achieve your dream. :-)