可拖动线在Matplotlib中相互选择

2024-10-04 03:21:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我尝试使用matplotlib处理和拾取来创建一个可拖动行的类。其目的是在图上设置不同的阈值和间隔。代码如下:

import matplotlib.pyplot as plt
import matplotlib.lines as lines
import numpy as np

class draggable_lines:

    def __init__(self, ax, kind, XorY):

        self.ax = ax
        self.c = ax.get_figure().canvas
        self.o = kind
        self.XorY = XorY

        if kind == "h":
            x = [-1, 1]
            y = [XorY, XorY]

        elif kind == "v":
            x = [XorY, XorY]
            y = [-1, 1]

        else:
            print("choose h or v line")

        self.line = lines.Line2D(x, y, picker=5)
        self.ax.add_line(self.line)
        self.c.draw()
        sid = self.c.mpl_connect('pick_event', self.clickonline)

    # pick line when I select it 
    def clickonline(self, event):

        self.active_line = 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)

    # The selected line must follow the mouse
    def followmouse(self, event):

        if self.o == "h":
            self.line.set_ydata([event.ydata, event.ydata])
        else:
            self.line.set_xdata([event.xdata, event.xdata])

        self.c.draw()

    # release line on click
    def releaseonclick(self, event):

        if self.o == "h":
            self.XorY = self.line.get_ydata()[0]
        else:
            self.XorY = self.line.get_xdata()[0]

        print (self.XorY)

        self.c.mpl_disconnect(self.releaser)
        self.c.mpl_disconnect(self.follower)


plt.ion()
fig = plt.figure()
ax = fig.add_subplot(111)
Vline = draggable_lines(ax, "h", 0.5)
Tline = draggable_lines(ax, "v", 0.5)
Tline2 = draggable_lines(ax, "v", 0.1)

当只使用一行代码时,这种行为是我所期望的(即使当我释放行时,它也会通知选择)。在

当我使用多个行时,它会同时选择所有行!在

我想我误解了事件管理器的功能,但是我不明白为什么不同的对象,很好的区分(正如我在print("line selected ", event.artist))中看到的那样,应该选择自己和另一个!在


Tags: importselfeventmatplotlibdeflineaxmpl
1条回答
网友
1楼 · 发布于 2024-10-04 03:21:14

有人可能会问不同的问题:如果单击其中任何一行,matplotlib如何知道要拖动哪一行?答:不会,因为它有三个回调,每行一个,并将执行所有回调。在

因此,解决方案是首先检查单击的行是否实际上是要在'pick_event'回调中移动的行:

if event.artist == self.line:
    # register other callbacks

(另一个注意事项:如果不经常调用canvas.draw(),而是canvas.draw_idle()),您会受益匪浅

^{pr2}$

相关问题 更多 >