Skip to content
Closed
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
21 changes: 17 additions & 4 deletions Orange/widgets/visualize/owsilhouetteplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,16 +136,17 @@ def __init__(self):
self._silhouette = None # type: Optional[np.ndarray]
self._silplot = None # type: Optional[SilhouettePlot]

controllayout = self.controlArea.layout()
assert isinstance(controllayout, QVBoxLayout)
info_box = gui.vBox(self.controlArea, "Info")
self.avg_silhouette_label = gui.widgetLabel(info_box, "")
self._update_avg_silhouette()

self._distances_gui_box = distbox = gui.widgetBox(
None, "Distance"
self.controlArea, "Distance"
)
self._distances_gui_cb = gui.comboBox(
distbox, self, "distance_idx",
items=[name for name, _ in OWSilhouettePlot.Distances],
orientation=Qt.Horizontal, callback=self._invalidate_distances)
controllayout.addWidget(distbox)

box = gui.vBox(self.controlArea, "Grouping")
self.cluster_var_model = itemmodels.VariableListModel(
Expand Down Expand Up @@ -177,6 +178,7 @@ def __init__(self):
ibox.setFixedWidth(ibox.sizeHint().width())
warning.setVisible(False)


gui.rubber(self.controlArea)

gui.auto_send(self.buttonsArea, self, "auto_commit")
Expand Down Expand Up @@ -292,6 +294,7 @@ def clear(self):
self._clear_scene()
self.Error.clear()
self.Warning.clear()
self._update_avg_silhouette() # Update the average silhouette display

def _clear_scene(self):
# Clear the graphics scene and associated objects
Expand Down Expand Up @@ -340,6 +343,14 @@ def _ensure_matrix(self):
else:
assert False, "invalid state"

def _update_avg_silhouette(self):
if self._silhouette is not None and len(self._silhouette) > 0:
avg_score = np.mean(self._silhouette)
self.avg_silhouette_label.setText(
f"Average Silhouette: {avg_score:.4f}")
else:
self.avg_silhouette_label.setText("Average Silhouette: N/A")

def _update(self):
# Update/recompute the effective distances and scores as required.
self._clear_messages()
Expand Down Expand Up @@ -384,6 +395,8 @@ def _update(self):
self.Warning.nan_distances(
count_nandist, s="s" if count_nandist > 1 else "")

self._update_avg_silhouette() # Update the average silhouette display
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this comment necessary?

I know: copilot and similar tools add heaps and heaps of comments to explain the code, but they often just state the obvious. PEP8 says they're distracting.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed


def _reset_all(self):
self._mask = None
self._silhouette = None
Expand Down
12 changes: 12 additions & 0 deletions Orange/widgets/visualize/tests/test_owsilhouetteplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,18 @@ def test_migration(self):
self.assertEqual(context.values["cluster_var"], ("cfoo", 101))
self.assertNotIn("annotation_var_idx", values)

def test_average_silhouette_score(self):
data = Table("brown-selected")
self.send_signal(self.widget.Inputs.data, data)
self.assertEqual(self.widget.avg_silhouette_label.text(),
"Average Silhouette: 0.4692")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let us hope this is stable...

self.send_signal(self.widget.Inputs.data, None)
self.assertEqual(self.widget.avg_silhouette_label.text(),
"Average Silhouette: N/A")
self.send_signal(self.widget.Inputs.data, data)
self.assertEqual(self.widget.avg_silhouette_label.text(),
"Average Silhouette: 0.4692")


if __name__ == "__main__":
unittest.main()
Loading