Skip to content

Commit

Permalink
Split off BqplotLassoMode from BqplotPolygonMode
Browse files Browse the repository at this point in the history
  • Loading branch information
dhomeier committed Aug 29, 2023
1 parent 6278156 commit a18dba9
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 22 deletions.
70 changes: 50 additions & 20 deletions glue_jupyter/bqplot/common/tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,12 +188,13 @@ class BqplotPolygonMode(BqplotSelectionTool):
Since Bqplot LassoSelector does not allow us to get the coordinates of the
selection (see https://github.com/bqplot/bqplot/pull/674), we simply use
a callback on the default viewer MouseInteraction and a patch to
display the selection.
display the selection. The parent class defaults to setting polygon vertices
by clicking in the selector.
"""
icon = 'glue_lasso'
icon = 'glue_point'
tool_id = 'bqplot:polygon'
action_text = 'Polygonal ROI'
tool_tip = ('Lasso a region of interest\n')
tool_tip = 'Define a polygonal region of interest'

def __init__(self, viewer, roi=None, finalize_callback=None, **kwargs):

Expand All @@ -210,6 +211,7 @@ def __init__(self, viewer, roi=None, finalize_callback=None, **kwargs):
if roi is not None:
self.update_from_roi(roi)

self._lasso = False
self.interact.observe(self.update_selection, "brushing")
self.interact.observe(self.on_selection_change, "selected_x")
self.interact.observe(self.on_selection_change, "selected_y")
Expand Down Expand Up @@ -267,6 +269,8 @@ def activate(self):
self.viewer.add_event_callback(self.on_msg, events=['dragstart', 'dragmove', 'dragend'])

def deactivate(self):
if len(self.patch.x) > 1:
self.close_vertices()
try:
self.viewer.remove_event_callback(self.on_msg)
except KeyError:
Expand All @@ -282,30 +286,56 @@ def on_msg(self, event):
name = event['event']
domain = event['domain']
x, y = domain['x'], domain['y']
if name == 'dragstart':
if name == 'dragstart' and len(self.patch.x) < 1:
self.original_marks = list(self.viewer.figure.marks)
self.viewer.figure.marks = self.original_marks + [self.patch]
self.patch.x = [x]
self.patch.y = [y]
elif name == 'dragmove':
elif name == 'dragmove' and self._lasso:
self.patch.x = np.append(self.patch.x, x)
self.patch.y = np.append(self.patch.y, y)
elif name == 'dragend':
roi = PolygonalROI(vx=self.patch.x, vy=self.patch.y)
self.viewer.apply_roi(roi)
self._roi = roi

new_marks = []
for mark in self.viewer.figure.marks:
if mark == self.patch:
pass
else:
new_marks.append(mark)
self.viewer.figure.marks = new_marks
self.patch.x = [[]]
self.patch.y = [[]]
if self.finalize_callback is not None:
self.finalize_callback()
# If new point is within 2% of maximum extent of the origin, finalise the polygon.
sz = max(self.patch.x) - min(self.patch.x), max(self.patch.y) - min(self.patch.y)
if self._lasso or (abs(x - self.patch.x[0]) < 0.02 * sz[0] and
abs(y - self.patch.y[0]) < 0.02 * sz[1]):
self.close_vertices()
else:
self.patch.x = np.append(self.patch.x, x)
self.patch.y = np.append(self.patch.y, y)

def close_vertices(self):
roi = PolygonalROI(vx=self.patch.x, vy=self.patch.y)
self.viewer.apply_roi(roi)

new_marks = []
for mark in self.viewer.figure.marks:
if mark == self.patch:
pass
else:
new_marks.append(mark)
self.viewer.figure.marks = new_marks
self.patch.x = [[]]
self.patch.y = [[]]
if self.finalize_callback is not None:
self.finalize_callback()


@viewer_tool
class BqplotLassoMode(BqplotPolygonMode):
"""
Subclass that defaults to creating a continous (lasso) polygonal selection
by dragging the pointer along the outline.
"""

icon = 'glue_lasso'
tool_id = 'bqplot:lasso'
tool_tip = 'Lasso a region of interest'

def __init__(self, viewer, roi=None, finalize_callback=None, **kwargs):

super().__init__(viewer, **kwargs)
self._lasso = True


@viewer_tool
Expand Down
2 changes: 1 addition & 1 deletion glue_jupyter/bqplot/image/viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class BqplotImageView(BqplotBaseView):
_options_cls = ImageViewerStateWidget

tools = ['bqplot:home', 'bqplot:panzoom', 'bqplot:rectangle', 'bqplot:circle',
'bqplot:ellipse', 'bqplot:polygon']
'bqplot:ellipse', 'bqplot:polygon', 'bqplot:lasso']

def __init__(self, session):

Expand Down
2 changes: 1 addition & 1 deletion glue_jupyter/bqplot/scatter/viewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class BqplotScatterView(BqplotBaseView):
_layer_style_widget_cls = ScatterLayerStateWidget

tools = ['bqplot:home', 'bqplot:panzoom', 'bqplot:rectangle', 'bqplot:circle',
'bqplot:xrange', 'bqplot:yrange', 'bqplot:polygon']
'bqplot:ellipse', 'bqplot:xrange', 'bqplot:yrange', 'bqplot:polygon', 'bqplot:lasso']

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
Expand Down

0 comments on commit a18dba9

Please sign in to comment.