0

这是问题所在。我需要创建“点击捕捉器”。我需要通过单击按钮(标记)打开点击捕获模式,然后,当我点击我的情节时,我希望我的程序记住点列表、坐标等。特别重要的是 - 其他按钮在点击时必须正常工作捕捉模式开启。例如我实现了打印按钮。我想在我的情节中单击几次,然后在不离开单击捕获模式的情况下单击“打印”按钮,然后查看咳嗽点列表。问题是我的程序将matplotlib.widgets按钮视为 anaxes并且每当我使用任何按钮时它都会从它们中捕获点。

我尝试使用event.inaxes whichwhich 应该检查光标是否在轴区域中。所以我已经实现了一些逻辑。不幸的是,它只适用于情节的外部,但根本不适用于按钮。似乎 matplotlib 将按钮视为轴对象,因此它完全不起作用。

请帮帮我,我是编程的初学者,自己学的(所以欢迎任何代码审查)。

* tl;dr:当你打开捕捉模式时,你可以很好地看到这个错误,点击情节,然后多次点击打印按钮。每次单击“打印”都会向点列表中添加额外的坐标。*

代码如下:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Button


class ClickCatcher:

    def __init__(self, window_object):
        self.window_object = window_object
        self.fig = self.window_object.fig
        self.ax = self.window_object.ax
        self.window_object.is_click_catcher_working = True

        self.cid = window_object.fig.canvas.mpl_connect('button_press_event', self)
        self.points, = self.ax.plot([], [], marker='.', ls='None', color='red')

        self.data_x = []
        self.data_y = []

    def __call__(self, event):
        if event.button == 1 and event.inaxes:
            self.data_x.append(event.xdata)
            self.data_y.append(event.ydata)
            self.update_plot()
            print('{:8.2f} {:8.2f}'.format(event.xdata, event.ydata))

            self.window_object.click_data = (self.data_x, self.data_y)

    def update_plot(self):
        self.points.set_data(self.data_x, self.data_y)
        self.fig.canvas.draw()


class Window:

    def __init__(self):
        self.is_click_catcher_working = False
        self.click_data = ()

        self.fig, self.ax = plt.subplots()
        self.configure_appearance()
        self._plot, = plt.plot(np.arange(0, 10, 0.1), np.sin(np.arange(0, 10, 0.1)),
                               drawstyle='steps-mid', color='black', lw=1)
        self._add_buttons()

    def configure_appearance(self):
        self.fig.set_size_inches(10, 5)
        self.ax.tick_params(axis='both', labelsize=14)
        self.ax.set_xlabel('Energy (keV)', fontsize=12)
        self.ax.set_ylabel('Number of counts', fontsize=12)
        plt.subplots_adjust(bottom=0.25)

    def _add_buttons(self):
        self.button_mark = Button(plt.axes([0.4, 0.05, 0.1, 0.075]), 'Mark')
        self.button_mark.on_clicked(self.activate_marking)
        self.button_print = Button(plt.axes([0.6, 0.05, 0.1, 0.075]), 'Print')
        self.button_print.on_clicked(self.print_points)

    def catch_coordinates(self):
        click = ClickCatcher(self)

    def activate_marking(self, event):
        if self.is_click_catcher_working:
            pass
        else:
            self.is_click_catcher_working = True
            self.catch_coordinates()

    def print_points(self, event):
        output = '({:.2f}, {:.2f}) ; '*len(self.click_data[0])
        print(output.format(*self.click_data[0], *self.click_data[1]))


if __name__ == '__main__':

    win = Window()
    plt.show()



4

0 回答 0