Skip to content

Commit 9907bfe

Browse files
committed
Distributions: Fix invalid selection and tooltip for some histograms
1 parent 2af0b98 commit 9907bfe

2 files changed

Lines changed: 44 additions & 14 deletions

File tree

Orange/widgets/visualize/owdistributions.py

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,11 @@ def mouseReleaseEvent(event):
6868

6969
class DistributionBarItem(pg.GraphicsObject):
7070
def __init__(self, x, width, padding, freqs, colors, stacked, expanded,
71-
tooltip, desc, hidden):
71+
tooltip, desc, hidden, low, high):
7272
super().__init__()
7373
self.x = x
74+
self.low = low
75+
self.high = high
7476
self.width = width
7577
self.freqs = freqs
7678
self.colors = colors
@@ -618,10 +620,10 @@ def _call_plotting(self):
618620
self.plot.autoRange()
619621

620622
def _add_bar(self, x, width, padding, freqs, colors, stacked, expanded,
621-
tooltip, desc, hidden=False):
623+
tooltip, desc, hidden=False, low=None, high=None):
622624
item = DistributionBarItem(
623625
x, width, padding, freqs, colors, stacked, expanded, tooltip,
624-
desc, hidden)
626+
desc, hidden, low, high)
625627
self.plot.addItem(item)
626628
self.bar_items.append(item)
627629

@@ -698,7 +700,9 @@ def _cont_plot(self):
698700
x0 + xoff, bar_width, 0,
699701
[tot_freq if self.cumulative_distr else freq],
700702
colors, stacked=False, expanded=False, tooltip=tooltip,
701-
desc=desc, hidden=self.hide_bars and self.fitted_distribution)
703+
desc=desc, hidden=self.hide_bars and self.fitted_distribution,
704+
low=x0, high=x1
705+
)
702706

703707
if self.fitted_distribution:
704708
self._plot_approximations(
@@ -747,7 +751,9 @@ def _cont_split_plot(self):
747751
hidden=self.hide_bars and self.fitted_distribution,
748752
tooltip=self._split_tooltip(
749753
desc, np.sum(plotfreqs), total, gvalues, plotfreqs),
750-
desc=desc)
754+
desc=desc,
755+
low=x0, high=x1
756+
)
751757

752758
if fitters:
753759
self._plot_approximations(bins[0], bins[-1], fitters, varcolors,
@@ -1022,14 +1028,16 @@ def show_selection(self):
10221028
group = list(group)
10231029
left_idx, right_idx = group[0], group[-1]
10241030
left_pad, right_pad = self._determine_padding(left_idx, right_idx)
1025-
x0 = self.bar_items[left_idx].x0 - left_pad
1026-
x1 = self.bar_items[right_idx].x1 + right_pad
1031+
left, right = (self.bar_items[it] for it in (left_idx, right_idx))
1032+
x0 = left.x0 - left_pad
1033+
x1 = right.x1 + right_pad
10271034
item = QGraphicsRectItem(x0, 0, x1 - x0, 1)
10281035
item.setPen(pen)
10291036
item.setBrush(brush)
10301037
if self.var.is_continuous:
10311038
valname = self.str_int(
1032-
x0, x1, not left_idx, right_idx == len(self.bar_items) - 1)
1039+
left.low, right.high,
1040+
self._is_first_bar(left_idx), self._is_last_bar(right_idx))
10331041
inside = sum(np.sum(self.bar_items[i].freqs) for i in group)
10341042
total = len(self.valid_data)
10351043
item.setToolTip(
@@ -1224,7 +1232,9 @@ def _get_output_indices_cont(self):
12241232
group_indices[mask] = group_idx
12251233
# pylint: disable=undefined-loop-variable
12261234
values.append(
1227-
self.str_int(x0, x1, not bar_idx, self._is_last_bar(bar_idx)))
1235+
self.str_int(
1236+
x0, x1,
1237+
self._is_first_bar(bar_idx), self._is_last_bar(bar_idx)))
12281238
return group_indices, values
12291239

12301240
def _get_histogram_table(self):
@@ -1251,16 +1261,22 @@ def _get_histogram_indices(self):
12511261
x0, x1, mask = self._get_cont_baritem_indices(col, bar_idx)
12521262
group_indices[mask] = bar_idx + 1
12531263
values.append(
1254-
self.str_int(x0, x1, not bar_idx, self._is_last_bar(bar_idx)))
1264+
self.str_int(
1265+
x0, x1,
1266+
self._is_first_bar(bar_idx), self._is_last_bar(bar_idx)))
12551267
return group_indices, values
12561268

12571269
def _get_cont_baritem_indices(self, col, bar_idx):
12581270
bar_item = self.bar_items[bar_idx]
1259-
minx = bar_item.x0
1260-
maxx = bar_item.x1 + (bar_idx == len(self.bar_items) - 1)
1271+
minx = bar_item.low
1272+
maxx = bar_item.high + self._is_last_bar(bar_idx)
12611273
with np.errstate(invalid="ignore"):
12621274
return minx, maxx, (col >= minx) * (col < maxx)
12631275

1276+
@staticmethod
1277+
def _is_first_bar(idx):
1278+
return idx == 0
1279+
12641280
def _is_last_bar(self, idx):
12651281
return idx == len(self.bar_items) - 1
12661282

Orange/widgets/visualize/tests/test_owdistributions.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import os
66
import unittest
7-
from unittest.mock import Mock
7+
from unittest.mock import Mock, patch
88

99
import numpy as np
1010
from AnyQt.QtCore import QItemSelection, Qt, QEvent
@@ -13,7 +13,8 @@
1313

1414
from orangewidget.utils.combobox import qcombobox_emit_activated
1515

16-
from Orange.data import Table, Domain, DiscreteVariable
16+
from Orange.data import Table, Domain, DiscreteVariable, ContinuousVariable
17+
from Orange.preprocess import BinDefinition
1718
from Orange.widgets.tests.base import WidgetTest
1819
from Orange.widgets.utils.annotated_data import ANNOTATED_DATA_FEATURE_NAME
1920
from Orange.widgets.utils.itemmodels import DomainModel
@@ -706,6 +707,19 @@ def test_keyboard_interaction_unsorted(self):
706707
widget.keyPressEvent(press(right, Qt.ShiftModifier))
707708
assert widget.selected_bars == {values[1], values[2]}
708709

710+
@patch("Orange.widgets.visualize.owdistributions.decimal_binnings")
711+
def test_selection_with_offset_cont_hist(self, dec_bin):
712+
widget = self.widget
713+
714+
dec_bin.return_value = [BinDefinition(np.arange(0, 1000, 100))]
715+
self.send_signal(Table.from_numpy(Domain([ContinuousVariable("y")]),
716+
np.arange(1000)[:, np.newaxis]))
717+
widget._on_item_clicked(widget.bar_items[2], Qt.NoModifier, False)
718+
widget._on_end_selecting()
719+
np.testing.assert_equal(
720+
self.get_output(widget.Outputs.selected_data).X,
721+
np.arange(200, 300)[:, np.newaxis])
722+
709723

710724
if __name__ == "__main__":
711725
unittest.main()

0 commit comments

Comments
 (0)