我已经写了一个代码,用ginput注册在绘图窗口中单击的x值,它工作得很好,只有当您在窗口内单击时才会注册。
然后我想使用matplotlib小部件添加一些控制按钮,我就是这么做的,它们使用这些方法也工作得很好,到目前为止一切都很好……
但是,我的问题是,当我点击按钮时,按钮的坐标也被ginput注册了,这是我不想要的。有什么方法可以防止这种情况发生吗?让按钮区域对ginput无效,还是以某种方式检测到并拒绝这些点击?
我也很乐意使用ginput的替代方法,我并不执着于任何特定的方法(我对python中的GUI非常陌生,只想设置一个简单的示例)。
以下是我的可重现示例,单击测试按钮也会向列表中添加行:-(
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Button
class Index:
def test(self, event):
print ("test")
# fake data
x=np.arange(30)
y=x**2
times=[]
fig,ax=plt.subplots()
ax.plot(x,y)
callback = Index()
buttonname=['test']
colors=['white']
idx=[0.2]
bax,buttons={},{}
# set up list of buttons.
for i,col,button in zip(idx,colors,buttonname):
bax[button] = plt.axes([0.92, i, 0.07, 0.07])
buttons[button] = Button(bax[button],button,color=col,hovercolor='green')
buttons[button].on_clicked(getattr(callback,button))
# register click on plot
while True:
pts=plt.ginput(1)
print ("pts is",pts)
timebegin=pts[0][0]
times.append(timebegin)
ax.axvline(x=timebegin)
print ("adding",timebegin)
print ("all ",times)
plt.pause(0.05)示例的屏幕截图:

编辑:我现在想到了一个技巧,在按钮方法中,我添加了一个弹出窗口来删除时间列表中的条目,并取消绘制线条(我也声明了时间和线条为全局),它是有效的,但它是笨拙的,不是很优雅,因为程序绘制了错误的线条,然后再次删除它。
# in the main code I now append the ax.axvline to a list "lines"
def test(self,event):
times.pop()
times.pop()
lines.pop().remove()发布于 2021-04-28 14:43:08
您可以在回调中执行times.append(nan),因此如果times[-1]为nan,则对其执行pop()操作并忽略单击。在注册按钮事件时有一些延迟,所以在检查times[-1]之前先执行pause()。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Button
times = []
# on click event, append nan
class Index:
def test(self, event):
global times
times.append(np.nan)
print('test')
fig, ax = plt.subplots()
x = np.arange(30)
y = x**2
ax.plot(x, y)
callback = Index()
bax = fig.add_axes([0.92, 0.2, 0.07, 0.07])
button = Button(bax, 'Test', color='white', hovercolor='green')
button.on_clicked(callback.test)
while True:
pts = plt.ginput(1)
# allow callback to finish (duration may need to be adjusted)
plt.pause(0.15)
# ignore if newest element is nan
if times and np.isnan(times[-1]):
print(f'ignoring {times[-1]}')
times.pop()
else: # otherwise store and plot
timebegin = pts[0][0]
print(f'adding {timebegin}')
times.append(timebegin)
ax.axvline(x=timebegin)
print(f'times = {times}')
plt.pause(0.05)发布于 2021-04-27 18:05:40
避免该问题的一种方法是不使用按钮来终止输入,而是使用ginput函数(描述为here)的mouse_stop参数,该参数与鼠标按钮或enter键一起工作。然后,可以向绘图中添加文本,以便为用户显式使用此方法……交互性不如一个按钮,但它是有效的。
https://stackoverflow.com/questions/67240971
复制相似问题