Skip to content

Commit 3241ee5

Browse files
committed
Box plot: Move 'order by importance' checkbox to groups
1 parent 7e33526 commit 3241ee5

File tree

1 file changed

+35
-40
lines changed

1 file changed

+35
-40
lines changed

Orange/widgets/visualize/owboxplot.py

Lines changed: 35 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ def __init__(self):
203203
self.scene_min_x = self.scene_max_x = self.scene_width = 0
204204
self.label_width = 0
205205

206-
self.attrs = VariableListModel()
206+
self.attrs = DomainModel(separators=False)
207207
view = gui.listView(
208208
self.controlArea, self, "attribute", box="Variable",
209209
model=self.attrs, callback=self.attr_changed)
@@ -212,18 +212,16 @@ def __init__(self):
212212
# set the minimal height (see the penultimate paragraph of
213213
# http://doc.qt.io/qt-4.8/qabstractscrollarea.html#addScrollBarWidget)
214214
view.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Ignored)
215-
gui.separator(view.box, 6, 6)
215+
self.group_vars = VariableListModel(placeholder="None")
216+
self.group_view = view = gui.listView(
217+
self.controlArea, self, "group_var", box="Subgroups",
218+
model=self.group_vars, callback=self.grouping_changed)
219+
gui.separator(self.group_view.box, 6, 6)
216220
self.cb_order = gui.checkBox(
217221
view.box, self, "order_by_importance",
218222
"Order by relevance",
219223
tooltip="Order by 𝜒² or ANOVA over the subgroups",
220224
callback=self.apply_sorting)
221-
self.group_vars = DomainModel(
222-
placeholder="None", separators=False,
223-
valid_types=Orange.data.DiscreteVariable)
224-
self.group_view = view = gui.listView(
225-
self.controlArea, self, "group_var", box="Subgroups",
226-
model=self.group_vars, callback=self.grouping_changed)
227225
view.setEnabled(False)
228226
view.setMinimumSize(QSize(30, 30))
229227
# See the comment above
@@ -289,11 +287,11 @@ def eventFilter(self, obj, event):
289287

290288
return super().eventFilter(obj, event)
291289

292-
def reset_attrs(self, domain):
293-
self.attrs[:] = [
290+
def reset_groups(self, domain):
291+
self.group_vars[:] = [
294292
var for var in chain(
295293
domain.class_vars, domain.metas, domain.attributes)
296-
if var.is_primitive()]
294+
if var.is_discrete]
297295

298296
# noinspection PyTypeChecker
299297
@Inputs.data
@@ -309,9 +307,9 @@ def set_data(self, dataset):
309307
self.attribute = None
310308
if dataset:
311309
domain = dataset.domain
312-
self.group_vars.set_domain(domain)
310+
self.attrs.set_domain(domain)
311+
self.reset_groups(domain)
313312
self.group_view.setEnabled(len(self.group_vars) > 1)
314-
self.reset_attrs(domain)
315313
self.select_default_variables(domain)
316314
self.openContext(self.dataset)
317315
self.grouping_changed()
@@ -332,37 +330,34 @@ def select_default_variables(self, domain):
332330
self.group_var = None # Reset to trigger selection via callback
333331

334332
def apply_sorting(self):
335-
def compute_score(attr):
336-
if attr is group_var:
333+
def compute_anova(group):
334+
group_col = data.get_column_view(group)[0].astype(float)
335+
groups = (attr_col[group_col == i]
336+
for i in range(len(group.values)))
337+
groups = (col[~np.isnan(col)] for col in groups)
338+
groups = [group for group in groups if len(group)]
339+
p = f_oneway(*groups)[1] if len(groups) > 1 else 2
340+
return 2 if math.isnan(p) else p
341+
342+
def compute_chi(group):
343+
if group is attr:
337344
return 3
338-
if attr.is_continuous:
339-
# One-way ANOVA
340-
col = data.get_column_view(attr)[0].astype(float)
341-
groups = (col[group_col == i] for i in range(n_groups))
342-
groups = (col[~np.isnan(col)] for col in groups)
343-
groups = [group for group in groups if len(group)]
344-
p = f_oneway(*groups)[1] if len(groups) > 1 else 2
345-
else:
346-
p = self._chi_square(group_var, attr)[1]
347-
if math.isnan(p):
348-
return 2
349-
return p
345+
p = self._chi_square(group, attr)[1]
346+
return 2 if math.isnan(p) else p
350347

351348
data = self.dataset
352349
if data is None:
353350
return
354351
domain = data.domain
355-
attribute = self.attribute
356-
group_var = self.group_var
357-
if self.order_by_importance and group_var is not None:
358-
n_groups = len(group_var.values)
359-
group_col = data.get_column_view(group_var)[0] if \
360-
domain.has_continuous_attributes(
361-
include_class=True, include_metas=True) else None
362-
self.attrs.sort(key=compute_score)
352+
attr = self.attribute
353+
if self.order_by_importance:
354+
if attr.is_continuous:
355+
attr_col = data.get_column_view(attr)[0]
356+
self.group_vars.sort(key=compute_anova)
357+
else:
358+
self.group_vars.sort(key=compute_chi)
363359
else:
364-
self.reset_attrs(domain)
365-
self.attribute = attribute
360+
self.reset_groups(domain)
366361

367362
def _chi_square(self, group_var, attr):
368363
# Chi-square with the given distribution into groups
@@ -379,15 +374,14 @@ def _chi_square(self, group_var, attr):
379374
def reset_all_data(self):
380375
self.clear_scene()
381376
self.stat_test = ""
382-
self.attrs.clear()
383-
self.group_vars.set_domain(None)
377+
self.attrs.set_domain(None)
378+
self.group_vars.clear()
384379
self.group_view.setEnabled(False)
385380
self.is_continuous = False
386381
self.update_display_box()
387382

388383
def grouping_changed(self):
389384
self.cb_order.setEnabled(self.group_var is not None)
390-
self.apply_sorting()
391385
self.attr_changed()
392386

393387
def select_box_items(self):
@@ -399,6 +393,7 @@ def select_box_items(self):
399393

400394
def attr_changed(self):
401395
self.compute_box_data()
396+
self.apply_sorting()
402397
self.update_display_box()
403398
self.layout_changed()
404399

0 commit comments

Comments
 (0)