def commit(self): """Output data instances corresponding to selected cells""" if self.results is not None and self.data is not None \ and self.selected_learner: indices = self.tableview.selectedIndexes() indices = {(ind.row() - 2, ind.column() - 2) for ind in indices} actual = self.results.actual learner_name = self.learners[self.selected_learner[0]] predicted = self.results.predicted[self.selected_learner[0]] selected = [i for i, t in enumerate(zip(actual, predicted)) if t in indices] extra = [] class_var = self.data.domain.class_var metas = self.data.domain.metas if self.append_predictions: extra.append(predicted.reshape(-1, 1)) var = Orange.data.DiscreteVariable( "{}({})".format(class_var.name, learner_name), class_var.values ) metas = metas + (var,) if self.append_probabilities and \ self.results.probabilities is not None: probs = self.results.probabilities[self.selected_learner[0]] extra.append(numpy.array(probs, dtype=object)) pvars = [Orange.data.ContinuousVariable("p({})".format(value)) for value in class_var.values] metas = metas + tuple(pvars) X = self.data.X Y = self.data.Y M = self.data.metas row_ids = self.data.ids M = numpy.hstack((M,) + tuple(extra)) domain = Orange.data.Domain( self.data.domain.attributes, self.data.domain.class_vars, metas ) data = Orange.data.Table.from_numpy(domain, X, Y, M) data.ids = row_ids data.name = learner_name if selected: annotated_data = create_annotated_table(data, selected) data = data[selected] else: annotated_data = create_annotated_table(data, []) data = None else: data = None annotated_data = None self.send("Selected Data", data) self.send(ANNOTATED_DATA_SIGNAL_NAME, annotated_data)
def send_selection(self): if not self.selection or self.data is None: self.send("Selected Data", None) self.send(ANNOTATED_DATA_SIGNAL_NAME, create_annotated_table(self.data, [])) return filters = [] self.Warning.no_cont_selection_sql.clear() if self.discrete_data is not self.data: if isinstance(self.data, SqlTable): self.Warning.no_cont_selection_sql() for i in self.selection: cols, vals, area = self.areas[i] filters.append( filter.Values( filter.FilterDiscrete(col, [val]) for col, val in zip(cols, vals))) if len(filters) > 1: filters = filter.Values(filters, conjunction=False) else: filters = filters[0] selection = filters(self.discrete_data) idset = set(selection.ids) sel_idx = [i for i, id in enumerate(self.data.ids) if id in idset] if self.discrete_data is not self.data: selection = self.data[sel_idx] self.send("Selected Data", selection) self.send(ANNOTATED_DATA_SIGNAL_NAME, create_annotated_table(self.data, sel_idx))
def test_create_annotated_table_selected(self): # check annotated column for no selected indices annotated = create_annotated_table(self.zoo, []) self.assertEqual(len(annotated), len(self.zoo)) self.assertEqual( 0, np.sum([i[ANNOTATED_DATA_FEATURE_NAME] for i in annotated])) # check annotated column fol all selectes indices annotated = create_annotated_table(self.zoo, list(range(len(self.zoo)))) self.assertEqual(len(annotated), len(self.zoo)) self.assertEqual( len(self.zoo), np.sum([i[ANNOTATED_DATA_FEATURE_NAME] for i in annotated]))
def commit(self): if self.embedding is not None: names = get_unique_names([v.name for v in self.data.domain.variables], ["mds-x", "mds-y"]) output = embedding = Orange.data.Table.from_numpy( Orange.data.Domain([ContinuousVariable(names[0]), ContinuousVariable(names[1])]), self.embedding ) else: output = embedding = None if self.embedding is not None and self.data is not None: domain = self.data.domain domain = Orange.data.Domain(domain.attributes, domain.class_vars, domain.metas + embedding.domain.attributes) output = self.data.transform(domain) output.metas[:, -2:] = embedding.X selection = self.graph.get_selection() if output is not None and len(selection) > 0: selected = output[selection] else: selected = None if self.graph.selection is not None and np.max(self.graph.selection) > 1: annotated = create_groups_table(output, self.graph.selection) else: annotated = create_annotated_table(output, selection) self.Outputs.selected_data.send(selected) self.Outputs.annotated_data.send(annotated)
def commit(self): if len(self.selection): cells = [] for ir, r in enumerate(self.rows.values): for ic, c in enumerate(self.columns.values): if (ir, ic) in self.selection: cells.append(Values([FilterDiscrete(self.rows, [r]), FilterDiscrete(self.columns, [c])])) selected_data = Values(cells, conjunction=False)(self.data) annotated_data = create_annotated_table(self.data, np.where(np.in1d(self.data.ids, selected_data.ids, True))) else: selected_data = None annotated_data = create_annotated_table(self.data, []) self.Outputs.contingency.send(self.table) self.Outputs.selected_data.send(selected_data) self.Outputs.annotated_data.send(annotated_data)
def _prepare_data(self): indices = self.tableview.selectedIndexes() indices = {(ind.row() - 2, ind.column() - 2) for ind in indices} actual = self.results.actual learner_name = self.learners[self.selected_learner[0]] predicted = self.results.predicted[self.selected_learner[0]] selected = [i for i, t in enumerate(zip(actual, predicted)) if t in indices] extra = [] class_var = self.data.domain.class_var metas = self.data.domain.metas if self.append_predictions: extra.append(predicted.reshape(-1, 1)) var = Orange.data.DiscreteVariable( "{}({})".format(class_var.name, learner_name), class_var.values ) metas = metas + (var,) if self.append_probabilities and \ self.results.probabilities is not None: probs = self.results.probabilities[self.selected_learner[0]] extra.append(np.array(probs, dtype=object)) pvars = [Orange.data.ContinuousVariable("p({})".format(value)) for value in class_var.values] metas = metas + tuple(pvars) domain = Orange.data.Domain(self.data.domain.attributes, self.data.domain.class_vars, metas) data = self.data.transform(domain) if len(extra): data.metas[:, len(self.data.domain.metas):] = \ np.hstack(tuple(extra)) data.name = learner_name if selected: annotated_data = create_annotated_table(data, selected) data = data[selected] else: annotated_data = create_annotated_table(data, []) data = None return data, annotated_data
def commit(self): self.conditions = [item.filter for item in self.box_scene.selectedItems() if item.filter] selected, selection = None, [] if self.conditions: selected = Values(self.conditions, conjunction=False)(self.dataset) selection = [i for i, inst in enumerate(self.dataset) if inst in selected] self.send("Selected Data", selected) self.send(ANNOTATED_DATA_SIGNAL_NAME, create_annotated_table(self.dataset, selection))
def update_selection(self): if self.model is None: return nodes = [item.node_inst for item in self.scene.selectedItems() if isinstance(item, TreeNode)] data = self.tree_adapter.get_instances_in_nodes(nodes) self.Outputs.selected_data.send(data) self.Outputs.annotated_data.send(create_annotated_table( self.dataset, self.tree_adapter.get_indices(nodes)))
def commit(self): self.conditions = [item.filter for item in self.box_scene.selectedItems() if item.filter] selected, selection = None, [] if self.conditions: selected = Values(self.conditions, conjunction=False)(self.dataset) selection = [i for i, inst in enumerate(self.dataset) if inst in selected] self.Outputs.selected_data.send(selected) self.Outputs.annotated_data.send(create_annotated_table(self.dataset, selection))
def update_selection(self): if self.model is None: return nodes = [item.node_inst for item in self.scene.selectedItems() if isinstance(item, TreeNode)] data = self.model.get_instances(nodes) self.send("Selected Data", data) self.send(ANNOTATED_DATA_SIGNAL_NAME, create_annotated_table(self.dataset, self.model.get_indices(nodes)))
def commit(self): self.conditions = [item.filter for item in self.box_scene.selectedItems() if item.filter] selected, selection = None, [] if self.conditions: selected = Values(self.conditions, conjunction=False)(self.dataset) selection = np.in1d( self.dataset.ids, selected.ids, assume_unique=True).nonzero()[0] self.Outputs.selected_data.send(selected) self.Outputs.annotated_data.send( create_annotated_table(self.dataset, selection))
def commit(self): if self.data: if self.selectedIndices: selected = self.data[self.selectedIndices] else: selected = None self.Outputs.selected_data.send(selected) self.Outputs.data.send(create_annotated_table( self.data, self.selectedIndices)) else: self.Outputs.selected_data.send(None) self.Outputs.data.send(None)
def commit(self): """Commit the selected data to output.""" if self.instances is None: self.Outputs.selected_data.send(None) self.Outputs.annotated_data.send(None) return nodes = [i.tree_node.label for i in self.scene.selectedItems() if isinstance(i, SquareGraphicsItem)] data = self.tree_adapter.get_instances_in_nodes(nodes) self.Outputs.selected_data.send(data) selected_indices = self.tree_adapter.get_indices(nodes) self.Outputs.annotated_data.send(create_annotated_table(self.instances, selected_indices))
def send_data(self): selected = None selection = None # TODO: Implement selection for sql data if isinstance(self.data, SqlTable): selected = self.data elif self.data is not None: selection = self.graph.get_selection() if len(selection) > 0: selected = self.data[selection] self.send("Selected Data", selected) self.send(ANNOTATED_DATA_SIGNAL_NAME, create_annotated_table(self.data, selection))
def test_cascade_annotated_tables_with_missing_annotated_feature(self): # check table for domain [..., "Feature", "Selected (3)] -> # [..., "Feature", "Selected (3), "Selected (4)"] data = self.zoo data.domain.metas[0].name = "{} ({})".format( ANNOTATED_DATA_FEATURE_NAME, 3) data = create_annotated_table( data, random.sample(range(0, len(self.zoo)), 20)) self.assertEqual(2, len(data.domain.metas)) self.assertEqual(data.domain.metas[0].name, "{} ({})".format(ANNOTATED_DATA_FEATURE_NAME, 3)) self.assertEqual(data.domain.metas[1].name, "{} ({})".format(ANNOTATED_DATA_FEATURE_NAME, 4))
def update_selection(self): """ Update the graph (pen width) to show the current selection. Filter and output the data. """ if self.areas is None or not self.selection: self.send("Selected Data", None) self.send(ANNOTATED_DATA_SIGNAL_NAME, create_annotated_table(self.data, [])) return filts = [] for i, area in enumerate(self.areas): if i in self.selection: width = 4 val_x, val_y = area.value_pair filts.append( filter.Values([ filter.FilterDiscrete(self.attr_x.name, [val_x]), filter.FilterDiscrete(self.attr_y.name, [val_y]) ])) else: width = 1 pen = area.pen() pen.setWidth(width) area.setPen(pen) if len(filts) == 1: filts = filts[0] else: filts = filter.Values(filts, conjunction=False) selection = filts(self.discrete_data) idset = set(selection.ids) sel_idx = [i for i, id in enumerate(self.data.ids) if id in idset] if self.discrete_data is not self.data: selection = self.data[sel_idx] self.send("Selected Data", selection) self.send(ANNOTATED_DATA_SIGNAL_NAME, create_annotated_table(self.data, sel_idx))
def set_tree(self, model=None): """When a different tree is given.""" self.clear() self.model = model if model is not None: self.instances = model.instances # this bit is important for the regression classifier if self.instances is not None and \ self.instances.domain != model.domain: self.clf_dataset = self.instances.transform(self.model.domain) else: self.clf_dataset = self.instances self.tree_adapter = self._get_tree_adapter(self.model) self.ptree.clear() self.ptree.set_tree( self.tree_adapter, weight_adjustment=self.SIZE_CALCULATION[self.size_calc_idx][1], target_class_index=self.target_class_index, ) self._update_depth_slider() self.color_palette = self.ptree.root.color_palette self._update_legend_colors() self._update_legend_visibility() self._update_info_box() self._update_target_class_combo() self._update_main_area() # The target class can also be passed from the meta properties # This must be set after `_update_target_class_combo` if hasattr(model, 'meta_target_class_index'): self.target_class_index = model.meta_target_class_index self.update_colors() # Get meta variables describing what the settings should look like # if the tree is passed from the Pythagorean forest widget. if hasattr(model, 'meta_size_calc_idx'): self.size_calc_idx = model.meta_size_calc_idx self.update_size_calc() # TODO There is still something wrong with this # if hasattr(model, 'meta_depth_limit'): # self.depth_limit = model.meta_depth_limit # self.update_depth() self.Outputs.annotated_data.send(create_annotated_table(self.instances, None))
def commit(self): """Commit the selected data to output.""" if self.instances is None: self.send('Selected Data', None) self.send(ANNOTATED_DATA_SIGNAL_NAME, None) return nodes = [i.tree_node.label for i in self.scene.selectedItems() if isinstance(i, SquareGraphicsItem)] data = self.tree_adapter.get_instances_in_nodes( self.clf_dataset, nodes) self.send('Selected Data', data) selected_indices = self.model.get_indices(nodes) self.send(ANNOTATED_DATA_SIGNAL_NAME, create_annotated_table(self.instances, selected_indices))
def test_cascade_annotated_tables(self): # check cascade of annotated tables data = self.zoo data.domain.metas[0].name = ANNOTATED_DATA_FEATURE_NAME for i in range(5): data = create_annotated_table( data, random.sample(range(0, len(self.zoo)), 20)) self.assertEqual(2 + i, len(data.domain.metas)) self.assertIn(self.zoo.domain.metas[0], data.domain.metas) self.assertIn(ANNOTATED_DATA_FEATURE_NAME, [m.name for m in data.domain.metas]) for j in range(1, i + 2): self.assertIn("{} ({})".format(ANNOTATED_DATA_FEATURE_NAME, j), [m.name for m in data.domain.metas])
def commit(self): """ Commit/send the current selection to the output. """ selected = indices = data = None if self.data is not None: selectedmask = numpy.full(len(self.data), False, dtype=bool) if self._silplot is not None: indices = self._silplot.selection() assert (numpy.diff(indices) > 0).all(), "strictly increasing" if self._mask is not None: indices = numpy.flatnonzero(~self._mask)[indices] selectedmask[indices] = True if self._mask is not None: scores = numpy.full(shape=selectedmask.shape, fill_value=numpy.nan) scores[~self._mask] = self._silhouette else: scores = self._silhouette silhouette_var = None if self.add_scores: var = self.cluster_var_model[self.cluster_var_idx] silhouette_var = Orange.data.ContinuousVariable( "Silhouette ({})".format(escape(var.name))) domain = Orange.data.Domain( self.data.domain.attributes, self.data.domain.class_vars, self.data.domain.metas + (silhouette_var, )) data = self.data.from_table( domain, self.data) else: domain = self.data.domain data = self.data if numpy.count_nonzero(selectedmask): selected = self.data.from_table( domain, self.data, numpy.flatnonzero(selectedmask)) if self.add_scores: if selected is not None: selected[:, silhouette_var] = numpy.c_[scores[selectedmask]] data[:, silhouette_var] = numpy.c_[scores] self.send("Selected Data", selected) self.send(ANNOTATED_DATA_SIGNAL_NAME, create_annotated_table(data, indices))
def commit(self): """ Commit/send the current selection to the output. """ selected = indices = data = None if self.data is not None: selectedmask = np.full(len(self.data), False, dtype=bool) if self._silplot is not None: indices = self._silplot.selection() assert (np.diff(indices) > 0).all(), "strictly increasing" if self._mask is not None: # pylint: disable=invalid-unary-operand-type indices = np.flatnonzero(~self._mask)[indices] selectedmask[indices] = True if self._mask is not None: scores = np.full(shape=selectedmask.shape, fill_value=np.nan) # pylint: disable=invalid-unary-operand-type scores[~self._mask] = self._silhouette else: scores = self._silhouette silhouette_var = None if self.add_scores: var = self.cluster_var_model[self.cluster_var_idx] silhouette_var = Orange.data.ContinuousVariable( "Silhouette ({})".format(escape(var.name))) domain = Orange.data.Domain( self.data.domain.attributes, self.data.domain.class_vars, self.data.domain.metas + (silhouette_var, )) data = self.data.transform(domain) else: domain = self.data.domain data = self.data if np.count_nonzero(selectedmask): selected = self.data.from_table( domain, self.data, np.flatnonzero(selectedmask)) if self.add_scores: if selected is not None: selected[:, silhouette_var] = np.c_[scores[selectedmask]] data[:, silhouette_var] = np.c_[scores] self.Outputs.selected_data.send(selected) self.Outputs.annotated_data.send(create_annotated_table(data, indices))
def commit(self): def prepare_components(): if self.placement in [self.Placement.Circular, self.Placement.LDA]: attrs = [a for a in self.model_selected[:]] axes = self.plotdata.axes elif self.placement == self.Placement.PCA: axes = self._pca.components_.T attrs = [a for a in self._pca.orig_domain.attributes] if self.placement != self.Placement.Projection: domain = Domain([ContinuousVariable(a.name, compute_value=lambda _: None) for a in attrs], metas=[StringVariable(name='component')]) metas = np.array([["{}{}".format(self.Component_name[self.placement], i + 1) for i in range(axes.shape[1])]], dtype=object).T components = Table(domain, axes.T, metas=metas) components.name = 'components' else: components = self.projection return components selected = annotated = components = None if self.data is not None and self.plotdata.data is not None: components = prepare_components() graph = self.graph mask = self.plotdata.valid_mask.astype(int) mask[mask == 1] = graph.selection if graph.selection is not None \ else [False * len(mask)] selection = np.array([], dtype=np.uint8) if mask is None else np.flatnonzero(mask) name = self.data.name data = self.plotdata.data if len(selection): selected = data[selection] selected.name = name + ": selected" selected.attributes = self.data.attributes if graph.selection is not None and np.max(graph.selection) > 1: annotated = create_groups_table(data, mask) else: annotated = create_annotated_table(data, selection) annotated.attributes = self.data.attributes annotated.name = name + ": annotated" self.Outputs.selected_data.send(selected) self.Outputs.annotated_data.send(annotated) self.Outputs.components.send(components)
def test_create_annotated_table(self): annotated = create_annotated_table(self.zoo, list(range(10))) # check annotated table domain self.assertEqual(annotated.domain.variables, self.zoo.domain.variables) self.assertEqual(2, len(annotated.domain.metas)) self.assertIn(self.zoo.domain.metas[0], annotated.domain.metas) self.assertIn(ANNOTATED_DATA_FEATURE_NAME, [m.name for m in annotated.domain.metas]) # check annotated table data np.testing.assert_array_equal(annotated.X, self.zoo.X) np.testing.assert_array_equal(annotated.Y, self.zoo.Y) np.testing.assert_array_equal(annotated.metas[:, 0].ravel(), self.zoo.metas.ravel()) self.assertEqual( 10, np.sum([i[ANNOTATED_DATA_FEATURE_NAME] for i in annotated]))
def set_tree(self, model=None): """When a different tree is given.""" self.closeContext() self.clear() self.model = model if model is not None: self.data = model.instances self.tree_adapter = self._get_tree_adapter(self.model) self.ptree.clear() self.ptree.set_tree( self.tree_adapter, weight_adjustment=self.SIZE_CALCULATION[self.size_calc_idx][1], target_class_index=self.target_class_index, ) self._update_depth_slider() self.color_palette = self.ptree.root.color_palette self._update_legend_colors() self._update_legend_visibility() self._update_info_box() self._update_target_class_combo() self._update_main_area() self.openContext(self.model) self.update_depth() # The forest widget sets the following attributes on the tree, # describing the settings on the forest widget. To keep the tree # looking the same as on the forest widget, we prefer these settings to # context settings, if set. if hasattr(model, "meta_target_class_index"): self.target_class_index = model.meta_target_class_index self.update_colors() if hasattr(model, "meta_size_calc_idx"): self.size_calc_idx = model.meta_size_calc_idx self.update_size_calc() if hasattr(model, "meta_depth_limit"): self.depth_limit = model.meta_depth_limit self.update_depth() self.Outputs.annotated_data.send(create_annotated_table(self.data, None))
def ctree(self, model=None): """Input signal handler""" self.clear_scene() self.color_combo.clear() self.closeContext() self.model = model self.target_class_index = 0 if model is None: self.info.setText('No tree.') self.root_node = None self.dataset = None self.tree_adapter = None else: self.tree_adapter = self._get_tree_adapter(model) self.domain = model.domain self.dataset = model.instances if self.dataset is not None and self.dataset.domain != self.domain: self.clf_dataset = self.dataset.transform(model.domain) else: self.clf_dataset = self.dataset class_var = self.domain.class_var if class_var.is_discrete: self.scene.colors = [QColor(*col) for col in class_var.colors] self.color_label.setText("Target class: ") self.color_combo.addItem("None") self.color_combo.addItems(self.domain.class_vars[0].values) self.color_combo.setCurrentIndex(self.target_class_index) else: self.scene.colors = \ ContinuousPaletteGenerator(*model.domain.class_var.colors) self.color_label.setText("Color by: ") self.color_combo.addItems(self.COL_OPTIONS) self.color_combo.setCurrentIndex(self.regression_colors) self.openContext(self.domain.class_var) # self.root_node = self.walkcreate(model.root, None) self.root_node = self.walkcreate(self.tree_adapter.root) self.info.setText('{} nodes, {} leaves'.format( self.tree_adapter.num_nodes, len(self.tree_adapter.leaves(self.tree_adapter.root)))) self.setup_scene() self.send("Selected Data", None) self.send(ANNOTATED_DATA_SIGNAL_NAME, create_annotated_table(self.dataset, []))
def commit(self): self.Warning.instances_not_matching.clear() subset_ids = [] if self.data_subset: subset_ids = self.data_subset.ids if not self.data: matching_output = None non_matching_output = None annotated_output = None else: if self.data_subset and len(np.intersect1d(subset_ids, self.data.ids)) == 0: self.Warning.instances_not_matching() row_sel = np.in1d(self.data.ids, subset_ids) matching_output = self.data[row_sel] non_matching_output = self.data[~row_sel] annotated_output = create_annotated_table(self.data, row_sel) self.Outputs.matching_data.send(matching_output) self.Outputs.non_matching_data.send(non_matching_output) self.Outputs.annotated_data.send(annotated_output)
def commit(self): selected = annotated = components = None graph = self.graph if self.data is not None and self.plotdata.validmask is not None: name = self.data.name metas = () + self.data.domain.metas + (self.variable_x, self.variable_y) domain = Domain(attributes=self.data.domain.attributes, class_vars=self.data.domain.class_vars, metas=metas) data = self.plotdata.data.transform(domain) validmask = self.plotdata.validmask mask = np.array(validmask, dtype=int) mask[mask == 1] = graph.selection if graph.selection is not None \ else [False * len(mask)] selection = np.array([], dtype=np.uint8) if mask is None else np.flatnonzero(mask) if len(selection): selected = data[selection] selected.name = name + ": selected" selected.attributes = self.data.attributes if graph.selection is not None and np.max(graph.selection) > 1: annotated = create_groups_table(data, mask) else: annotated = create_annotated_table(data, selection) annotated.attributes = self.data.attributes annotated.name = name + ": annotated" comp_domain = Domain( self.data.domain.attributes, metas=[StringVariable(name='component')]) metas = np.array([["FreeViz 1"], ["FreeViz 2"]]) components = Table.from_numpy( comp_domain, X=self.plotdata.anchors.T, metas=metas) components.name = name + ": components" self.Outputs.selected_data.send(selected) self.Outputs.annotated_data.send(annotated) self.Outputs.components.send(components)
def send_data(self): selected = None selection = None # TODO: Implement selection for sql data graph = self.graph if isinstance(self.data, SqlTable): selected = self.data elif self.data is not None: selection = graph.get_selection() if len(selection) > 0: selected = self.data[selection] if graph.selection is not None and np.max(graph.selection) > 1: annotated = self.create_groups_table(self.data, graph.selection) else: annotated = create_annotated_table(self.data, selection) self.Outputs.selected_data.send(selected) self.Outputs.annotated_data.send(annotated) # Store current selection in a setting that is stored in workflow if self.selection is not None and len(selection): self.selection = list(selection)
def commit(self): data = None indices = None if self.merge_kmeans: merge_indices = self.merge_indices else: merge_indices = None if self.input_data is not None and self.selected_rows: indices = self.selected_rows if merge_indices is not None: # expand merged indices indices = np.hstack([merge_indices[i] for i in indices]) data = self.input_data[indices] summary = len(data) if data else self.info.NoOutput details = format_summary_details(data) if data else "" self.info.set_output_summary(summary, details) self.Outputs.selected_data.send(data) self.Outputs.annotated_data.send(create_annotated_table(self.input_data, indices))
def send_data(self): selected = None selection = None # TODO: Implement selection for sql data graph = self.graph if isinstance(self.data, SqlTable): selected = self.data elif self.data is not None: selection = graph.get_selection() if len(selection) > 0: selected = self.data[selection] if graph.selection is not None and np.max(graph.selection) > 1: annotated = self.create_groups_table(self.data, graph.selection) else: annotated = create_annotated_table(self.data, selection) self.send("Selected Data", selected) self.send(ANNOTATED_DATA_SIGNAL_NAME, annotated) # Store current selection in a setting that is stored in workflow if self.selection is not None and len(selection): self.selection = list(selection)
def ctree(self, model=None): """Input signal handler""" self.clear_scene() self.color_combo.clear() self.closeContext() self.model = model self.target_class_index = 0 if model is None: self.infolabel.setText('No tree.') self.root_node = None self.dataset = None self.tree_adapter = None else: self.tree_adapter = self._get_tree_adapter(model) self.domain = model.domain self.dataset = model.instances if self.dataset is not None and self.dataset.domain != self.domain: self.clf_dataset = self.dataset.transform(model.domain) else: self.clf_dataset = self.dataset class_var = self.domain.class_var self.scene.colors = class_var.palette if class_var.is_discrete: self.color_label.setText("Target class: ") self.color_combo.addItem("None") self.color_combo.addItems(self.domain.class_vars[0].values) self.color_combo.setCurrentIndex(self.target_class_index) else: self.color_label.setText("Color by: ") self.color_combo.addItems(self.COL_OPTIONS) self.color_combo.setCurrentIndex(self.regression_colors) self.openContext(self.domain.class_var) # self.root_node = self.walkcreate(model.root, None) self.root_node = self.walkcreate(self.tree_adapter.root) self.infolabel.setText('{} nodes, {} leaves'.format( self.tree_adapter.num_nodes, len(self.tree_adapter.leaves(self.tree_adapter.root)))) self.setup_scene() self.Outputs.selected_data.send(None) self.Outputs.annotated_data.send(create_annotated_table(self.dataset, []))
def commit(self): """ Commit/send the current selection to the output. """ selected = indices = data = None if self.data is not None: selectedmask = np.full(len(self.data), False, dtype=bool) if self._silplot is not None: indices = self._silplot.selection() assert (np.diff(indices) > 0).all(), "strictly increasing" if self._mask is not None: # pylint: disable=invalid-unary-operand-type indices = np.flatnonzero(~self._mask)[indices] selectedmask[indices] = True if self._mask is not None: scores = np.full(shape=selectedmask.shape, fill_value=np.nan) # pylint: disable=invalid-unary-operand-type scores[~self._mask] = self._silhouette else: scores = self._silhouette var = self.cluster_var_model[self.cluster_var_idx] silhouette_var = Orange.data.ContinuousVariable( "Silhouette ({})".format(escape(var.name))) domain = Orange.data.Domain( self.data.domain.attributes, self.data.domain.class_vars, self.data.domain.metas + (silhouette_var, )) data = self.data.transform(domain) if np.count_nonzero(selectedmask): selected = self.data.from_table(domain, self.data, np.flatnonzero(selectedmask)) if selected is not None: selected[:, silhouette_var] = np.c_[scores[selectedmask]] data[:, silhouette_var] = np.c_[scores] self.Outputs.selected_data.send(selected) self.Outputs.annotated_data.send(create_annotated_table(data, indices))
def commit(self): selected = annotated = components = None graph = self.graph if self.plotdata.data is not None: name = self.data.name data = self.plotdata.data mask = self.plotdata.valid_mask.astype(int) mask[mask == 1] = graph.selection if graph.selection is not None \ else [False * len(mask)] selection = np.array( [], dtype=np.uint8) if mask is None else np.flatnonzero(mask) if len(selection): selected = data[selection] selected.name = name + ": selected" selected.attributes = self.data.attributes if graph.selection is not None and np.max(graph.selection) > 1: annotated = create_groups_table(data, mask) else: annotated = create_annotated_table(data, selection) annotated.attributes = self.data.attributes annotated.name = name + ": annotated" comp_domain = Domain(self.plotdata.points[:, 2], metas=[StringVariable(name='component')]) metas = np.array([["RX"], ["RY"], ["angle"]]) angle = np.arctan2( np.array(self.plotdata.points[:, 1].T, dtype=float), np.array(self.plotdata.points[:, 0].T, dtype=float)) components = Table.from_numpy(comp_domain, X=np.row_stack( (self.plotdata.points[:, :2].T, angle)), metas=metas) components.name = name + ": components" self.Outputs.selected_data.send(selected) self.Outputs.annotated_data.send(annotated) self.Outputs.components.send(components)
def commit(self): if self.data: # add Group column (group number) self.Outputs.selected_data.send( create_groups_table(self.image_grid.image_list, self.selection, False, "Group")) # filter out empty cells - keep only indices of cells that contain images # add Selected column (Yes/No if one group, else Unselected or group number) if self.selection is not None and np.max(self.selection) > 1: out_data = create_groups_table( self.image_grid.image_list[self.nonempty], self.selection[self.nonempty]) else: out_data = create_annotated_table( self.image_grid.image_list[self.nonempty], self.selection[self.nonempty]) self.Outputs.data.send(out_data) else: self.Outputs.data.send(None) self.Outputs.selected_data.send(None)
def commit(self): """Commit the selected data to output.""" if self.data is None: self.info.set_output_summary(self.info.NoOutput) self.Outputs.selected_data.send(None) self.Outputs.annotated_data.send(None) return nodes = [ i.tree_node.label for i in self.scene.selectedItems() if isinstance(i, SquareGraphicsItem) ] data = self.tree_adapter.get_instances_in_nodes(nodes) summary = len(data) if data else self.info.NoOutput details = format_summary_details(data) if data else "" self.info.set_output_summary(summary, details) self.Outputs.selected_data.send(data) selected_indices = self.tree_adapter.get_indices(nodes) self.Outputs.annotated_data.send( create_annotated_table(self.data, selected_indices) )
def commit(self): data_output = None self._save_selected(actual=True) selected_indices = [] data = self.data or self.classifier and self.classifier.instances if (self.selected is not None and data is not None and self.classifier is not None and data.domain.attributes == self.classifier.original_domain.attributes): status = np.ones(data.X.shape[0], dtype=bool) for i in self.selected: rule = self.classifier.rule_list[i] status &= rule.evaluate_data(data.X) selected_indices = status.nonzero()[0] data_output = data.from_table_rows(data, selected_indices) \ if len(selected_indices) else None self.Outputs.selected_data.send(data_output) self.Outputs.annotated_data.send( create_annotated_table(data, selected_indices))
def ctree(self, model=None): """Input signal handler""" self.clear_scene() self.color_combo.clear() self.closeContext() self.model = model if model is None: self.info.setText('No tree.') self.root_node = None self.dataset = None else: self.domain = model.domain self.dataset = model.instances if self.dataset is not None and self.dataset.domain != self.domain: self.clf_dataset = Table.from_table(model.domain, self.dataset) else: self.clf_dataset = self.dataset class_var = self.domain.class_var if class_var.is_discrete: self.scene.colors = [QColor(*col) for col in class_var.colors] self.color_label.setText("Target class: ") self.color_combo.addItem("None") self.color_combo.addItems(self.domain.class_vars[0].values) self.color_combo.setCurrentIndex(self.target_class_index) else: self.scene.colors = \ ContinuousPaletteGenerator(*model.domain.class_var.colors) self.color_label.setText("Color by: ") self.color_combo.addItems(self.COL_OPTIONS) self.color_combo.setCurrentIndex(self.regression_colors) self.openContext(self.domain.class_var) self.root_node = self.walkcreate(model.root, None) self.scene.addItem(self.root_node) self.info.setText('{} nodes, {} leaves'.format( model.node_count(), model.leaf_count())) self.setup_scene() self.send("Selected Data", None) self.send(ANNOTATED_DATA_SIGNAL_NAME, create_annotated_table(self.dataset, None))
def send_data(self): data, graph_sel = self.data, self.graph.get_selection() selected_data, ann_data = None, None if data: group_sel = np.zeros(len(data), dtype=int) if len(graph_sel): # we get selection by region ids so we have to map it to points for id, s in zip(self.region_ids, graph_sel): if s == 0: continue id_indices = np.where(self.data_ids == id)[0] group_sel[id_indices] = s else: graph_sel = [0] if np.sum(graph_sel) > 0: selected_data = create_groups_table(data, group_sel, False, "Group") if data is not None: if np.max(graph_sel) > 1: ann_data = create_groups_table(data, group_sel) else: ann_data = create_annotated_table(data, group_sel.astype(bool)) self.output_changed.emit(selected_data) self.Outputs.selected_data.send(selected_data) self.Outputs.annotated_data.send(ann_data) # Added by Jean 2020/06/20, output aggdata for future usage agg_data = self.agg_data # type: Optional[np.ndarray] region_ids = self.region_ids # type: Optional[np.ndarray] if agg_data is not None: agg_data = agg_data.reshape(agg_data.shape[0], 1) region_ids = region_ids.reshape(region_ids.shape[0], 1) agg_data = Table.from_numpy(None, agg_data, None, region_ids) self.Outputs.agg_data.send(agg_data)
def commit(self): datasubset = None featuresubset = None if not self._selection: pass elif isinstance(self.items, Orange.data.Table): indices = self._selection if self.matrix.axis == 1: datasubset = self.items.from_table_rows(self.items, indices) elif self.matrix.axis == 0: domain = Orange.data.Domain( [self.items.domain[i] for i in indices], self.items.domain.class_vars, self.items.domain.metas) datasubset = Orange.data.Table.from_table(domain, self.items) elif isinstance(self.items, widget.AttributeList): subset = [self.items[i] for i in self._selection] featuresubset = widget.AttributeList(subset) self.send("Selected Data", datasubset) self.send(ANNOTATED_DATA_SIGNAL_NAME, create_annotated_table(self.items, self._selection)) self.send("Features", featuresubset)
def commit(self): datasubset = None featuresubset = None if not self._selection: pass elif isinstance(self.items, Orange.data.Table): indices = self._selection if self.matrix.axis == 1: datasubset = self.items.from_table_rows(self.items, indices) elif self.matrix.axis == 0: domain = Orange.data.Domain( [self.items.domain[i] for i in indices], self.items.domain.class_vars, self.items.domain.metas) datasubset = self.items.transform(domain) elif isinstance(self.items, widget.AttributeList): subset = [self.items[i] for i in self._selection] featuresubset = widget.AttributeList(subset) self.Outputs.selected_data.send(datasubset) self.Outputs.annotated_data.send(create_annotated_table(self.items, self._selection)) self.Outputs.features.send(featuresubset)
def apply(self): data = self.data selected_data = annotated_data = histogram_data = None if self.is_valid: if self.var.is_discrete: group_indices, values = self._get_output_indices_disc() else: group_indices, values = self._get_output_indices_cont() hist_indices, hist_values = self._get_histogram_indices() histogram_data = create_groups_table(data, hist_indices, values=hist_values) selected = np.nonzero(group_indices)[0] if selected.size: selected_data = create_groups_table(data, group_indices, include_unselected=False, values=values) annotated_data = create_annotated_table(data, selected) self.Outputs.selected_data.send(selected_data) self.Outputs.annotated_data.send(annotated_data) self.Outputs.histogram_data.send(histogram_data)
def commit(self): data_output = None self._save_selected(actual=True) selected_indices = [] data = self.data or self.classifier and self.classifier.instances if (self.selected is not None and data is not None and self.classifier is not None and data.domain.attributes == self.classifier.original_domain.attributes): status = np.ones(data.X.shape[0], dtype=bool) for i in self.selected: rule = self.classifier.rule_list[i] status &= rule.evaluate_data(data.X) selected_indices = status.nonzero()[0] data_output = data.from_table_rows(data, selected_indices) \ if len(selected_indices) else None self.Outputs.selected_data.send(data_output) self.Outputs.annotated_data.send(create_annotated_table(data, selected_indices))
def commit(self): """ Commit/send the current selection to the output. """ selected = indices = data = None if self.data is not None: selectedmask = numpy.full(len(self.data), False, dtype=bool) if self._silplot is not None: indices = self._silplot.selection() selectedmask[indices] = True scores = self._silhouette silhouette_var = None if self.add_scores: var = self.cluster_var_model[self.cluster_var_idx] silhouette_var = Orange.data.ContinuousVariable( "Silhouette ({})".format(escape(var.name))) domain = Orange.data.Domain( self.data.domain.attributes, self.data.domain.class_vars, self.data.domain.metas + (silhouette_var, )) data = self.data.from_table(domain, self.data) else: domain = self.data.domain data = self.data if numpy.count_nonzero(selectedmask): selected = self.data.from_table( domain, self.data, numpy.flatnonzero(selectedmask)) if self.add_scores: if selected is not None: selected[:, silhouette_var] = numpy.c_[scores[selectedmask]] data[:, silhouette_var] = numpy.c_[scores] self.send("Selected Data", selected) self.send(ANNOTATED_DATA_SIGNAL_NAME, create_annotated_table(data, indices))
def commit(self): if self.embedding is not None: names = get_unique_names( [v.name for v in self.data.domain.variables], ["mds-x", "mds-y"]) output = embedding = Orange.data.Table.from_numpy( Orange.data.Domain([ ContinuousVariable(names[0]), ContinuousVariable(names[1]) ]), self.embedding, ) else: output = embedding = None if self.embedding is not None and self.data is not None: domain = self.data.domain domain = Orange.data.Domain( domain.attributes, domain.class_vars, domain.metas + embedding.domain.attributes, ) output = self.data.transform(domain) output.metas[:, -2:] = embedding.X selection = self.graph.get_selection() if output is not None and len(selection) > 0: selected = output[selection] else: selected = None if self.graph.selection is not None and np.max( self.graph.selection) > 1: annotated = create_groups_table(output, self.graph.selection) else: annotated = create_annotated_table(output, selection) self.Outputs.selected_data.send(selected) self.Outputs.annotated_data.send(annotated)
def send_data(self): selected = None selection = None # TODO: Implement selection for sql data graph = self.graph if isinstance(self.data, SqlTable): selected = self.data elif self.data is not None: selection = graph.get_selection() if len(selection) > 0: selected = self.data[selection] if graph.selection is not None and np.max(graph.selection) > 1: annotated = create_groups_table(self.data, graph.selection) else: annotated = create_annotated_table(self.data, selection) self.Outputs.selected_data.send(selected) self.Outputs.annotated_data.send(annotated) # Store current selection in a setting that is stored in workflow if selection is not None and len(selection): self.selection_group = list( zip(selection, graph.selection[selection])) else: self.selection_group = None
def send_data(self): data, graph_sel = self.data, self.graph.get_selection() group_sel, selected_data, ann_data = None, None, None if data is not None and len(data) and self.region_ids is not None: # we get selection by region ids so we have to map it to points group_sel = np.zeros(len(data), dtype=int) for id, s in zip(self.region_ids, graph_sel): if s == 0: continue id_indices = np.where(self.data_ids == id)[0] group_sel[id_indices] = s if np.sum(graph_sel) > 0: selected_data = create_groups_table(data, group_sel, False, "Group") if data is not None: if np.max(graph_sel) > 1: ann_data = create_groups_table(data, group_sel) else: ann_data = create_annotated_table(data, group_sel.astype(bool)) self.output_changed.emit(selected_data) self.Outputs.selected_data.send(selected_data) self.Outputs.annotated_data.send(ann_data)
def _get_annotated_data(data, group_sel, graph_sel): if graph_sel is not None and np.max(graph_sel) > 1: return create_groups_table(data, group_sel) else: return create_annotated_table(data, np.nonzero(group_sel)[0])
def test_create_annotated_table_none_data(self): self.assertIsNone(create_annotated_table(None, None))
def _get_annotated(): if graph.selection is not None and np.max(graph.selection) > 1: return create_groups_table(data, graph.selection) else: return create_annotated_table(data, selection)
def _get_annotated_data(data, selection, group_sel, graph_sel): if graph_sel is not None and np.max(graph_sel) > 1: return create_groups_table(data, group_sel) else: return create_annotated_table(data, selection)
def set_tree(self, model=None): """When a different tree is given.""" self.clear() self.model = model if model is not None: # We need to know what kind of tree we have in order to properly # show colors and tooltips if model.domain.class_var.is_discrete: self.tree_type = self.CLASSIFICATION elif model.domain.class_var.is_continuous: self.tree_type = self.REGRESSION else: self.tree_type = self.GENERAL self.instances = model.instances # this bit is important for the regression classifier if self.instances is not None and \ self.instances.domain != model.domain: self.clf_dataset = Table.from_table(self.model.domain, self.instances) else: self.clf_dataset = self.instances self.tree_adapter = self._get_tree_adapter(self.model) self.color_palette = self._tree_specific('_get_color_palette')() self.ptree.clear() self.ptree.set_tree(self.tree_adapter) self.ptree.set_tooltip_func(self._tree_specific('_get_tooltip')) self.ptree.set_node_color_func( self._tree_specific('_get_node_color')) self._tree_specific('_update_legend_colors')() self._update_legend_visibility() self._update_info_box() self._update_depth_slider() self._tree_specific('_update_target_class_combo')() self._update_main_area() # Get meta variables describing pythagoras tree if given from # forest. if hasattr(model, 'meta_size_calc_idx'): self.size_calc_idx = model.meta_size_calc_idx if hasattr(model, 'meta_size_log_scale'): self.size_log_scale = model.meta_size_log_scale # Updating the size calc redraws the whole tree if hasattr(model, 'meta_size_calc_idx') or \ hasattr(model, 'meta_size_log_scale'): self.update_size_calc() # The target class can also be passed from the meta properties if hasattr(model, 'meta_target_class_index'): self.target_class_index = model.meta_target_class_index self.update_colors() # TODO this messes up the viewport in pythagoras tree viewer # it seems the viewport doesn't reset its size if this is applied # if hasattr(model, 'meta_depth_limit'): # self.depth_limit = model.meta_depth_limit # self.update_depth() self.send(ANNOTATED_DATA_SIGNAL_NAME, create_annotated_table(self.instances, None))
def commit(self): self.Outputs.selected_data.send(self.selection) self.Outputs.annotated_data.send( create_annotated_table(self.data, self._indices))
def commit(self): selected = self.data[self.selection] \ if self.data is not None and len(self.selection) > 0 else None annotated = create_annotated_table(self.data, self.selection) self.Outputs.selected_data.send(selected) self.Outputs.annotated_data.send(annotated)
def commit(self): self.send('Selected Data', self.selection) self.send(ANNOTATED_DATA_SIGNAL_NAME, create_annotated_table(self.data, self._indices))
def commit(self): """Output data instances corresponding to selected cells""" if self.results is not None and self.data is not None \ and self.selected_learner: indices = self.tableview.selectedIndexes() indices = {(ind.row() - 2, ind.column() - 2) for ind in indices} actual = self.results.actual learner_name = self.learners[self.selected_learner[0]] predicted = self.results.predicted[self.selected_learner[0]] selected = [i for i, t in enumerate(zip(actual, predicted)) if t in indices] extra = [] class_var = self.data.domain.class_var metas = self.data.domain.metas if self.append_predictions: extra.append(predicted.reshape(-1, 1)) var = Orange.data.DiscreteVariable( "{}({})".format(class_var.name, learner_name), class_var.values ) metas = metas + (var,) if self.append_probabilities and \ self.results.probabilities is not None: probs = self.results.probabilities[self.selected_learner[0]] extra.append(numpy.array(probs, dtype=object)) pvars = [Orange.data.ContinuousVariable("p({})".format(value)) for value in class_var.values] metas = metas + tuple(pvars) X = self.data.X Y = self.data.Y M = self.data.metas row_ids = self.data.ids M = numpy.hstack((M,) + tuple(extra)) domain = Orange.data.Domain( self.data.domain.attributes, self.data.domain.class_vars, metas ) data = Orange.data.Table.from_numpy(domain, X, Y, M) data.ids = row_ids data.name = learner_name data.attributes = self.data.attributes if selected: annotated_data = create_annotated_table(data, selected) data = data[selected] else: annotated_data = create_annotated_table(data, []) data = None else: data = None annotated_data = None self.send("Selected Data", data) self.send(ANNOTATED_DATA_SIGNAL_NAME, annotated_data)
def commit(self): matching_output = self.data non_matching_output = None annotated_output = None self.Error.clear() if self.data: domain = self.data.domain conditions = [] for attr_name, oper_idx, values in self.conditions: attr_index = domain.index(attr_name) attr = domain[attr_index] operators = self.Operators[type(attr)] opertype, _ = operators[oper_idx] if attr.is_continuous: try: floats = self._values_to_floats(attr, values) except ValueError as e: self.Error.parsing_error(e.args[0]) return if floats is None: continue filter = data_filter.FilterContinuous( attr_index, opertype, *floats) elif attr.is_string: filter = data_filter.FilterString( attr_index, opertype, *[str(v) for v in values]) else: if opertype == FilterDiscreteType.IsDefined: f_values = None else: if not values or not values[0]: continue values = [attr.values[i - 1] for i in values] if opertype == FilterDiscreteType.Equal: f_values = {values[0]} elif opertype == FilterDiscreteType.NotEqual: f_values = set(attr.values) f_values.remove(values[0]) elif opertype == FilterDiscreteType.In: f_values = set(values) else: raise ValueError("invalid operand") filter = data_filter.FilterDiscrete(attr_index, f_values) conditions.append(filter) if conditions: self.filters = data_filter.Values(conditions) matching_output = self.filters(self.data) self.filters.negate = True non_matching_output = self.filters(self.data) row_sel = np.in1d(self.data.ids, matching_output.ids) annotated_output = create_annotated_table(self.data, row_sel) # if hasattr(self.data, "name"): # matching_output.name = self.data.name # non_matching_output.name = self.data.name purge_attrs = self.purge_attributes purge_classes = self.purge_classes if (purge_attrs or purge_classes) and \ not isinstance(self.data, SqlTable): attr_flags = sum([ Remove.RemoveConstant * purge_attrs, Remove.RemoveUnusedValues * purge_attrs ]) class_flags = sum([ Remove.RemoveConstant * purge_classes, Remove.RemoveUnusedValues * purge_classes ]) # same settings used for attributes and meta features remover = Remove(attr_flags, class_flags, attr_flags) matching_output = remover(matching_output) non_matching_output = remover(non_matching_output) annotated_output = remover(annotated_output) if matching_output is not None and not len(matching_output): matching_output = None if non_matching_output is not None and not len(non_matching_output): non_matching_output = None if annotated_output is not None and not len(annotated_output): annotated_output = None self.Outputs.matching_data.send(matching_output) self.Outputs.unmatched_data.send(non_matching_output) self.Outputs.annotated_data.send(annotated_output) self.match_desc = report.describe_data_brief(matching_output) self.nonmatch_desc = report.describe_data_brief(non_matching_output) self.update_info(matching_output, self.data_out_rows, "Out: ")
def test_create_annotated_table_none_indices(self): annotated = create_annotated_table(self.zoo, None) self.assertEqual(len(annotated), len(self.zoo)) self.assertEqual( 0, np.sum([i[ANNOTATED_DATA_FEATURE_NAME] for i in annotated]))
def commit(self): """ Commit/send the current selected row/column selection. """ selected_data = table = rowsel = None view = self.tabs.currentWidget() if view and view.model() is not None: model = self._get_model(view) table = model.source # The input data table # Selections of individual instances are not implemented # for SqlTables if isinstance(table, SqlTable): self.Outputs.selected_data.send(selected_data) self.Outputs.annotated_data.send(None) return rowsel, colsel = self.get_selection(view) self.selected_rows, self.selected_cols = rowsel, colsel def select(data, rows, domain): """ Select the data subset with specified rows and domain subsets. If either rows or domain is None they mean select all. """ if rows is not None and domain is not None: return data.from_table(domain, data, rows) elif rows is not None: return data.from_table(data.domain, rows) elif domain is not None: return data.from_table(domain, data) else: return data domain = table.domain if len(colsel) < len(domain) + len(domain.metas): # only a subset of the columns is selected allvars = domain.class_vars + domain.metas + domain.attributes columns = [(c, model.headerData(c, Qt.Horizontal, TableModel.DomainRole)) for c in colsel] assert all(role is not None for _, role in columns) def select_vars(role): """select variables for role (TableModel.DomainRole)""" return [allvars[c] for c, r in columns if r == role] attrs = select_vars(TableModel.Attribute) if attrs and issparse(table.X): # for sparse data you can only select all attributes attrs = table.domain.attributes class_vars = select_vars(TableModel.ClassVar) metas = select_vars(TableModel.Meta) domain = Orange.data.Domain(attrs, class_vars, metas) # Avoid a copy if all/none rows are selected. if not rowsel: selected_data = None elif len(rowsel) == len(table): selected_data = select(table, None, domain) else: selected_data = select(table, rowsel, domain) self.Outputs.selected_data.send(selected_data) self.Outputs.annotated_data.send(create_annotated_table(table, rowsel))
def commit(self): items = getattr(self.matrix, "items", self.items) if not items: self.Outputs.selected_data.send(None) self.Outputs.annotated_data.send(None) return selection = self.dendrogram.selected_nodes() selection = sorted(selection, key=lambda c: c.value.first) indices = [leaf.value.index for leaf in leaves(self.root)] maps = [ indices[node.value.first:node.value.last] for node in selection ] selected_indices = list(chain(*maps)) unselected_indices = sorted( set(range(self.root.value.last)) - set(selected_indices)) if not selected_indices: self.Outputs.selected_data.send(None) annotated_data = create_annotated_table(items, []) \ if self.selection_method == 0 and self.matrix.axis else None self.Outputs.annotated_data.send(annotated_data) return selected_data = None if isinstance(items, Orange.data.Table) and self.matrix.axis == 1: # Select rows c = np.zeros(self.matrix.shape[0]) for i, indices in enumerate(maps): c[indices] = i c[unselected_indices] = len(maps) mask = c != len(maps) data, domain = items, items.domain attrs = domain.attributes classes = domain.class_vars metas = domain.metas var_name = get_unique_names(domain, "Cluster") values = [f"C{i + 1}" for i in range(len(maps))] clust_var = Orange.data.DiscreteVariable(var_name, values=values + ["Other"]) domain = Orange.data.Domain(attrs, classes, metas + (clust_var, )) data = items.transform(domain) with data.unlocked(data.metas): data.get_column_view(clust_var)[0][:] = c if selected_indices: selected_data = data[mask] clust_var = Orange.data.DiscreteVariable(var_name, values=values) selected_data.domain = Domain(attrs, classes, metas + (clust_var, )) annotated_data = create_annotated_table(data, selected_indices) elif isinstance(items, Orange.data.Table) and self.matrix.axis == 0: # Select columns attrs = [] for clust, indices in chain(enumerate(maps, start=1), [(0, unselected_indices)]): for i in indices: attr = items.domain[i].copy() attr.attributes["cluster"] = clust attrs.append(attr) domain = Orange.data.Domain( # len(unselected_indices) can be 0 attrs[:len(attrs) - len(unselected_indices)], items.domain.class_vars, items.domain.metas) selected_data = items.from_table(domain, items) domain = Orange.data.Domain(attrs, items.domain.class_vars, items.domain.metas) annotated_data = items.from_table(domain, items) self.Outputs.selected_data.send(selected_data) self.Outputs.annotated_data.send(annotated_data)