Example #1
0
    def draw_attribute(self, y, atr_name, atr_val, atr_contrib, error):
        fix = (self.offset_left + self.atr_area_w)
        """vertical line where x = 0"""
        self.scene.addLine(0 + fix, y, 0 + fix, y +
                           self.rect_height, self.black_pen)
        """borders"""
        self.scene.addLine(self.offset_left,
                           y, fix + self.atr_area_w, y, self.gray_pen)
        self.scene.addLine(self.offset_left, y + self.rect_height,
                           fix + self.atr_area_w, y + self.rect_height, self.gray_pen)

        if atr_name is not None and atr_val is not None and atr_contrib is not None:
            atr_contrib_x = atr_contrib * self.scale + fix
            error_x = error * self.scale

            padded_rect = self.rect_height - 2 * self.offset_y
            len_rec = 2 * error_x
            graphed_rect = QGraphicsRectItem(
                atr_contrib_x - error_x, y + self.offset_y, len_rec, padded_rect)
            graphed_rect.setBrush(self.brush)
            graphed_rect.setPen(QPen(Qt.NoPen))
            self.scene.addItem(graphed_rect)
            """vertical line marks calculated contribution of attribute"""
            self.atr_line = self.scene.addLine(atr_contrib_x, y + self.offset_y + 2, atr_contrib_x,
                                               y + self.rect_height - self.offset_y - 2, self.blue_pen)

            """atr name and value on the left"""
            self.place_left(QGraphicsSimpleTextItem(
                atr_val, None), y + self.rect_height/2)
            self.place_left_edge(QGraphicsSimpleTextItem(
                atr_name, None), y + self.rect_height/2)

            """atr score on the right"""
            self.place_right(self.format_marking(
                atr_contrib), y + self.rect_height/2)
    def __init__(self, value: float, label: Tuple[str, float],
                 norm_value: float):
        super().__init__()
        color = QColor(*self.light_rgb)
        self.value = value
        self.norm_value = norm_value
        self.setPath(self.get_path())
        pen = QPen(color)
        pen.setWidth(2)
        self.setPen(pen)

        value = np.abs(value)
        self.value_item = item = QGraphicsSimpleTextItem(_str(value))
        item.setToolTip(_str(value, 3))
        font = item.font()
        font.setPixelSize(11)
        item.setFont(font)
        width = item.boundingRect().width()
        item.setX(StripeItem.WIDTH / 2 - width / 2)
        item.setPen(color)
        item.setBrush(color)

        self.label_item = QGraphicsSimpleTextItem(
            f"{label[0]} = {_str(label[1])}")
        self.label_item.setToolTip(f"{label[0]} = {_str(label[1], 3)}")
        self.label_item.setX(StripeItem.WIDTH + StripePlot.SPACING)
Example #3
0
    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._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):
        # 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)
        axispen = QPen(Qt.black)

        ax = pg.AxisItem(parent=self, orientation="top", maxTickLength=7,
                         pen=axispen)
        ax.setRange(smin, smax)
        self.__topScale = ax
        self.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)
            self.layout().addItem(silhouettegroup, i + 1, 2)

            if group.label:
                self.layout().addItem(Line(orientation=Qt.Vertical), i + 1, 1)
                label = QGraphicsSimpleTextItem(self)
                label.setText("{} ({})".format(escape(group.label),
                                               len(group.scores)))
                item = WrapperLayoutItem(label, Qt.Vertical, parent=self)
                self.layout().addItem(item, i + 1, 0, Qt.AlignCenter)

            textlist = TextListWidget(self, font=font)
            sp = textlist.sizePolicy()
            sp.setVerticalPolicy(QSizePolicy.Ignored)
            textlist.setSizePolicy(sp)
            textlist.setParent(self)
            if group.rownames is not None:
                textlist.setItems(group.items)
                textlist.setVisible(self.__rowNamesVisible)
            else:
                textlist.setVisible(False)

            self.layout().addItem(textlist, i + 1, 3)

        ax = pg.AxisItem(parent=self, orientation="bottom", maxTickLength=7,
                         pen=axispen)
        ax.setRange(smin, smax)
        self.__bottomScale = ax
        self.layout().addItem(ax, len(self.__groups) + 1, 2)
