def update_profiles_color(self, selection): color = QColor(self.color) alpha = LinePlotStyle.UNSELECTED_LINE_ALPHA if not selection \ else LinePlotStyle.UNSELECTED_LINE_ALPHA_SEL color.setAlpha(alpha) x, y = self.profiles.getData() self.profiles.setData(x=x, y=y, pen=self.make_pen(color))
def make_color_legend(self): if self.attr_color is None: return use_shape = self.attr_shape == self.get_color() if self.attr_color.is_discrete: if not self.legend: self.create_legend() palette = self.discrete_palette for i, value in enumerate(self._get_values(self.attr_color)): color = QColor(*palette.getRGB(i)) pen = _make_pen(color.darker(self.DarkerValue), 1.5) color.setAlpha( self.alpha_value if self.subset_indices is None else 255) brush = QBrush(color) self.legend.addItem( ScatterPlotItem( pen=pen, brush=brush, size=10, symbol=self.CurveSymbols[i] if use_shape else "o"), escape(value)) else: legend = self.color_legend = LegendItem() legend.setParentItem(self.plot_widget.getViewBox()) legend.restoreAnchor(self.__color_legend_anchor) label = PaletteItemSample(self.continuous_palette, self.scale) legend.addItem(label, "") legend.setGeometry(label.boundingRect())
def _get_same_colors(self, subset): """ Return the same pen for all points while the brush color depends upon whether the point is in the subset or not Args: subset (np.ndarray): a bool array indicating whether a data point is in the subset or not (e.g. in the 'Data Subset' signal in the Scatter plot and similar widgets); Returns: (tuple): a list of pens and list of brushes """ color = self.plot_widget.palette().color(OWPalette.Data) pen = [_make_pen(color, 1.5) for _ in range(self.n_shown)] if subset is not None: brush = np.where( subset, *(QBrush(QColor(*col)) for col in (self.COLOR_SUBSET, self.COLOR_NOT_SUBSET))) else: color = QColor(*self.COLOR_DEFAULT) color.setAlpha(self.alpha_value) brush = [QBrush(color) for _ in range(self.n_shown)] return pen, brush
def make_color_legend(self): if self.attr_color is None: return use_shape = self.attr_shape == self.get_color() if self.attr_color.is_discrete: if not self.legend: self.create_legend() palette = self.discrete_palette for i, value in enumerate(self._get_values(self.attr_color)): color = QColor(*palette.getRGB(i)) pen = _make_pen(color.darker(self.DarkerValue), 1.5) color.setAlpha(self.alpha_value if self.subset_indices is None else 255) brush = QBrush(color) self.legend.addItem( ScatterPlotItem( pen=pen, brush=brush, size=10, symbol=self.CurveSymbols[i] if use_shape else "o"), escape(value)) else: legend = self.color_legend = LegendItem() legend.setParentItem(self.plot_widget.getViewBox()) legend.restoreAnchor(self.__color_legend_anchor) label = PaletteItemSample(self.continuous_palette, self.scale) legend.addItem(label, "") legend.setGeometry(label.boundingRect())
def _get_range_curve(self): color = QColor(self.color) color.setAlpha(LinePlotStyle.RANGE_ALPHA) bottom, top = nanmin(self.y_data, axis=0), nanmax(self.y_data, axis=0) return pg.FillBetweenItem(pg.PlotDataItem(x=self.x_data, y=bottom), pg.PlotDataItem(x=self.x_data, y=top), brush=color)
def update_sel_profiles_color(self, subset): color = QColor(Qt.black) if subset else QColor(self.color) color.setAlpha( self.graph.parameter_setter.sel_line_settings[Updater.ALPHA_LABEL]) pen = self.sel_profiles.opts["pen"] pen.setColor(color) self.sel_profiles.setPen(pen)
def update_profiles_color(self, selection): color = QColor(self.color) alpha = self.graph.line_settings[Updater.ALPHA_LABEL] \ if not selection else LinePlotStyle.UNSELECTED_LINE_ALPHA_SEL color.setAlpha(alpha) pen = self.profiles.opts["pen"] pen.setColor(color) self.profiles.setPen(pen)
def _get_range_curve(self): color = QColor(self.color) color.setAlpha(LinePlotStyle.RANGE_ALPHA) bottom, top = nanmin(self.y_data, axis=0), nanmax(self.y_data, axis=0) return pg.FillBetweenItem( pg.PlotDataItem(x=self.x_data, y=bottom), pg.PlotDataItem(x=self.x_data, y=top), brush=color )
def _get_range_curve(self): color = QColor(self.color) color.setAlpha(self.graph.range_settings[Updater.ALPHA_LABEL]) bottom, top = nanmin(self.y_data, axis=0), nanmax(self.y_data, axis=0) return pg.FillBetweenItem( pg.PlotDataItem(x=self.x_data, y=bottom), pg.PlotDataItem(x=self.x_data, y=top), brush=color )
def __init__(self, parent): super().__init__(parent) color = QColor(*self.COLOR) color.setAlpha(100) self.setBrush(color) color = QColor(*self.COLOR) self.setPen(color)
def add_points(): nonlocal cur, image_token if image_token != self._image_token: return batch = visible[cur:cur + self.N_POINTS_PER_ITER] batch_lat = lat[batch] batch_lon = lon[batch] x, y = self.Projection.latlon_to_easting_northing(batch_lat, batch_lon) x, y = self.Projection.easting_northing_to_pixel(x, y, zoom, origin, map_pane_pos) if self._jittering: dx, dy = self._jittering_offsets[batch].T x, y = x + dx, y + dy colors = (self._colorgen.getRGB(self._scaled_color_values[batch]).tolist() if self._color_attr else repeat((0xff, 0, 0))) sizes = self._size_coef * \ (self._sizes[batch] if self._size_attr else np.tile(10, len(batch))) for x, y, is_selected, size, color, _in_subset in \ zip(x, y, selected[batch], sizes, colors, in_subset[batch]): pensize2, selpensize2 = (.35, 1.5) if size >= 5 else (.15, .7) pensize2 *= self._size_coef selpensize2 *= self._size_coef size2 = size / 2 if is_selected: painter.setPen(QPen(QBrush(Qt.green), 2 * selpensize2)) painter.drawEllipse(x - size2 - selpensize2, y - size2 - selpensize2, size + selpensize2, size + selpensize2) color = QColor(*color) color.setAlpha(self._opacity) painter.setBrush(QBrush(color) if _in_subset else Qt.NoBrush) painter.setPen(QPen(QBrush(color.darker(180)), 2 * pensize2)) painter.drawEllipse(x - size2 - pensize2, y - size2 - pensize2, size + pensize2, size + pensize2) im.save(self._overlay_image_path, 'PNG') self.evalJS('markersImageLayer.setUrl("{}#{}"); 0;' .format(self.toFileURL(self._overlay_image_path), np.random.random())) cur += self.N_POINTS_PER_ITER if cur < len(visible): QTimer.singleShot(10, add_points) self._owwidget.progressBarAdvance(100 / n_iters, None) else: self._owwidget.progressBarFinished(None)
def _update_shape_legend(self, labels): self.shape_legend.clear() if labels is None or self.scatterplot_item is None: return color = QColor(0, 0, 0) color.setAlpha(self.alpha_value) for label, symbol in zip(labels, self.CurveSymbols): self.shape_legend.addItem( ScatterPlotItem(pen=color, brush=color, size=10, symbol=symbol), escape(label))
def _update_color_legend(self, labels): symbols = ['o' for _ in range(len(labels))] colors = self.palette.values_to_colors(np.arange(len(labels))) for color, label, symbol in zip(colors, labels, symbols): color = QColor(*color) pen = self._make_pen(color.darker(120), 1.5) color.setAlpha(self.alpha_value) brush = QBrush(color) sis = SymbolItemSample(pen=pen, brush=brush, size=10, symbol=symbol) self.color_legend.addItem(sis, escape(label))
def add_points(): nonlocal cur, image_token if image_token != self._image_token: return batch = visible[cur:cur + self.N_POINTS_PER_ITER] batch_lat = lat[batch] batch_lon = lon[batch] x, y = self.Projection.latlon_to_easting_northing( batch_lat, batch_lon) x, y = self.Projection.easting_northing_to_pixel( x, y, zoom, origin, map_pane_pos) if self._jittering: dx, dy = self._jittering_offsets[batch].T x, y = x + dx, y + dy colors = (self._colorgen.getRGB( self._scaled_color_values[batch]).tolist() if self._color_attr else repeat((0xff, 0, 0))) sizes = self._size_coef * \ (self._sizes[batch] if self._size_attr else np.tile(10, len(batch))) for x, y, is_selected, size, color, _in_subset in \ zip(x, y, selected[batch], sizes, colors, in_subset[batch]): pensize2, selpensize2 = (.35, 1.5) if size >= 5 else (.15, .7) pensize2 *= self._size_coef selpensize2 *= self._size_coef size2 = size / 2 if is_selected: painter.setPen(QPen(QBrush(Qt.green), 2 * selpensize2)) painter.drawEllipse(x - size2 - selpensize2, y - size2 - selpensize2, size + selpensize2, size + selpensize2) color = QColor(*color) color.setAlpha(self._opacity) painter.setBrush(QBrush(color) if _in_subset else Qt.NoBrush) painter.setPen(QPen(QBrush(color.darker(180)), 2 * pensize2)) painter.drawEllipse(x - size2 - pensize2, y - size2 - pensize2, size + pensize2, size + pensize2) im.save(self._overlay_image_path, 'PNG') self.evalJS('markersImageLayer.setUrl("{}#{}"); 0;'.format( self.toFileURL(self._overlay_image_path), np.random.random())) cur += self.N_POINTS_PER_ITER if cur < len(visible): QTimer.singleShot(10, add_points) self._owwidget.progressBarAdvance(100 / n_iters, None) else: self._owwidget.progressBarFinished(None)
def make_shape_legend(self): if self.attr_shape is None or self.attr_shape == self.get_color(): return if not self.legend: self.create_legend() color = QColor(0, 0, 0) color.setAlpha(self.alpha_value) for i, value in enumerate(self._get_values(self.attr_shape)): self.legend.addItem( ScatterPlotItem(pen=color, brush=color, size=10, symbol=self.CurveSymbols[i]), escape(value))
def __init__(self, view_box, x, y, text, tooltip): bg_color = QColor(Qt.white) bg_color.setAlpha(200) color = QColor(Qt.black) super().__init__(text, pg.mkColor(color), fill=pg.mkBrush(bg_color)) self._x = x self._y = y self._view_box = view_box self._view_box.sigStateChanged.connect(self.center) self.textItem.setToolTip(tooltip) self.setPos(x, y) self.center()
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 make_shape_legend(self): shape = self.get_shape() if shape is None or shape == self.get_color(): return if not self.legend: self.create_legend() color = QColor(0, 0, 0) color.setAlpha(self.alpha_value) for i, value in enumerate(self.attr_shape.values): self.legend.addItem( ScatterPlotItem(pen=color, brush=color, size=10, symbol=self.CurveSymbols[i]), escape(value))
def draw_distributions(self): """Draw distributions with discrete attributes""" if not (self.show_distributions and self.data is not None and self.domain.has_discrete_class): return class_count = len(self.domain.class_var.values) class_ = self.domain.class_var # we create a hash table of possible class values (happens only if we have a discrete class) if self.domain_contingencies is None: self.domain_contingencies = dict( zip([attr for attr in self.domain if attr.is_discrete], get_contingencies(self.data, skipContinuous=True))) self.domain_contingencies[class_] = get_contingency(self.data, class_, class_) max_count = max([contingency.max() for contingency in self.domain_contingencies.values()] or [1]) sorted_class_values = get_variable_values_sorted(self.domain.class_var) for axis_idx, attr_idx in enumerate(self.attribute_indices): attr = self.domain[attr_idx] if attr.is_discrete: continue contingency = self.domain_contingencies[attr] attr_len = len(attr.values) # we create a hash table of variable values and their indices sorted_variable_values = get_variable_values_sorted(attr) # create bar curve for j in range(attr_len): attribute_value = sorted_variable_values[j] value_count = contingency[:, attribute_value] for i in range(class_count): class_value = sorted_class_values[i] color = QColor(*self.colors[i]) color.setAlpha(self.alpha_value) width = float(value_count[class_value] * 0.5) / float(max_count) y_off = float(1.0 + 2.0 * j) / float(2 * attr_len) height = 0.7 / float(class_count * attr_len) y_low_bottom = y_off + float(class_count * height) / 2.0 - i * height curve = PolygonCurve(QPen(color), QBrush(color), xData=[axis_idx, axis_idx + width, axis_idx + width, axis_idx], yData=[y_low_bottom, y_low_bottom, y_low_bottom - height, y_low_bottom - height], tooltip=attr.name) curve.attach(self)
def _update_colored_legend(self, legend, labels, symbols): if self.scatterplot_item is None or not self.palette: return if isinstance(symbols, str): symbols = itertools.repeat(symbols, times=len(labels)) for i, (label, symbol) in enumerate(zip(labels, symbols)): color = QColor(*self.palette.getRGB(i)) pen = _make_pen(color.darker(self.DarkerValue), 1.5) color.setAlpha(255 if self.subset_is_shown else self.alpha_value) brush = QBrush(color) legend.addItem( ScatterPlotItem(pen=pen, brush=brush, size=10, symbol=symbol), escape(label))
def make_shape_legend(self): shape_index = self.get_shape_index() if shape_index == -1 or shape_index == self.get_color_index(): return if not self.legend: self.create_legend() shape_var = self.domain[shape_index] color = QColor(0, 0, 0) color.setAlpha(self.alpha_value) for i, value in enumerate(shape_var.values): self.legend.addItem( ScatterPlotItem(pen=color, brush=color, size=10, symbol=self.CurveSymbols[i]), escape(value))
def _change_pen(self): pen = QPen(self._pen) if self._in_subset and self._selected: color = QColor(self._pen.color()) color.setAlpha(255) pen.setWidth(4) pen.setColor(color) elif not self._in_subset and self._selected: color = QColor(self._pen.color()) color.setAlpha(255) pen.setColor(color) elif self._in_subset and not self._selected: pen.setWidth(4) self.setPen(pen) self.setSymbolPen(pen)
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 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() 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 _change_pen(self): pen = QPen(self._pen) color = QColor(Qt.black) if self._selected and self.master.has_subset \ else QColor(self._pen.color()) if self._in_subset or self._selected: width = LinePlotStyle.SELECTED_LINE_WIDTH alpha = LinePlotStyle.SELECTED_LINE_ALPHA else: width = LinePlotStyle.UNSELECTED_LINE_WIDTH alpha = LinePlotStyle.UNSELECTED_LINE_ALPHA_WITH_SELECTION \ if self.master.has_subset or self.master.has_selection else \ LinePlotStyle.UNSELECTED_LINE_ALPHA pen.setWidth(width) color.setAlpha(alpha) pen.setColor(color) self.setPen(pen)
def __init__(self, view_box, x, y, words, tooltip): bg_color = QColor(Qt.white) bg_color.setAlpha(200) color = QColor(Qt.black) super().__init__( color=pg.mkColor(color), fill=pg.mkBrush(bg_color), html="<br>".join(words), ) option = self.textItem.document().defaultTextOption() option.setAlignment(Qt.AlignCenter) self.textItem.document().setDefaultTextOption(option) self.textItem.setTextWidth(self.textItem.boundingRect().width()) self._x = x self._y = y self._view_box = view_box self._view_box.sigStateChanged.connect(self.center) self.textItem.setToolTip(tooltip) self.setPos(x, y) self.center()
def __preview_color(self): """ Shows selected colors in two QLabel widgets. The first shows true color, while the second presents the color with an opacity as seen in the timeline and with some dummy text to preview readability. """ pixmap = QPixmap(50, 25) color = QColor(*self.color.getRgb()) # Preview color color.setAlpha(int(255 * 1.0)) pixmap.fill(color) self._ui.label_color.setPixmap(pixmap) # Preview color with transparency and some text color.setAlpha(int(255 * 0.5)) pixmap.fill(color) painter = QPainter(pixmap) painter.setFont(QFont('Decorative', 8)) painter.drawText(pixmap.rect(), QtCore.Qt.AlignCenter, "Text") painter.end() self._ui.label_color_alpha.setPixmap(pixmap)
def _change_pen(self): pen = QPen(self._pen) if self._in_subset and self._selected: color = QColor(self._pen.color()) color.setAlpha(255) pen.setWidth(4) pen.setColor(color) elif not self._in_subset and self._selected: color = QColor(self._pen.color()) color.setAlpha(255) pen.setColor(color) elif self._in_subset and not self._selected: color = QColor(self._pen.color()) color.setAlpha(LinePlotColors.LIGHT_ALPHA) pen.setWidth(4) pen.setColor(color) else: color = QColor(self._pen.color()) color.setAlpha(LinePlotColors.LIGHT_ALPHA) pen.setColor(color) self.setPen(pen)
def _get_sel_range_curve(self): color = QColor(self.color) color.setAlpha(LinePlotStyle.SELECTED_RANGE_ALPHA) curve1 = curve2 = pg.PlotDataItem(x=self.x_data, y=self.__mean) return pg.FillBetweenItem(curve1, curve2, brush=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 _setup_plot(self): """Setup the plot with new curve data.""" assert self.data is not None data, domain = self.data, self.data.domain if is_discrete(domain.class_var): class_col_data, _ = data.get_column_view(domain.class_var) group_indices = [np.flatnonzero(class_col_data == i) for i in range(len(domain.class_var.values))] else: group_indices = [np.arange(len(data))] X = np.arange(1, len(domain.attributes)+1) groups = [] for i, indices in enumerate(group_indices): if self.classes: color = self.class_colors[i] else: color = QColor(Qt.darkGray) group_data = data[indices, :] plot_x, plot_y, connect = disconnected_curve_data(group_data.X, x=X) color.setAlpha(200) lightcolor = QColor(color.lighter(factor=150)) lightcolor.setAlpha(150) pen = QPen(color, 2) pen.setCosmetic(True) lightpen = QPen(lightcolor, 1) lightpen.setCosmetic(True) hoverpen = QPen(pen) hoverpen.setWidth(2) curve = pg.PlotCurveItem( x=plot_x, y=plot_y, connect=connect, pen=lightpen, symbolSize=2, antialias=True, ) self.graph.addItem(curve) hovercurves = [] for index, profile in zip(indices, group_data.X): hcurve = HoverCurve(x=X, y=profile, pen=hoverpen, antialias=True) hcurve.setToolTip('{}'.format(index)) hcurve._data_index = index hovercurves.append(hcurve) self.graph.addItem(hcurve) mean = np.nanmean(group_data.X, axis=0) meancurve = pg.PlotDataItem( x=X, y=mean, pen=pen, size=5, symbol="o", pxMode=True, symbolSize=5, antialias=True ) hoverpen = QPen(hoverpen) hoverpen.setWidth(5) hc = HoverCurve(x=X, y=mean, pen=hoverpen, antialias=True) hc.setFlag(QGraphicsItem.ItemIsSelectable, False) self.graph.addItem(hc) self.graph.addItem(meancurve) self.legend_items.append(meancurve) q1, q2, q3 = np.nanpercentile(group_data.X, [25, 50, 75], axis=0) # TODO: implement and use a box plot item errorbar = pg.ErrorBarItem( x=X, y=mean, bottom=np.clip(mean - q1, 0, mean - q1), top=np.clip(q3 - mean, 0, q3 - mean), beam=0.5 ) self.graph.addItem(errorbar) groups.append( namespace( data=group_data, indices=indices, profiles=curve, hovercurves=hovercurves, mean=meancurve, boxplot=errorbar) ) self.__groups = groups self.__update_visibility() self.__update_tooltips()
def update_sel_profiles_color(self, subset): color = QColor(Qt.black) if subset else QColor(self.color) color.setAlpha(LinePlotStyle.SELECTED_LINE_ALPHA) pen = self.make_pen(color, LinePlotStyle.SELECTED_LINE_WIDTH) x, y = self.sel_profiles.getData() self.sel_profiles.setData(x=x, y=y, pen=pen)
def _get_sel_range_curve(self): color = QColor(self.color) color.setAlpha(self.graph.sel_range_settings[Updater.ALPHA_LABEL]) curve1 = curve2 = pg.PlotDataItem(x=self.x_data, y=self.__mean) return pg.FillBetweenItem(curve1, curve2, brush=color)
def _get_sel_profiles_curve(self): color = QColor(self.color) color.setAlpha(LinePlotStyle.SELECTED_LINE_ALPHA) pen = self.make_pen(color, LinePlotStyle.SELECTED_LINE_WIDTH) return pg.PlotCurveItem(x=None, y=None, pen=pen, antialias=False)
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 draw_distributions(self): """Draw distributions with discrete attributes""" if not (self.show_distributions and self.data is not None and self.domain.has_discrete_class): return class_count = len(self.domain.class_var.values) class_ = self.domain.class_var # we create a hash table of possible class values (happens only if we have a discrete class) if self.domain_contingencies is None: self.domain_contingencies = dict( zip([attr for attr in self.domain if attr.is_discrete], get_contingencies(self.data, skipContinuous=True))) self.domain_contingencies[class_] = get_contingency( self.data, class_, class_) max_count = max([ contingency.max() for contingency in self.domain_contingencies.values() ] or [1]) sorted_class_values = get_variable_values_sorted(self.domain.class_var) for axis_idx, attr_idx in enumerate(self.attribute_indices): attr = self.domain[attr_idx] if attr.is_discrete: continue contingency = self.domain_contingencies[attr] attr_len = len(attr.values) # we create a hash table of variable values and their indices sorted_variable_values = get_variable_values_sorted(attr) # create bar curve for j in range(attr_len): attribute_value = sorted_variable_values[j] value_count = contingency[:, attribute_value] for i in range(class_count): class_value = sorted_class_values[i] color = QColor(*self.colors[i]) color.setAlpha(self.alpha_value) width = float( value_count[class_value] * 0.5) / float(max_count) y_off = float(1.0 + 2.0 * j) / float(2 * attr_len) height = 0.7 / float(class_count * attr_len) y_low_bottom = y_off + float( class_count * height) / 2.0 - i * height curve = PolygonCurve(QPen(color), QBrush(color), xData=[ axis_idx, axis_idx + width, axis_idx + width, axis_idx ], yData=[ y_low_bottom, y_low_bottom, y_low_bottom - height, y_low_bottom - height ], tooltip=attr.name) curve.attach(self)
def draw_statistics(self): """Draw lines that represent standard deviation or quartiles""" return # TODO: Implement using BasicStats if self.show_statistics and self.data is not None: data = [] domain = self.data.domain for attr_idx in self.attribute_indices: if not self.domain[attr_idx].is_continuous: data.append([()]) continue # only for continuous attributes if not domain.class_var or domain.has_continuous_class: if self.show_statistics == MEANS: m = self.domain_data_stat[attr_idx].mean dev = self.domain_data_stat[attr_idx].var data.append([(m - dev, m, m + dev)]) elif self.show_statistics == MEDIAN: data.append([(0, 0, 0)]) continue sorted_array = np.sort(attr_values) if len(sorted_array) > 0: data.append([ (sorted_array[int(len(sorted_array) / 4.0)], sorted_array[int(len(sorted_array) / 2.0)], sorted_array[int(len(sorted_array) * 0.75)]) ]) else: data.append([(0, 0, 0)]) else: curr = [] class_values = get_variable_values_sorted( self.domain.class_var) class_index = self.domain.index(self.domain.class_var) for c in range(len(class_values)): attr_values = self.data[attr_idx, self.data[class_index] == c] attr_values = attr_values[~np.isnan(attr_values)] if len(attr_values) == 0: curr.append((0, 0, 0)) continue if self.show_statistics == MEANS: m = attr_values.mean() dev = attr_values.std() curr.append((m - dev, m, m + dev)) elif self.show_statistics == MEDIAN: sorted_array = np.sort(attr_values) curr.append( (sorted_array[int(len(attr_values) / 4.0)], sorted_array[int(len(attr_values) / 2.0)], sorted_array[int(len(attr_values) * 0.75)])) data.append(curr) # draw vertical lines for i in range(len(data)): for c in range(len(data[i])): if data[i][c] == (): continue x = i - 0.03 * (len(data[i]) - 1) / 2.0 + c * 0.03 col = QColor(self.discrete_palette[c]) col.setAlpha(self.alpha_value_2) self.add_curve( "", col, col, 3, OWCurve.Lines, OWPoint.NoSymbol, xData=[x, x, x], yData=[data[i][c][0], data[i][c][1], data[i][c][2]], lineWidth=4) self.add_curve("", col, col, 1, OWCurve.Lines, OWPoint.NoSymbol, xData=[x - 0.03, x + 0.03], yData=[data[i][c][0], data[i][c][0]], lineWidth=4) self.add_curve("", col, col, 1, OWCurve.Lines, OWPoint.NoSymbol, xData=[x - 0.03, x + 0.03], yData=[data[i][c][1], data[i][c][1]], lineWidth=4) self.add_curve("", col, col, 1, OWCurve.Lines, OWPoint.NoSymbol, xData=[x - 0.03, x + 0.03], yData=[data[i][c][2], data[i][c][2]], lineWidth=4) # draw lines with mean/median values if not domain.class_var or domain.has_continuous_class: class_count = 1 else: class_count = len(self.domain.class_var.values) for c in range(class_count): diff = -0.03 * (class_count - 1) / 2.0 + c * 0.03 ys = [] xs = [] for i in range(len(data)): if data[i] != [()]: ys.append(data[i][c][1]) xs.append(i + diff) else: if len(xs) > 1: col = QColor(self.discrete_palette[c]) col.setAlpha(self.alpha_value_2) self.add_curve("", col, col, 1, OWCurve.Lines, OWPoint.NoSymbol, xData=xs, yData=ys, lineWidth=4) xs = [] ys = [] col = QColor(self.discrete_palette[c]) col.setAlpha(self.alpha_value_2) self.add_curve("", col, col, 1, OWCurve.Lines, OWPoint.NoSymbol, xData=xs, yData=ys, lineWidth=4)
def _get_profiles_curve(self): x, y, con = self.__get_disconnected_curve_data(self.y_data) color = QColor(self.color) color.setAlpha(LinePlotStyle.UNSELECTED_LINE_ALPHA) pen = self.make_pen(color) return pg.PlotCurveItem(x=x, y=y, connect=con, pen=pen, antialias=True)
def draw_statistics(self): """Draw lines that represent standard deviation or quartiles""" return # TODO: Implement using BasicStats if self.show_statistics and self.data is not None: data = [] domain = self.data.domain for attr_idx in self.attribute_indices: if not self.domain[attr_idx].is_continuous: data.append([()]) continue # only for continuous attributes if not domain.class_var or domain.has_continuous_class: if self.show_statistics == MEANS: m = self.domain_data_stat[attr_idx].mean dev = self.domain_data_stat[attr_idx].var data.append([(m - dev, m, m + dev)]) elif self.show_statistics == MEDIAN: data.append([(0, 0, 0)]); continue sorted_array = np.sort(attr_values) if len(sorted_array) > 0: data.append([(sorted_array[int(len(sorted_array) / 4.0)], sorted_array[int(len(sorted_array) / 2.0)], sorted_array[int(len(sorted_array) * 0.75)])]) else: data.append([(0, 0, 0)]) else: curr = [] class_values = get_variable_values_sorted(self.domain.class_var) class_index = self.domain.index(self.domain.class_var) for c in range(len(class_values)): attr_values = self.data[attr_idx, self.data[class_index] == c] attr_values = attr_values[~np.isnan(attr_values)] if len(attr_values) == 0: curr.append((0, 0, 0)) continue if self.show_statistics == MEANS: m = attr_values.mean() dev = attr_values.std() curr.append((m - dev, m, m + dev)) elif self.show_statistics == MEDIAN: sorted_array = np.sort(attr_values) curr.append((sorted_array[int(len(attr_values) / 4.0)], sorted_array[int(len(attr_values) / 2.0)], sorted_array[int(len(attr_values) * 0.75)])) data.append(curr) # draw vertical lines for i in range(len(data)): for c in range(len(data[i])): if data[i][c] == (): continue x = i - 0.03 * (len(data[i]) - 1) / 2.0 + c * 0.03 col = QColor(self.discrete_palette[c]) col.setAlpha(self.alpha_value_2) self.add_curve("", col, col, 3, OWCurve.Lines, OWPoint.NoSymbol, xData=[x, x, x], yData=[data[i][c][0], data[i][c][1], data[i][c][2]], lineWidth=4) self.add_curve("", col, col, 1, OWCurve.Lines, OWPoint.NoSymbol, xData=[x - 0.03, x + 0.03], yData=[data[i][c][0], data[i][c][0]], lineWidth=4) self.add_curve("", col, col, 1, OWCurve.Lines, OWPoint.NoSymbol, xData=[x - 0.03, x + 0.03], yData=[data[i][c][1], data[i][c][1]], lineWidth=4) self.add_curve("", col, col, 1, OWCurve.Lines, OWPoint.NoSymbol, xData=[x - 0.03, x + 0.03], yData=[data[i][c][2], data[i][c][2]], lineWidth=4) # draw lines with mean/median values if not domain.class_var or domain.has_continuous_class: class_count = 1 else: class_count = len(self.domain.class_var.values) for c in range(class_count): diff = - 0.03 * (class_count - 1) / 2.0 + c * 0.03 ys = [] xs = [] for i in range(len(data)): if data[i] != [()]: ys.append(data[i][c][1]) xs.append(i + diff) else: if len(xs) > 1: col = QColor(self.discrete_palette[c]) col.setAlpha(self.alpha_value_2) self.add_curve("", col, col, 1, OWCurve.Lines, OWPoint.NoSymbol, xData=xs, yData=ys, lineWidth=4) xs = [] ys = [] col = QColor(self.discrete_palette[c]) col.setAlpha(self.alpha_value_2) self.add_curve("", col, col, 1, OWCurve.Lines, OWPoint.NoSymbol, xData=xs, yData=ys, lineWidth=4)
def get_color(self, alpha) -> QColor: color = QColor(*self.color) if self.color else QColor(Qt.darkGray) color.setAlpha(alpha) return color