Repository: biolab/orange3

Issue:
Box Plot: selecting subset crashes with None
**Describe the bug**
Selection in Box Plot sometimes results in an error. I suspect sparse data.

**To Reproduce**

Steps to reproduce the behavior go **here**:
1. Corpus (bookexcerpts)
2. Bag of Words (uncheck Hide box attributes)
3. Box Plot (select variable doors and adults group).

**Orange version:**
3.26.0.dev

**Expected behavior**
No error.

**Operating system:**
OSX

**Additional context**
```
Traceback (most recent call last):
  File "/Users/ajda/orange/orange3/Orange/widgets/visualize/owboxplot.py", line 1119, in commit
    selected = Values(self.conditions, conjunction=False)(self.dataset)
  File "/Users/ajda/orange/orange3/Orange/data/filter.py", line 220, in __call__
    return data._filter_values(self)
  File "/Users/ajda/orange/orange3/Orange/data/table.py", line 1183, in _filter_values
    selection = self._values_filter_to_indicator(filter)
  File "/Users/ajda/orange/orange3/Orange/data/table.py", line 1213, in _values_filter_to_indicator
    selection = self._filter_to_indicator(f)
  File "/Users/ajda/orange/orange3/Orange/data/table.py", line 1240, in _filter_to_indicator
    return self._values_filter_to_indicator(filter)
  File "/Users/ajda/orange/orange3/Orange/data/table.py", line 1213, in _values_filter_to_indicator
    selection = self._filter_to_indicator(f)
  File "/Users/ajda/orange/orange3/Orange/data/table.py", line 1285, in _filter_to_indicator
    return col_filter(col_indices[0])
  File "/Users/ajda/orange/orange3/Orange/data/table.py", line 1269, in col_filter
    return self._continuous_filter_to_indicator(filter, col)
  File "/Users/ajda/orange/orange3/Orange/data/table.py", line 1331, in _continuous_filter_to_indicator
    return self._range_filter_to_indicator(filter, col, filter.min, filter.max)
  File "/Users/ajda/orange/orange3/Orange/data/table.py", line 1386, in _range_filter_to_indicator
    return (col >= fmin) * (col <= fmax)
TypeError: '>=' not supported between instances of 'float' and 'NoneType'
```






Discussion:
While working on #4663, I discovered that `OWBoxPlot.clear_scene` calls `openContext`. I wanted to write that whoever has done this needs to be properly disciplined, but then I discovered -- to my surprise -- that it actually wasn't me. (Though I still suspect it was done on my advice. Responsible programmers, for instance @VesnaT, would never do it by her own volition.)

This call may cause the problem you encountered. Even if not, this bug may go away with a fix for #4663 due to redesign of the way widget uses filters.

Please do not start working on this before we see what happens with #4663.

Resolving patch:
diff --git a/Orange/widgets/visualize/owboxplot.py b/Orange/widgets/visualize/owboxplot.py
--- a/Orange/widgets/visualize/owboxplot.py
+++ b/Orange/widgets/visualize/owboxplot.py
@@ -99,7 +99,7 @@ def __init__(self, dist, group_val=None):
         # The code below omits the q25 or q75 in the plot when they are None
         self.q25 = None if q25 == median else q25
         self.q75 = None if q75 == median else q75
-        self.data_range = ContDataRange(self.q25, self.q75, group_val)
+        self.data_range = ContDataRange(q25, q75, group_val)
 
 
 class FilterGraphicsRectItem(QGraphicsRectItem):


Test patch:
diff --git a/Orange/widgets/visualize/tests/test_owboxplot.py b/Orange/widgets/visualize/tests/test_owboxplot.py
--- a/Orange/widgets/visualize/tests/test_owboxplot.py
+++ b/Orange/widgets/visualize/tests/test_owboxplot.py
@@ -347,6 +347,14 @@ def test_value_all_missing_for_group(self):
         self.__select_group("a")
         self.assertTupleEqual(self.widget.conts.shape, (3, 2))
 
+    def test_valid_data_range(self):
+        self.send_signal(self.widget.Inputs.data, self.iris)
+        self.__select_variable("petal width")
+        self.__select_group("iris")
+        for box in self.widget.box_scene.items():
+            if isinstance(box, FilterGraphicsRectItem):
+                box.setSelected(True)
+
     def test_summary(self):
         """Check if status bar is updated when data is received"""
         data, info = self.titanic, self.widget.info
@@ -407,3 +415,7 @@ def test(self):
                        [0.0, 0.25, 0.5, 0.75, 1.0], interpolation="lower"),
             [1, 1, 2, 3, 4]
         )
+
+
+if __name__ == '__main__':
+    unittest.main()