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.
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.
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('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.