将matplotlib的鼠标按钮事件与挑选事件相结合

时间:2015-09-07 19:09:27

标签: python matplotlib widget scatter-plot

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

由于我添加了pick事件,上述功能正常工作,直到第一次触发pick事件。当它被触发时,似乎画布被锁定,我不能使用任何其他功能。虽然,我得到所选点的索引,但我没有得到任何错误,并且画布变得没有响应。

我修改了从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()

有关可能导致此故障的原因的任何建议?提前谢谢。

0 个答案:

没有答案