Example #5
0
    def __setup(self):
        # Setup the subwidgets/groups/layout
        smax = max((numpy.max(g.scores) for g in self.__groups
                    if g.scores.size),
                   default=1)

        smin = min((numpy.min(g.scores) for g in self.__groups
                    if g.scores.size),
                   default=-1)
        smin = min(smin, 0)

        font = self.font()
        font.setPixelSize(self.__barHeight)
        axispen = QPen(Qt.black)

        ax = pg.AxisItem(parent=self, orientation="top", maxTickLength=7,
                         pen=axispen)
        ax.setRange(smin, smax)
        self.layout().addItem(ax, 0, 2)

        for i, group in enumerate(self.__groups):
            silhouettegroup = BarPlotItem(parent=self)
            silhouettegroup.setBrush(self.__brush)
            silhouettegroup.setPen(self.__pen)
            silhouettegroup.setDataRange(smin, smax)
            silhouettegroup.setPlotData(group.scores)
            silhouettegroup.setPreferredBarSize(self.__barHeight)
            silhouettegroup.setData(0, group.indices)
            self.layout().addItem(silhouettegroup, i + 1, 2)

            if group.label:
                line = QFrame(frameShape=QFrame.VLine)
                proxy = QGraphicsProxyWidget(self)
                proxy.setWidget(line)
                self.layout().addItem(proxy, i + 1, 1)
                label = QGraphicsSimpleTextItem(self)
                label.setText("{} ({})".format(escape(group.label),
                                               len(group.scores)))
                item = WrapperLayoutItem(label, Qt.Vertical, parent=self)
                self.layout().addItem(item, i + 1, 0, Qt.AlignCenter)

            textlist = TextListWidget(self, font=font)
            sp = textlist.sizePolicy()
            sp.setVerticalPolicy(QSizePolicy.Ignored)
            textlist.setSizePolicy(sp)
            textlist.setParent(self)
            if group.rownames is not None:
                textlist.setItems(group.items)
                textlist.setVisible(self.__rowNamesVisible)
            else:
                textlist.setVisible(False)

            self.layout().addItem(textlist, i + 1, 3)

        ax = pg.AxisItem(parent=self, orientation="bottom", maxTickLength=7,
                         pen=axispen)
        ax.setRange(smin, smax)
        self.layout().addItem(ax, len(self.__groups) + 1, 2)
Example #6
0
    def draw_axis(self):
        """Draw the horizontal axis and sets self.scale_x"""
        misssing_stats = not self.stats
        stats = self.stats or [BoxData(np.array([[0.], [1.]]), self.attribute)]
        mean_labels = self.mean_labels or [
            self.mean_label(stats[0], self.attribute, "")
        ]
        bottom = min(stat.a_min for stat in stats)
        top = max(stat.a_max for stat in stats)

        first_val, step = compute_scale(bottom, top)
        while bottom <= first_val:
            first_val -= step
        bottom = first_val
        no_ticks = math.ceil((top - first_val) / step) + 1
        top = max(top, first_val + no_ticks * step)

        gbottom = min(bottom, min(stat.mean - stat.dev for stat in stats))
        gtop = max(top, max(stat.mean + stat.dev for stat in stats))

        bv = self.box_view
        viewrect = bv.viewport().rect().adjusted(15, 15, -15, -30)
        self.scale_x = scale_x = viewrect.width() / (gtop - gbottom)

        # In principle we should repeat this until convergence since the new
        # scaling is too conservative. (No chance am I doing this.)
        mlb = min(stat.mean + mean_lab.min_x / scale_x
                  for stat, mean_lab in zip(stats, mean_labels))
        if mlb < gbottom:
            gbottom = mlb
            self.scale_x = scale_x = viewrect.width() / (gtop - gbottom)

        self.scene_min_x = gbottom * scale_x
        self.scene_max_x = gtop * scale_x
        self.scene_width = self.scene_max_x - self.scene_min_x

        val = first_val
        last_text = self.scene_min_x
        while True:
            l = self.box_scene.addLine(val * scale_x, -1, val * scale_x, 1,
                                       self._pen_axis_tick)
            l.setZValue(100)
            t = QGraphicsSimpleTextItem(
                self.attribute.str_val(val) if not misssing_stats else "?")
            t.setFont(self._axis_font)
            t.setFlags(t.flags() | QGraphicsItem.ItemIgnoresTransformations)
            r = t.boundingRect()
            x_start = val * scale_x - r.width() / 2
            x_finish = x_start + r.width()
            if x_start > last_text + 10 and x_finish < self.scene_max_x:
                t.setPos(x_start, 8)
                self.box_scene.addItem(t)
                last_text = x_finish
            if val >= top:
                break
            val += step
        self.box_scene.addLine(bottom * scale_x - 4, 0, top * scale_x + 4, 0,
                               self._pen_axis)
 def __init__(self, parent, label: str):
     self.__name: str = None
     self.__value: Optional[str] = None
     self.__name_item = QGraphicsSimpleTextItem()
     self.__value_item = QGraphicsSimpleTextItem()
     font = Updater.change_font(QFont(), self.VALUE_FONT_SETTING)
     self.__value_item.setFont(font)
     self.__max_len = self.MAX_LABEL_LEN
     super().__init__(parent)
     self._set_data(label)
Example #8
0
 def _set_labels(self, labels: List[str]):
     for i, (label, _) in enumerate(zip(labels, self.__violin_items)):
         short = f"{label[:self.MAX_ATTR_LEN - 1]}..." \
             if len(label) > self.MAX_ATTR_LEN else label
         text = QGraphicsSimpleTextItem(short, self)
         text.setToolTip(label)
         item = SimpleLayoutItem(text)
         item.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
         self.__layout.addItem(item, i, ViolinPlot.LABEL_COLUMN,
                               Qt.AlignRight | Qt.AlignVCenter)
