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