简体   繁体   中英

How can I pick more than one point using matplotlib?

I have written the code to plot, pick, drag and get the final coordinates using matplotlib. But once I pick the first point I can't pick except for the first one. How can I pick other points also and get the new location(coordinates) for all?

Here is the code:

import matplotlib.pyplot as plt
import matplotlib.lines as lines
from matplotlib.collections import PathCollection

lines.VertexSelector

class draggable_lines:
    def __init__(self, ax):
        self.ax = ax
        self.c = ax.get_figure().canvas

        self.line = lines.Line2D(x, y, picker=5, marker='o', markerfacecolor='r', color='w')
        self.ax.add_line(self.line)
        self.c.draw_idle()
        self.sid = self.c.mpl_connect('pick_event', self.clickonline)

    def clickonline(self, event):
        if event.artist:
            print("line selected ", event.artist)
            self.follower = self.c.mpl_connect("motion_notify_event", self.followmouse)
            self.releaser = self.c.mpl_connect("button_press_event", self.releaseonclick)

    def followmouse(self, event):
        self.line.set_data([event.xdata, event.ydata])
        self.c.draw_idle()

    def releaseonclick(self, event):
        data = self.line.get_data()
        print(data)

        self.c.mpl_disconnect(self.releaser)
        self.c.mpl_disconnect(self.follower)
fig = plt.figure()
ax = fig.add_subplot(111)
x, y = [2,4,5,7], [8, 6, 12,9]
ax.plot(x, y)
Vline = draggable_lines(ax)
plt.show()

Your current problem is, that you set your entire x and y data to only one x, y datapoint.

You need to make note of the index of the event you picked in your method clickonline and then modify only the data at that index during your followmouse method. Also, I don't know if it is on purpose, but you might want to change your event for the releasonclick method to a "button_release_event" .

Here's the complete code which should work as expected:

import matplotlib.pyplot as plt
import matplotlib.lines as lines

class draggable_lines:
    def __init__(self, ax):
        self.ax = ax
        self.c = ax.get_figure().canvas

        self.line = lines.Line2D(x, y, picker=5, marker='o', markerfacecolor='r', color='b')
        self.ax.add_line(self.line)
        self.c.draw_idle()
        self.sid = self.c.mpl_connect('pick_event', self.clickonline)

    def clickonline(self, event):
        if event.artist:
            print("line selected ", event.artist)
            self.currentIdx = event.ind
            self.follower = self.c.mpl_connect("motion_notify_event", self.followmouse)
            self.releaser = self.c.mpl_connect("button_release_event", self.releaseonclick)

    def followmouse(self, event):
        if self.currentIdx.size != 0:
            if event.xdata and event.ydata:
                d = list(self.line.get_data())
                d[0][int(self.currentIdx)] = event.xdata
                d[1][int(self.currentIdx)] = event.ydata
                self.line.set_data(d)
                self.c.draw_idle()

    def releaseonclick(self, event):
        data = self.line.get_data()
        print(data)
        self.c.mpl_disconnect(self.releaser)
        self.c.mpl_disconnect(self.follower)

fig = plt.figure()
ax = fig.add_subplot(111)
x, y = [2,4,5,7], [8, 6, 12,9]
ax.plot(x, y, color='w')
Vline = draggable_lines(ax)
plt.show()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM