【问题标题】:I want to use matplotlib's buttons to append an item to a list我想使用 matplotlib 的按钮将项目附加到列表中
【发布时间】:2020-06-08 23:45:05
【问题描述】:

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

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】:

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

    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 函数中,它工作得很好。

    【讨论】:

      猜你喜欢
      • 2019-05-30
      • 1970-01-01
      • 1970-01-01
      • 2023-01-25
      • 2011-10-12
      • 1970-01-01
      • 2011-05-15
      • 2011-01-31
      相关资源
      最近更新 更多