为了账号安全,请及时绑定邮箱和手机立即绑定

如何绘制可拖动的多边形

如何绘制可拖动的多边形

侃侃无极 2022-05-19 14:15:27
关于这个绘制可拖动矩形的 matplotlib 示例,我尝试对多边形做同样的事情。到目前为止,我能够绘制一个多边形并将其拖到画布上的某个位置。如果我释放鼠标按钮,我将无法再次移动多边形,这就是我的问题。我想尽可能多地通过每次鼠标按下来拖放多边形。我还注意到,在移动多边形后,我仍然可以单击多边形曾经所在的位置并再次拖动它。所以初始geometry必须保存在某个地方,但我想它应该被覆盖。编辑:正如下面评论中所建议的,我将添加一个补丁而不是一个集合,因为我只会绘制一个多边形(请参阅旧代码注释掉)。此外,我关闭了多边形以演示您只能通过单击多边形内部而不是单击其边缘来拖动补丁。如果我想再次拖动多边形,它会自动跳回其初始位置。import matplotlib.pyplot as pltfrom matplotlib.patches import Polygon#from matplotlib.collections import PatchCollectionclass DraggablePolygon:    lock = None    def __init__(self, polygon):        self.poly = polygon        self.press = None    def connect(self):        'connect to all the events we need'        self.cidpress = self.poly.figure.canvas.mpl_connect(            'button_press_event', self.on_press)        self.cidrelease = self.poly.figure.canvas.mpl_connect(            'button_release_event', self.on_release)        self.cidmotion = self.poly.figure.canvas.mpl_connect(            'motion_notify_event', self.on_motion)    def on_press(self, event):        'on button press we will see if the mouse is over us and store some data'        if event.inaxes != self.poly.axes: return        if DraggablePolygon.lock is not None: return        contains, attrd = self.poly.contains(event)        if not contains: return        x0, y0 = geometry[0]        self.press = x0, y0, event.xdata, event.ydata        DraggablePolygon.lock = self我假设geometryand的定义newGeometry必须在代码中的不同位置,但经过几次尝试后我找不到有效的解决方案。有没有人发现我犯的错误?
查看完整描述

1 回答

?
牧羊人nacy

TA贡献1862条经验 获得超7个赞

问题下方的评论有助于最终找到有效的代码。也许这不是最好和最 Pythonic 的方式,但它可以满足我的需求。


import matplotlib.pyplot as plt

from matplotlib.patches import Polygon


class DraggablePolygon:

    lock = None

    def __init__(self):

        print('__init__')

        self.press = None


        fig = plt.figure()

        ax = fig.add_subplot(111)


        self.geometry = [[0.0,0.0],[0.1,0.05],[0.2,0.15],[0.3,0.20],[0.4,0.25],[0.5,0.30],

                    [0.6,0.25],[0.7,0.15],[0.8,0.05],[0.9,0.025],[1.0,0.0]]

        self.newGeometry = []

        poly = plt.Polygon(self.geometry, closed=True, fill=False, linewidth=3, color='#F97306')

        ax.add_patch(poly)

        self.poly = poly


    def connect(self):

        'connect to all the events we need'

        print('connect')

        self.cidpress = self.poly.figure.canvas.mpl_connect(

        'button_press_event', self.on_press)

        self.cidrelease = self.poly.figure.canvas.mpl_connect(

        'button_release_event', self.on_release)

        self.cidmotion = self.poly.figure.canvas.mpl_connect(

        'motion_notify_event', self.on_motion)


    def on_press(self, event):

        'on button press we will see if the mouse is over us and store some data'

        print('on_press')

        if event.inaxes != self.poly.axes: return

        if DraggablePolygon.lock is not None: return

        contains, attrd = self.poly.contains(event)

        if not contains: return


        if not self.newGeometry:

            x0, y0 = self.geometry[0]

        else:

            x0, y0 = self.newGeometry[0]


        self.press = x0, y0, event.xdata, event.ydata

        DraggablePolygon.lock = self


    def on_motion(self, event):

        'on motion we will move the rect if the mouse is over us'

        if DraggablePolygon.lock is not self:

            return

        if event.inaxes != self.poly.axes: return

        x0, y0, xpress, ypress = self.press

        dx = event.xdata - xpress

        dy = event.ydata - ypress


        xdx = [i+dx for i,_ in self.geometry]

        ydy = [i+dy for _,i in self.geometry]

        self.newGeometry = [[a, b] for a, b in zip(xdx, ydy)]

        self.poly.set_xy(self.newGeometry)

        self.poly.figure.canvas.draw()


    def on_release(self, event):

        'on release we reset the press data'

        print('on_release')

        if DraggablePolygon.lock is not self:

            return


        self.press = None

        DraggablePolygon.lock = None

        self.geometry = self.newGeometry



    def disconnect(self):

        'disconnect all the stored connection ids'

        print('disconnect')

        self.poly.figure.canvas.mpl_disconnect(self.cidpress)

        self.poly.figure.canvas.mpl_disconnect(self.cidrelease)

        self.poly.figure.canvas.mpl_disconnect(self.cidmotion)



dp = DraggablePolygon()

dp.connect()


plt.show()


查看完整回答
反对 回复 2022-05-19
  • 1 回答
  • 0 关注
  • 128 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信