Example #9
0
    def __init__(self, name, values, scale, name_offset, offset, labels=None):
        super().__init__()

        # leading label
        font = name.document().defaultFont()
        if self.bold_label:
            font.setWeight(QFont.Bold)
        name.setFont(font)
        name.setPos(name_offset, -10)
        name.setParentItem(self)

        # prediction marker
        self.dot = self.DOT_ITEM_CLS(self.dot_r, scale, offset, values[0],
                                     values[-1])
        self.dot.setParentItem(self)

        # line
        line = QGraphicsLineItem(
            min(values) * scale + offset, 0,
            max(values) * scale + offset, 0)
        line.setParentItem(self)

        if labels is None:
            labels = [str(abs(v) if v == -0 else v) for v in values]

        old_x_tick = None
        shown_items = []
        w = QGraphicsSimpleTextItem(labels[0]).boundingRect().width()
        text_finish = values[0] * scale - w + offset - 10
        for i, (label, value) in enumerate(zip(labels, values)):
            text = QGraphicsSimpleTextItem(label)
            x_text = value * scale - text.boundingRect().width() / 2 + offset
            if text_finish > x_text - 10:
                y_text, y_tick = self.dot_r * 0.7, 0
                text_finish = values[0] * scale + offset
            else:
                y_text = -text.boundingRect().height() - self.dot_r * 0.7
                y_tick = -self.tick_height
                text_finish = x_text + text.boundingRect().width()
            text.setPos(x_text, y_text)
            if not collides(text, shown_items):
                text.setParentItem(self)
                shown_items.append(text)

            x_tick = value * scale - self.tick_width / 2 + offset
            tick = QGraphicsRectItem(x_tick, y_tick, self.tick_width,
                                     self.tick_height)
            tick.setBrush(QColor(Qt.black))
            tick.setParentItem(self)

            if self.half_tick_height and i:
                x = x_tick - (x_tick - old_x_tick) / 2
                half_tick = QGraphicsLineItem(x, -self.half_tick_height, x, 0)
                half_tick.setParentItem(self)
            old_x_tick = x_tick
Example #10
0
    def display_changed_disc(self):
        self.clear_scene()
        self.attr_labels = [QGraphicsSimpleTextItem(lab)
                            for lab in self.label_txts_all]

        if not self.stretched:
            if self.group_var:
                self.labels = [
                    QGraphicsTextItem("{}".format(int(sum(cont))))
                    for cont in self.conts]
            else:
                self.labels = [
                    QGraphicsTextItem(str(int(sum(self.dist))))]

        self.draw_axis_disc()
        if self.group_var:
            self.boxes = [self.strudel(cont, i) for i, cont in enumerate(self.conts)]
        else:
            self.boxes = [self.strudel(self.dist)]

        for row, box in enumerate(self.boxes):
            y = (-len(self.boxes) + row) * 40 + 10

            label = self.attr_labels[row]
            b = label.boundingRect()
            label.setPos(-b.width() - 10, y - b.height() / 2)
            self.box_scene.addItem(label)
            if not self.stretched:
                label = self.labels[row]
                b = label.boundingRect()
                if self.group_var:
                    right = self.scale_x * sum(self.conts[row])
                else:
                    right = self.scale_x * sum(self.dist)
                label.setPos(right + 10, y - b.height() / 2)
                self.box_scene.addItem(label)

            if self.attribute is not self.group_var:
                for text_item, bar_part in zip(box[1::2], box[::2]):
                    label = QGraphicsSimpleTextItem(
                        text_item.toPlainText())
                    label.setPos(bar_part.boundingRect().x(),
                                 y - label.boundingRect().height() - 8)
                    self.box_scene.addItem(label)
            for item in box:
                if isinstance(item, QGraphicsTextItem):
                    continue
                self.box_scene.addItem(item)
                item.setPos(0, y)
        self.box_scene.setSceneRect(-self.label_width - 5,
                                    -30 - len(self.boxes) * 40,
                                    self.scene_width, len(self.boxes * 40) + 90)
        self.infot1.setText("")
        self.select_box_items()
    def draw_header_footer(self, wp, header_h, unit_pixels, last_y, first_y, marking_len=15):
        """header"""
        max_x = self.max_contrib * self.scale

        atr_label = QGraphicsSimpleTextItem("Name", None)
        val_label = QGraphicsSimpleTextItem("Value", None)
        score_label = QGraphicsSimpleTextItem("Score", None)

        font = score_label.font()
        font.setBold(True)
        font.setPointSize(13)
        atr_label.setFont(font)
        val_label.setFont(font)
        score_label.setFont(font)

        white_pen = QPen(Qt.white, 3)

        fix = self.offset_left + self.atr_area_w

        self.place_left(val_label, -self.atr_area_h - header_h*0.85)
        self.place_left_edge(atr_label, -self.atr_area_h - header_h*0.85)
        self.place_right(score_label, -self.atr_area_h - header_h*0.85)

        self.scene.addLine(-max_x + fix, -self.atr_area_h - header_h,
                           max_x + fix, -self.atr_area_h - header_h, white_pen)

        """footer"""
        line_y = max(first_y + wp.height() + header_h/2 - 10,
                     last_y + header_h/2 + self.rect_height)
        self.scene.addLine(-max_x + fix, line_y, max_x +
                           fix, line_y, self.black_pen)

        previous = 0
        recomended_d = 35
        for i in range(0, int(self.max_contrib / self.unit) + 1):
            x = unit_pixels * i
            """grid lines"""
            self.scene.addLine(x + fix, first_y, x + fix,
                               line_y, self.light_gray_pen)
            self.scene.addLine(-x + fix, first_y, -x + fix,
                               line_y, self.light_gray_pen)

            self.scene.addLine(x + fix, line_y, x + fix, line_y +
                               marking_len, self.black_pen)
            self.scene.addLine(-x + fix, line_y, -x + fix, line_y +
                               marking_len, self.black_pen)
            """markings on the ruler"""
            if x + fix - previous > recomended_d:
                self.place_centered(self.format_marking(
                    i*self.unit), x + fix, line_y + marking_len + 5)
                if x > 0:
                    self.place_centered(
                        self.format_marking(-i*self.unit), -x + fix, line_y + marking_len + 5)
                previous = x + fix
Example #12
0
        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
Example #13
0
 def _add_low_label(self):
     font = self.font()
     font.setPixelSize(9)
     item = QGraphicsSimpleTextItem("Low")
     item.setFont(font)
     item.setX(self.BAR_WIDTH + self.__offset)
     item.setY(self.__bar_height - item.boundingRect().height())
     self.__group.addToGroup(item)
Example #14
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.setToolTip(text)
         t.setData(0, text)
         self.__textitems.append(t)
     group.setParentItem(self)
     self.__group = group
 def get_needed_offset(self, explanations):
     max_n = 0
     word = ""
     max_v = 0
     val = ""
     for e in explanations:
         if max_n < len(str(e._metas[0])):
             word = str(e._metas[0])
             max_n = len(str(e._metas[0]))
         if max_v < len(str(e._metas[1])):
             val = str(e._metas[1])
             max_v = len(str(e._metas[1]))
     w = QGraphicsSimpleTextItem(word, None)
     v = QGraphicsSimpleTextItem(val, None)
     return w.boundingRect().width(), v.boundingRect().width()
Example #16
0
 def _add_high_label(self):
     font = self.font()
     font.setPixelSize(9)
     item = QGraphicsSimpleTextItem("High")
     item.setFont(font)
     item.setX(self.BAR_WIDTH + self.__offset)
     item.setY(0)
     self.__group.addToGroup(item)
Example #17
0
    def layout_changed(self):
        attr = self.attribute
        if not attr:
            return
        self.clear_scene()
        if self.dataset is None or len(self.conts) == len(self.dist) == 0:
            return

        if not self.is_continuous:
            self.display_changed_disc()
            return

        self.mean_labels = [
            self.mean_label(stat, attr, lab)
            for stat, lab in zip(self.stats, self.label_txts)
        ]
        self.draw_axis()
        self.boxes = [self.box_group(stat) for stat in self.stats]
        self.labels = [
            self.label_group(stat, attr, mean_lab)
            for stat, mean_lab in zip(self.stats, self.mean_labels)
        ]
        self.attr_labels = [
            QGraphicsSimpleTextItem(lab) for lab in self.label_txts
        ]
        for it in chain(self.labels, self.attr_labels):
            self.box_scene.addItem(it)
        self.display_changed()
Example #18
0
    def _display_changed_cont(self):
        self.mean_labels = [self.mean_label(stat, self.attribute, lab)
                            for stat, lab in zip(self.stats, self.label_txts)]
        self.draw_axis()
        self.boxes = [self.box_group(stat) for stat in self.stats]
        self.labels = [self.label_group(stat, self.attribute, mean_lab)
                       for stat, mean_lab in zip(self.stats, self.mean_labels)]
        self.attr_labels = [QGraphicsSimpleTextItem(lab)
                            for lab in self.label_txts]
        for it in chain(self.labels, self.attr_labels):
            self.box_scene.addItem(it)

        self.order = list(range(len(self.stats)))
        criterion = self._sorting_criteria_attrs[self.compare]
        if criterion:
            vals = [getattr(stat, criterion) for stat in self.stats]
            overmax = max((val for val in vals if val is not None), default=0) \
                      + 1
            vals = [val if val is not None else overmax for val in vals]
            self.order = sorted(self.order, key=vals.__getitem__)

        heights = 90 if self.show_annotations else 60

        for row, box_index in enumerate(self.order):
            y = (-len(self.stats) + row) * heights + 10
            for item in self.boxes[box_index]:
                self.box_scene.addItem(item)
                item.setY(y)
            labels = self.labels[box_index]

            if self.show_annotations:
                labels.show()
                labels.setY(y)
            else:
                labels.hide()

            label = self.attr_labels[box_index]
            label.setY(y - 15 - label.boundingRect().height())
            if self.show_annotations:
                label.hide()
            else:
                stat = self.stats[box_index]

                if self.compare == OWBoxPlot.CompareMedians and \
                        stat.median is not None:
                    pos = stat.median + 5 / self.scale_x
                elif self.compare == OWBoxPlot.CompareMeans or stat.q25 is None:
                    pos = stat.mean + 5 / self.scale_x
                else:
                    pos = stat.q25
                label.setX(pos * self.scale_x)
                label.show()

        r = QRectF(self.scene_min_x, -30 - len(self.stats) * heights,
                   self.scene_width, len(self.stats) * heights + 90)
        self.box_scene.setSceneRect(r)

        self._compute_tests_cont()
        self._show_posthoc()
