diff --git a/Orange/widgets/visualize/owmosaic.py b/Orange/widgets/visualize/owmosaic.py index 2f1b652c72e..88b2b6e5bee 100644 --- a/Orange/widgets/visualize/owmosaic.py +++ b/Orange/widgets/visualize/owmosaic.py @@ -512,6 +512,20 @@ def update_graph(self): spacing = self.SPACING bar_width = self.BAR_WIDTH + def get_counts(attr_vals, values): + """This function calculates rectangles' widths. + If all widths are zero then all widths are set to 1.""" + if attr_vals == "": + counts = [conditionaldict[val] for val in values] + else: + counts = [conditionaldict[attr_vals + "-" + val] + for val in values] + total = sum(counts) + if total == 0: + counts = [1] * len(values) + total = sum(counts) + return total, counts + def draw_data(attr_list, x0_x1, y0_y1, side, condition, total_attrs, used_attrs, used_vals, attr_vals=""): x0, x1 = x0_x1 @@ -542,12 +556,7 @@ def draw_data(attr_list, x0_x1, y0_y1, side, condition, if whole == 0: edge = (y1 - y0) / float(len(values) - 1) - if attr_vals == "": - counts = [conditionaldict[val] for val in values] - else: - counts = [conditionaldict[attr_vals + "-" + val] - for val in values] - total = sum(counts) + total, counts = get_counts(attr_vals, values) # if we are visualizing the third attribute and the first attribute # has the last value, we have to reverse the order in which the @@ -633,15 +642,7 @@ def draw_text(side, attr, x0_x1, y0_y1, # calculate position of first attribute currpos = 0 - if attr_vals == "": - counts = [conditionaldict.get(val, 1) for val in values] - else: - counts = [conditionaldict.get(attr_vals + "-" + val, 1) - for val in values] - total = sum(counts) - if total == 0: - counts = [1] * len(values) - total = sum(counts) + total, counts = get_counts(attr_vals, values) aligns = [Qt.AlignTop | Qt.AlignHCenter, Qt.AlignRight | Qt.AlignVCenter, diff --git a/Orange/widgets/visualize/tests/test_owmosaic.py b/Orange/widgets/visualize/tests/test_owmosaic.py index d1e87b6af5a..563afa6aa29 100644 --- a/Orange/widgets/visualize/tests/test_owmosaic.py +++ b/Orange/widgets/visualize/tests/test_owmosaic.py @@ -7,7 +7,7 @@ from Orange.data import Table, DiscreteVariable, Domain, ContinuousVariable from Orange.widgets.tests.base import WidgetTest, WidgetOutputsTestMixin -from Orange.widgets.visualize.owmosaic import OWMosaicDisplay, MosaicVizRank +from Orange.widgets.visualize.owmosaic import OWMosaicDisplay class TestOWMosaicDisplay(WidgetTest, WidgetOutputsTestMixin): @@ -194,3 +194,21 @@ def test_does_not_crash(self): data = Table("housing.tab") widget.set_data(data) vizrank.toggle() + + def test_nan_column(self): + """ + A column with only NaN-s used to throw an error + (ZeroDivisionError) when loaded into widget. + GH-2046 + """ + table = Table( + Domain( + [ContinuousVariable("a"), ContinuousVariable("b"), ContinuousVariable("c")]), + np.array([ + [0, np.NaN, 0], + [0, np.NaN, 0], + [0, np.NaN, 0] + ]) + ) + self.send_signal("Data", table) +