我有一个简单的代码,其中显示了两个子图,并允许用户在记录x,y这些点击的坐标时在第二个子图上单击鼠标左键。
问题在于,单击以选择要缩放的区域并拖动子图的单击也被标识为左键单击。
有没有办法区分和过滤掉这些左击?
import numpy as np
import matplotlib.pyplot as plt
def onclick(event, ax):
# Only clicks inside this axis are valid.
if event.inaxes == ax:
if event.button == 1:
print(event.xdata, event.ydata)
# Draw the click just made
ax.scatter(event.xdata, event.ydata)
ax.figure.canvas.draw()
elif event.button == 2:
# Do nothing
print("scroll click")
elif event.button == 3:
# Do nothing
print("right click")
else:
pass
fig, (ax1, ax2) = plt.subplots(1, 2)
# Plot some random scatter data
ax2.scatter(np.random.uniform(0., 10., 10), np.random.uniform(0., 10., 10))
fig.canvas.mpl_connect(
'button_press_event', lambda event: onclick(event, ax2))
plt.show()
Run Code Online (Sandbox Code Playgroud)
您可以检查在先前移动鼠标后是否释放了鼠标按钮。由于要进行缩放和平移,因此只有在没有以前的移动发生时,才可以调用该函数以绘制新点。
import numpy as np
import matplotlib.pyplot as plt
class Click():
def __init__(self, ax, func, button=1):
self.ax=ax
self.func=func
self.button=button
self.press=False
self.move = False
self.c1=self.ax.figure.canvas.mpl_connect('button_press_event', self.onpress)
self.c2=self.ax.figure.canvas.mpl_connect('button_release_event', self.onrelease)
self.c3=self.ax.figure.canvas.mpl_connect('motion_notify_event', self.onmove)
def onclick(self,event):
if event.inaxes == self.ax:
if event.button == self.button:
self.func(event, self.ax)
def onpress(self,event):
self.press=True
def onmove(self,event):
if self.press:
self.move=True
def onrelease(self,event):
if self.press and not self.move:
self.onclick(event)
self.press=False; self.move=False
def func(event, ax):
print(event.xdata, event.ydata)
ax.scatter(event.xdata, event.ydata)
ax.figure.canvas.draw()
fig, (ax1, ax2) = plt.subplots(1, 2)
# Plot some random scatter data
ax2.scatter(np.random.uniform(0., 10., 10), np.random.uniform(0., 10., 10))
click = Click(ax2, func, button=1)
plt.show()
Run Code Online (Sandbox Code Playgroud)
小智 7
我意识到这是一个老问题,但我也遇到了同样的问题,我想我找到了一个巧妙的解决方案;然而它目前仅适用于 Qt 后端(其他后端也可能存在类似的解决方案)。这个想法是 matplotlib 在缩放或平移时改变光标形状,因此您可以检查这一点。这是改编后的代码:
import numpy as np
import matplotlib
matplotlib.use('qt5agg')
import matplotlib.pyplot as plt
def onclick(event, ax):
# Only clicks inside this axis are valid.
try: # use try/except in case we are not using Qt backend
zooming_panning = ( fig.canvas.cursor().shape() != 0 ) # 0 is the arrow, which means we are not zooming or panning.
except:
zooming_panning = False
if zooming_panning:
print("Zooming or panning")
return
if event.inaxes == ax:
if event.button == 1:
print(event.xdata, event.ydata)
# Draw the click just made
ax.scatter(event.xdata, event.ydata)
ax.figure.canvas.draw()
elif event.button == 2:
# Do nothing
print("scroll click")
elif event.button == 3:
# Do nothing
print("right click")
else:
pass
fig, (ax1, ax2) = plt.subplots(1, 2)
# Plot some random scatter data
ax2.scatter(np.random.uniform(0., 10., 10), np.random.uniform(0., 10., 10))
fig.canvas.mpl_connect(
'button_press_event', lambda event: onclick(event, ax2))
plt.show()
Run Code Online (Sandbox Code Playgroud)