class PartItem(QGraphicsPathItem):
    COLOR = NotImplemented
    TIP_LEN = 13

    def __init__(self, value: float, label: Tuple[str, float],
                 norm_value: float):
        super().__init__()
        color = QColor(*self.light_rgb)
        self.value = value
        self.norm_value = norm_value
        self.setPath(self.get_path())
        pen = QPen(color)
        pen.setWidth(2)
        self.setPen(pen)

        value = np.abs(value)
        self.value_item = item = QGraphicsSimpleTextItem(_str(value))
        item.setToolTip(_str(value, 3))
        font = item.font()
        font.setPixelSize(11)
        item.setFont(font)
        width = item.boundingRect().width()
        item.setX(StripeItem.WIDTH / 2 - width / 2)
        item.setPen(color)
        item.setBrush(color)

        self.label_item = QGraphicsSimpleTextItem(
            f"{label[0]} = {_str(label[1])}")
        self.label_item.setToolTip(f"{label[0]} = {_str(label[1], 3)}")
        self.label_item.setX(StripeItem.WIDTH + StripePlot.SPACING)

    @property
    def light_rgb(self) -> List[int]:
        rgb = np.array(self.COLOR)
        return list((rgb + (255 - rgb) * 0.7).astype(int))

    @property
    def value_height(self) -> float:
        return self.value_item.boundingRect().height()

    @property
    def label_height(self) -> float:
        return self.label_item.boundingRect().height()

    def get_path(self) -> QPainterPath:
        raise NotImplementedError
 def pie_label(self, x, y, label):
     if not label:
         return
     text = QGraphicsSimpleTextItem(label)
     for cut in range(1, len(label)):
         if text.boundingRect().width() < 0.95 * SCALE:
             break
         text = QGraphicsSimpleTextItem(label[:-cut] + "...")
     text.setPos(x - text.boundingRect().width() / 2, y + 0.5 * SCALE)
     self.scene.addItem(text)
Example #21
0
 def draw_stat(self):
     if self.stat_test:
         label = QGraphicsSimpleTextItem(self.stat_test)
         label.setPos((self.scene_min_x + self.scene_max_x)/2 - label.boundingRect().width()/2,
                      8 + self._axis_font.pixelSize()*2)
         label.setFlag(QGraphicsItem.ItemIgnoresTransformations)
         self.box_scene.addItem(label)
Example #22
0
    def __init__(self, name, values, scale, name_offset, offset, labels=None):
        super().__init__()

        # leading label
        font = name.document().defaultFont()
        if self.bold_label:
            font.setWeight(QFont.Bold)
        name.setFont(font)
        name.setPos(name_offset, -10)
        name.setParentItem(self)

        # prediction marker
        self.dot = self.DOT_ITEM_CLS(self.DOT_RADIUS, scale, offset, values[0],
                                     values[-1])
        self.dot.setParentItem(self)

        # pylint: disable=unused-variable
        # line
        line = QGraphicsLineItem(min(values) * scale + offset, 0,
                                 max(values) * scale + offset, 0,
                                 self)

        if labels is None:
            labels = [str(abs(v) if v == -0 else v) for v in values]

        old_x_tick = None
        shown_items = []
        w = QGraphicsSimpleTextItem(labels[0]).boundingRect().width()
        text_finish = values[0] * scale - w + offset - 10
        for i, (label, value) in enumerate(zip(labels, values)):
            text = QGraphicsSimpleTextItem(label)
            x_text = value * scale - text.boundingRect().width() / 2 + offset
            if text_finish > x_text - 10:
                y_text, y_tick = self.DOT_RADIUS * 0.7, 0
                text_finish = values[0] * scale + offset
            else:
                y_text = - text.boundingRect().height() - self.DOT_RADIUS * 0.7
                y_tick = - self.tick_height
                text_finish = x_text + text.boundingRect().width()
            text.setPos(x_text, y_text)
            if not collides(text, shown_items):
                text.setParentItem(self)
                shown_items.append(text)

            x_tick = value * scale - self.tick_width / 2 + offset
            tick = QGraphicsRectItem(
                x_tick, y_tick, self.tick_width, self.tick_height,
                self)
            tick.setBrush(QColor(Qt.black))

            if self.half_tick_height and i:
                x = x_tick - (x_tick - old_x_tick) / 2
                half_tick = QGraphicsLineItem(x, - self.half_tick_height, x, 0,
                                              self)
            old_x_tick = x_tick
Example #23
0
 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
Example #24
0
    def _display_changed_disc(self):
        self.clear_scene()
        self.attr_labels = [
            QGraphicsSimpleTextItem(lab) for lab in self.label_txts_all
        ]

        if not self.show_stretched:
            if self.group_var:
                self.labels = [
                    QGraphicsTextItem("{}".format(int(sum(cont))))
                    for cont in self.conts.array_with_unknowns
                    if np.sum(cont) > 0
                ]
            else:
                self.labels = [QGraphicsTextItem(str(int(sum(self.dist))))]

        self.order = list(range(len(self.attr_labels)))

        self.draw_axis_disc()
        if self.group_var:
            conts = self.conts.array_with_unknowns
            self.boxes = [
                self.strudel(cont, val)
                for cont, val in zip(conts, self.group_var.values + ("", ))
                if np.sum(cont) > 0
            ]
            sums_ = np.sum(conts, axis=1)
            sums_ = sums_[sums_ > 0]  # only bars with sum > 0 are shown

            if self.sort_freqs:
                # pylint: disable=invalid-unary-operand-type
                self.order = sorted(self.order, key=(-sums_).__getitem__)
        else:
            conts = self.dist.array_with_unknowns
            self.boxes = [self.strudel(conts)]
            sums_ = [np.sum(conts)]

        for row, box_index in enumerate(self.order):
            y = (-len(self.boxes) + row) * 40 + 10
            box = self.boxes[box_index]
            bars, labels = box[::2], box[1::2]

            self.__draw_group_labels(y, box_index)
            if not self.show_stretched:
                self.__draw_row_counts(y, self.labels[box_index],
                                       sums_[box_index])
            if self.show_labels and self.attribute is not self.group_var:
                self.__draw_bar_labels(y, bars, labels)
            self.__draw_bars(y, bars)

        self.box_scene.setSceneRect(
            -self.label_width - 5,
            -30 - len(self.boxes) * 40,
            self.scene_width,
            len(self.boxes * 40) + 90,
        )
        self._compute_tests_disc()
