예제 #1
0
 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
예제 #2
0
    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
예제 #3
0
    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
예제 #4
0
 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()
예제 #5
0
 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)
예제 #6
0
    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)
예제 #7
0
 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)
예제 #8
0
 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
예제 #9
0
 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)
예제 #10
0
    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]
예제 #11
0
    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)
예제 #12
0
    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)
예제 #13
0
 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
예제 #14
0
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
예제 #15
0
        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)
예제 #16
0
    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)