我想使用matplotlib的按钮将项目追加到列表中

问题描述 投票:0回答:1

最后,我希望能够将两个圆心的位置附加到单独的列表中。但是,我定义了一个按钮来执行此操作,单击该按钮会给我一个错误。

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import matplotlib.patches as patches
from matplotlib.widgets import Button
import os

class DraggablePoint:
    lock = None #only one can be animated at a time
    def __init__(self, point):
        self.point = point
        self.press = None
        self.background = None

    def connect(self):
        'connect to all the events we need'
        self.cidpress = self.point.figure.canvas.mpl_connect('button_press_event', self.on_press)
        self.cidrelease = self.point.figure.canvas.mpl_connect('button_release_event', self.on_release)
        self.cidmotion = self.point.figure.canvas.mpl_connect('motion_notify_event', self.on_motion)

    def on_press(self, event):
        if event.inaxes != self.point.axes: return
        if DraggablePoint.lock is not None: return
        contains, attrd = self.point.contains(event)
        if not contains: return
        self.press = (self.point.center), event.xdata, event.ydata
        DraggablePoint.lock = self

        # draw everything but the selected rectangle and store the pixel buffer
        canvas = self.point.figure.canvas
        axes = self.point.axes
        self.point.set_animated(True)
        canvas.draw()
        self.background = canvas.copy_from_bbox(self.point.axes.bbox)

        # now redraw just the rectangle
        axes.draw_artist(self.point)

        # and blit just the redrawn area
        canvas.blit(axes.bbox)

    def on_motion(self, event):
        if DraggablePoint.lock is not self:
            return
        if event.inaxes != self.point.axes: return
        self.point.center, xpress, ypress = self.press
        dx = event.xdata - xpress
        dy = event.ydata - ypress
        self.point.center = (self.point.center[0]+dx, self.point.center[1]+dy)

        canvas = self.point.figure.canvas
        axes = self.point.axes
        # restore the background region
        canvas.restore_region(self.background)

        # redraw just the current rectangle
        axes.draw_artist(self.point)

        # blit just the redrawn area
        canvas.blit(axes.bbox)

    def on_release(self, event):
        'on release we reset the press data'
        if DraggablePoint.lock is not self:
            return

        self.press = None
        DraggablePoint.lock = None

        # turn off the rect animation property and reset the background
        self.point.set_animated(False)
        self.background = None

        # redraw the full figure
        self.point.figure.canvas.draw()

    # Want to use this function
    def get_coordinates(self):
        pos = list(self.point.center)
        return(pos)

    def disconnect(self):
        'disconnect all the stored connection ids'
        self.point.figure.canvas.mpl_disconnect(self.cidpress)
        self.point.figure.canvas.mpl_disconnect(self.cidrelease)
        self.point.figure.canvas.mpl_disconnect(self.cidmotion)


Pos = []

rootdir = r'...\images'
point_array = []
# Goes through the input directory and finds the .png files
for subdir, dirs, files in os.walk(rootdir):
    for file in files:
        if file.endswith(('.png')):
            input_image = os.path.join(subdir,file)
            #print(input_image)
            img = mpimg.imread(input_image)
            #img = np.array(img)
            im = plt.imshow(img)
            fig = plt.gcf()
            ax = plt.gca()

            drs = []
            circles = [patches.Circle((800, 500), 10, fc='r', alpha=0.5),
                           patches.Circle((900,500), 10, fc='g', alpha=0.5)]

            for circ in circles:
                ax.add_patch(circ)
                dr = DraggablePoint(circ)
                dr.connect()
                drs.append(dr)

            pos = dr.get_coordinates()
            # Use a button to append an x,y point to an array
            axsave = plt.axes([0.7, 0.05, 0.1, 0.075]) # button position, size stuff
            bsave = Button(axsave,'save')
            plt.axis('scaled')
            plt.show()

print(Pos)

我知道,目前仅保存了一个圈子位置,没关系。当它运行时,on_clicked命令被激活,但是当我单击按钮时,它给了我这个错误:

Traceback (most recent call last):
  File "...\Python\Python36\lib\site-packages\matplotlib\cbook\__init__.py", line 196, in process
    func(*args, **kwargs)
  File "...\Python\Python36\lib\site-packages\matplotlib\widgets.py", line 211, in _release
    func(event)
TypeError: 'NoneType' object is not callable

我不知道为什么它会在单击按钮之前运行。我不知道为什么会给我这个错误。有人知道我在做什么错吗?

python matplotlib button
1个回答
0
投票

我解决了我的问题。我加了

self.center_points = []

在开始时和

def append_center(self,event):
        self.center_points.append(list(self.point.center))

    def get_centers(self):
        return self.center_points

上课。我将追加定义添加到按钮on_click函数中,并且效果很好。

© www.soinside.com 2019 - 2024. All rights reserved.