首页 > 解决方案 > 如何使用 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()

标签: pythonpython-3.xmatplotlib

解决方案


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

您需要记下您在方法中选择的事件的索引clickonline,然后在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()

推荐阅读