In a wxPython
我想使用的面板matplotlib's
Lasso http://matplotlib.org/api/widgets_api.html?highlight=lasso#matplotlib.widgets.Lasso小部件。在我的实现中Lasso
用于三种不同的功能。尽管如此,为了完成这些功能,我必须将按键事件与鼠标按钮事件结合起来。
默认情况下,初始Lasso
按下鼠标左键即可使用该功能。因此,对于我的第一个功能,我按下鼠标左键,选择感兴趣的区域并使用包含的点执行某些操作。对于第二个功能,我想选择另一个感兴趣的区域并用这些点做其他事情。我试图通过按来做到这一点shift
+LMB
。最后,在我的第三个功能中,我想通过按对选定的点执行其他操作Ctrl
+LMB
.
简而言之,我想执行以下操作:
if left mouse button is pressed:
use Lasso and with the included points do the 1st functionality
if shift is press and left mouse button is pressed:
use Lasso and with the included points do the 2nd functionality
if ctrl is press and lmb is also pressed :
call Lasso and with the included points do the 3rd functionality
不幸的是,我无法实现我的目标,并且出现以下错误:if self.shift_is_held == True:
AttributeError: object has no attribute 'shift_is_held'
。似乎它无法识别按钮事件,而在其他情况下widgetlock
命令似乎没有使轴可用。
这是我的代码的一部分:
def scatter(self,data):
#create scatter plot
fig = self._view_frame.figure
fig.clf()
Data = []
self.lmans = []
self.points_colors = []
Data2 = []
self.lmans_2 = []
Data3 = []
self.lmans_2 = []
ax = fig.add_subplot('111')
datum = []
datum_2 = []
datum_3 = []
for x,y in zip(self.data[:,0],self.data[:,1]):
datum.append(Datum(x,y))
datum_2.append(Datum2(x,y))
datum_3.append(Datum3(x,y))
ax.scatter(self.data[:, 0], self.data[:, 1], s=150, marker='d')
ax.set_xlim((min(self.data[:,0]), max(self.data[:,0])))
ax.set_ylim((min(self.data[:,1]), max(self.data[:,1])))
ax.set_aspect('auto')
Data.append(datum)
Data2.append(datum_2)
Data3.append(datum_3)
lman = self.LassoManager(ax, datum, Data)
lman_2 = self.LassoManager2(ax, datum_2, Data2)
lman_3 = self.LassoManager3(ax, datum_3, Data3)
fig.canvas.draw()
self.lmans.append(lman)
self.lmans_2.append(lman_2)
self.lmans_3.append(lman_3)
fig.canvas.mpl_connect('axes_enter_event', self.enter_axes)
class Lasso(AxesWidget):
"""Selection curve of an arbitrary shape.
The selected path can be used in conjunction with
:func:`~matplotlib.path.Path.contains_point` to select data points
from an image.
Unlike :class:`LassoSelector`, this must be initialized with a starting
point `xy`, and the `Lasso` events are destroyed upon release.
Parameters:
*ax* : :class:`~matplotlib.axes.Axes`
The parent axes for the widget.
*xy* : array
Coordinates of the start of the lasso.
*callback* : function
Whenever the lasso is released, the `callback` function is called and
passed the vertices of the selected path.
"""
def __init__(self, ax, xy, callback=None, useblit=True):
AxesWidget.__init__(self, ax)
self.useblit = useblit and self.canvas.supports_blit
if self.useblit:
self.background = self.canvas.copy_from_bbox(self.ax.bbox)
x, y = xy
self.verts = [(x, y)]
self.line = Line2D([x], [y], linestyle='-', color='black', lw=2)
self.ax.add_line(self.line)
self.callback = callback
self.connect_event('button_release_event', self.onrelease)
self.connect_event('motion_notify_event', self.onmove)
def onrelease(self, event):
if self.ignore(event):
return
if self.verts is not None:
self.verts.append((event.xdata, event.ydata))
if len(self.verts) > 2:
self.callback(self.verts)
self.ax.lines.remove(self.line)
self.verts = None
self.disconnect_events()
def onmove(self, event):
if self.ignore(event):
return
if self.verts is None:
return
if event.inaxes != self.ax:
return
if event.button != 1:
return
self.verts.append((event.xdata, event.ydata))
self.line.set_data(list(zip(*self.verts)))
if self.useblit:
self.canvas.restore_region(self.background)
self.ax.draw_artist(self.line)
self.canvas.blit(self.ax.bbox)
else:
self.canvas.draw_idle()
def enter_axes(self, event):
self.idfig = event.inaxes.colNum
self._view_frame.figure.canvas.mpl_connect('button_press_event', self.onpress_2)
self._view_frame.figure.canvas.mpl_connect('key_press_event', self.onkey_press_2)
self._view_frame.figure.canvas.mpl_connect('key_release_event', self.onkey_release_2)
self._view_frame.figure.canvas.mpl_connect('button_press_event', self.onpress_3)
self._view_frame.figure.canvas.mpl_connect('key_press_event', self.onkey_press_3)
self._view_frame.figure.canvas.mpl_connect('key_release_event', self.onkey_release_3)
def LassoManager(self, ax, data, Data):
self.axes = ax
self.canvas = ax.figure.canvas
self.data = data
self.Data = Data
self.Nxy = len(data)
# self.facecolors = [d.color for d in data]
self.xys = [(d.x, d.y) for d in data]
fig = ax.figure
#self.cid = self.canvas.mpl_connect('button_press_event', self.onpress)
def callback(self, verts):
#facecolors = self.facecolors#collection.get_facecolors()
#colorin = colorConverter.to_rgba('red')
#colorout = colorConverter.to_rgba('blue')
p = path.Path(verts)
self.ind = p.contains_points([(d.x, d.y) for d in self.Data[self.where.colNum]])
self._view_frame.figure.canvas.mpl_connect('button_press_event', self.onpress)
#Functionality 1
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)
self.where = event.inaxes
# acquire a lock on the widget drawing
self.canvas.widgetlock(self.lasso)
def onkey_press_2(self,event):
if event.key =='shift':
self.merge_is_held = True
def onkey_press_3(self,event):
if event.key == 'control':
self.split_is_held = True
def onkey_release_2(self, event):
if event.key == 'shift':
self.merge_is_held = False
def onkey_release_3(self, event):
if event.key == 'control':
self.split_is_held = False
def LassoManagerMerge(self, ax, data2, Data2):
self.axes = ax
self.canvas = ax.figure.canvas
self.data2 = data2
self.Data2 = Data2
self.Nxy = len(dataMerge)
self.facecolors_2 = [d.color for d in data2]
# print "facecolors",self.facecolors
self.xys = [(d.x, d.y) for d in data2]
# print "xys",self.xys
fig = ax.figure
self.collection_2 = RegularPolyCollection(
fig.dpi, 6, sizes=(0,),
facecolors=self.facecolors_2,
offsets = self.xys,
transOffset = ax.transData)
ax.add_collection(self.collection_2)
def callback_2(self, verts):
self.facecolors_2 = self.collection_2.get_facecolors()
#colorin = colorConverter.to_rgba('red')
#colorout = colorConverter.to_rgba('blue')
p = path.Path(verts)
self.ind = p.contains_points([(d.x, d.y) for d in self.Data2[self.where.colNum]])
#Functionality 2
self.canvas.draw_idle()
self.canvas.widgetlock.release(self.lasso_2)
del self.lasso_2
def onpress_2(self, event):
if self.canvas.widgetlock.locked(): return
if event.inaxes is None: return
if event.button == 1:
if self.shift_is_held == True:
print "Shift pressed"
self.lasso_2 = Lasso(event.inaxes, (event.xdata, event.ydata), self.callback_2)
print "Shift pressed"
self.where = event.inaxes
self.canvas.widgetlock(self.lasso_2)
def LassoManager3(self, ax, data3, Data3):
self.axes = ax
self.canvas = ax.figure.canvas
self.data3 = data3
self.Data3 = Data3
self.Nxy = len(data3)
self.facecolors_3= [d.color for d in data3]
# print "facecolors",self.facecolors
self.xys = [(d.x, d.y) for d in data3]
# print "xys",self.xys
fig = ax.figure
self.collection_3 = RegularPolyCollection(
fig.dpi, 6, sizes=(0,),
facecolors=self.facecolors_3,
offsets = self.xys,
transOffset = ax.transData)
ax.add_collection(self.collection_3)
def callback_3(self, verts):
self.facecolors_3 = self.collection_3.get_facecolors()
#colorin = colorConverter.to_rgba('red')
#colorout = colorConverter.to_rgba('blue')
p = path.Path(verts)
self.ind = p.contains_points([(d.x, d.y) for d in self.Data3[self.where.colNum]])
#Functionality 3
self.canvas.draw_idle()
self.canvas.widgetlock.release(self.lasso_3)
del self.lasso_3
def onpress_3(self, event):
if self.canvas.widgetlock.locked(): return
if event.inaxes is None: return
if event.button == 1:
if self.split_is_held == True:
print " Split pressed"
self.lasso_3 = Lasso(event.inaxes, (event.xdata, event.ydata), self.callback_3)
print "Split pressed"
self.where = event.inaxes
# acquire a lock on the widget drawing
self.canvas.widgetlock(self.lasso_3)
有什么建议么?