class _SelectionItem(QGraphicsItemGroup): def __init__(self, parent, path, unscaled_path, label=""): super().__init__(parent) self.path = QGraphicsPathItem(path, self) self.path.setPen(make_pen(width=1, cosmetic=True)) self.addToGroup(self.path) self.label = QGraphicsSimpleTextItem(label) self._update_label_pos() self.addToGroup(self.label) self.unscaled_path = unscaled_path def set_path(self, path): self.path.setPath(path) self._update_label_pos() def set_label(self, label): self.label.setText(label) self.label.setBrush(Qt.blue) self._update_label_pos() def set_color(self, color): self.path.setBrush(QColor(color)) def _update_label_pos(self): path = self.path.path() elements = (path.elementAt(i) for i in range(path.elementCount())) points = ((p.x, p.y) for p in elements) p1, p2, *rest = sorted(points) x, y = p1[0], (p1[1] + p2[1]) / 2 brect = self.label.boundingRect() # leaf nodes' paths are 4 pixels higher; leafs are `len(rest) == 3` self.label.setPos(x - brect.width() - 4, y - brect.height() + 4 * (len(rest) == 3))
def __setup(self) -> None: self.__clear() font = self.__effectiveFont if self.__autoScale else self.font() assert self.__group is None group = QGraphicsItemGroup() brush = self.palette().brush(QPalette.Text) for text in self.__items: t = QGraphicsSimpleTextItem(group) t.setBrush(brush) t.setFont(font) t.setText(text) t.setData(0, text) self.__textitems.append(t) group.setParentItem(self) self.__group = group
def mean_label(self, stat, attr, val_name): label = QGraphicsItemGroup() t = QGraphicsSimpleTextItem("%.*f" % (attr.number_of_decimals + 1, 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 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 __setup(self): # Setup the subwidgets/groups/layout smax = max( (np.nanmax(g.scores) for g in self.__groups if g.scores.size), default=1) smax = 1 if np.isnan(smax) else smax smin = min( (np.nanmin(g.scores) for g in self.__groups if g.scores.size), default=-1) smin = -1 if np.isnan(smin) else smin smin = min(smin, 0) font = self.font() font.setPixelSize(self.__barHeight) foreground = self.palette().brush(QPalette.WindowText) ax = AxisItem(parent=self, orientation="top", maxTickLength=7) ax.setRange(smin, smax) self.__topScale = ax layout = self.__layout assert layout is self.layout() layout.addItem(ax, 0, 2) for i, group in enumerate(self.__groups): silhouettegroup = BarPlotItem(parent=self) silhouettegroup.setBrush(QBrush(QColor(*group.color))) silhouettegroup.setPen(self.__pen) silhouettegroup.setDataRange(smin, smax) silhouettegroup.setPlotData(group.scores) silhouettegroup.setPreferredBarSize(self.__barHeight) silhouettegroup.setData(0, group.indices) layout.addItem(silhouettegroup, i + 1, 2) if group.label: layout.addItem(Line(orientation=Qt.Vertical), i + 1, 1) text = group.label if group.scores.size: text += f" ({np.mean(group.scores):.3f})" label = QGraphicsSimpleTextItem(text, self) label.setBrush(foreground) label.setPen(QPen(Qt.NoPen)) label.setRotation(-90) item = SimpleLayoutItem( label, anchor=(0., 1.0), anchorItem=(0., 0.), ) item.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) layout.addItem(item, i + 1, 0, Qt.AlignCenter) textlist = _SilhouettePlotTextListWidget(self, font=font, elideMode=Qt.ElideRight, alignment=Qt.AlignLeft | Qt.AlignVCenter) textlist.setMaximumWidth(750) textlist.setFlag(TextListWidget.ItemClipsChildrenToShape, False) sp = textlist.sizePolicy() sp.setVerticalPolicy(QSizePolicy.Ignored) textlist.setSizePolicy(sp) if group.rownames is not None: textlist.setItems(group.items) textlist.setVisible(self.__rowNamesVisible) else: textlist.setVisible(False) layout.addItem(textlist, i + 1, 3) ax = AxisItem(parent=self, orientation="bottom", maxTickLength=7) ax.setRange(smin, smax) self.__bottomScale = ax layout.addItem(ax, len(self.__groups) + 1, 2)