def set_sampled_data(self, dataset): if dataset is None: return domain = dataset.domain cvars = [var for var in domain.variables if var.is_continuous] dvars = [var for var in domain.variables if var.is_discrete] self.x_var_model[:] = cvars self.y_var_model[:] = cvars self.z_var_model[:] = dvars nvars = len(cvars) self.x_var_index = min(max(0, self.x_var_index), nvars - 1) self.y_var_index = min(max(0, self.y_var_index), nvars - 1) self.z_var_index = min(max(0, self.z_var_index), len(dvars) - 1) if domain.has_discrete_class: self.z_var_index = dvars.index(domain.class_var) else: self.z_var_index = len(dvars) - 1 self.openContext(dataset) if 0 <= self.z_var_index < len(self.z_var_model): self.z_values = self.z_var_model[self.z_var_index].values k = len(self.z_values) self.selected_z_values = range(k) self.colors = colorpalette.ColorPaletteGenerator(k) for i in range(k): item = self.z_values_view.item(i) item.setIcon(colorpalette.ColorPixmap(self.colors[i])) self.error("Data contains no continuous features", shown=not cvars) self.setup_plot()
def __init__(self): super().__init__() self.data = None self.current_tool = None self._selected_indices = None self._scatter_item = None self.labels = ["C1", "C2"] self.undo_stack = QtGui.QUndoStack(self) self.class_model = ColoredListModel(self.labels, self, flags=QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsEditable) self.class_model.dataChanged.connect(self._class_value_changed) self.class_model.rowsInserted.connect(self._class_count_changed) self.class_model.rowsRemoved.connect(self._class_count_changed) self.data = np.zeros((0, 3)) self.colors = colorpalette.ColorPaletteGenerator( len(colorpalette.DefaultRGBColors)) self.tools_cache = {} self._init_ui()
def colors(data, variable, palette=None): if palette is None: if is_discrete(variable): palette = colorpalette.ColorPaletteGenerator(len(variable.values)) elif is_continuous(variable): palette = colorpalette.ColorPaletteBW() palette = colorpalette.ContinuousPaletteGenerator( QtGui.QColor(220, 220, 220), QtGui.QColor(0, 0, 0), False) else: raise TypeError() x = numpy.array(data[:, variable]).ravel() if is_discrete(variable): nvalues = len(variable.values) x[numpy.isnan(x)] = nvalues color_index = palette.getRGB(numpy.arange(nvalues + 1)) # Unknown values as gray # TODO: This should already be a part of palette color_index[nvalues] = (128, 128, 128) colors = color_index[x.astype(int)] else: x, _ = scaled(x) mask = numpy.isnan(x) colors = numpy.empty((len(x), 3)) colors[mask] = (128, 128, 128) colors[~mask] = [palette.getRGB(v) for v in x[~mask]] # colors[~mask] = interpolate(palette, x[~mask], left=Qt.gray) return colors
def generate_colors(self, number_of_colors): scheme = colorbrewer.colorSchemes["qualitative"]["Dark2"] if number_of_colors > len(scheme): scheme = colorpalette.DefaultRGBColors self.colors = colorpalette.ColorPaletteGenerator( number_of_colors, scheme)
def reset_to_input(self): """Reset the painting to input data if present.""" if self.input_data is None: return self.undo_stack.clear() index = self.selected_class_label() if self.input_colors is not None: colors = self.input_colors else: colors = colorpalette.DefaultRGBColors palette = colorpalette.ColorPaletteGenerator( number_of_colors=len(colors), rgb_colors=colors) self.colors = palette self.class_model.colors = palette self.class_model[:] = self.input_classes newindex = min(max(index, 0), len(self.class_model) - 1) itemmodels.select_row(self.classValuesView, newindex) self.data = self.input_data.tolist() self.__buffer = self.input_data.copy() prev_attr2 = self.hasAttr2 self.hasAttr2 = self.input_has_attr2 if prev_attr2 != self.hasAttr2: self.set_dimensions() else: # set_dimensions already calls _replot, no need to call it again self._replot()
def __init__(self, parent=None): super().__init__(parent) self.data = None self.current_tool = None self._invalidated = False self.labels = ["Class-1", "Class-2"] self.undo_stack = QtGui.QUndoStack(self) self.class_model = ColoredListModel(self.labels, self, flags=QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsEditable) self.class_model.dataChanged.connect(self._class_value_changed) self.class_model.rowsInserted.connect(self._class_count_changed) self.class_model.rowsRemoved.connect(self._class_count_changed) self.tools_cache = {} self._init_ui() self.data = numpy.zeros((0, 3)) self.colors = colorpalette.ColorPaletteGenerator(10)
def _setup_plot(self): have_data = self.data is not None if self._pen_data is None: if have_data and self.color_var > 0: color_var = self.colorvar_model[self.color_var] if is_discrete(color_var): palette = colorpalette.ColorPaletteGenerator( len(color_var.values)) else: palette = None color_data = colors(self.data, color_var, palette) pen_data = [ QtGui.QPen(QtGui.QColor(r, g, b)) for r, g, b in color_data ] else: pen_data = QtGui.QPen(Qt.black) self._pen_data = pen_data if self._shape_data is None: if have_data and self.shape_var > 0: Symbols = pg.graphicsItems.ScatterPlotItem.Symbols symbols = numpy.array(list(Symbols.keys())) shape_var = self.shapevar_model[self.shape_var] data = numpy.array(self.data[:, shape_var]).ravel() data = data % (len(Symbols) - 1) data[numpy.isnan(data)] = len(Symbols) - 1 shape_data = symbols[data.astype(int)] else: shape_data = "o" self._shape_data = shape_data if self._size_data is None: MinPointSize = 1 point_size = 8 + MinPointSize if have_data and self.size_var > 0: size_var = self.sizevar_model[self.size_var] size_data = numpy.array(self.data[:, size_var]).ravel() dmin, dmax = numpy.nanmin(size_data), numpy.nanmax(size_data) if dmax - dmin > 0: size_data = (size_data - dmin) / (dmax - dmin) size_data = MinPointSize + size_data * point_size else: size_data = point_size item = pg.ScatterPlotItem(x=self.embeding[:, 0], y=self.embeding[:, 1], pen=self._pen_data, symbol=self._shape_data, brush=QtGui.QBrush(Qt.transparent), size=size_data, antialias=True) # plot(x, y, colors=plot.colors(data[:, color_var]), # point_size=data[:, size_var], # symbol=data[:, symbol_var]) self.plot.addItem(item)
def color_data(table, var=None, mask=None, plotstyle=None): N = len(table) if mask is not None: mask = numpy.asarray(mask, dtype=bool) N = numpy.count_nonzero(mask) if plotstyle is None: plotstyle = mdsplotutils.plotstyle if var is None: col = numpy.zeros(N, dtype=float) color_data = numpy.full(N, plotstyle.default_color, dtype=object) elif var.is_primitive(): col = mdsplotutils.column_data(table, var, mask) if var.is_discrete: palette = plotstyle.discrete_palette if len(var.values) >= palette.number_of_colors: palette = colorpalette.ColorPaletteGenerator(len(var.values)) color_data = plotutils.discrete_colors( col, nvalues=len(var.values), palette=palette) elif var.is_continuous: color_data = plotutils.continuous_colors( col, palette=plotstyle.continuous_palette) else: raise TypeError("Discrete/Continuous variable or None expected.") return color_data
def legend_data(color_var=None, shape_var=None, plotstyle=None): if plotstyle is None: plotstyle = mdsplotutils.plotstyle if color_var is not None and not color_var.is_discrete: color_var = None assert shape_var is None or shape_var.is_discrete if color_var is None and shape_var is None: return [] if color_var is not None: palette = plotstyle.discrete_palette if len(color_var.values) >= palette.number_of_colors: palette = colorpalette.ColorPaletteGenerator(len(color_var.values)) else: palette = None symbols = list(plotstyle.symbols) if shape_var is color_var: items = [(palette[i], symbols[i], name) for i, name in enumerate(color_var.values)] else: colors = shapes = [] if color_var is not None: colors = [(palette[i], "o", name) for i, name in enumerate(color_var.values)] if shape_var is not None: shapes = [(QtGui.QColor(Qt.gray), symbols[i % (len(symbols) - 1)], name) for i, name in enumerate(shape_var.values)] items = colors + shapes return items
def __init__(self, iterable, parent, flags, list_item_role=QtCore.Qt.DisplayRole, supportedDropActions=QtCore.Qt.MoveAction): super().__init__(iterable, parent, flags, list_item_role, supportedDropActions) self.colors = colorpalette.ColorPaletteGenerator(10)
def create_image(contingencies, palette=None, scale=None): # import scipy.signal # import scipy.ndimage if scale is None: scale = lambda c: c / (contingencies.max() or 1) P = scale(contingencies) # if scale > 0: # P = contingencies / scale # else: # P = contingencies # nbins = node.xbins.shape[0] - 1 # smoothing = 32 # bandwidth = nbins / smoothing if P.ndim == 3: ncol = P.shape[-1] if palette is None: palette = colorpalette.ColorPaletteGenerator(ncol) colors = [palette[i] for i in range(ncol)] colors = np.array( [[c.red(), c.green(), c.blue()] for c in colors] ) # P = scipy.ndimage.filters.gaussian_filter( # P, bandwidth, mode="constant") # P /= P.max() argmax = np.argmax(P, axis=2) irow, icol = np.indices(argmax.shape) P_max = P[irow, icol, argmax] positive = P_max > 0 P_max = np.where(positive, P_max * 0.95 + 0.05, 0.0) colors = 255 - colors[argmax.ravel()] # XXX: Non linear intensity scaling colors = colors * P_max.ravel().reshape(-1, 1) colors = colors.reshape(P_max.shape + (3,)) colors = 255 - colors elif P.ndim == 2: palette = colorpalette.ColorPaletteBW() mix = P positive = mix > 0 mix = np.where(positive, mix * 0.99 + 0.01, 0.0) # mix = scipy.ndimage.filters.gaussian_filter( # mix, bandwidth, mode="constant") # mix /= mix.max() if total else 1.0 colors = np.zeros((np.prod(mix.shape), 3)) + 255 colors = colors - mix.ravel().reshape(-1, 1) * 255 colors = colors.reshape(mix.shape + (3,)) return colors.astype(int)
def discrete_colors(data, nvalues, palette=None): if palette is None: palette = colorpalette.ColorPaletteGenerator(nvalues) color_index = palette.getRGB(numpy.arange(nvalues + 1)) # Unknown values as gray # TODO: This should already be a part of palette color_index[nvalues] = (128, 128, 128) data = numpy.where(numpy.isnan(data), nvalues, data) data = data.astype(int) return color_index[data]
def _setup_plot(self): self.plot.clear() points = self.ca variables = self.selected_vars() colors = colorpalette.ColorPaletteGenerator(len(variables)) p_axes = self._p_axes() if points == None: return if len(variables) == 2: row_points = self.ca.row_factors[:, p_axes] col_points = self.ca.col_factors[:, p_axes] points = [row_points, col_points] else: points = self.ca.row_factors[:, p_axes] counts = [len(var.values) for var in variables] range_indices = numpy.cumsum([0] + counts) ranges = zip(range_indices, range_indices[1:]) points = [points[s:e] for s, e in ranges] for i, (v, points) in enumerate(zip(variables, points)): color_outline = colors[i] color_outline.setAlpha(200) color = QColor(color_outline) color.setAlpha(120) item = ScatterPlotItem( x=points[:, 0], y=points[:, 1], brush=QBrush(color), pen=pg.mkPen(color_outline.darker(120), width=1.5), size=numpy.full((points.shape[0], ), 10.1), ) self.plot.addItem(item) for name, point in zip(v.values, points): item = pg.TextItem(name, anchor=(0.5, 0)) self.plot.addItem(item) item.setPos(point[0], point[1]) inertia = self.ca.inertia_of_axis() if numpy.sum(inertia) == 0: inertia = 100 * inertia else: inertia = 100 * inertia / numpy.sum(inertia) ax = self.plot.getAxis("bottom") ax.setLabel("Component {} ({:.1f}%)".format(p_axes[0] + 1, inertia[p_axes[0]])) ax = self.plot.getAxis("left") ax.setLabel("Component {} ({:.1f}%)".format(p_axes[1] + 1, inertia[p_axes[1]]))
def _on_z_var_changed(self): if 0 <= self.z_var_index < len(self.z_var_model): self.z_values = self.z_var_model[self.z_var_index].values k = len(self.z_values) self.selected_z_values = range(k) self.colors = colorpalette.ColorPaletteGenerator(k) for i in range(k): item = self.z_values_view.item(i) item.setIcon(colorpalette.ColorPixmap(self.colors[i])) self.replot()
def update_group_var(self): data_attr, _ = self.data.get_column_view(self.group_var) class_vals = self.data.domain[self.group_var].values self.classes = list(class_vals) self.class_colors = \ colorpalette.ColorPaletteGenerator(len(class_vals)) self.selected_classes = list(range(len(class_vals))) for i in range(len(class_vals)): item = self.group_listbox.item(i) item.setIcon(colorpalette.ColorPixmap(self.class_colors[i])) self._setup_plot() self.__on_class_selection_changed()
def __init__( self, iterable, parent, flags, list_item_role=Qt.DisplayRole, supportedDropActions=Qt.MoveAction, ): super().__init__(iterable, parent, flags, list_item_role, supportedDropActions) self.colors = colorpalette.ColorPaletteGenerator( len(colorpalette.DefaultRGBColors))
def _re_enumerate_selections(self): """Re enumerate the selection items and update the colors.""" # Order the clusters items = sorted(self._selection.items(), key=lambda item: item[0].node.value.first) palette = colorpalette.ColorPaletteGenerator(len(items)) for i, (item, selection_item) in enumerate(items): # delete and then reinsert to update the ordering del self._selection[item] self._selection[item] = selection_item color = palette[i] color.setAlpha(150) selection_item.setBrush(QColor(color))
def _initialize(self, results): N = len(results.predicted) names = getattr(results, "learner_names", None) if names is None: names = ["#{}".format(i + 1) for i in range(N)] self.classifier_names = names self.colors = colorpalette.ColorPaletteGenerator( N, colorbrewer.colorSchemes["qualitative"]["Dark2"]) for i in range(N): item = self.classifiers_list_box.item(i) item.setIcon(colorpalette.ColorPixmap(self.colors[i])) self.selected_classifiers = list(range(N)) self.target_cb.addItems(results.data.domain.class_var.values)
def set_data(self, data): """ Set the input profile dataset. """ self.closeContext() self.clear() self.clear_legend() self.data = data if data is not None: n_instances = len(data) n_attrs = len(data.domain.attributes) self.infoLabel.setText("%i genes on input\n%i attributes" % (n_instances, n_attrs)) if is_discrete(data.domain.class_var): class_vals = data.domain.class_var.values else: class_vals = [] self.classes = list(class_vals) self.class_colors = \ colorpalette.ColorPaletteGenerator(len(class_vals)) self.selected_classes = list(range(len(class_vals))) for i in range(len(class_vals)): item = self.group_listbox.item(i) item.setIcon(colorpalette.ColorPixmap(self.class_colors[i])) variables = data.domain.variables + data.domain.metas annotvars = [ var for var in variables if is_discrete(var) or is_string(var) ] for var in annotvars: self.annot_cb.addItem(*gui.attributeItem(var)) if data.domain.class_var in annotvars: self.annot_index = annotvars.index(data.domain.class_var) self.annotation_variables = annotvars self.openContext(data) if n_attrs: self._setup_plot() self.commit()
def _initialize(self, results): names = getattr(results, "learner_names", None) if names is None: names = ["#{}".format(i + 1) for i in range(len(results.predicted))] scheme = colorbrewer.colorSchemes["qualitative"]["Dark2"] if len(names) > len(scheme): scheme = colorpalette.DefaultRGBColors self.colors = colorpalette.ColorPaletteGenerator(len(names), scheme) self.classifier_names = names self.selected_classifiers = list(range(len(names))) for i in range(len(names)): listitem = self.classifiers_list_box.item(i) listitem.setIcon(colorpalette.ColorPixmap(self.colors[i])) class_var = results.data.domain.class_var self.target_cb.addItems(class_var.values)
def __init__(self): super().__init__() self.input_data = None self.input_classes = [] self.input_colors = None self.input_has_attr2 = True self.current_tool = None self._selected_indices = None self._scatter_item = None #: A private data buffer (can be modified in place). `self.data` is #: a copy of this array (as seen when the `invalidate` method is #: called self.__buffer = None self.undo_stack = QUndoStack(self) self.class_model = ColoredListModel( self.labels, self, flags=Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsEditable, ) self.class_model.dataChanged.connect(self._class_value_changed) self.class_model.rowsInserted.connect(self._class_count_changed) self.class_model.rowsRemoved.connect(self._class_count_changed) if not self.data: self.data = [] self.__buffer = np.zeros((0, 3)) elif isinstance(self.data, np.ndarray): self.__buffer = self.data.copy() self.data = self.data.tolist() else: self.__buffer = np.array(self.data) self.colors = colorpalette.ColorPaletteGenerator( len(colorpalette.DefaultRGBColors)) self.tools_cache = {} self._init_ui() self.commit()
def set_sampled_data(self, dataset): if dataset is not None: domain = dataset.domain cvars = list(filter(is_continuous, domain.variables)) dvars = list(filter(is_discrete, domain.variables)) self.x_var_model[:] = cvars self.y_var_model[:] = cvars self.z_var_model[:] = dvars nvars = len(cvars) self.x_var_index = min(max(0, self.x_var_index), nvars - 1) self.y_var_index = min(max(0, self.y_var_index), nvars - 1) self.z_var_index = min(max(0, self.z_var_index), len(cvars) - 1) if is_discrete(domain.class_var): self.z_var_index = dvars.index(domain.class_var) else: self.z_var_index = len(dvars) - 1 self.openContext(dataset) if 0 <= self.z_var_index < len(self.z_var_model): self.z_values = self.z_var_model[self.z_var_index].values k = len(self.z_values) self.selected_z_values = range(k) self.colors = colorpalette.ColorPaletteGenerator(k) for i in range(k): item = self.z_values_view.item(i) item.setIcon(colorpalette.ColorPixmap(self.colors[i])) self.labelDataInput.setText( 'Data set: %s' % (getattr(self.dataset, "name", "untitled"),) ) self.setup_plot() else: self.labelDataInput.setText('No data on input') self.send("Sampled data", None)
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()
class mdsplotutils(plotutils): NoFlags, Selected, Highlight = 0, 1, 2 NoFill, Filled = 0, 1 plotstyle = namespace( selected_pen=make_pen(Qt.yellow, width=3, cosmetic=True), highligh_pen=QtGui.QPen(Qt.blue, 1), selected_brush=None, default_color=QtGui.QColor(Qt.darkGray).rgba(), discrete_palette=colorpalette.ColorPaletteGenerator(), continuous_palette=colorpalette.ContinuousPaletteGenerator( QtGui.QColor(220, 220, 220), QtGui.QColor(0, 0, 0), False ), symbols=ScatterPlotItem.Symbols, point_size=10, min_point_size=5, ) @staticmethod def column_data(table, var, mask=None): col, _ = table.get_column_view(var) dtype = float if var.is_primitive() else object col = numpy.asarray(col, dtype=dtype) if mask is not None: mask = numpy.asarray(mask, dtype=bool) return col[mask] else: return col @staticmethod def color_data(table, var=None, mask=None, plotstyle=None): N = len(table) if mask is not None: mask = numpy.asarray(mask, dtype=bool) N = numpy.count_nonzero(mask) if plotstyle is None: plotstyle = mdsplotutils.plotstyle if var is None: col = numpy.zeros(N, dtype=float) color_data = numpy.full(N, plotstyle.default_color, dtype=object) elif var.is_primitive(): col = mdsplotutils.column_data(table, var, mask) if var.is_discrete: palette = plotstyle.discrete_palette if len(var.values) >= palette.number_of_colors: palette = colorpalette.ColorPaletteGenerator(len(var.values)) color_data = plotutils.discrete_colors( col, nvalues=len(var.values), palette=palette) elif var.is_continuous: color_data = plotutils.continuous_colors( col, palette=plotstyle.continuous_palette) else: raise TypeError("Discrete/Continuous variable or None expected.") return color_data @staticmethod def pen_data(basecolors, flags=None, plotstyle=None): if plotstyle is None: plotstyle = mdsplotutils.plotstyle pens = numpy.array( [mdsplotutils.make_pen(QtGui.QColor(*rgba), width=1) for rgba in basecolors], dtype=object) if flags is None: return pens selected_mask = flags & mdsplotutils.Selected if numpy.any(selected_mask): pens[selected_mask.astype(bool)] = plotstyle.selected_pen highlight_mask = flags & mdsplotutils.Highlight if numpy.any(highlight_mask): pens[highlight_mask.astype(bool)] = plotstyle.hightlight_pen return pens @staticmethod def brush_data(basecolors, flags=None, plotstyle=None): if plotstyle is None: plotstyle = mdsplotutils.plotstyle brush = numpy.array( [mdsplotutils.make_brush(QtGui.QColor(*c)) for c in basecolors], dtype=object) if flags is None: return brush fill_mask = flags & mdsplotutils.Filled if not numpy.all(fill_mask): brush[~fill_mask] = QtGui.QBrush(Qt.NoBrush) return brush @staticmethod def shape_data(table, var, mask=None, plotstyle=None): if plotstyle is None: plotstyle = mdsplotutils.plotstyle N = len(table) if mask is not None: mask = numpy.asarray(mask, dtype=bool) N = numpy.nonzero(mask) if var is None: return numpy.full(N, "o", dtype=object) elif var.is_discrete: shape_data = mdsplotutils.column_data(table, var, mask) maxsymbols = len(plotstyle.symbols) - 1 validmask = numpy.isfinite(shape_data) shape = shape_data % (maxsymbols - 1) shape[~validmask] = maxsymbols # Special symbol for unknown values symbols = numpy.array(list(plotstyle.symbols)) shape_data = symbols[numpy.asarray(shape, dtype=int)] if mask is None: return shape_data else: return shape_data[mask] else: raise TypeError() @staticmethod def size_data(table, var, mask=None, plotstyle=None): if plotstyle is None: plotstyle = mdsplotutils.plotstyle N = len(table) if mask is not None: mask = numpy.asarray(mask, dtype=bool) N = numpy.nonzero(mask) if var is None: return numpy.full(N, plotstyle.point_size, dtype=float) else: size_data = mdsplotutils.column_data(table, var, mask) size_data = mdsplotutils.normalized(size_data) size_mask = numpy.isnan(size_data) size_data = size_data * plotstyle.point_size + \ plotstyle.min_point_size size_data[size_mask] = plotstyle.min_point_size - 2 if mask is None: return size_data else: return size_data[mask] @staticmethod def legend_data(color_var=None, shape_var=None, plotstyle=None): if plotstyle is None: plotstyle = mdsplotutils.plotstyle if color_var is not None and not color_var.is_discrete: color_var = None assert shape_var is None or shape_var.is_discrete if color_var is None and shape_var is None: return [] if color_var is not None: palette = plotstyle.discrete_palette if len(color_var.values) >= palette.number_of_colors: palette = colorpalette.ColorPaletteGenerator(len(color_var.values)) else: palette = None symbols = list(plotstyle.symbols) if shape_var is color_var: items = [(palette[i], symbols[i], name) for i, name in enumerate(color_var.values)] else: colors = shapes = [] if color_var is not None: colors = [(palette[i], "o", name) for i, name in enumerate(color_var.values)] if shape_var is not None: shapes = [(QtGui.QColor(Qt.gray), symbols[i % (len(symbols) - 1)], name) for i, name in enumerate(shape_var.values)] items = colors + shapes return items @staticmethod def make_pen(color, width=1, cosmetic=True): pen = QtGui.QPen(color) pen.setWidthF(width) pen.setCosmetic(cosmetic) return pen @staticmethod def make_brush(color, ): return QtGui.QBrush(color, )
def _setup_plot(self): def get_minmax(points): minmax = [float("inf"), float("-inf"), float("inf"), float("-inf")] for pp in points: for p in pp: minmax[0] = min(p[0], minmax[0]) minmax[1] = max(p[0], minmax[1]) minmax[2] = min(p[1], minmax[2]) minmax[3] = max(p[1], minmax[3]) return minmax self.plot.clear() points = self.ca variables = self.selected_vars() colors = colorpalette.ColorPaletteGenerator(len(variables)) p_axes = self._p_axes() if points is None: return if len(variables) == 2: row_points = self.ca.row_factors[:, p_axes] col_points = self.ca.col_factors[:, p_axes] points = [row_points, col_points] else: points = self.ca.row_factors[:, p_axes] counts = [len(var.values) for var in variables] range_indices = np.cumsum([0] + counts) ranges = zip(range_indices, range_indices[1:]) points = [points[s:e] for s, e in ranges] minmax = get_minmax(points) margin = abs(minmax[0] - minmax[1]) margin = margin * 0.05 if margin > 1e-10 else 1 self.plot.setXRange(minmax[0] - margin, minmax[1] + margin) margin = abs(minmax[2] - minmax[3]) margin = margin * 0.05 if margin > 1e-10 else 1 self.plot.setYRange(minmax[2] - margin, minmax[3] + margin) for i, (v, points) in enumerate(zip(variables, points)): color_outline = colors[i] color_outline.setAlpha(200) color = QColor(color_outline) color.setAlpha(120) item = ScatterPlotItem( x=points[:, 0], y=points[:, 1], brush=QBrush(color), pen=pg.mkPen(color_outline.darker(120), width=1.5), size=np.full((points.shape[0], ), 10.1), ) self.plot.addItem(item) for name, point in zip(v.values, points): item = pg.TextItem(name, anchor=(0.5, 0)) self.plot.addItem(item) item.setPos(point[0], point[1]) inertia = self.ca.inertia_of_axis() if np.sum(inertia) == 0: inertia = 100 * inertia else: inertia = 100 * inertia / np.sum(inertia) ax = self.plot.getAxis("bottom") ax.setLabel("Component {} ({:.1f}%)".format(p_axes[0] + 1, inertia[p_axes[0]])) ax = self.plot.getAxis("left") ax.setLabel("Component {} ({:.1f}%)".format(p_axes[1] + 1, inertia[p_axes[1]]))
def set_contingency(self, cont, var, cvar): """ Set the contingency to display. """ assert len(cont) > 0 self.plot.clear() leftaxis = self.plot.getAxis("left") bottomaxis = self.plot.getAxis("bottom") bottomaxis.setLabel(var.name) palette = colorpalette.ColorPaletteGenerator(len(cvar.values)) colors = [palette[i] for i in range(len(cvar.values))] if is_continuous(var): if self.cont_est_type == OWDistributions.Hist: leftaxis.setLabel("Frequency") else: leftaxis.setLabel("Density") bottomaxis.setTicks(None) weights = numpy.array([numpy.sum(W) for _, W in cont]) weights /= numpy.sum(weights) curve_est = self._density_estimator() curves = [curve_est(dist) for dist in cont] curves = [(X, Y * w) for (X, Y), w in zip(curves, weights)] cum_curves = [curves[0]] for X, Y in curves[1:]: cum_curves.append(sum_rect_curve(X, Y, *cum_curves[-1])) for (X, Y), color in reversed(list(zip(cum_curves, colors))): item = pg.PlotCurveItem() item.setData(X, Y, antialias=True, stepMode=True, fillLevel=0, brush=QtGui.QBrush(color)) item.setPen(QtGui.QPen(color)) self.plot.addItem(item) # # XXX: sum the individual curves and not the distributions. # # The conditional distributions might be 'smother' then # # the cumulative one # cum_dist = [cont[0]] # for dist in cont[1:]: # cum_dist.append(dist_sum(dist, cum_dist[-1])) # # curves = [rect_kernel_curve(dist) for dist in cum_dist] # colors = [Qt.blue, Qt.red, Qt.magenta] # for (X, Y), color in reversed(list(zip(curves, colors))): # item = pg.PlotCurveItem() # item.setData(X, Y, antialias=True, stepMode=True, # fillLevel=0, brush=QtGui.QBrush(color)) # item.setPen(QtGui.QPen(color)) # self.plot.addItem(item) elif is_discrete(var): leftaxis.setLabel("Frequency") bottomaxis.setTicks([list(enumerate(var.values))]) cont = numpy.array(cont) for i, (value, dist) in enumerate(zip(var.values, cont.T)): dsum = sum(dist) geom = QtCore.QRectF(i - 0.333, 0, 0.666, dsum) item = DistributionBarItem(geom, dist / dsum, colors) self.plot.addItem(item)
def __init__(self): super().__init__() self.dataset = None self.z_values = [] self._root = None self._displayed_root = None self._item = None self._cache = {} self.colors = colorpalette.ColorPaletteGenerator(10) box = gui.vBox(self.controlArea, "Axes") self.x_var_model = itemmodels.VariableListModel() self.comboBoxAttributesX = gui.comboBox( box, self, value='x_var_index', callback=self.replot, contentsLength=12) self.comboBoxAttributesX.setModel(self.x_var_model) self.y_var_model = itemmodels.VariableListModel() self.comboBoxAttributesY = gui.comboBox( box, self, value='y_var_index', callback=self.replot, contentsLength=12) self.comboBoxAttributesY.setModel(self.y_var_model) box = gui.vBox(self.controlArea, "Color") self.z_var_model = itemmodels.VariableListModel() self.comboBoxClassvars = gui.comboBox( box, self, value='z_var_index', callback=self._on_z_var_changed, contentsLength=12) self.comboBoxClassvars.setModel(self.z_var_model) self.z_values_view = gui.listBox( box, self, "selected_z_values", "z_values", callback=self._on_z_values_selection_changed, selectionMode=QtGui.QListView.MultiSelection, addSpace=False ) gui.comboBox(box, self, "color_scale", label="Scale: ", orientation=Qt.Horizontal, items=["Linear", "Square root", "Logarithmic"], callback=self._on_color_scale_changed) self.sampling_box = gui.vBox(self.controlArea, "Sampling") sampling_options = (self.sample_times_captions + self.sample_percentages_captions) self.sample_combo = gui.comboBox( self.sampling_box, self, 'sample_level', items=sampling_options, callback=self.update_sample) gui.button(self.sampling_box, self, "Sharpen", self.sharpen) gui.rubber(self.controlArea) self.plot = pg.PlotWidget(background="w") self.plot.setMenuEnabled(False) self.plot.setFrameStyle(QtGui.QFrame.StyledPanel) self.plot.setMinimumSize(500, 500) def font_resize(font, factor, minsize=None, maxsize=None): font = QtGui.QFont(font) fontinfo = QtGui.QFontInfo(font) size = fontinfo.pointSizeF() * factor if minsize is not None: size = max(size, minsize) if maxsize is not None: size = min(size, maxsize) font.setPointSizeF(size) return font axisfont = font_resize(self.font(), 0.8, minsize=11) axispen = QtGui.QPen(self.palette().color(QtGui.QPalette.Text)) axis = self.plot.getAxis("bottom") axis.setTickFont(axisfont) axis.setPen(axispen) axis = self.plot.getAxis("left") axis.setTickFont(axisfont) axis.setPen(axispen) self.plot.getViewBox().sigTransformChanged.connect( self._on_transform_changed) self.mainArea.layout().addWidget(self.plot)
def paint(self, painter, option, index): dist = self.distribution(index) if dist is None or self.__colors is None: return super().paint(painter, option, index) if not numpy.isfinite(numpy.sum(dist)): return super().paint(painter, option, index) nvalues = len(dist) if len(self.__colors) < nvalues: colors = colorpalette.ColorPaletteGenerator(nvalues) colors = [colors[i] for i in range(nvalues)] else: colors = self.__colors if option.widget is not None: style = option.widget.style() else: style = QApplication.style() self.initStyleOption(option, index) text = option.text metrics = option.fontMetrics margin = style.pixelMetric(QStyle.PM_FocusFrameHMargin, option, option.widget) + 1 bottommargin = min(margin, 1) rect = option.rect.adjusted(margin, margin, -margin, -bottommargin) textrect = style.subElementRect(QStyle.SE_ItemViewItemText, option, option.widget) # Are the margins included in the subElementRect?? -> No! textrect = textrect.adjusted(margin, margin, -margin, -bottommargin) text = option.fontMetrics.elidedText(text, option.textElideMode, textrect.width()) spacing = max(metrics.leading(), 1) distheight = rect.height() - metrics.height() - spacing distheight = numpy.clip(distheight, 2, metrics.height()) painter.save() painter.setClipRect(option.rect) painter.setFont(option.font) painter.setRenderHint(QPainter.Antialiasing) style.drawPrimitive(QStyle.PE_PanelItemViewRow, option, painter, option.widget) style.drawPrimitive(QStyle.PE_PanelItemViewItem, option, painter, option.widget) if option.state & QStyle.State_Selected: color = option.palette.highlightedText().color() else: color = option.palette.text().color() painter.setPen(QtGui.QPen(color)) textrect = textrect.adjusted(0, 0, 0, -distheight - spacing) distrect = QtCore.QRect( textrect.bottomLeft() + QtCore.QPoint(0, spacing), QtCore.QSize(rect.width(), distheight)) painter.setPen(QtGui.QPen(Qt.lightGray, 0.3)) drawDistBar(painter, distrect, dist, colors) painter.restore() if text: style.drawItemText(painter, textrect, option.displayAlignment, option.palette, option.state & QStyle.State_Enabled, text)
def _setup_plot(self): have_data = self.data is not None have_matrix_transposed = self.matrix is not None and not self.matrix.axis 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) 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 if have_data and self.color_index > 0: color_var = self.colorvar_model[self.color_index] if color_var.is_discrete: palette = colorpalette.ColorPaletteGenerator( len(color_var.values)) else: palette = None color_data = mdsplotutils.color_data( self.data, color_var, plotstyle=mdsplotutils.plotstyle) color_data = numpy.hstack((color_data, numpy.full((len(color_data), 1), self.symbol_opacity))) pen_data = mdsplotutils.pen_data(color_data, pointflags) elif have_matrix_transposed and self.colorvar_model[ self.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)) pen_data = mdsplotutils.pen_data(color_data, pointflags) else: pen_data = make_pen(QtGui.QColor(Qt.darkGray), cosmetic=True) pen_data = numpy.full(len(self.data), pen_data, dtype=object) self._pen_data = pen_data if self._shape_data is None: if have_data and self.shape_index > 0: Symbols = ScatterPlotItem.Symbols symbols = numpy.array(list(Symbols.keys())) shape_var = self.shapevar_model[self.shape_index] data = column(self.data, shape_var) 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[ self.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 if have_data and self.size_index == 1: # size by stress size_data = stress(self.embedding, self._effective_matrix.X) size_data = scale(size_data) size_data = MinPointSize + size_data * point_size elif have_data and self.size_index > 0: size_var = self.sizevar_model[self.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 if self._label_data is None: if have_data and self.label_index > 0: label_var = self.labelvar_model[self.label_index] label_data = column(self.data, label_var) label_data = [label_var.repr_val(val) for val in label_data] label_items = [ pg.TextItem(text, anchor=(0.5, 0)) for text in label_data ] elif have_matrix_transposed and self.labelvar_model[ self.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 self._scatter_item = item = ScatterPlotItem( x=self.embedding[:, 0], y=self.embedding[:, 1], pen=self._pen_data, symbol=self._shape_data, brush=QtGui.QBrush(Qt.transparent), size=size_data, data=numpy.arange(len(self.data)), antialias=True) self.plot.addItem(item) if self._label_data is not None: for (x, y), text_item in zip(self.embedding, self._label_data): self.plot.addItem(text_item) text_item.setPos(x, y)
def __init__(self, parent=None): super().__init__(self, parent) self.dataset = None self.z_values = [] self._root = None self._displayed_root = None self._item = None self._cache = {} self.colors = colorpalette.ColorPaletteGenerator(10) self.sampling_box = box = gui.widgetBox(self.controlArea, "Sampling") sampling_options =\ self.sample_times_captions + self.sample_percentages_captions gui.comboBox(box, self, 'sample_level', items=sampling_options, callback=self.update_sample) gui.button(box, self, "Sharpen", self.sharpen) box = gui.widgetBox(self.controlArea, "Input") self.labelDataInput = gui.widgetLabel(box, 'No data on input') self.labelDataInput.setTextFormat(Qt.PlainText) self.labelOutput = gui.widgetLabel(box, '') self.x_var_model = itemmodels.VariableListModel() self.comboBoxAttributesX = gui.comboBox(self.controlArea, self, value='x_var_index', box='X Attribute', callback=self.replot) self.comboBoxAttributesX.setModel(self.x_var_model) self.y_var_model = itemmodels.VariableListModel() self.comboBoxAttributesY = gui.comboBox(self.controlArea, self, value='y_var_index', box='Y Attribute', callback=self.replot) self.comboBoxAttributesY.setModel(self.y_var_model) box = gui.widgetBox(self.controlArea, "Color by") self.z_var_model = itemmodels.VariableListModel() self.comboBoxClassvars = gui.comboBox(box, self, value='z_var_index', callback=self._on_z_var_changed) self.comboBoxClassvars.setModel(self.z_var_model) box1 = gui.widgetBox(box, 'Colors displayed', margin=0) box1.setFlat(True) self.z_values_view = gui.listBox( box1, self, "selected_z_values", "z_values", callback=self._on_z_values_selection_changed, selectionMode=QtGui.QListView.MultiSelection, addSpace=False) box1 = gui.widgetBox(box, "Color Scale", margin=0) box1.setFlat(True) gui.comboBox(box1, self, "color_scale", items=["Linear", "Square root", "Logarithmic"], callback=self._on_color_scale_changed) self.mouseBehaviourBox = gui.radioButtons( self.controlArea, self, value='mouse_mode', btnLabels=('Drag', 'Select'), box='Mouse left button behavior', callback=self._update_mouse_mode) gui.rubber(self.controlArea) self.plot = pg.PlotWidget(background="w") self.plot.setMenuEnabled(False) self.plot.setFrameStyle(QtGui.QFrame.StyledPanel) self.plot.setMinimumSize(500, 500) def font_resize(font, factor, minsize=None, maxsize=None): font = QtGui.QFont(font) fontinfo = QtGui.QFontInfo(font) size = fontinfo.pointSizeF() * factor if minsize is not None: size = max(size, minsize) if maxsize is not None: size = min(size, maxsize) font.setPointSizeF(size) return font axisfont = font_resize(self.font(), 0.8, minsize=11) axispen = QtGui.QPen(self.palette().color(QtGui.QPalette.Text)) axis = self.plot.getAxis("bottom") axis.setTickFont(axisfont) axis.setPen(axispen) axis = self.plot.getAxis("left") axis.setTickFont(axisfont) axis.setPen(axispen) self.plot.getViewBox().sigTransformChanged.connect( self._on_transform_changed) self.mainArea.layout().addWidget(self.plot)