diff --git a/Orange/widgets/visualize/owheatmap.py b/Orange/widgets/visualize/owheatmap.py index 23036903474..6a28b7c9fdb 100644 --- a/Orange/widgets/visualize/owheatmap.py +++ b/Orange/widgets/visualize/owheatmap.py @@ -617,9 +617,15 @@ def _make_parts(self, data, group_var=None): _col_data = table_column_data(data, group_var) row_indices = [np.flatnonzero(_col_data == i) for i in range(len(group_var.values))] + row_groups = [RowPart(title=name, indices=ind, cluster=None, cluster_ordered=None) for name, ind in zip(group_var.values, row_indices)] + if np.any(_col_data.mask): + row_groups.append(RowPart( + title="N/A", indices=np.flatnonzero(_col_data.mask), + cluster=None, cluster_ordered=None + )) else: row_groups = [RowPart(title=None, indices=range(0, len(data)), cluster=None, cluster_ordered=None)] diff --git a/Orange/widgets/visualize/tests/test_owheatmap.py b/Orange/widgets/visualize/tests/test_owheatmap.py index 03e1cf6ea9d..7aba80d85fc 100644 --- a/Orange/widgets/visualize/tests/test_owheatmap.py +++ b/Orange/widgets/visualize/tests/test_owheatmap.py @@ -33,6 +33,7 @@ def setUpClass(cls): cls.housing = Table("housing") cls.titanic = Table("titanic") + cls.brown_selected = Table("brown-selected") cls.signal_name = "Data" cls.signal_data = cls.data @@ -211,7 +212,7 @@ def test_saved_selection(self): self.assertEqual(len(self.get_output(w.Outputs.selected_data)), 21) def test_set_split_var(self): - data = Table("brown-selected") + data = self.brown_selected[::3] w = self.widget self.send_signal(self.widget.Inputs.data, data, widget=w) self.assertIs(w.split_by_var, data.domain.class_var) @@ -221,6 +222,15 @@ def test_set_split_var(self): self.assertIs(w.split_by_var, None) self.assertEqual(len(w.parts.rows), 1) + def test_set_split_var_missing(self): + data = self.brown_selected[::3].copy() + data.Y[::5] = np.nan + w = self.widget + self.send_signal(self.widget.Inputs.data, data, widget=w) + self.assertIs(w.split_by_var, data.domain.class_var) + self.assertEqual(len(w.parts.rows), + len(data.domain.class_var.values) + 1) + def test_palette_centering(self): data = np.arange(2).reshape(-1, 1) table = Table.from_numpy(Domain([ContinuousVariable("y")]), data) diff --git a/Orange/widgets/visualize/utils/heatmap.py b/Orange/widgets/visualize/utils/heatmap.py index a616fa1c5d0..c51b0210e1f 100644 --- a/Orange/widgets/visualize/utils/heatmap.py +++ b/Orange/widgets/visualize/utils/heatmap.py @@ -368,21 +368,18 @@ def setHeatmaps(self, parts: 'Parts') -> None: row_dendrograms: List[Optional[DendrogramWidget]] = [None] * N right_side_colors: List[Optional[GraphicsPixmapWidget]] = [None] * N - ncols = sum(c.size for c in parts.columns) - nrows = sum(r.size for r in parts.rows) data = parts.data if parts.col_names is None: - col_names = np.full(ncols, "", dtype=object) + col_names = np.full(data.shape[1], "", dtype=object) else: col_names = np.asarray(parts.col_names, dtype=object) if parts.row_names is None: - row_names = np.full(nrows, "", dtype=object) + row_names = np.full(data.shape[0], "", dtype=object) else: row_names = np.asarray(parts.row_names, dtype=object) - assert data.shape == (nrows, ncols) - assert len(col_names) == ncols - assert len(row_names) == nrows + assert len(col_names) == data.shape[1] + assert len(row_names) == data.shape[0] for i, rowitem in enumerate(parts.rows): if rowitem.title: @@ -710,8 +707,6 @@ def set_visible(item: GraphicsPixmapWidget): legend_container.setVisible(True) parts = self.parts.rows - nrows = sum(p.size for p in parts) - assert len(data) == nrows for p, item in zip(parts, items): if item is not None: subset = data[p.normalized_indices]