def __init__(self): super().__init__() self.data = None self.distributions = None self.contingencies = None self.var = self.cvar = None varbox = gui.widgetBox(self.controlArea, "Variable") self.varmodel = itemmodels.VariableListModel() self.groupvarmodel = [] self.varview = QtGui.QListView( selectionMode=QtGui.QListView.SingleSelection) self.varview.setSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) self.varview.setModel(self.varmodel) self.varview.setSelectionModel( itemmodels.ListSingleSelectionModel(self.varmodel)) self.varview.selectionModel().selectionChanged.connect( self._on_variable_idx_changed) varbox.layout().addWidget(self.varview) box = gui.widgetBox(self.controlArea, "Precision") gui.separator(self.controlArea, 4, 4) box2 = gui.widgetBox(box, orientation="horizontal") self.l_smoothing_l = gui.widgetLabel(box2, "Smooth") gui.hSlider(box2, self, "smoothing_index", minValue=0, maxValue=len(self.smoothing_facs) - 1, callback=self._on_set_smoothing, createLabel=False) self.l_smoothing_r = gui.widgetLabel(box2, "Precise") self.cb_disc_cont = gui.checkBox( gui.indentedBox(box, sep=4), self, "disc_cont", "Bin continuous variables", callback=self._on_groupvar_idx_changed, tooltip="Show continuous variables as discrete.") box = gui.widgetBox(self.controlArea, "Group by") self.icons = gui.attributeIconDict self.groupvarview = gui.comboBox( box, self, "groupvar_idx", callback=self._on_groupvar_idx_changed, valueType=str, contentsLength=12) box2 = gui.indentedBox(box, sep=4) self.cb_rel_freq = gui.checkBox( box2, self, "relative_freq", "Show relative frequencies", callback=self._on_relative_freq_changed, tooltip= "Normalize probabilities so that probabilities for each group-by value sum to 1." ) gui.separator(box2) self.cb_prob = gui.comboBox( box2, self, "show_prob", label="Show probabilities", orientation="horizontal", callback=self._on_relative_freq_changed, tooltip= "Show probabilities for a chosen group-by value (at each point probabilities for all group-by values sum to 1)." ) self.plotview = pg.PlotWidget(background=None) self.plotview.setRenderHint(QtGui.QPainter.Antialiasing) self.mainArea.layout().addWidget(self.plotview) w = QtGui.QLabel() w.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed) self.mainArea.layout().addWidget(w, Qt.AlignCenter) self.ploti = pg.PlotItem() self.plot = self.ploti.vb self.ploti.hideButtons() self.plotview.setCentralItem(self.ploti) self.plot_prob = pg.ViewBox() self.ploti.hideAxis('right') self.ploti.scene().addItem(self.plot_prob) self.ploti.getAxis("right").linkToView(self.plot_prob) self.ploti.getAxis("right").setLabel("Probability") self.plot_prob.setZValue(10) self.plot_prob.setXLink(self.ploti) self.update_views() self.ploti.vb.sigResized.connect(self.update_views) self.plot_prob.setRange(yRange=[0, 1]) self.inline_graph_report() def disable_mouse(plot): plot.setMouseEnabled(False, False) plot.setMenuEnabled(False) disable_mouse(self.plot) disable_mouse(self.plot_prob) self.tooltip_items = [] self.plot.scene().installEventFilter( HelpEventDelegate(self.help_event, self)) pen = QtGui.QPen(self.palette().color(QtGui.QPalette.Text)) for axis in ("left", "bottom"): self.ploti.getAxis(axis).setPen(pen) self._legend = LegendItem() self._legend.setParentItem(self.plot) self._legend.hide() self._legend.anchor((1, 0), (1, 0))
def _setup_plot(self): have_data = self.data is not None have_matrix_transposed = self.matrix is not None and not self.matrix.axis plotstyle = mdsplotutils.plotstyle size = self._effective_matrix.shape[0] def column(data, variable): a, _ = data.get_column_view(variable) return a.ravel() def attributes(matrix): return matrix.row_items.domain.attributes def scale(a): dmin, dmax = numpy.nanmin(a), numpy.nanmax(a) if dmax - dmin > 0: return (a - dmin) / (dmax - dmin) else: return numpy.zeros_like(a) def jitter(x, factor=1, rstate=None): if rstate is None: rstate = numpy.random.RandomState() elif not isinstance(rstate, numpy.random.RandomState): rstate = numpy.random.RandomState(rstate) span = numpy.nanmax(x) - numpy.nanmin(x) if span < numpy.finfo(x.dtype).eps * 100: span = 1 a = factor * span / 100. return x + (rstate.random_sample(x.shape) - 0.5) * a if self._pen_data is None: if self._selection_mask is not None: pointflags = numpy.where( self._selection_mask, mdsplotutils.Selected, mdsplotutils.NoFlags) else: pointflags = None color_index = self.cb_color_value.currentIndex() if have_data and color_index > 0: color_var = self.colorvar_model[color_index] if color_var.is_discrete: palette = colorpalette.ColorPaletteGenerator( len(color_var.values) ) plotstyle = plotstyle.updated(discrete_palette=palette) else: palette = None color_data = mdsplotutils.color_data( self.data, color_var, plotstyle=plotstyle) color_data = numpy.hstack( (color_data, numpy.full((len(color_data), 1), self.symbol_opacity, dtype=float)) ) pen_data = mdsplotutils.pen_data(color_data * 0.8, pointflags) brush_data = mdsplotutils.brush_data(color_data) elif have_matrix_transposed and \ self.colorvar_model[color_index] == 'Attribute names': attr = attributes(self.matrix) palette = colorpalette.ColorPaletteGenerator(len(attr)) color_data = [palette.getRGB(i) for i in range(len(attr))] color_data = numpy.hstack(( color_data, numpy.full((len(color_data), 1), self.symbol_opacity, dtype=float)) ) pen_data = mdsplotutils.pen_data(color_data * 0.8, pointflags) brush_data = mdsplotutils.brush_data(color_data) else: pen_data = make_pen(QtGui.QColor(Qt.darkGray), cosmetic=True) if self._selection_mask is not None: pen_data = numpy.array( [pen_data, plotstyle.selected_pen]) pen_data = pen_data[self._selection_mask.astype(int)] else: pen_data = numpy.full(self._effective_matrix.dim, pen_data, dtype=object) brush_data = numpy.full( size, pg.mkColor((192, 192, 192, self.symbol_opacity)), dtype=object) if self._subset_mask is not None and have_data and \ self._subset_mask.shape == (size, ): # clear brush fill for non subset data brush_data[~self._subset_mask] = QtGui.QBrush(Qt.NoBrush) self._pen_data = pen_data self._brush_data = brush_data if self._shape_data is None: shape_index = self.cb_shape_value.currentIndex() if have_data and shape_index > 0: Symbols = ScatterPlotItem.Symbols symbols = numpy.array(list(Symbols.keys())) shape_var = self.shapevar_model[shape_index] data = column(self.data, shape_var).astype(numpy.float) data = data % (len(Symbols) - 1) data[numpy.isnan(data)] = len(Symbols) - 1 shape_data = symbols[data.astype(int)] elif have_matrix_transposed and \ self.shapevar_model[shape_index] == 'Attribute names': Symbols = ScatterPlotItem.Symbols symbols = numpy.array(list(Symbols.keys())) attr = [i % (len(Symbols) - 1) for i, _ in enumerate(attributes(self.matrix))] shape_data = symbols[attr] else: shape_data = "o" self._shape_data = shape_data if self._size_data is None: MinPointSize = 3 point_size = self.symbol_size + MinPointSize size_index = self.cb_size_value.currentIndex() if have_data and size_index == 1: # size by stress size_data = stress(self.embedding, self._effective_matrix) size_data = scale(size_data) size_data = MinPointSize + size_data * point_size elif have_data and size_index > 0: size_var = self.sizevar_model[size_index] size_data = column(self.data, size_var) size_data = scale(size_data) size_data = MinPointSize + size_data * point_size else: size_data = point_size self._size_data = size_data if self._label_data is None: label_index = self.cb_label_value.currentIndex() if have_data and label_index > 0: label_var = self.labelvar_model[label_index] label_data = column(self.data, label_var) label_data = [label_var.str_val(val) for val in label_data] label_items = [pg.TextItem(text, anchor=(0.5, 0), color=0.0) for text in label_data] elif have_matrix_transposed and \ self.labelvar_model[label_index] == 'Attribute names': attr = attributes(self.matrix) label_items = [pg.TextItem(str(text), anchor=(0.5, 0)) for text in attr] else: label_items = None self._label_data = label_items emb_x, emb_y = self.embedding[:, 0], self.embedding[:, 1] if self.jitter > 0: _, jitter_factor = self.JitterAmount[self.jitter] emb_x = jitter(emb_x, jitter_factor, rstate=42) emb_y = jitter(emb_y, jitter_factor, rstate=667) if self.connected_pairs and self.__draw_similar_pairs: if self._similar_pairs is None: # This code requires storing lower triangle of X (n x n / 2 # doubles), n x n / 2 * 2 indices to X, n x n / 2 indices for # argsort result. If this becomes an issue, it can be reduced to # n x n argsort indices by argsorting the entire X. Then we # take the first n + 2 * p indices. We compute their coordinates # i, j in the original matrix. We keep those for which i < j. # n + 2 * p will suffice to exclude the diagonal (i = j). If the # number of those for which i < j is smaller than p, we instead # take i > j. Among those that remain, we take the first p. # Assuming that MDS can't show so many points that memory could # become an issue, I preferred using simpler code. m = self._effective_matrix n = len(m) p = (n * (n - 1) // 2 * self.connected_pairs) // 100 indcs = numpy.triu_indices(n, 1) sorted = numpy.argsort(m[indcs])[:p] self._similar_pairs = fpairs = numpy.empty(2 * p, dtype=int) fpairs[::2] = indcs[0][sorted] fpairs[1::2] = indcs[1][sorted] for i in range(int(len(emb_x[self._similar_pairs]) / 2)): item = QtGui.QGraphicsLineItem( emb_x[self._similar_pairs][i * 2], emb_y[self._similar_pairs][i * 2], emb_x[self._similar_pairs][i * 2 + 1], emb_y[self._similar_pairs][i * 2 + 1] ) pen = QtGui.QPen(QtGui.QBrush(QtGui.QColor(204, 204, 204)), 2) pen.setCosmetic(True) item.setPen(pen) self.plot.addItem(item) data = numpy.arange(size) self._scatter_item = item = ScatterPlotItem( x=emb_x, y=emb_y, pen=self._pen_data, brush=self._brush_data, symbol=self._shape_data, size=self._size_data, data=data, antialias=True ) self.plot.addItem(item) if self._label_data is not None: if self.label_only_selected: if self._selection_mask is not None: for (x, y), text_item, selected \ in zip(self.embedding, self._label_data, self._selection_mask): if selected: self.plot.addItem(text_item) text_item.setPos(x, y) else: for (x, y), text_item in zip(self.embedding, self._label_data): self.plot.addItem(text_item) text_item.setPos(x, y) self._legend_item = LegendItem() viewbox = self.plot.getViewBox() self._legend_item.setParentItem(self.plot.getViewBox()) self._legend_item.setZValue(viewbox.zValue() + 10) self._legend_item.restoreAnchor(self.legend_anchor) color_var = shape_var = None color_index = self.cb_color_value.currentIndex() if have_data and 1 <= color_index < len(self.colorvar_model): color_var = self.colorvar_model[color_index] assert isinstance(color_var, Orange.data.Variable) shape_index = self.cb_shape_value.currentIndex() if have_data and 1 <= shape_index < len(self.shapevar_model): shape_var = self.shapevar_model[shape_index] assert isinstance(shape_var, Orange.data.Variable) if shape_var is not None or \ (color_var is not None and color_var.is_discrete): legend_data = mdsplotutils.legend_data( color_var, shape_var, plotstyle=plotstyle) for color, symbol, text in legend_data: self._legend_item.addItem( ScatterPlotItem(pen=color, brush=color, symbol=symbol, size=10), escape(text) ) else: self._legend_item.hide()
def __init__(self): super().__init__() self.varmodel = itemmodels.VariableListModel() self.groupvarmodel = [] self.distributions = [ distribution.value for distribution in self.available_distributions ] box = gui.vBox(self.controlArea, 'Tests') gui.radioButtonsInBox( box, self, 'test_idx', btnLabels=[test.name for test in self.available_tests], callback=self.test_changed, ) box = gui.vBox(self.controlArea, 'Distributions') self.distribution_choose = gui.radioButtonsInBox( box, self, 'distribution_idx', btnLabels=self.distributions, callback=self.distribution_changed, ) self.column_chose = gui.comboBox( self.controlArea, self, 'column_idx', box='Selected column', items=[], orientation=Qt.Horizontal, callback=self.column_changed, ) self.available_columns = itemmodels.VariableListModel(parent=self) self.column_chose.setModel(self.available_columns) self.infolabel = gui.widgetLabel(box, "<center>p-value: </center>") self.mainArea.setMinimumWidth(800) self.own_distribution_choose = gui.comboBox( self.controlArea, self, 'own_distribution_idx', box='Own distribution', items=[], orientation=Qt.Horizontal, callback=self.column_changed, ) self.own_distribution_choose.setModel(self.available_columns) self.data = None self.plotview = pg.PlotWidget(background=None) self.plotview.setRenderHint(QPainter.Antialiasing) self.mainArea.layout().addWidget(self.plotview) w = QLabel() w.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.mainArea.layout().addWidget(w, Qt.AlignCenter) self.ploti = pg.PlotItem() self.box_scene = self.ploti.vb self.ploti.hideButtons() self.plotview.setCentralItem(self.ploti) self.plot_prob = pg.ViewBox() self.ploti.scene().addItem(self.plot_prob) self.ploti.getAxis("right").linkToView(self.plot_prob) self.ploti.getAxis("right").setLabel("Probability") self.plot_prob.setZValue(10) self.plot_prob.setXLink(self.ploti) self.update_views() self.ploti.vb.sigResized.connect(self.update_views) self.plot_prob.setRange(yRange=[0, 1]) def disable_mouse(box_scene): box_scene.setMouseEnabled(False, False) box_scene.setMenuEnabled(False) disable_mouse(self.box_scene) disable_mouse(self.plot_prob) self.tooltip_items = [] pen = QPen(self.palette().color(QPalette.Text)) for axis in ("left", "bottom"): self.ploti.getAxis(axis).setPen(pen) self._legend = LegendItem() self._legend.setParentItem(self.box_scene) self._legend.hide() self._legend.anchor((1, 0), (1, 0)) self.test_changed()