Example #25
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)
Example #26
0
 def draw_stat(self):
     if self.stat_test:
         label = QGraphicsSimpleTextItem(self.stat_test)
         brect = self.box_scene.sceneRect()
         label.setPos(
             brect.center().x() - label.boundingRect().width() / 2,
             8 + self._axis_font.pixelSize() * 2,
         )
         label.setFlag(QGraphicsItem.ItemIgnoresTransformations)
         self.box_scene.addItem(label)
Example #27
0
 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
Example #28
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)
Example #29
0
    def display_changed_disc(self):
        self.clear_scene()
        self.attr_labels = [
            QGraphicsSimpleTextItem(lab) for lab in self.label_txts_all
        ]

        if not self.stretched:
            if self.group_var:
                self.labels = [
                    QGraphicsTextItem("{}".format(int(sum(cont))))
                    for cont in self.conts
                ]
            else:
                self.labels = [QGraphicsTextItem(str(int(sum(self.dist))))]

        self.draw_axis_disc()
        if self.group_var:
            self.boxes = [
                self.strudel(cont, i) for i, cont in enumerate(self.conts)
            ]
        else:
            self.boxes = [self.strudel(self.dist)]

        for row, box in enumerate(self.boxes):
            y = (-len(self.boxes) + row) * 40 + 10

            label = self.attr_labels[row]
            b = label.boundingRect()
            label.setPos(-b.width() - 10, y - b.height() / 2)
            self.box_scene.addItem(label)
            if not self.stretched:
                label = self.labels[row]
                b = label.boundingRect()
                if self.group_var:
                    right = self.scale_x * sum(self.conts[row])
                else:
                    right = self.scale_x * sum(self.dist)
                label.setPos(right + 10, y - b.height() / 2)
                self.box_scene.addItem(label)

            if self.attribute is not self.group_var:
                for text_item, bar_part in zip(box.childItems()[1::2],
                                               box.childItems()[::2]):
                    label = QGraphicsSimpleTextItem(text_item.toPlainText())
                    label.setPos(bar_part.boundingRect().x(),
                                 y - label.boundingRect().height() - 8)
                    self.box_scene.addItem(label)
            for text_item in box.childItems()[1::2]:
                box.removeFromGroup(text_item)
            for item in box.childItems():
                self.box_scene.addItem(item)
                item.setPos(0, y)
        self.box_scene.setSceneRect(-self.label_width - 5,
                                    -30 - len(self.boxes) * 40,
                                    self.scene_width,
                                    len(self.boxes * 40) + 90)
        self.infot1.setText("")
        self.select_box_items()
Example #30
0
    def display_changed_disc(self):
        assert not self.is_continuous
        self.clear_scene()
        self.attr_labels = [
            QGraphicsSimpleTextItem(lab) for lab in self.label_txts_all
        ]

        if not self.stretched:
            if self.group_var:
                self.labels = [
                    QGraphicsTextItem("{}".format(int(sum(cont))))
                    for cont in self.conts if np.sum(cont) > 0
                ]
            else:
                self.labels = [QGraphicsTextItem(str(int(sum(self.dist))))]

        self.order = list(range(len(self.attr_labels)))

        self.draw_axis_disc()
        if self.group_var:
            self.boxes = \
                [self.strudel(cont, i) for i, cont in enumerate(self.conts)
                 if np.sum(cont) > 0]
            self.conts = self.conts[np.sum(np.array(self.conts), axis=1) > 0]

            if self.sort_freqs:
                # pylint: disable=invalid-unary-operand-type
                self.order = sorted(
                    self.order, key=(-np.sum(self.conts, axis=1)).__getitem__)
        else:
            self.boxes = [self.strudel(self.dist)]

        for row, box_index in enumerate(self.order):
            y = (-len(self.boxes) + row) * 40 + 10
            box = self.boxes[box_index]
            bars, labels = box[::2], box[1::2]

            self.__draw_group_labels(y, box_index)
            if not self.stretched:
                self.__draw_row_counts(y, box_index)
            if self.show_labels and self.attribute is not self.group_var:
                self.__draw_bar_labels(y, bars, labels)
            self.__draw_bars(y, bars)

        self.box_scene.setSceneRect(-self.label_width - 5,
                                    -30 - len(self.boxes) * 40,
                                    self.scene_width,
                                    len(self.boxes * 40) + 90)
        self.infot1.setText("")
        self.select_box_items()
 def __init__(self, title, rank):
     super().__init__()
     self.setAcceptedMouseButtons(Qt.LeftButton)
     self.setCacheMode(self.DeviceCoordinateCache)
     self.setZValue(10)
     self.edges = []
     self.name = title
     self.squares = GroupOfSquares(self)
     # Add text labels
     if len(title) > 20: title = title[:20] + '…'
     title = self.title = QGraphicsSimpleTextItem(title, self)
     subtitle = self.subtitle = QGraphicsSimpleTextItem('', self)
     self.rank = rank
     title.setFont(Node.Font.TITLE)
     subtitle.setFont(Node.Font.SUBTITLE)
     title.setZValue(12)
     subtitle.setZValue(11)
     # Set node's rect accoring to title size
     title = self.title.boundingRect()
     NODE_WIDTH, NODE_HEIGHT = 1.4, 3
     self.setRect(-NODE_WIDTH / 2 * title.width(),
                  -NODE_HEIGHT / 2 * title.height(),
                  NODE_WIDTH * title.width(), NODE_HEIGHT * title.height())
     self.selected = False
 def pie_label(self, x, y, label):
     if not label:
         return
     text = QGraphicsSimpleTextItem(label)
     for cut in range(1, len(label)):
         if text.boundingRect().width() < 0.95 * SCALE:
             break
         text = QGraphicsSimpleTextItem(label[:-cut] + "...")
     text.setPos(x - text.boundingRect().width() / 2, y + 0.5 * SCALE)
     self.scene.addItem(text)
