如何使用matplotlib选择多个点?

时间:2019-02-28 10:47:08

标签: python python-3.x matplotlib

我已经编写了使用matplotlib绘制,拾取,拖动并获得最终坐标的代码。但是,一旦我选择了第一点,就只能选择第一点。 我如何还能选择其他点并获得所有的新位置(坐标)?

代码如下:

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()

1 个答案:

答案 0 :(得分:1)

当前的问题是,您将整个xy数据设置为仅一个x, y数据点。

您需要记下在方法clickonline中选择的事件的 index ,然后在followmouse方法期间仅修改该索引处的数据。 另外,我不知道它是否是故意的,但是您可能希望将releasonclick方法的事件更改为"button_release_event"

以下是应按预期工作的完整代码:

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()