diff --git a/Orange/widgets/visualize/owsilhouetteplot.py b/Orange/widgets/visualize/owsilhouetteplot.py index e0a2b169048..df660aaa273 100644 --- a/Orange/widgets/visualize/owsilhouetteplot.py +++ b/Orange/widgets/visualize/owsilhouetteplot.py @@ -177,6 +177,11 @@ def __init__(self): ibox.setFixedWidth(ibox.sizeHint().width()) warning.setVisible(False) + # box displaying the average silhouette score + avg_box = gui.vBox(self.controlArea, "Average Silhouette Score") + self.avg_silhouette_label = gui.widgetLabel(avg_box, "") + self._update_avg_silhouette() + gui.rubber(self.controlArea) gui.auto_send(self.buttonsArea, self, "auto_commit") @@ -292,6 +297,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 @@ -340,6 +346,15 @@ def _ensure_matrix(self): else: assert False, "invalid state" + def _update_avg_silhouette(self): + # update the average silhouette score + if self._silhouette is not None and len(self._silhouette) > 0: + avg_score = np.mean(self._silhouette) + self.avg_silhouette_label.setText( + f"Silhouette: {avg_score:.4f}") + else: + self.avg_silhouette_label.setText("Silhouette: N/A") + def _update(self): # Update/recompute the effective distances and scores as required. self._clear_messages() @@ -384,6 +399,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 + def _reset_all(self): self._mask = None self._silhouette = None diff --git a/Orange/widgets/visualize/tests/test_owsilhouetteplot.py b/Orange/widgets/visualize/tests/test_owsilhouetteplot.py index 3674722b61e..e0c1d475a9f 100644 --- a/Orange/widgets/visualize/tests/test_owsilhouetteplot.py +++ b/Orange/widgets/visualize/tests/test_owsilhouetteplot.py @@ -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(), + "Silhouette: 0.4692") + self.send_signal(self.widget.Inputs.data, None) + self.assertEqual(self.widget.avg_silhouette_label.text(), + "Silhouette: N/A") + self.send_signal(self.widget.Inputs.data, data) + self.assertEqual(self.widget.avg_silhouette_label.text(), + "Silhouette: 0.4692") + if __name__ == "__main__": unittest.main()