Example #33
0
    def display_changed_disc(self):
        assert not self.is_continuous
        self.clear_scene()
        self.attr_labels = [
            QGraphicsSimpleTextItem(lab) for lab in self.label_txts_all
        ]

        if not self.stretched:
            if self.group_var:
                self.labels = [
                    QGraphicsTextItem("{}".format(int(sum(cont))))
                    for cont in self.conts if np.sum(cont) > 0
                ]
            else:
                self.labels = [QGraphicsTextItem(str(int(sum(self.dist))))]

        self.draw_axis_disc()
        if self.group_var:
            self.boxes = \
                [self.strudel(cont, i) for i, cont in enumerate(self.conts)
                 if np.sum(cont) > 0]
            self.conts = self.conts[np.sum(np.array(self.conts), axis=1) > 0]
        else:
            self.boxes = [self.strudel(self.dist)]

        for row, box in enumerate(self.boxes):
            y = (-len(self.boxes) + row) * 40 + 10
            bars, labels = box[::2], box[1::2]

            self.__draw_group_labels(y, row)
            if not self.stretched:
                self.__draw_row_counts(y, row)
            if self.show_labels and self.attribute is not self.group_var:
                self.__draw_bar_labels(y, bars, labels)
            self.__draw_bars(y, bars)

        self.box_scene.setSceneRect(-self.label_width - 5,
                                    -30 - len(self.boxes) * 40,
                                    self.scene_width,
                                    len(self.boxes * 40) + 90)
        self.infot1.setText("")
        self.select_box_items()
Example #34
0
    def __init__(self, rect=QRectF(-5, -5, 10, 10), view=None):
        super().__init__(rect)
        self.setCacheMode(self.DeviceCoordinateCache)
        self.setAcceptHoverEvents(True)
        self.setFlags(self.ItemIsMovable | self.ItemIsSelectable
                      | self.ItemIgnoresTransformations
                      | self.ItemIgnoresParentOpacity
                      | self.ItemSendsGeometryChanges)
        self.setZValue(4)

        self.edges = []
        self._radius = rect.width() / 2
        self.__transform = view.transform
        # Add text labels
        label = self.label = QGraphicsSimpleTextItem('test', self)
        label.setVisible(False)
        label.setFlags(self.ItemIgnoresParentOpacity
                       | self.ItemIgnoresTransformations)
        label.setZValue(3)
        view.scene().addItem(label)
 def get_needed_offset(self, explanations):
     max_n = 0
     word = ""
     max_v = 0
     val = ""
     for e in explanations:
         if max_n < len(str(e._metas[0])):
             word = str(e._metas[0])
             max_n = len(str(e._metas[0]))
         if max_v < len(str(e._metas[1])):
             val = str(e._metas[1])
             max_v = len(str(e._metas[1]))
     w = QGraphicsSimpleTextItem(word, None)
     v = QGraphicsSimpleTextItem(val, None)
     return w.boundingRect().width(), v.boundingRect().width()
Example #36
0
    def __init__(self, source, dest, view=None):
        super().__init__()
        self.setAcceptedMouseButtons(Qt.NoButton)
        self.setFlags(self.ItemIgnoresTransformations
                      | self.ItemIgnoresParentOpacity)
        self.setZValue(1)
        self.setPen(QPen(Qt.gray, .7))

        source.addEdge(self)
        dest.addEdge(self)
        self.source = source
        self.dest = dest
        self.__transform = view.transform
        # Add text labels
        label = self.label = QGraphicsSimpleTextItem('test', self)
        label.setVisible(False)
        label.setBrush(Qt.gray)
        label.setZValue(2)
        label.setFlags(self.ItemIgnoresParentOpacity
                       | self.ItemIgnoresTransformations)
        view.scene().addItem(label)

        self.adjust()
