如何使matplotlib按钮\按下\事件忽略单击图形按钮?由于按钮是axis对象,因此event.inax不起作用

2024-04-24 19:11:52 发布

您现在位置:Python中文网/ 问答频道 /正文

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

我尝试使用event.inaxes which来检查光标是否在轴区域。所以我实现了一些逻辑。不幸的是,它只适用于绘图的外部,但对按钮根本不起作用。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()




Tags: selfeventdataobjectplotdef模式fig