def strudel(self, dist): attr = self.attribute ss = np.sum(dist) box = QGraphicsItemGroup() if ss < 1e-6: QGraphicsRectItem(0, -10, 1, 10, box) cum = 0 for i, v in enumerate(dist): if v < 1e-6: continue if self.stretched: v /= ss v *= self.scale_x rect = QGraphicsRectItem(cum + 1, -6, v - 2, 12, box) rect.setBrush(QBrush(QColor(*attr.colors[i]))) rect.setPen(QPen(Qt.NoPen)) if self.stretched: tooltip = "{}: {:.2f}%".format(attr.values[i], 100 * dist[i] / sum(dist)) else: tooltip = "{}: {}".format(attr.values[i], int(dist[i])) rect.setToolTip(tooltip) text = QGraphicsTextItem(attr.values[i]) box.addToGroup(text) cum += v return box
def box_group(self, stat, height=20): def line(x0, y0, x1, y1, *args): return QGraphicsLineItem(x0 * scale_x, y0, x1 * scale_x, y1, *args) scale_x = self.scale_x box = QGraphicsItemGroup() whisker1 = line(stat.a_min, -1.5, stat.a_min, 1.5, box) whisker2 = line(stat.a_max, -1.5, stat.a_max, 1.5, box) vert_line = line(stat.a_min, 0, stat.a_max, 0, box) mean_line = line(stat.mean, -height / 3, stat.mean, height / 3, box) for it in (whisker1, whisker2, mean_line): it.setPen(self._pen_paramet) vert_line.setPen(self._pen_dotted) var_line = line(stat.mean - stat.dev, 0, stat.mean + stat.dev, 0, box) var_line.setPen(self._pen_paramet) mbox = QGraphicsRectItem(stat.q25 * scale_x, -height / 2, (stat.q75 - stat.q25) * scale_x, height, box) mbox.setBrush(self._box_brush) mbox.setPen(QPen(Qt.NoPen)) mbox.setZValue(-200) median_line = line(stat.median, -height / 2, stat.median, height / 2, box) median_line.setPen(self._pen_median) median_line.setZValue(-150) return box
def label_group(self, stat, attr, mean_lab): def centered_text(val, pos): t = QGraphicsSimpleTextItem( "%.*f" % (attr.number_of_decimals + 1, val), labels ) t.setFont(self._label_font) bbox = t.boundingRect() t.setPos(pos - bbox.width() / 2, 22) return t def line(x, down=1): QGraphicsLineItem(x, 12 * down, x, 20 * down, labels) def move_label(label, frm, to): label.setX(to) to += t_box.width() / 2 path = QPainterPath() path.lineTo(0, 4) path.lineTo(to - frm, 4) path.lineTo(to - frm, 8) p = QGraphicsPathItem(path) p.setPos(frm, 12) labels.addToGroup(p) labels = QGraphicsItemGroup() labels.addToGroup(mean_lab) m = stat.mean * self.scale_x mean_lab.setPos(m, -22) line(m, -1) if stat.median is not None: msc = stat.median * self.scale_x med_t = centered_text(stat.median, msc) med_box_width2 = med_t.boundingRect().width() line(msc) if stat.q25 is not None: x = stat.q25 * self.scale_x t = centered_text(stat.q25, x) t_box = t.boundingRect() med_left = msc - med_box_width2 if x + t_box.width() / 2 >= med_left - 5: move_label(t, x, med_left - t_box.width() - 5) else: line(x) if stat.q75 is not None: x = stat.q75 * self.scale_x t = centered_text(stat.q75, x) t_box = t.boundingRect() med_right = msc + med_box_width2 if x - t_box.width() / 2 <= med_right + 5: move_label(t, x, med_right + 5) else: line(x) return labels
def __init__(self, parent): super().__init__(parent) self.__offset = 2 self.__group = QGraphicsItemGroup(self) self.__bar_height = ViolinItem.HEIGHT * 3 self._add_bar() self._add_high_label() self._add_low_label() self._add_feature_label()
def __init__(self, parent, attr_name: str, x_range: Tuple[float], width: int): super().__init__(parent) self._attr_name = attr_name self._width = width self._height = self.HEIGHT self._range = x_range self._x_data: Optional[Union[np.ndarray, float]] = None self._group = QGraphicsItemGroup(self)
def __setup(self): self.__clear() font = self.font() group = QGraphicsItemGroup(self) for text in self.__items: t = QGraphicsSimpleTextItem(text, group) t.setData(0, text) t.setFont(font) t.setToolTip(text) self.__textitems.append(t)
def __init__(self, parent): super().__init__(parent) self.__offset = 2 self.__group = QGraphicsItemGroup(self) self._add_bar() self._add_high_label() self._add_low_label() self._add_feature_label() font = self.font() font.setPointSize(self.FONT_SIZE) self.set_font(font)
def __setup(self) -> None: self.__clear() font = self.__effectiveFont if self.__autoScale else self.font() assert self.__group is None group = QGraphicsItemGroup() for text in self.__items: t = QGraphicsSimpleTextItem(group) t.setFont(font) t.setText(text) t.setData(0, text) self.__textitems.append(t) group.setParentItem(self) self.__group = group
def redraw_grid(self): if self.grid is not None: self.scene.removeItem(self.grid) self.grid = QGraphicsItemGroup() self.grid.setZValue(-200) self.grid_cells = np.full((self.size_y, self.size_x), None) for y in range(self.size_y): for x in range(self.size_x - (y % 2) * self.hexagonal): if self.hexagonal: cell = QGraphicsPathItem(_hexagon_path) cell.setPos(x + (y % 2) / 2, y * sqrt3_2) else: cell = QGraphicsRectItem(x - 0.5, y - 0.5, 1, 1) self.grid_cells[y, x] = cell cell.setPen(self._grid_pen) self.grid.addToGroup(cell) self.scene.addItem(self.grid)
def __init__(self, parent): super().__init__(parent) self.__range = None # type: Tuple[float] self.__value_range = None # type: Tuple[float] self.__model_output = None # type: float self.__base_value = None # type: float self.__group = QGraphicsItemGroup(self) low_color, high_color = QColor(*RGB_LOW), QColor(*RGB_HIGH) self.__low_item = QGraphicsRectItem() self.__low_item.setPen(QPen(low_color)) self.__low_item.setBrush(QBrush(low_color)) self.__high_item = QGraphicsRectItem() self.__high_item.setPen(QPen(high_color)) self.__high_item.setBrush(QBrush(high_color)) self.__low_cover_item = LowCoverItem() self.__high_cover_item = HighCoverItem() pen = QPen(IndicatorItem.COLOR) pen.setStyle(Qt.DashLine) pen.setWidth(1) self.__model_output_line = QGraphicsLineItem() self.__model_output_line.setPen(pen) self.__base_value_line = QGraphicsLineItem() self.__base_value_line.setPen(pen) self.__model_output_ind = IndicatorItem("Model prediction: {}") self.__base_value_ind = IndicatorItem("Base value: {}\nThe average " "prediction for selected class.") self.__group.addToGroup(self.__low_item) self.__group.addToGroup(self.__high_item) self.__group.addToGroup(self.__low_cover_item) self.__group.addToGroup(self.__high_cover_item) self.__group.addToGroup(self.__model_output_line) self.__group.addToGroup(self.__base_value_line) self.__group.addToGroup(self.__model_output_ind) self.__group.addToGroup(self.__base_value_ind) self.__low_parts = [] # type: List[LowPartItem] self.__high_parts = [] # type: List[HighPartItem]
def set_data(self, x_data: np.ndarray, color_data: np.ndarray): def put_point(_x, _y): item = QGraphicsEllipseItem() item.setX(_x) item.setY(_y) item.setRect(0, 0, self.POINT_R, self.POINT_R) color = QColor(*colors.pop().astype(int)) item.setPen(QPen(color)) item.setBrush(QBrush(color)) self.__group.addToGroup(item) self.x_data = x_data self.__group = QGraphicsItemGroup(self) x_data_unique, dist, x_data = self.prepare_data() for x, d in zip(x_data_unique, dist): colors = color_data[x_data == np.round(x, 3)] colors = list(colors[np.random.choice(len(colors), 11)]) y = self.HEIGHT / 2 - self.POINT_R / 2 self.plot_data(put_point, x, y, d)
def updateSelectionArea(self): mask = self.selectionMask() brush = self._stylebrush[mask.astype(int)] self._item.setBrush(brush) if self._selitem is not None: self.removeItem(self._selitem) self._selitem = None if self.__selectiondelegate is not None: self._selitem = QGraphicsItemGroup() self._selitem.dataBounds = \ lambda axis, frac=1.0, orthoRange=None: None for p1, p2 in self.__selectiondelegate.selection: r = QRectF(p1, p2).normalized() ritem = QGraphicsRectItem(r, self._selitem) ritem.setBrush(QBrush(Qt.NoBrush)) ritem.setPen(QPen(Qt.red, 0)) self.addItem(self._selitem)
def mean_label(self, stat, attr, val_name): label = QGraphicsItemGroup() t = QGraphicsSimpleTextItem(attr.str_val(stat.mean), label) t.setFont(self._label_font) bbox = t.boundingRect() w2, h = bbox.width() / 2, bbox.height() t.setPos(-w2, -h) tpm = QGraphicsSimpleTextItem( " \u00b1 " + "%.*f" % (attr.number_of_decimals + 1, stat.dev), label) tpm.setFont(self._label_font) tpm.setPos(w2, -h) if val_name: vnm = QGraphicsSimpleTextItem(val_name + ": ", label) vnm.setFont(self._label_font) vnm.setBrush(self._attr_brush) vb = vnm.boundingRect() label.min_x = -w2 - vb.width() vnm.setPos(label.min_x, -h) else: label.min_x = -w2 return label
def wrap_legend_items(items, max_width, hspacing, vspacing): def line_width(line): return sum(item.boundingRect().width() for item in line) \ + hspacing * (len(line) - 1) def create_line(line, yi, fixed_width=None): x = 0 for item in line: item.setPos(x, yi * vspacing) paragraph.addToGroup(item) if fixed_width: x += fixed_width else: x += item.boundingRect().width() + hspacing max_item = max(item.boundingRect().width() + hspacing for item in items) in_line = int(max_width // max_item) if line_width(items) < max_width: # single line lines = [items] fixed_width = None elif in_line < 2: lines = [[]] for i, item in enumerate(items): # just a single column - free wrap lines[-1].append(item) if line_width(lines[-1]) > max_width and len(lines[-1]) > 1: lines.append([lines[-1].pop()]) fixed_width = None else: # arrange into grid lines = [ items[i:i + in_line] for i in range(0, len(items) + in_line - 1, in_line) ] fixed_width = max_item paragraph = QGraphicsItemGroup() for yi, line in enumerate(lines): create_line(line, yi, fixed_width=fixed_width) return paragraph
def create_legend(): if self.variable_color is None: names = ["<-8", "-8:-4", "-4:-2", "-2:2", "2:4", "4:8", ">8", "Residuals:"] colors = self.RED_COLORS[::-1] + self.BLUE_COLORS[1:] edges = repeat(Qt.black) else: names = get_variable_values_sorted(class_var) edges = colors = [QColor(*col) for col in class_var.colors] items = [] size = 8 for name, color, edgecolor in zip(names, colors, edges): item = QGraphicsItemGroup() item.addToGroup( CanvasRectangle(None, -size / 2, -size / 2, size, size, edgecolor, color)) item.addToGroup( CanvasText(None, name, size, 0, Qt.AlignVCenter)) items.append(item) return wrap_legend_items( items, hspacing=20, vspacing=16 + size, max_width=self.canvas_view.width() - xoff)
def _redraw(self): self.Warning.missing_colors.clear() if self.elements: self.scene.removeItem(self.elements) self.elements = None self.view.set_dimensions(self.size_x, self.size_y, self.hexagonal) if self.cells is None: return sizes = self.cells[:, :, 1] - self.cells[:, :, 0] sizes = sizes.astype(float) if not self.size_by_instances: sizes[sizes != 0] = 0.8 else: sizes *= 0.8 / np.max(sizes) self.elements = QGraphicsItemGroup() self.scene.addItem(self.elements) if self.attr_color is None: self._draw_same_color(sizes) elif self.pie_charts: self._draw_pie_charts(sizes) else: self._draw_colored_circles(sizes)