gpt4 book ai didi

python - 将 matplotlib 的鼠标按钮事件与 pick 事件结合起来

转载 作者:太空宇宙 更新时间:2023-11-03 17:26:45 24 4
gpt4 key购买 nike

基于鼠标按钮和按键事件的组合,对散点图的点应用不同的功能。当按下鼠标左键时matplotlib的Lasso调用小部件并使用包含的点功能 1 发生。当按下 Shift+LMB 时,将绘制一个 Lasso,并使用包含的点执行功能 2。当按下 Alt+LMB 时,将绘制一个 Lasso,并使用包含的点执行功能 3。最后但并非最不重要的一点是,当我按下 RMB 时,会触发拾取事件,并给出散点图中所选点的索引。

自从我添加了 pick 事件后,上述功能就可以正常工作,直到 第一次触发 pick 事件。当它被触发时, Canvas 似乎被锁定,我无法使用任何其他功能。虽然我获得了所选点的索引,但没有收到任何错误,并且 Canvas 变得无响应。

我修改了取自 this 的代码问题,这实际上是我想做的。

代码:

import logging
import matplotlib
from matplotlib.widgets import Lasso
from matplotlib.colors import colorConverter
from matplotlib.collections import RegularPolyCollection
from matplotlib import path
import numpy as np
import matplotlib.pyplot as plt
from numpy.random import rand

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)


class Datum(object):
colorin = colorConverter.to_rgba('red')
colorShift = colorConverter.to_rgba('cyan')
colorCtrl = colorConverter.to_rgba('pink')
colorout = colorConverter.to_rgba('blue')

def __init__(self, x, y, include=False):
self.x = x
self.y = y
if include:
self.color = self.colorin
else:
self.color = self.colorout


class LassoManager(object):
def __init__(self, ax, data):
self.axes = ax
self.canvas = ax.figure.canvas
self.data = data

self.Nxy = len(data)

facecolors = [d.color for d in data]
self.xys = [(d.x, d.y) for d in data]
fig = ax.figure
self.collection = RegularPolyCollection(fig.dpi, 6, sizes=(100,),facecolors=facecolors, offsets = self.xys, transOffset = ax.transData)

ax.add_collection(self.collection)

self.pick=self.canvas.mpl_connect('pick_event', self.onpick)
self.cid = self.canvas.mpl_connect('button_press_event', self.onpress)
self.keyPress = self.canvas.mpl_connect('key_press_event', self.onKeyPress)
self.keyRelease = self.canvas.mpl_connect('key_release_event', self.onKeyRelease)
self.lasso = None
self.shiftKey = False
self.ctrlKey = False

def callback(self, verts):
logging.debug('in LassoManager.callback(). Shift: %s, Ctrl: %s' % (self.shiftKey, self.ctrlKey))
facecolors = self.collection.get_facecolors()
p = path.Path(verts)
ind = p.contains_points(self.xys)
for i in range(len(self.xys)):
if ind[i]:
if self.shiftKey:
facecolors[i] = Datum.colorShift
elif self.ctrlKey:
facecolors[i] = Datum.colorCtrl
else:
facecolors[i] = Datum.colorin
print self.xys[i]
else:
facecolors[i] = Datum.colorout

self.canvas.draw_idle()
self.canvas.widgetlock.release(self.lasso)
del self.lasso

def onpress(self, event):
if self.canvas.widgetlock.locked(): return
if event.inaxes is None: return
self.lasso = Lasso(event.inaxes, (event.xdata, event.ydata), self.callback)
# acquire a lock on the widget drawing
self.canvas.widgetlock(self.lasso)

def onKeyPress(self, event):
logging.debug('in LassoManager.onKeyPress(). Event received: %s (key: %s)' % (event, event.key))
if event.key == 'alt':
self.ctrlKey = True
if event.key == 'shift':
self.shiftKey = True

def onKeyRelease(self, event):
logging.debug('in LassoManager.onKeyRelease(). Event received: %s (key: %s)' % (event, event.key))
if event.key == 'alt':
self.ctrlKey = False
if event.key == 'shift':
self.shiftKey = False


def onpick(self,event):

if event.mouseevent.button == 3:

index = event.ind
print('onpick scatter:', index, np.take(x, index), np.take(y, index))

if __name__ == '__main__':

x,y =rand(2,100)
data = [Datum(*xy) for xy in zip(x,y)]
fig = plt.figure()
ax = plt.axes()

