如何绘制可拖动的多边形

关于这个绘制可拖动矩形的 matplotlib 示例,我尝试对多边形做同样的事情。


到目前为止,我能够绘制一个多边形并将其拖到画布上的某个位置。如果我释放鼠标按钮,我将无法再次移动多边形,这就是我的问题。我想尽可能多地通过每次鼠标按下来拖放多边形。


我还注意到,在移动多边形后,我仍然可以单击多边形曾经所在的位置并再次拖动它。所以初始geometry必须保存在某个地方,但我想它应该被覆盖。


编辑:正如下面评论中所建议的,我将添加一个补丁而不是一个集合,因为我只会绘制一个多边形(请参阅旧代码注释掉)。此外,我关闭了多边形以演示您只能通过单击多边形内部而不是单击其边缘来拖动补丁。


如果我想再次拖动多边形,它会自动跳回其初始位置。


import matplotlib.pyplot as plt

from matplotlib.patches import Polygon

#from matplotlib.collections import PatchCollection


class 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必须在代码中的不同位置,但经过几次尝试后我找不到有效的解决方案。有没有人发现我犯的错误?


侃侃无极
浏览 129回答 1
1回答

牧羊人nacy

问题下方的评论有助于最终找到有效的代码。也许这不是最好和最 Pythonic 的方式,但它可以满足我的需求。import matplotlib.pyplot as pltfrom matplotlib.patches import Polygonclass 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()
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python