Problem : Combining mouse button events with pick events in a scatter plot

Hello everybody,

I am trying to combine mouse button events with a pick event in scatter
plot. Different functionalities take place, based on the mouse button
pressed each time. I want each functionality to be triggered with a
combination of mouse buttons events and/or key press events. 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.

Since I added the pick event, the aforementioned functionalities work
correctly until a pick event is triggered. When it is triggered it seems
that the canvas gets locked and I can not use any other functionality. I
don't get the index of the selected points and I do not get any errors.

----------------Code-------------------------

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('onpick3 scatter:', index)

      if __name__ == '__main__':

         data = [Datum(*xy) for xy in rand(100, 2)]

         ax = plt.axes(xlim=(0,1), ylim=(0,1), autoscale_on=False)
         lman = LassoManager(ax, data)

         plt.show()

------------------End of Code-----------------------------

Any suggestions on what might be causing this malfunction? What am I doing
wrong?

···

--
View this message in context: http://matplotlib.1069221.n5.nabble.com/Problem-Combining-mouse-button-events-with-pick-events-in-a-scatter-plot-tp46109.html
Sent from the matplotlib - users mailing list archive at Nabble.com.

The issue unrelated to the pick events, it is due to clicking without
moving the mouse (and can be reproduced with all of the pick logic removed).

In your `onpress` you lock the widget and then in the `callback` you pass
to lasso widget you release it, however if you start the lasso, but do not
move the mouse no move_events are generated, then the callback is never
called.

You probably should handle the unlocking in a 'button_release_event'.

Tom

···

On Fri, Oct 9, 2015 at 7:19 AM joh <johtoldr at yahoo.gr> wrote:

Hello everybody,

I am trying to combine mouse button events with a pick event in scatter
plot. Different functionalities take place, based on the mouse button
pressed each time. I want each functionality to be triggered with a
combination of mouse buttons events and/or key press events. 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.

Since I added the pick event, the aforementioned functionalities work
correctly until a pick event is triggered. When it is triggered it seems
that the canvas gets locked and I can not use any other functionality. I
don't get the index of the selected points and I do not get any errors.

----------------Code-------------------------

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('onpick3 scatter:', index)

      if __name__ == '__main__':

         data = [Datum(*xy) for xy in rand(100, 2)]

         ax = plt.axes(xlim=(0,1), ylim=(0,1), autoscale_on=False)
         lman = LassoManager(ax, data)

         plt.show()

------------------End of Code-----------------------------

Any suggestions on what might be causing this malfunction? What am I doing
wrong?

--
View this message in context:
http://matplotlib.1069221.n5.nabble.com/Problem-Combining-mouse-button-events-with-pick-events-in-a-scatter-plot-tp46109.html
Sent from the matplotlib - users mailing list archive at Nabble.com.
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users at python.org
https://mail.python.org/mailman/listinfo/matplotlib-users

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/matplotlib-users/attachments/20151011/331b2101/attachment.html>