diff --git a/Orange/widgets/visualize/tests/test_owprojectionwidget.py b/Orange/widgets/visualize/tests/test_owprojectionwidget.py index c425ef720dd..2319129da5a 100644 --- a/Orange/widgets/visualize/tests/test_owprojectionwidget.py +++ b/Orange/widgets/visualize/tests/test_owprojectionwidget.py @@ -1,5 +1,6 @@ # Test methods with long descriptive names can omit docstrings # pylint: disable=missing-docstring +import unittest from unittest.mock import patch import numpy as np @@ -164,3 +165,39 @@ def test_too_many_labels(self): self.widget.graph.too_many_labels.emit(False) self.assertFalse(w.is_shown()) + + def test_invalid_subset(self): + widget = self.widget + + data = Table("iris") + self.send_signal(widget.Inputs.data_subset, data[40:60]) + self.assertFalse(widget.Warning.subset_independent.is_shown()) + self.assertFalse(widget.Warning.subset_not_subset.is_shown()) + + self.send_signal(widget.Inputs.data, data[30:70]) + self.assertFalse(widget.Warning.subset_independent.is_shown()) + self.assertFalse(widget.Warning.subset_not_subset.is_shown()) + + self.send_signal(widget.Inputs.data, data[30:50]) + self.assertFalse(widget.Warning.subset_independent.is_shown()) + self.assertTrue(widget.Warning.subset_not_subset.is_shown()) + + self.send_signal(widget.Inputs.data, data[20:30]) + self.assertTrue(widget.Warning.subset_independent.is_shown()) + self.assertFalse(widget.Warning.subset_not_subset.is_shown()) + + self.send_signal(widget.Inputs.data, data[30:70]) + self.assertFalse(widget.Warning.subset_independent.is_shown()) + self.assertFalse(widget.Warning.subset_not_subset.is_shown()) + + self.send_signal(widget.Inputs.data, data[30:50]) + self.assertFalse(widget.Warning.subset_independent.is_shown()) + self.assertTrue(widget.Warning.subset_not_subset.is_shown()) + + self.send_signals([(widget.Inputs.data, Table("titanic")), + (widget.Inputs.data_subset, None)]) + self.assertFalse(widget.Warning.subset_independent.is_shown()) + self.assertFalse(widget.Warning.subset_not_subset.is_shown()) + +if __name__ == "__main__": + unittest.main() diff --git a/Orange/widgets/visualize/utils/widget.py b/Orange/widgets/visualize/utils/widget.py index 143e184c08e..0fe5be30038 100644 --- a/Orange/widgets/visualize/utils/widget.py +++ b/Orange/widgets/visualize/utils/widget.py @@ -363,6 +363,11 @@ class Outputs: class Warning(OWProjectionWidgetBase.Warning): too_many_labels = Msg( "Too many labels to show (zoom in or label only selected)") + subset_not_subset = Msg( + "Subset data contains some instances that do not appear in " + "input data") + subset_independent = Msg( + "None of subset data instance appear in input data") settingsHandler = DomainContextHandler() selection = Setting(None, schema_only=True) @@ -463,10 +468,19 @@ def handleNewSignals(self): self.commit() def get_subset_mask(self): - if self.subset_indices: - return np.array([ex.id in self.subset_indices - for ex in self.data[self.valid_data]]) - return None + self.Warning.subset_independent.clear() + self.Warning.subset_not_subset.clear() + if not self.subset_indices: + return None + valid_data = self.data[self.valid_data] + mask = np.fromiter((ex.id in self.subset_indices for ex in valid_data), + dtype=np.bool, count=len(valid_data)) + in_mask = mask.sum() + if not in_mask: + self.Warning.subset_independent() + elif in_mask < len(self.subset_indices): + self.Warning.subset_not_subset() + return mask # Plot def get_embedding(self):