将matplotlib的鼠标按钮事件与pick事件结合起来 [英] Combining matplotlib's mouse button events with pick events

查看:52
本文介绍了将matplotlib的鼠标按钮事件与pick事件结合起来的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Based on combination of mouse button and key events, different functionalities are applied to the points of a scatter plot. When the left mouse button is pressed matplotlib's Lasso widget is called and with the included points functionality 1 takes place. When Shift+LMB are pressed a Lasso is drawn and functionality 2 takes place with the included points. When Alt+LMB are pressed a Lasso is drawn and with the included points functionality 3 takes place. Last, but not least, when I press the RMB a pick event is triggered and the index of the selected point in the scatter plot is given.

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

Since I added the pick event, the aforementioned functionalities work correctly until a pick event is triggered for the first time. When it is triggered it seems that the canvas gets locked and I can not use any other functionality. Although, I get the index of the selected point, I do not get any errors, and the canvas becomes unresponsive.

我修改了从中获取的代码问题,这实际上是我想要做的.

I modified the code taken from this question, which is actually what I want to do.

代码:

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()

有关导致此故障的原因的任何建议?预先感谢.

Any suggestions on what might be causing this malfunction? Thanks in advance.

推荐答案

您这次遇到的问题是您同时拥有一个 PickEvent 和一个 MouseEvent在您单击艺术家时同时生成. MouseEvent 锁定画布,并阻止您之后再执行其他任何操作.

The problem you're having this time is that you have both a PickEvent and a MouseEvent that are generated at the same time when you click on an artist. The MouseEvent locks the canvas and prevents you from doing anything else afterward.

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

The best solution would be to prevent the MouseEvent from being fired after the PickEvent, but I don't know if there's a way to do that. Instead, I added a test to check whether onpress() was called after onpick() to disable the locking mechanism.

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()

这篇关于将matplotlib的鼠标按钮事件与pick事件结合起来的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