Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FIX] SOM: Store selection Settings in list instead of np.ndarray #6423

Merged
merged 1 commit into from
Apr 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 21 additions & 9 deletions Orange/widgets/unsupervised/owsom.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,15 +422,18 @@ def on_selection_change(self, selection, action=SomView.SelectionSet):
return
if self.selection is None:
self.selection = np.zeros(self.grid_cells.T.shape, dtype=np.int16)

selection_np = np.array(self.selection)
if action == SomView.SelectionSet:
self.selection[:] = 0
self.selection[selection] = 1
selection_np[:] = 0
selection_np[selection] = 1
elif action == SomView.SelectionAddToGroup:
self.selection[selection] = max(1, np.max(self.selection))
selection_np[selection] = max(1, np.max(selection_np))
elif action == SomView.SelectionNewGroup:
self.selection[selection] = 1 + np.max(self.selection)
selection_np[selection] = 1 + np.max(selection_np)
elif action & SomView.SelectionRemove:
self.selection[selection] = 0
selection_np[selection] = 0
self.selection = selection_np.tolist()
self.redraw_selection()
self.update_output()

Expand All @@ -445,6 +448,7 @@ def on_selection_move(self, event: QKeyEvent):
x, y = np.nonzero(self.selection)
if len(x) > 1:
return
x, y = x[0], y[0]
if event.key() == Qt.Key_Up and y > 0:
y -= 1
if event.key() == Qt.Key_Down and y < self.size_y - 1:
Expand All @@ -455,11 +459,11 @@ def on_selection_move(self, event: QKeyEvent):
x += 1
x -= self.hexagonal and x == self.size_x - 1 and y % 2

if self.selection is not None and self.selection[x, y]:
if self.selection is not None and self.selection[x][y]:
return
selection = np.zeros(self.grid_cells.shape, dtype=bool)
selection[x, y] = True
self.on_selection_change(selection)
self.on_selection_change(selection.tolist())

def on_selection_mark_change(self, marks):
self.redraw_selection(marks=marks)
Expand All @@ -484,7 +488,7 @@ def redraw_selection(self, marks=None):
for x in range(self.size_x - (y % 2) * self.hexagonal):
cell = self.grid_cells[y, x]
marked = marks is not None and marks[x, y]
sel_group = self.selection is not None and self.selection[x, y]
sel_group = self.selection is not None and self.selection[x][y]
if marked:
cell.setBrush(mark_brush)
cell.setPen(mark_pen)
Expand Down Expand Up @@ -821,7 +825,7 @@ def update_output(self):
for y in range(self.size_y):
for x in range(self.size_x):
rows = self.get_member_indices(x, y)
indices[rows] = self.selection[x, y]
indices[rows] = self.selection[x][y]

if np.any(indices):
sel_data = create_groups_table(self.data, indices, False, "Group")
Expand Down Expand Up @@ -930,6 +934,14 @@ def send_report(self):
self.report_caption(
f"Self-organizing map colored by '{self.attr_color.name}'")

@classmethod
def migrate_settings(cls, settings, _):
# previously selection was saved as np.ndarray which is not supported
# by widget-base, change selection to list
selection = settings.get('selection')
if selection is not None and isinstance(selection, np.ndarray):
settings['selection'] = selection.tolist()


def _draw_hexagon():
path = QPainterPath()
Expand Down
5 changes: 5 additions & 0 deletions Orange/widgets/unsupervised/tests/test_owsom.py
Original file line number Diff line number Diff line change
Expand Up @@ -543,24 +543,29 @@ def selm(*cells):
m = selm((0, 0)).astype(int)
widget.on_selection_change(selm((0, 0)))
np.testing.assert_equal(widget.selection, m)
self.assertIsInstance(widget.selection, list)
widget.redraw_selection.assert_called_once()
widget.update_output.assert_called_once()

m = selm((0, 1)).astype(int)
widget.on_selection_change(selm((0, 1)))
np.testing.assert_equal(widget.selection, m)
self.assertIsInstance(widget.selection, list)

m[0, 0] = 1
widget.on_selection_change(selm((0, 0)), SomView.SelectionAddToGroup)
np.testing.assert_equal(widget.selection, m)
self.assertIsInstance(widget.selection, list)

m[0, 0] = 0
widget.on_selection_change(selm((0, 0)), SomView.SelectionRemove)
np.testing.assert_equal(widget.selection, m)
self.assertIsInstance(widget.selection, list)

m[0, 0] = 2
widget.on_selection_change(selm((0, 0)), SomView.SelectionNewGroup)
np.testing.assert_equal(widget.selection, m)
self.assertIsInstance(widget.selection, list)

@_patch_recompute_som
def test_on_selection_change_on_empty(self):
Expand Down