Skip to content

Commit 782b9ea

Browse files
committed
Merge pull request #1947 from VesnaT/fix_owheatmap
OWHeatMap: Fix crash when data is one instance or one feature (cherry picked from commit ece0ee7)
1 parent 175fc73 commit 782b9ea

File tree

2 files changed

+55
-10
lines changed

2 files changed

+55
-10
lines changed

Orange/widgets/visualize/owheatmap.py

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,10 @@ class Information(widget.OWWidget.Information):
476476

477477
class Error(widget.OWWidget.Error):
478478
no_continuous = Msg("No continuous feature columns")
479+
not_enough_features = Msg("Not enough features for column clustering")
480+
not_enough_instances = Msg("Not enough instances")
481+
not_enough_instances_k_means = Msg(
482+
"Not enough instances for k-means merging")
479483
not_enough_memory = Msg("Not enough memory to show this data")
480484

481485
class Warning(widget.OWWidget.Warning):
@@ -753,10 +757,22 @@ def set_dataset(self, data=None):
753757
def update_heatmaps(self):
754758
if self.data is not None:
755759
self.clear_scene()
756-
self.construct_heatmaps(self.data)
757-
self.construct_heatmaps_scene(
758-
self.heatmapparts, self.effective_data)
759-
self.selected_rows = []
760+
self.clear_messages()
761+
if self.sort_columns not in (OWHeatMap.NoSorting,) and \
762+
len(self.data.domain.attributes) < 2:
763+
self.Error.not_enough_features()
764+
elif (self.sort_columns not in (OWHeatMap.NoSorting,) or
765+
self.sort_rows not in (OWHeatMap.NoSorting,
766+
OWHeatMap.SortBarycenter)) and \
767+
len(self.data) < 2:
768+
self.Error.not_enough_instances()
769+
elif self.merge_kmeans and len(self.data) < 3:
770+
self.Error.not_enough_instances_k_means()
771+
else:
772+
self.construct_heatmaps(self.data)
773+
self.construct_heatmaps_scene(
774+
self.heatmapparts, self.effective_data)
775+
self.selected_rows = []
760776
else:
761777
self.clear()
762778
self.commit()
@@ -1423,12 +1439,10 @@ def update_color_schema(self):
14231439
legend.set_color_table(palette)
14241440

14251441
def update_sorting_examples(self):
1426-
if self.effective_data is not None:
1427-
self.update_heatmaps()
1442+
self.update_heatmaps()
14281443

14291444
def update_sorting_attributes(self):
1430-
if self.effective_data is not None:
1431-
self.update_heatmaps()
1445+
self.update_heatmaps()
14321446

14331447
def update_legend(self):
14341448
for item in self.heatmap_scene.items():
@@ -1538,7 +1552,6 @@ def commit(self):
15381552
data = None
15391553
indices = None
15401554
if self.merge_kmeans:
1541-
assert self.merge_indices is not None
15421555
merge_indices = self.merge_indices
15431556
else:
15441557
merge_indices = None

Orange/widgets/visualize/tests/test_owheatmap.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# Test methods with long descriptive names can omit docstrings
22
# pylint: disable=missing-docstring
3-
from Orange.data import Table
3+
import numpy as np
4+
5+
from Orange.data import Table, Domain, DiscreteVariable, ContinuousVariable
46
from Orange.preprocess import Continuize
57
from Orange.widgets.visualize.owheatmap import OWHeatMap
68
from Orange.widgets.tests.base import WidgetTest, WidgetOutputsTestMixin
@@ -74,3 +76,33 @@ def _select_data(self):
7476
self.widget.selection_manager.select_rows(selected_indices)
7577
self.widget.on_selection_finished()
7678
return selected_indices
79+
80+
def test_not_enough_data_settings_changed(self):
81+
"""Check widget for dataset with one feature or for one instance"""
82+
self._test_helper()
83+
self.widget.controls.merge_kmeans.setChecked(True)
84+
self._test_helper(True)
85+
86+
def _test_helper(self, checked=False):
87+
iris = Table("iris")
88+
msg = self.widget.Error
89+
for i in range(0, self.widget.colsortcb.count()):
90+
self.widget.colsortcb.activated.emit(i)
91+
self.widget.colsortcb.setCurrentIndex(i)
92+
self.send_signal("Data", None)
93+
self.send_signal("Data", iris[:, 0])
94+
if i > 0:
95+
self.assertTrue(msg.not_enough_features.is_shown())
96+
for j in range(0, self.widget.rowsortcb.count()):
97+
self.widget.rowsortcb.activated.emit(j)
98+
self.widget.rowsortcb.setCurrentIndex(j)
99+
self.send_signal("Data", None)
100+
self.send_signal("Data", iris[0:1])
101+
if j > 1:
102+
self.assertTrue(msg.not_enough_instances.is_shown())
103+
elif checked and j > 1:
104+
self.assertTrue(msg.not_enough_instances_k_means.is_shown())
105+
self.send_signal("Data", None)
106+
self.assertFalse(msg.not_enough_features.is_shown())
107+
self.assertFalse(msg.not_enough_instances.is_shown())
108+
self.assertFalse(msg.not_enough_instances_k_means.is_shown())

0 commit comments

Comments
 (0)