def setGeometry(self, rect): QStackedLayout.setGeometry(self, rect) for i in range(self.count()): w = self.widget(i) hint = w.sizeHint() geom = QRect(rect) size = clipMinMax(rect.size(), w.minimumSize(), w.maximumSize()) size = fixSizePolicy(size, hint, w.sizePolicy()) geom.setSize(size) if geom != w.geometry(): w.setGeometry(geom)
def addWidget(self, w): QStackedLayout.addWidget(self, w) rect = self.__rect hint = w.sizeHint() geom = QRect(rect) size = clipMinMax(rect.size(), w.minimumSize(), w.maximumSize()) size = fixSizePolicy(size, hint, w.sizePolicy()) geom.setSize(size) if geom != w.geometry(): w.setGeometry(geom)
def __init__(self, *args, **kwargs): super().__init__(*args) layout = QStackedLayout(self) self.double_spin = QDoubleSpinBox() self.double_spin.valueChanged.connect(self.double_value_changed) self.double_spin.editingFinished.connect(self.double_editing_finished) layout.addWidget(self.double_spin) self.int_spin = QSpinBox() self.int_spin.setMaximum(10 ** 4) self.int_spin.valueChanged.connect(self.int_value_changed) self.int_spin.editingFinished.connect(self.int_editing_finished) layout.addWidget(self.int_spin) self.setValue(kwargs.get('value', 0.))
def sizeHint(self): current = self.currentWidget() if current: hint = current.sizeHint() # Clip the hint with min/max sizes. hint = clipMinMax(hint, current.minimumSize(), current.maximumSize()) return hint else: return QStackedLayout.sizeHint(self)
def setGeometry(self, rect): if not isinstance(rect, QRect): raise TypeError("QRect required") if rect == self.__rect: return self.__rect = QRect(rect) QStackedLayout.setGeometry(self, rect) for i in range(self.count()): w = self.widget(i) hint = w.sizeHint() geom = QRect(rect) size = clipMinMax(rect.size(), w.minimumSize(), w.maximumSize()) size = fixSizePolicy(size, hint, w.sizePolicy()) geom.setSize(size) if geom != w.geometry(): w.setGeometry(geom)
def __init__(self, *args, **kwargs): super().__init__(*args) layout = QStackedLayout(self) self.double_spin = QDoubleSpinBox() self.double_spin.valueChanged.connect(self.double_value_changed) self.double_spin.editingFinished.connect(self.double_editing_finished) layout.addWidget(self.double_spin) self.int_spin = QSpinBox() self.int_spin.setMaximum(10**4) self.int_spin.valueChanged.connect(self.int_value_changed) self.int_spin.editingFinished.connect(self.int_editing_finished) layout.addWidget(self.int_spin) self.setValue(kwargs.get('value', 0.))
def maximumSize(self): current = self.currentWidget() if current: return current.maximumSize() else: return QStackedLayout.maximumSize(self)
def __init__(self, parent=None): self.__rect = QRect() QStackedLayout.__init__(self, parent) self.currentChanged.connect(self._onCurrentChanged)
def __init__(self): super().__init__() self.measure_scores = None self.update_scores = True self.usefulAttributes = [] self.learners = {} self.labels = [] self.out_domain_desc = None self.all_measures = SCORES self.selectedMeasures = dict([(m.name, True) for m in self.all_measures]) # Discrete (0) or continuous (1) class mode self.rankMode = 0 self.data = None self.discMeasures = [m for m in self.all_measures if issubclass(DiscreteVariable, m.score.class_type)] self.contMeasures = [m for m in self.all_measures if issubclass(ContinuousVariable, m.score.class_type)] self.score_checks = [] self.cls_scoring_box = gui.vBox(None, "Scoring for Classification") self.reg_scoring_box = gui.vBox(None, "Scoring for Regression") boxes = [self.cls_scoring_box] * 7 + [self.reg_scoring_box] * 2 for _score, var, box in zip(SCORES, self._score_vars, boxes): check = gui.checkBox( box, self, var, label=_score.name, callback=lambda val=_score: self.measuresSelectionChanged(val)) self.score_checks.append(check) self.score_stack = QStackedWidget(self) self.score_stack.addWidget(self.cls_scoring_box) self.score_stack.addWidget(self.reg_scoring_box) self.score_stack.addWidget(QWidget()) self.controlArea.layout().addWidget(self.score_stack) gui.rubber(self.controlArea) selMethBox = gui.vBox( self.controlArea, "Select Attributes", addSpace=True) grid = QGridLayout() grid.setContentsMargins(6, 0, 6, 0) self.selectButtons = QButtonGroup() self.selectButtons.buttonClicked[int].connect(self.setSelectMethod) def button(text, buttonid, toolTip=None): b = QRadioButton(text) self.selectButtons.addButton(b, buttonid) if toolTip is not None: b.setToolTip(toolTip) return b b1 = button(self.tr("None"), OWRank.SelectNone) b2 = button(self.tr("All"), OWRank.SelectAll) b3 = button(self.tr("Manual"), OWRank.SelectManual) b4 = button(self.tr("Best ranked:"), OWRank.SelectNBest) s = gui.spin(selMethBox, self, "nSelected", 1, 100, callback=self.nSelectedChanged) grid.addWidget(b1, 0, 0) grid.addWidget(b2, 1, 0) grid.addWidget(b3, 2, 0) grid.addWidget(b4, 3, 0) grid.addWidget(s, 3, 1) self.selectButtons.button(self.selectMethod).setChecked(True) selMethBox.layout().addLayout(grid) gui.auto_commit(selMethBox, self, "auto_apply", "Send", box=False) # Discrete, continuous and no_class table views are stacked self.ranksViewStack = QStackedLayout() self.mainArea.layout().addLayout(self.ranksViewStack) self.discRanksView = QTableView() self.ranksViewStack.addWidget(self.discRanksView) self.discRanksView.setSelectionBehavior(QTableView.SelectRows) self.discRanksView.setSelectionMode(QTableView.MultiSelection) self.discRanksView.setSortingEnabled(True) self.discRanksLabels = ["#"] + [m.shortname for m in self.discMeasures] self.discRanksModel = QStandardItemModel(self) self.discRanksModel.setHorizontalHeaderLabels(self.discRanksLabels) self.discRanksProxyModel = MySortProxyModel(self) self.discRanksProxyModel.setSourceModel(self.discRanksModel) self.discRanksView.setModel(self.discRanksProxyModel) self.discRanksView.setColumnWidth(0, 20) self.discRanksView.selectionModel().selectionChanged.connect( self.commit ) self.discRanksView.pressed.connect(self.onSelectItem) self.discRanksView.horizontalHeader().sectionClicked.connect( self.headerClick ) self.discRanksView.verticalHeader().sectionClicked.connect( self.onSelectItem ) if self.headerState[0] is not None: self.discRanksView.horizontalHeader().restoreState( self.headerState[0]) self.contRanksView = QTableView() self.ranksViewStack.addWidget(self.contRanksView) self.contRanksView.setSelectionBehavior(QTableView.SelectRows) self.contRanksView.setSelectionMode(QTableView.MultiSelection) self.contRanksView.setSortingEnabled(True) self.contRanksLabels = ["#"] + [m.shortname for m in self.contMeasures] self.contRanksModel = QStandardItemModel(self) self.contRanksModel.setHorizontalHeaderLabels(self.contRanksLabels) self.contRanksProxyModel = MySortProxyModel(self) self.contRanksProxyModel.setSourceModel(self.contRanksModel) self.contRanksView.setModel(self.contRanksProxyModel) self.contRanksView.setColumnWidth(0, 20) self.contRanksView.selectionModel().selectionChanged.connect( self.commit ) self.contRanksView.pressed.connect(self.onSelectItem) self.contRanksView.horizontalHeader().sectionClicked.connect( self.headerClick ) self.contRanksView.verticalHeader().sectionClicked.connect( self.onSelectItem ) if self.headerState[1] is not None: self.contRanksView.horizontalHeader().restoreState( self.headerState[1]) self.noClassRanksView = QTableView() self.ranksViewStack.addWidget(self.noClassRanksView) self.noClassRanksView.setSelectionBehavior(QTableView.SelectRows) self.noClassRanksView.setSelectionMode(QTableView.MultiSelection) self.noClassRanksView.setSortingEnabled(True) self.noClassRanksLabels = ["#"] self.noClassRanksModel = QStandardItemModel(self) self.noClassRanksModel.setHorizontalHeaderLabels(self.noClassRanksLabels) self.noClassRanksProxyModel = MySortProxyModel(self) self.noClassRanksProxyModel.setSourceModel(self.noClassRanksModel) self.noClassRanksView.setModel(self.noClassRanksProxyModel) self.noClassRanksView.setColumnWidth(0, 20) self.noClassRanksView.selectionModel().selectionChanged.connect( self.commit ) self.noClassRanksView.pressed.connect(self.onSelectItem) self.noClassRanksView.horizontalHeader().sectionClicked.connect( self.headerClick ) self.noClassRanksView.verticalHeader().sectionClicked.connect( self.onSelectItem ) if self.headerState[2] is not None: self.noClassRanksView.horizontalHeader().restoreState( self.headerState[2]) # Switch the current view to Discrete self.switchRanksMode(0) self.resetInternals() self.updateDelegates() self.updateVisibleScoreColumns() self.resize(690, 500) self.measure_scores = table((len(self.measures), 0), None)
class OWRank(OWWidget): name = "Rank" description = "Rank and filter data features by their relevance." icon = "icons/Rank.svg" priority = 1102 buttons_area_orientation = Qt.Vertical inputs = [("Data", Table, "setData"), ("Scorer", score.Scorer, "set_learner", widget.Multiple)] outputs = [("Reduced Data", Table, widget.Default), ("Scores", Table)] SelectNone, SelectAll, SelectManual, SelectNBest = range(4) cls_default_selected = Setting({"Gain Ratio", "Gini Decrease"}) reg_default_selected = Setting({"Univariate Linear Regression", "RReliefF"}) selectMethod = Setting(SelectNBest) nSelected = Setting(5) auto_apply = Setting(True) # Header state for discrete/continuous/no_class scores headerState = Setting([None, None, None]) settings_version = 1 settingsHandler = DomainContextHandler() selected_rows = ContextSetting([]) gain = inf_gain = gini = anova = chi2 = ulr = relief = rrelief = fcbc = True _score_vars = ["gain", "inf_gain", "gini", "anova", "chi2", "relief", "fcbc", "ulr", "rrelief"] class Warning(OWWidget.Warning): no_target_var = Msg("Data does not have a target variable") class Error(OWWidget.Error): invalid_type = Msg("Cannot handle target variable type {}") inadequate_learner = Msg("{}") def __init__(self): super().__init__() self.measure_scores = None self.update_scores = True self.usefulAttributes = [] self.learners = {} self.labels = [] self.out_domain_desc = None self.all_measures = SCORES self.selectedMeasures = dict([(m.name, True) for m in self.all_measures]) # Discrete (0) or continuous (1) class mode self.rankMode = 0 self.data = None self.discMeasures = [m for m in self.all_measures if issubclass(DiscreteVariable, m.score.class_type)] self.contMeasures = [m for m in self.all_measures if issubclass(ContinuousVariable, m.score.class_type)] self.score_checks = [] self.cls_scoring_box = gui.vBox(None, "Scoring for Classification") self.reg_scoring_box = gui.vBox(None, "Scoring for Regression") boxes = [self.cls_scoring_box] * 7 + [self.reg_scoring_box] * 2 for _score, var, box in zip(SCORES, self._score_vars, boxes): check = gui.checkBox( box, self, var, label=_score.name, callback=lambda val=_score: self.measuresSelectionChanged(val)) self.score_checks.append(check) self.score_stack = QStackedWidget(self) self.score_stack.addWidget(self.cls_scoring_box) self.score_stack.addWidget(self.reg_scoring_box) self.score_stack.addWidget(QWidget()) self.controlArea.layout().addWidget(self.score_stack) gui.rubber(self.controlArea) selMethBox = gui.vBox( self.controlArea, "Select Attributes", addSpace=True) grid = QGridLayout() grid.setContentsMargins(6, 0, 6, 0) self.selectButtons = QButtonGroup() self.selectButtons.buttonClicked[int].connect(self.setSelectMethod) def button(text, buttonid, toolTip=None): b = QRadioButton(text) self.selectButtons.addButton(b, buttonid) if toolTip is not None: b.setToolTip(toolTip) return b b1 = button(self.tr("None"), OWRank.SelectNone) b2 = button(self.tr("All"), OWRank.SelectAll) b3 = button(self.tr("Manual"), OWRank.SelectManual) b4 = button(self.tr("Best ranked:"), OWRank.SelectNBest) s = gui.spin(selMethBox, self, "nSelected", 1, 100, callback=self.nSelectedChanged) grid.addWidget(b1, 0, 0) grid.addWidget(b2, 1, 0) grid.addWidget(b3, 2, 0) grid.addWidget(b4, 3, 0) grid.addWidget(s, 3, 1) self.selectButtons.button(self.selectMethod).setChecked(True) selMethBox.layout().addLayout(grid) gui.auto_commit(selMethBox, self, "auto_apply", "Send", box=False) # Discrete, continuous and no_class table views are stacked self.ranksViewStack = QStackedLayout() self.mainArea.layout().addLayout(self.ranksViewStack) self.discRanksView = QTableView() self.ranksViewStack.addWidget(self.discRanksView) self.discRanksView.setSelectionBehavior(QTableView.SelectRows) self.discRanksView.setSelectionMode(QTableView.MultiSelection) self.discRanksView.setSortingEnabled(True) self.discRanksLabels = ["#"] + [m.shortname for m in self.discMeasures] self.discRanksModel = QStandardItemModel(self) self.discRanksModel.setHorizontalHeaderLabels(self.discRanksLabels) self.discRanksProxyModel = MySortProxyModel(self) self.discRanksProxyModel.setSourceModel(self.discRanksModel) self.discRanksView.setModel(self.discRanksProxyModel) self.discRanksView.setColumnWidth(0, 20) self.discRanksView.selectionModel().selectionChanged.connect( self.commit ) self.discRanksView.pressed.connect(self.onSelectItem) self.discRanksView.horizontalHeader().sectionClicked.connect( self.headerClick ) self.discRanksView.verticalHeader().sectionClicked.connect( self.onSelectItem ) if self.headerState[0] is not None: self.discRanksView.horizontalHeader().restoreState( self.headerState[0]) self.contRanksView = QTableView() self.ranksViewStack.addWidget(self.contRanksView) self.contRanksView.setSelectionBehavior(QTableView.SelectRows) self.contRanksView.setSelectionMode(QTableView.MultiSelection) self.contRanksView.setSortingEnabled(True) self.contRanksLabels = ["#"] + [m.shortname for m in self.contMeasures] self.contRanksModel = QStandardItemModel(self) self.contRanksModel.setHorizontalHeaderLabels(self.contRanksLabels) self.contRanksProxyModel = MySortProxyModel(self) self.contRanksProxyModel.setSourceModel(self.contRanksModel) self.contRanksView.setModel(self.contRanksProxyModel) self.contRanksView.setColumnWidth(0, 20) self.contRanksView.selectionModel().selectionChanged.connect( self.commit ) self.contRanksView.pressed.connect(self.onSelectItem) self.contRanksView.horizontalHeader().sectionClicked.connect( self.headerClick ) self.contRanksView.verticalHeader().sectionClicked.connect( self.onSelectItem ) if self.headerState[1] is not None: self.contRanksView.horizontalHeader().restoreState( self.headerState[1]) self.noClassRanksView = QTableView() self.ranksViewStack.addWidget(self.noClassRanksView) self.noClassRanksView.setSelectionBehavior(QTableView.SelectRows) self.noClassRanksView.setSelectionMode(QTableView.MultiSelection) self.noClassRanksView.setSortingEnabled(True) self.noClassRanksLabels = ["#"] self.noClassRanksModel = QStandardItemModel(self) self.noClassRanksModel.setHorizontalHeaderLabels(self.noClassRanksLabels) self.noClassRanksProxyModel = MySortProxyModel(self) self.noClassRanksProxyModel.setSourceModel(self.noClassRanksModel) self.noClassRanksView.setModel(self.noClassRanksProxyModel) self.noClassRanksView.setColumnWidth(0, 20) self.noClassRanksView.selectionModel().selectionChanged.connect( self.commit ) self.noClassRanksView.pressed.connect(self.onSelectItem) self.noClassRanksView.horizontalHeader().sectionClicked.connect( self.headerClick ) self.noClassRanksView.verticalHeader().sectionClicked.connect( self.onSelectItem ) if self.headerState[2] is not None: self.noClassRanksView.horizontalHeader().restoreState( self.headerState[2]) # Switch the current view to Discrete self.switchRanksMode(0) self.resetInternals() self.updateDelegates() self.updateVisibleScoreColumns() self.resize(690, 500) self.measure_scores = table((len(self.measures), 0), None) def switchRanksMode(self, index): """ Switch between discrete/continuous/no_class mode """ self.rankMode = index self.ranksViewStack.setCurrentIndex(index) if index == 0: self.ranksView = self.discRanksView self.ranksModel = self.discRanksModel self.ranksProxyModel = self.discRanksProxyModel self.measures = self.discMeasures self.selected_checks = self.cls_default_selected self.reg_scoring_box.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) self.cls_scoring_box.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) elif index == 1: self.ranksView = self.contRanksView self.ranksModel = self.contRanksModel self.ranksProxyModel = self.contRanksProxyModel self.measures = self.contMeasures self.selected_checks = self.reg_default_selected self.cls_scoring_box.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) self.reg_scoring_box.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) else: self.ranksView = self.noClassRanksView self.ranksModel = self.noClassRanksModel self.ranksProxyModel = self.noClassRanksProxyModel self.measures = [] self.selected_checks = set() self.reg_scoring_box.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) self.cls_scoring_box.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) shape = (len(self.measures) + len(self.learners), 0) self.measure_scores = table(shape, None) self.update_scores = False for check, score in zip(self.score_checks, SCORES): check.setChecked(score.name in self.selected_checks) self.update_scores = True self.score_stack.setCurrentIndex(index) self.updateVisibleScoreColumns() @check_sql_input def setData(self, data): self.closeContext() self.clear_messages() self.resetInternals() self.data = data self.switchRanksMode(0) if self.data is not None: domain = self.data.domain attrs = domain.attributes self.usefulAttributes = [attr for attr in attrs if attr.is_discrete or attr.is_continuous] if domain.has_continuous_class: self.switchRanksMode(1) elif not domain.class_var: self.Warning.no_target_var() self.switchRanksMode(2) elif not domain.has_discrete_class: self.Error.invalid_type(type(domain.class_var).__name__) if issparse(self.data.X): # keep only measures supporting sparse data self.measures = [m for m in self.measures if m.score.supports_sparse_data] self.ranksModel.setRowCount(len(attrs)) for i, a in enumerate(attrs): if a.is_discrete: v = len(a.values) else: v = "C" item = ScoreValueItem() item.setData(v, Qt.DisplayRole) self.ranksModel.setItem(i, 0, item) item = QStandardItem(a.name) item.setData(gui.attributeIconDict[a], Qt.DecorationRole) self.ranksModel.setVerticalHeaderItem(i, item) shape = (len(self.measures) + len(self.learners), len(attrs)) self.measure_scores = table(shape, None) self.updateScores() else: self.send("Scores", None) self.selected_rows = [] self.openContext(data) self.selectMethodChanged() self.commit() def get_selection(self): selection = self.ranksView.selectionModel().selection() return list(set(ind.row() for ind in selection.indexes())) def set_learner(self, learner, lid=None): if learner is None and lid is not None: del self.learners[lid] elif learner is not None: self.learners[lid] = score_meta( learner.name, learner.name, learner ) attrs_len = 0 if not self.data else len(self.data.domain.attributes) shape = (len(self.learners), attrs_len) self.measure_scores = self.measure_scores[:len(self.measures)] self.measure_scores += table(shape, None) self.contRanksModel.setHorizontalHeaderLabels(self.contRanksLabels) self.discRanksModel.setHorizontalHeaderLabels(self.discRanksLabels) self.noClassRanksModel.setHorizontalHeaderLabels( self.noClassRanksLabels) measures_mask = [False] * len(self.measures) measures_mask += [True for _ in self.learners] self.updateScores(measures_mask) self.commit() def updateScores(self, measuresMask=None): """ Update the current computed scores. If `measuresMask` is given it must be an list of bool values indicating what measures should be recomputed. """ if not self.data: return if self.data.has_missing(): self.information("Missing values have been imputed.") measures = self.measures + [v for k, v in self.learners.items()] if measuresMask is None: # Update all selected measures measuresMask = [self.selectedMeasures.get(m.name) for m in self.measures] measuresMask = measuresMask + [v.name for k, v in self.learners.items()] data = self.data learner_col = len(self.measures) if len(measuresMask) <= len(self.measures) or \ measuresMask[len(self.measures)]: self.labels = [] self.Error.inadequate_learner.clear() self.setStatusMessage("Running") with self.progressBar(): n_measure_update = len([x for x in measuresMask if x is not False]) count = 0 for index, (meas, mask) in enumerate(zip(measures, measuresMask)): if not mask: continue self.progressBarSet(90 * count / n_measure_update) count += 1 if index < len(self.measures): estimator = meas.score() try: self.measure_scores[index] = estimator(data) except ValueError: self.measure_scores[index] = [] for attr in data.domain.attributes: try: self.measure_scores[index].append( estimator(data, attr)) except ValueError: self.measure_scores[index].append(None) else: learner = meas.score if isinstance(learner, Learner) and \ not learner.check_learner_adequacy(self.data.domain): self.Error.inadequate_learner( learner.learner_adequacy_err_msg) scores = table((1, len(data.domain.attributes))) else: scores = meas.score.score_data(data) for i, row in enumerate(scores): self.labels.append(meas.shortname + str(i + 1)) if len(self.measure_scores) > learner_col: self.measure_scores[learner_col] = row else: self.measure_scores.append(row) learner_col += 1 self.progressBarSet(90) self.contRanksModel.setHorizontalHeaderLabels( self.contRanksLabels + self.labels ) self.discRanksModel.setHorizontalHeaderLabels( self.discRanksLabels + self.labels ) self.noClassRanksModel.setHorizontalHeaderLabels( self.noClassRanksLabels + self.labels ) self.updateRankModel(measuresMask) self.ranksProxyModel.invalidate() self.selectMethodChanged() self.send("Scores", self.create_scores_table(self.labels)) self.setStatusMessage("") def updateRankModel(self, measuresMask): """ Update the rankModel. """ values = [] diff = len(self.measure_scores) - len(measuresMask) if len(measuresMask): measuresMask += [measuresMask[-1]] * diff for i in range(self.ranksModel.columnCount() - 1, len(self.measure_scores), -1): self.ranksModel.removeColumn(i) for i, (scores, m) in enumerate(zip(self.measure_scores, measuresMask)): if not m and self.ranksModel.item(0, i + 1): values.append([]) continue values_one = [] for j, _score in enumerate(scores): values_one.append(_score) item = self.ranksModel.item(j, i + 1) if not item: item = ScoreValueItem() self.ranksModel.setItem(j, i + 1, item) item.setData(_score, Qt.DisplayRole) values.append(values_one) for i, (vals, m) in enumerate(zip(values, measuresMask)): if not m: continue valid_vals = [v for v in vals if v is not None] if valid_vals: vmin, vmax = min(valid_vals), max(valid_vals) for j, v in enumerate(vals): if v is not None: # Set the bar ratio role for i-th measure. ratio = float((v - vmin) / ((vmax - vmin) or 1)) item = self.ranksModel.item(j, i + 1) item.setData(ratio, gui.BarRatioRole) self.ranksView.setColumnWidth(0, 20) self.ranksView.resizeRowsToContents() def resetInternals(self): self.data = None self.usefulAttributes = [] self.ranksModel.setRowCount(0) def onSelectItem(self, index): """ Called when the user selects/unselects an item in the table view. """ self.selectMethod = OWRank.SelectManual # Manual self.selectButtons.button(self.selectMethod).setChecked(True) self.commit() def setSelectMethod(self, method): if self.selectMethod != method: self.selectMethod = method self.selectButtons.button(method).setChecked(True) self.selectMethodChanged() def selectMethodChanged(self): self.autoSelection() self.ranksView.setFocus() def nSelectedChanged(self): self.selectMethod = OWRank.SelectNBest self.selectButtons.button(self.selectMethod).setChecked(True) self.selectMethodChanged() def autoSelection(self): selModel = self.ranksView.selectionModel() rowCount = self.ranksModel.rowCount() columnCount = self.ranksModel.columnCount() model = self.ranksProxyModel if self.selectMethod == OWRank.SelectNone: selection = QItemSelection() elif self.selectMethod == OWRank.SelectAll: selection = QItemSelection( model.index(0, 0), model.index(rowCount - 1, columnCount - 1) ) elif self.selectMethod == OWRank.SelectNBest: nSelected = min(self.nSelected, rowCount) selection = QItemSelection( model.index(0, 0), model.index(nSelected - 1, columnCount - 1) ) else: selection = QItemSelection() if len(self.selected_rows): selection = QItemSelection() for row in self.selected_rows: selection.append(QItemSelectionRange( model.index(row, 0), model.index(row, columnCount - 1))) selModel.select(selection, QItemSelectionModel.ClearAndSelect) def headerClick(self, index): if index >= 1 and self.selectMethod == OWRank.SelectNBest: # Reselect the top ranked attributes self.autoSelection() # Store the header states disc = bytes(self.discRanksView.horizontalHeader().saveState()) cont = bytes(self.contRanksView.horizontalHeader().saveState()) no_class = bytes(self.noClassRanksView.horizontalHeader().saveState()) self.headerState = [disc, cont, no_class] def measuresSelectionChanged(self, measure): """Measure selection has changed. Update column visibility. """ checked = self.selectedMeasures[measure.name] self.selectedMeasures[measure.name] = not checked if not checked: self.selected_checks.add(measure.name) elif measure.name in self.selected_checks: self.selected_checks.remove(measure.name) measures_mask = [False] * len(self.measures) measures_mask += [False for _ in self.learners] # Update scores for shown column if they are not yet computed. if measure in self.measures and self.measure_scores: index = self.measures.index(measure) if all(s is None for s in self.measure_scores[index]): measures_mask[index] = True if self.update_scores: self.updateScores(measures_mask) self.updateVisibleScoreColumns() def updateVisibleScoreColumns(self): """ Update the visible columns of the scores view. """ for i, measure in enumerate(self.measures): shown = self.selectedMeasures.get(measure.name) self.ranksView.setColumnHidden(i + 1, not shown) self.ranksView.setColumnWidth(i + 1, 100) index = self.ranksView.horizontalHeader().sortIndicatorSection() if self.ranksView.isColumnHidden(index): self.headerState[self.rankMode] = None if self.headerState[self.rankMode] is None: def get_sort_by_col(measures, selected_measures): cols = [i + 1 for i, m in enumerate(measures) if m.name in selected_measures] return cols[0] if cols else len(measures) + 1 col = get_sort_by_col(self.measures, self.selected_checks) self.ranksView.sortByColumn(col, Qt.DescendingOrder) self.autoSelection() def updateDelegates(self): self.contRanksView.setItemDelegate(gui.ColoredBarItemDelegate(self)) self.discRanksView.setItemDelegate(gui.ColoredBarItemDelegate(self)) self.noClassRanksView.setItemDelegate(gui.ColoredBarItemDelegate(self)) def send_report(self): if not self.data: return self.report_domain("Input", self.data.domain) self.report_table("Ranks", self.ranksView, num_format="{:.3f}") if self.out_domain_desc is not None: self.report_items("Output", self.out_domain_desc) def commit(self): self.selected_rows = self.get_selection() if self.data and len(self.data.domain.attributes) == len( self.selected_rows): self.selectMethod = OWRank.SelectAll self.selectButtons.button(self.selectMethod).setChecked(True) selected = self.selectedAttrs() if not self.data or not selected: self.send("Reduced Data", None) self.out_domain_desc = None else: data = Table(Domain(selected, self.data.domain.class_var, self.data.domain.metas), self.data) self.send("Reduced Data", data) self.out_domain_desc = report.describe_domain(data.domain) def selectedAttrs(self): if self.data: inds = self.ranksView.selectionModel().selectedRows(0) source = self.ranksProxyModel.mapToSource inds = map(source, inds) inds = [ind.row() for ind in inds] return [self.data.domain.attributes[i] for i in inds] else: return [] def create_scores_table(self, labels): indices = [i for i, m in enumerate(self.measures) if self.selectedMeasures.get(m.name, False)] measures = [s.name for s in self.measures if self.selectedMeasures.get(s.name, False)] measures += [label for label in labels] if not measures: return None features = [ContinuousVariable(s) for s in measures] metas = [StringVariable("Feature name")] domain = Domain(features, metas=metas) scores = np.array([row for i, row in enumerate(self.measure_scores) if i in indices or i >= len(self.measures)]).T feature_names = np.array([a.name for a in self.data.domain.attributes]) # Reshape to 2d array as Table does not like 1d arrays feature_names = feature_names[:, None] new_table = Table(domain, scores, metas=feature_names) new_table.name = "Feature Scores" return new_table @classmethod def migrate_settings(cls, settings, version): if not version: # Before fc5caa1e1d716607f1f5c4e0b0be265c23280fa0 # headerState had length 2 headerState = settings.get("headerState", None) if headerState is not None and \ isinstance(headerState, tuple) and \ len(headerState) < 3: headerState = (list(headerState) + [None] * 3)[:3] settings["headerState"] = headerState
def __init__(self, parent=None): super().__init__(parent) self.selectedDatabase = 0 self.uniqueRows = True gui.button(gui.widgetBox(self.controlArea, "Cache", addSpace=True), self, "Clear cache", tooltip="Clear saved query results", callback=self.clearCache) self.serviceindex = 0 self.serviceCombo = gui.comboBox( self.controlArea, self, "serviceindex", "Mart Service", callback=self._setServiceUrl ) for name, url in MartServices: self.serviceCombo.addItem(name, userData=url) idx = self.serviceCombo.findData(self.selectedService, Qt.UserRole) self.serviceCombo.setCurrentIndex(idx) # self.selectedService = self.serviceCombo.itemData(self.serviceCombo.currentItem()) self.martsCombo = gui.comboBox( self.controlArea, self, "selectedDatabase", "Database", callback=self.setSelectedMart, addSpace=True) self.martsCombo.setMaximumWidth(250) self.datasetsCombo = gui.comboBox( self.controlArea, self, "selectedDataset", "Dataset", callback=self.setSelectedDataset, addSpace=True) self.datasetsCombo.setMaximumWidth(250) gui.rubber(self.controlArea) box = gui.widgetBox(self.controlArea, "Results") gui.checkBox( box, self, "uniqueRows", "Unique results only", tooltip="Return unique results only.",) self.commitButton = gui.button( box, self, "Get Results", callback=self.commit, tooltip="Query the BioMart server and output the results", autoDefault=True) self.commitButton.setEnabled(False) self.mainWidget = gui.widgetBox( self.mainArea, orientation=QStackedLayout()) self.mainTab = QTabWidget() self.mainWidget.layout().addWidget(self.mainTab) self.attributesConfigurationBox = gui.createTabPage(self.mainTab, "Attributes") if self.SHOW_FILTERS: # ?? self.filtersConfigurationBox = gui.createTabPage(self.mainTab, "Filters") self.error(0) self.setEnabled(False) self._task = None self._executor = concurrent.ThreadExecutor( threadPool=QThreadPool(maxThreadCount=2) ) service = self.selectedService self._task = task = concurrent.Task( function=partial(self._get_registry, url=service)) task.resultReady.connect(self.setBioMartRegistry) task.exceptionReady.connect(self._handleException) self._executor.submit(task) self._setServiceUrl() self._afterInitQueue = [] try: from Bio import SeqIO self.hasBiopython = True except ImportError: self.warning(100, "Biopython package not found.\nTo retrieve FASTA sequence data from BioMart install Biopython.") self.hasBiopython = False
def __init__(self): super().__init__() main_layout = QVBoxLayout() main_layout.setContentsMargins(10, 10, 10, 10) self.controlArea.layout().addLayout(main_layout) box = QGroupBox(title=self.tr("Default Method"), flat=False) box_layout = QVBoxLayout(box) main_layout.addWidget(box) button_group = QButtonGroup() button_group.buttonClicked[int].connect(self.set_default_method) for i, method in enumerate(self.METHODS): if not method.columns_only: button = QRadioButton(method.name) button.setChecked(i == self.default_method_index) button_group.addButton(button, i) box_layout.addWidget(button) self.default_button_group = button_group box = QGroupBox(title=self.tr("Individual Attribute Settings"), flat=False) main_layout.addWidget(box) horizontal_layout = QHBoxLayout(box) main_layout.addWidget(box) self.varview = QListView(selectionMode=QListView.ExtendedSelection) self.varview.setItemDelegate(DisplayFormatDelegate()) self.varmodel = itemmodels.VariableListModel() self.varview.setModel(self.varmodel) self.varview.selectionModel().selectionChanged.connect( self._on_var_selection_changed) self.selection = self.varview.selectionModel() horizontal_layout.addWidget(self.varview) method_layout = QVBoxLayout() horizontal_layout.addLayout(method_layout) button_group = QButtonGroup() for i, method in enumerate(self.METHODS): button = QRadioButton(text=method.name) button_group.addButton(button, i) method_layout.addWidget(button) self.value_combo = QComboBox( minimumContentsLength=8, sizeAdjustPolicy=QComboBox.AdjustToMinimumContentsLength, activated=self._on_value_selected) self.value_combo.currentIndexChanged.connect(self._on_value_changed) self.value_double = QDoubleSpinBox( editingFinished=self._on_value_selected, minimum=-1000., maximum=1000., singleStep=.1, decimals=3, value=self.default_value) self.value_stack = value_stack = QStackedLayout() value_stack.addWidget(self.value_combo) value_stack.addWidget(self.value_double) method_layout.addLayout(value_stack) button_group.buttonClicked[int].connect( self.set_method_for_current_selection) method_layout.addStretch(2) reset_button = QPushButton("Restore All to Default", checked=False, checkable=False, clicked=self.reset_variable_methods, default=False, autoDefault=False) method_layout.addWidget(reset_button) self.variable_button_group = button_group box = gui.auto_commit(self.controlArea, self, "autocommit", "Apply", orientation=Qt.Horizontal, checkbox_label="Apply automatically") box.layout().insertSpacing(0, 80) box.layout().insertWidget(0, self.report_button) self.data = None self.modified = False self.default_method = self.METHODS[self.default_method_index] self.update_varview()