Example #37
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
Example #38
0
 def centered_text(val, pos):
     t = QGraphicsSimpleTextItem(attr.str_val(val), labels)
     t.setFont(self._label_font)
     bbox = t.boundingRect()
     t.setPos(pos - bbox.width() / 2, 22)
     return t
    def replot_experiments(self):
        """Replot the whole quality plot.
        """
        self.scene.clear()
        labels = []

        max_dist = numpy.nanmax(list(filter(None, self.distances)))
        rug_widgets = []

        group_pen = QPen(Qt.black)
        group_pen.setWidth(2)
        group_pen.setCapStyle(Qt.RoundCap)
        background_pen = QPen(QColor(0, 0, 250, 150))
        background_pen.setWidth(1)
        background_pen.setCapStyle(Qt.RoundCap)

        main_widget = QGraphicsWidget()
        layout = QGraphicsGridLayout()
        attributes = self.data.domain.attributes
        if self.data is not None:
            for (group, indices), dist_vec in zip(self.groups, self.distances):
                indices_set = set(indices)
                rug_items = []
                if dist_vec is not None:
                    for i, attr in enumerate(attributes):
                        # Is this a within group distance or background
                        in_group = i in indices_set
                        if in_group:
                            rug_item = ClickableRugItem(dist_vec[i] / max_dist,
                                           1.0, self.on_rug_item_clicked)
                            rug_item.setPen(group_pen)
                            tooltip = experiment_description(attr)
                            rug_item.setToolTip(tooltip)
                            rug_item.group_index = indices.index(i)
                            rug_item.setZValue(rug_item.zValue() + 1)
                        else:
                            rug_item = ClickableRugItem(dist_vec[i] / max_dist,
                                           0.85, self.on_rug_item_clicked)
                            rug_item.setPen(background_pen)
                            tooltip = experiment_description(attr)
                            rug_item.setToolTip(tooltip)

                        rug_item.group = group
                        rug_item.index = i
                        rug_item.in_group = in_group

                        rug_items.append(rug_item)

                rug_widget = RugGraphicsWidget(parent=main_widget)
                rug_widget.set_rug(rug_items)

                rug_widgets.append(rug_widget)

                label = group_label(self.selected_split_by_labels(), group)
                label_item = QGraphicsSimpleTextItem(label, main_widget)
                label_item = GraphicsSimpleTextLayoutItem(label_item, parent=layout)
                label_item.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
                labels.append(label_item)

        for i, (label, rug_w) in enumerate(zip(labels, rug_widgets)):
            layout.addItem(label, i, 0, Qt.AlignVCenter)
            layout.addItem(rug_w, i, 1)
            layout.setRowMaximumHeight(i, 30)

        main_widget.setLayout(layout)
        self.scene.addItem(main_widget)
        self.main_widget = main_widget
        self.rug_widgets = rug_widgets
        self.labels = labels
        self.on_view_resize(self.scene_view.size())
Example #40
0
 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
Example #41
0
    def __init__(self, name, data_extremes, values, scale, name_offset, offset):
        super().__init__()
        data_start, data_stop = data_extremes[0], data_extremes[1]
        labels = [str(np.round(data_start + (data_stop - data_start) * i /
                               (self.n_tck - 1), 1)) for i in range(self.n_tck)]

        # leading label
        font = name.document().defaultFont()
        name.setFont(font)
        name.setPos(name_offset, -10)
        name.setParentItem(self)

        # labels
        ascending = data_start < data_stop
        y_start, y_stop = (self.y_diff, 0) if ascending else (0, self.y_diff)
        for i in range(self.n_tck):
            text = QGraphicsSimpleTextItem(labels[i], self)
            w = text.boundingRect().width()
            y = y_start + (y_stop - y_start) / (self.n_tck - 1) * i
            text.setPos(-5 - w, y - 8)
            tick = QGraphicsLineItem(-2, y, 2, y, self)

        # prediction marker
        self.dot = Continuous2DMovableDotItem(
            self.DOT_RADIUS, scale, offset, values[0], values[-1], y_start, y_stop)
        self.dot.tooltip_labels = labels
        self.dot.tooltip_values = values
        self.dot.setParentItem(self)
        h_line = QGraphicsLineItem(values[0] * scale + offset, self.y_diff / 2,
                                   values[-1] * scale + offset, self.y_diff / 2,
                                   self)
        pen = QPen(Qt.DashLine)
        pen.setBrush(QColor(Qt.red))
        h_line.setPen(pen)
        self.dot.horizontal_line = h_line

        # pylint: disable=unused-variable
        # line
        line = QGraphicsLineItem(values[0] * scale + offset, y_start,
                                 values[-1] * scale + offset, y_stop,
                                 self)

        # ticks
        for value in values:
            diff_ = np.nan_to_num(values[-1] - values[0])
            k = (value - values[0]) / diff_ if diff_ else 0
            y_tick = (y_stop - y_start) * k + y_start - self.tick_height / 2
            x_tick = value * scale - self.tick_width / 2 + offset
            tick = QGraphicsRectItem(
                x_tick, y_tick, self.tick_width, self.tick_height,
                self)
            tick.setBrush(QColor(Qt.black))

        # rect
        rect = QGraphicsRectItem(
            values[0] * scale + offset, -self.y_diff * 0.125,
            values[-1] * scale + offset, self.y_diff * 1.25,
            self)
        pen = QPen(Qt.DotLine)
        pen.setBrush(QColor(50, 150, 200, 255))
        rect.setPen(pen)
        self.setPreferredSize(self.preferredWidth(), self.y_diff * 1.5)