ax.scatter(x,y,picker=True)

lman = LassoManager(ax, data)
plt.show()

对于可能导致此故障的原因有什么建议吗?提前致谢。

最佳答案

这次您遇到的问题是,当您单击艺术家时,会同时生成 PickEventMouseEventMouseEvent 会锁定 Canvas 并阻止您随后执行任何其他操作。

最好的解决方案是防止在 PickEvent 之后触发 MouseEvent,但我不知道是否有办法做到这一点。相反,我添加了一个测试来检查是否在 onpick() 之后调用 onpress() 以禁用锁定机制。

import logging
import matplotlib
from matplotlib.widgets import Lasso
from matplotlib.colors import colorConverter
from matplotlib.collections import RegularPolyCollection
from matplotlib import path
import numpy as np
import matplotlib.pyplot as plt
from numpy.random import rand

logger = logging.getLogger()
logger.setLevel(logging.DEBUG)


class Datum(object):
colorin = colorConverter.to_rgba('red')
colorShift = colorConverter.to_rgba('cyan')
colorCtrl = colorConverter.to_rgba('pink')
colorout = colorConverter.to_rgba('blue')

def __init__(self, x, y, include=False):
self.x = x
self.y = y
if include:
self.color = self.colorin
else:
self.color = self.colorout


class LassoManager(object):
def __init__(self, ax, data):
self.axes = ax
self.canvas = ax.figure.canvas
self.data = data

self.Nxy = len(data)

facecolors = [d.color for d in data]
self.xys = [(d.x, d.y) for d in data]
fig = ax.figure
self.collection = RegularPolyCollection(fig.dpi, 6, sizes=(100,),facecolors=facecolors, offsets = self.xys, transOffset = ax.transData)

ax.add_collection(self.collection)

self.cid = self.canvas.mpl_connect('button_press_event', self.onpress)
self.keyPress = self.canvas.mpl_connect('key_press_event', self.onKeyPress)
self.keyRelease = self.canvas.mpl_connect('key_release_event', self.onKeyRelease)
self.pick=self.canvas.mpl_connect('pick_event', self.onpick)
self.lasso = None
self.shiftKey = False
self.ctrlKey = False
self.pickEvent = False

def callback(self, verts):
logging.debug('in LassoManager.callback(). Shift: %s, Ctrl: %s' % (self.shiftKey, self.ctrlKey))
facecolors = self.collection.get_facecolors()
p = path.Path(verts)
ind = p.contains_points(self.xys)
for i in range(len(self.xys)):
if ind[i]:
if self.shiftKey:
facecolors[i] = Datum.colorShift
elif self.ctrlKey:
facecolors[i] = Datum.colorCtrl
else:
facecolors[i] = Datum.colorin
print self.xys[i]
else:
facecolors[i] = Datum.colorout

self.canvas.draw_idle()
self.canvas.widgetlock.release(self.lasso)
del self.lasso

def onpress(self, event):
logging.debug('in LassoManager.onpress(). Event received: %s' % event)
if self.pickEvent:
self.pickEvent = False
return
if self.canvas.widgetlock.locked(): return
if event.inaxes is None: return
self.lasso = Lasso(event.inaxes, (event.xdata, event.ydata), self.callback)
# acquire a lock on the widget drawing
self.canvas.widgetlock(self.lasso)

def onKeyPress(self, event):
logging.debug('in LassoManager.onKeyPress(). Event received: %s (key: %s)' % (event, event.key))
if event.key == 'alt':
self.ctrlKey = True
if event.key == 'shift':
self.shiftKey = True

def onKeyRelease(self, event):
logging.debug('in LassoManager.onKeyRelease(). Event received: %s (key: %s)' % (event, event.key))
if event.key == 'alt':
self.ctrlKey = False
if event.key == 'shift':
self.shiftKey = False

def onpick(self, event):
logging.debug('in LassoManager.onpick(). Event received: %s' % event)
self.pickEvent = True
if event.mouseevent.button == 3:
index = event.ind
print 'onpick scatter: ', index, np.take(x, index), np.take(y, index)


if __name__ == '__main__':
x,y =rand(2,100)
data = [Datum(*xy) for xy in zip(x,y)]
fig = plt.figure()
ax = plt.axes()

ax.scatter(x,y,picker=True)

lman = LassoManager(ax, data)
plt.show()

关于python - 将 matplotlib 的鼠标按钮事件与 pick 事件结合起来,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32444770/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com