예제 #1
0
    def _anchor_circle(self, variables):
        # minimum visible anchor radius (radius)
        min_radius = self._get_min_radius()
        axisitems = []
        for anchor, var in zip(self.plotdata.axes, variables[:]):
            axitem = AnchorItem(line=QLineF(0, 0, *anchor), text=var.name,)
            axitem.setVisible(np.linalg.norm(anchor) > min_radius)
            axitem.setPen(pg.mkPen((100, 100, 100)))
            axitem.setArrowVisible(True)
            self.viewbox.addItem(axitem)
            axisitems.append(axitem)

        self.plotdata.axisitems = axisitems
        if self.placement == self.Placement.Circular:
            return

        hidecircle = QGraphicsEllipseItem()
        hidecircle.setRect(QRectF(-min_radius, -min_radius, 2 * min_radius, 2 * min_radius))

        _pen = QPen(Qt.lightGray, 1)
        _pen.setCosmetic(True)
        hidecircle.setPen(_pen)

        self.viewbox.addItem(hidecircle)
        self.plotdata.hidecircle = hidecircle
예제 #2
0
    def _anchor_circle(self):
        # minimum visible anchor radius (radius)
        minradius = self.radius / 100 + 1e-5
        for item in chain(self.plotdata.anchoritem, self.plotdata.items):
            self.viewbox.removeItem(item)
        self.plotdata.anchoritem = []
        self.plotdata.items = []
        for anchor, var in zip(self.plotdata.anchors, self.data.domain.attributes):
            if True or np.linalg.norm(anchor) > minradius:
                axitem = AnchorItem(
                    line=QLineF(0, 0, *anchor), text=var.name,)
                axitem.setVisible(np.linalg.norm(anchor) > minradius)
                axitem.setPen(pg.mkPen((100, 100, 100)))
                axitem.setArrowVisible(True)
                self.plotdata.anchoritem.append(axitem)
                self.viewbox.addItem(axitem)

        hidecircle = QGraphicsEllipseItem()
        hidecircle.setRect(
            QRectF(-minradius, -minradius,
                   2 * minradius, 2 * minradius))

        _pen = QPen(Qt.lightGray, 1)
        _pen.setCosmetic(True)
        hidecircle.setPen(_pen)
        self.viewbox.addItem(hidecircle)
        self.plotdata.items.append(hidecircle)
        self.plotdata.hidecircle = hidecircle
예제 #3
0
 def _draw_border(point_1, point_2, border_width, parent):
     pen = QPen(QColor(self.border_color))
     pen.setCosmetic(True)
     pen.setWidth(border_width)
     line = QGraphicsLineItem(QLineF(point_1, point_2), parent)
     line.setPen(pen)
     return line
예제 #4
0
        def generate_pens(basecolor):
            pen = QPen(basecolor, 1)
            pen.setCosmetic(True)

            shadow_pen = QPen(pen.color().lighter(160), 2.5)
            shadow_pen.setCosmetic(True)
            return pen, shadow_pen
예제 #5
0
    def __init__(self, tree_node, parent=None, **kwargs):
        self.tree_node = tree_node
        super().__init__(self._get_rect_attributes(), parent)
        self.tree_node.graphics_item = self

        self.setTransformOriginPoint(self.boundingRect().center())
        self.setRotation(degrees(self.tree_node.square.angle))

        self.setBrush(kwargs.get('brush', QColor('#297A1F')))
        # The border should be invariant to scaling
        pen = QPen(QColor(Qt.black))
        pen.setWidthF(0.75)
        pen.setCosmetic(True)
        self.setPen(pen)

        self.setAcceptHoverEvents(True)
        self.setZValue(kwargs.get('zvalue', 0))
        self.z_step = Z_STEP

        # calculate the correct z values based on the parent
        if self.tree_node.parent != TreeAdapter.ROOT_PARENT:
            p = self.tree_node.parent
            # override root z step
            num_children = len(p.children)
            own_index = [1 if c.label == self.tree_node.label else 0
                         for c in p.children].index(1)

            self.z_step = int(p.graphics_item.z_step / num_children)
            base_z = p.graphics_item.zValue()

            self.setZValue(base_z + own_index * self.z_step)
예제 #6
0
 def paint(self, painter, option, widget=None):
     painter.save()
     palette = self.palette()
     border = palette.brush(QPalette.Mid)
     pen = QPen(border, 1)
     pen.setCosmetic(True)
     painter.setPen(pen)
     painter.setBrush(palette.brush(QPalette.Window))
     brect = self.boundingRect()
     painter.drawRoundedRect(brect, 4, 4)
     painter.restore()
예제 #7
0
    def _setup_plot(self):
        target = self.target_index
        selected = self.selected_classifiers
        curves = [self.plot_curves(target, clf_idx) for clf_idx in selected]

        for curve in curves:
            self.plot.addItem(curve.curve_item)

        if self.display_convex_hull:
            hull = convex_hull([c.curve.hull for c in curves])
            self.plot.plot(hull[0], hull[1], pen="y", antialias=True)

        pen = QPen(QColor(100, 100, 100, 100), 1, Qt.DashLine)
        pen.setCosmetic(True)
        self.plot.plot([0, 1], [0, 1], pen=pen, antialias=True)
예제 #8
0
    def __init__(self, size=None, offset=None, pen=None, brush=None):
        super().__init__(size, offset)

        self.layout.setContentsMargins(5, 5, 5, 5)
        self.layout.setHorizontalSpacing(15)
        self.layout.setColumnAlignment(1, Qt.AlignLeft | Qt.AlignVCenter)

        if pen is None:
            pen = QPen(QColor(196, 197, 193, 200), 1)
            pen.setCosmetic(True)
        self.__pen = pen

        if brush is None:
            brush = QBrush(QColor(232, 232, 232, 100))
        self.__brush = brush
예제 #9
0
    def __updateStyleState(self):
        """
        Update the arrows' brush, pen, ... based on it's state
        """
        if self.isSelected():
            color = self.__color.darker(150)
            pen = QPen(QColor(96, 158, 215), Qt.DashDotLine)
            pen.setWidthF(1.25)
            pen.setCosmetic(True)
            self.__shadow.setColor(pen.color().darker(150))
        else:
            color = self.__color
            pen = QPen(Qt.NoPen)
            self.__shadow.setColor(QColor(63, 63, 63, 180))

        self.__arrowItem.setBrush(color)
        self.__arrowItem.setPen(pen)
예제 #10
0
 def paint(self, painter, option, widget=None):
     # Override the default selected appearance
     if self.isSelected():
         option.state ^= QStyle.State_Selected
         rect = self.rect()
         # this must render before overlay due to order in which it's drawn
         super().paint(painter, option, widget)
         painter.save()
         pen = QPen(QColor(Qt.black))
         pen.setWidthF(2)
         pen.setCosmetic(True)
         pen.setJoinStyle(Qt.MiterJoin)
         painter.setPen(pen)
         painter.drawRect(rect)
         painter.restore()
     else:
         super().paint(painter, option, widget)
예제 #11
0
    def __paint(self):
        picture = QPicture()
        painter = QPainter(picture)
        pen = QPen(QBrush(Qt.white), 0.5)
        pen.setCosmetic(True)
        painter.setPen(pen)

        geom = self.geometry
        x, y = geom.x(), geom.y()
        w, h = geom.width(), geom.height()
        wsingle = w / len(self.dist)
        for d, c in zip(self.dist, self.colors):
            painter.setBrush(QBrush(c))
            painter.drawRect(QRectF(x, y, wsingle, d * h))
            x += wsingle
        painter.end()

        self.__picture = picture
예제 #12
0
    def display_distribution(self):
        dist = self.distributions
        var = self.var
        if dist is None or not len(dist):
            return
        self.plot.clear()
        self.plot_prob.clear()
        self.ploti.hideAxis('right')
        self.tooltip_items = []

        bottomaxis = self.ploti.getAxis("bottom")
        bottomaxis.setLabel(var.name)
        bottomaxis.resizeEvent()

        self.set_left_axis_name()
        if var and var.is_continuous:
            bottomaxis.setTicks(None)
            if not len(dist[0]):
                return
            edges, curve = ash_curve(dist, None, m=OWDistributions.ASH_HIST,
                                     smoothing_factor=self.smoothing_factor)
            edges = edges + (edges[1] - edges[0])/2
            edges = edges[:-1]
            if self.cumulative_distr:
                dx = edges[1] - edges[0]
                curve = numpy.cumsum(curve) * dx
            item = pg.PlotCurveItem()
            pen = QPen(QBrush(Qt.white), 3)
            pen.setCosmetic(True)
            item.setData(edges, curve, antialias=True, stepMode=False,
                         fillLevel=0, brush=QBrush(Qt.gray), pen=pen)
            self.plot.addItem(item)
            item.tooltip = "Density"
            self.tooltip_items.append((self.plot, item))
        else:
            bottomaxis.setTicks([list(enumerate(var.values))])
            for i, w in enumerate(dist):
                geom = QRectF(i - 0.33, 0, 0.66, w)
                item = DistributionBarItem(geom, [1.0],
                                           [QColor(128, 128, 128)])
                self.plot.addItem(item)
                item.tooltip = "Frequency for %s: %r" % (var.values[i], w)
                self.tooltip_items.append((self.plot, item))
예제 #13
0
    def plot_curves(self, target, clf_idx):
        if (target, clf_idx) not in self._curve_data:
            curve = liftCurve_from_results(self.results, clf_idx, target)
            color = self.colors[clf_idx]
            pen = QPen(color, 1)
            pen.setCosmetic(True)
            shadow_pen = QPen(pen.color().lighter(160), 2.5)
            shadow_pen.setCosmetic(True)
            item = pg.PlotDataItem(
                curve.points[0], curve.points[1],
                pen=pen, shadowPen=shadow_pen,
                symbol="+", symbolSize=3, symbolPen=shadow_pen,
                antialias=True
            )
            hull_item = pg.PlotDataItem(
                curve.hull[0], curve.hull[1],
                pen=pen, antialias=True
            )
            self._curve_data[target, clf_idx] = \
                PlotCurve(curve, item, hull_item)

        return self._curve_data[target, clf_idx]
예제 #14
0
    def _setup_plot(self):
        target = self.target_index
        selected = self.selected_classifiers
        curves = [self.plot_curves(target, clf_idx) for clf_idx in selected]

        for curve in curves:
            self.plot.addItem(curve.curve_item)

        if self.display_convex_hull:
            hull = convex_hull([c.curve.hull for c in curves])
            self.plot.plot(hull[0], hull[1], pen="y", antialias=True)

        pen = QPen(QColor(100, 100, 100, 100), 1, Qt.DashLine)
        pen.setCosmetic(True)
        self.plot.plot([0, 1], [0, 1], pen=pen, antialias=True)

        warning = ""
        if not all(c.curve.is_valid for c in curves):
            if any(c.curve.is_valid for c in curves):
                warning = "Some lift curves are undefined"
            else:
                warning = "All lift curves are undefined"

        self.warning(warning)
예제 #15
0
    def _setup_plot(self):
        target = self.target_index
        selected = self.selected_classifiers

        curves = [self.plot_curves(target, i) for i in selected]
        selected = [self.curve_data(target, i) for i in selected]

        if self.roc_averaging == OWROCAnalysis.Merge:
            for curve in curves:
                graphics = curve.merge()
                curve = graphics.curve
                self.plot.addItem(graphics.curve_item)

                if self.display_convex_curve:
                    self.plot.addItem(graphics.hull_item)

                if self.display_def_threshold:
                    points = curve.points
                    ind = numpy.argmin(numpy.abs(points.thresholds - 0.5))
                    item = pg.TextItem(text="{:.3f}".format(
                        points.thresholds[ind]), )
                    item.setPos(points.fpr[ind], points.tpr[ind])
                    self.plot.addItem(item)

            hull_curves = [curve.merged.hull for curve in selected]
            if hull_curves:
                self._rocch = convex_hull(hull_curves)
                iso_pen = QPen(QColor(Qt.black), 1)
                iso_pen.setCosmetic(True)
                self._perf_line = InfiniteLine(pen=iso_pen, antialias=True)
                self.plot.addItem(self._perf_line)

        elif self.roc_averaging == OWROCAnalysis.Vertical:
            for curve in curves:
                graphics = curve.avg_vertical()

                self.plot.addItem(graphics.curve_item)
                self.plot.addItem(graphics.confint_item)

            hull_curves = [curve.avg_vertical.hull for curve in selected]

        elif self.roc_averaging == OWROCAnalysis.Threshold:
            for curve in curves:
                graphics = curve.avg_threshold()
                self.plot.addItem(graphics.curve_item)
                self.plot.addItem(graphics.confint_item)

            hull_curves = [curve.avg_threshold.hull for curve in selected]

        elif self.roc_averaging == OWROCAnalysis.NoAveraging:
            for curve in curves:
                graphics = curve.folds()
                for fold in graphics:
                    self.plot.addItem(fold.curve_item)
                    if self.display_convex_curve:
                        self.plot.addItem(fold.hull_item)
            hull_curves = [
                fold.hull for curve in selected for fold in curve.folds
            ]

        if self.display_convex_hull and hull_curves:
            hull = convex_hull(hull_curves)
            hull_pen = QPen(QColor(200, 200, 200, 100), 2)
            hull_pen.setCosmetic(True)
            item = self.plot.plot(hull.fpr,
                                  hull.tpr,
                                  pen=hull_pen,
                                  brush=QBrush(QColor(200, 200, 200, 50)),
                                  fillLevel=0)
            item.setZValue(-10000)

        pen = QPen(QColor(100, 100, 100, 100), 1, Qt.DashLine)
        pen.setCosmetic(True)
        self.plot.plot([0, 1], [0, 1], pen=pen, antialias=True)

        if self.roc_averaging == OWROCAnalysis.Merge:
            self._update_perf_line()
예제 #16
0
    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()
예제 #17
0
 def pen(color):
     pen = QPen(color, 1)
     pen.setCosmetic(True)
     return pen
 def makeline(pos):
     pen = QPen(Qt.darkGray, 1)
     pen.setCosmetic(True)
     line = InfiniteLine(angle=90, pos=pos, pen=pen, movable=True)
     line.setCursor(Qt.SizeHorCursor)
     return line
예제 #19
0
 def make_pen(color, width=1):
     pen = QPen(color, width)
     pen.setCosmetic(True)
     return pen
예제 #20
0
 def pen(color):
     pen = QPen(color, 1)
     pen.setCosmetic(True)
     return pen
예제 #21
0
def _make_pen(color, width):
    p = QPen(color, width)
    p.setCosmetic(True)
    return p
예제 #22
0
    def _setup_plot(self):
        def merge_averaging():
            for curve in curves:
                graphics = curve.merge()
                curve = graphics.curve
                self.plot.addItem(graphics.curve_item)

                if self.display_convex_curve:
                    self.plot.addItem(graphics.hull_item)

                if self.display_def_threshold and curve.is_valid:
                    points = curve.points
                    ind = np.argmin(np.abs(points.thresholds - 0.5))
                    item = pg.TextItem(text="{:.3f}".format(
                        points.thresholds[ind]), )
                    item.setPos(points.fpr[ind], points.tpr[ind])
                    self.plot.addItem(item)

            hull_curves = [curve.merged.hull for curve in selected]
            if hull_curves:
                self._rocch = convex_hull(hull_curves)
                iso_pen = QPen(QColor(Qt.black), 1)
                iso_pen.setCosmetic(True)
                self._perf_line = InfiniteLine(pen=iso_pen, antialias=True)
                self.plot.addItem(self._perf_line)
            return hull_curves

        def vertical_averaging():
            for curve in curves:
                graphics = curve.avg_vertical()

                self.plot.addItem(graphics.curve_item)
                self.plot.addItem(graphics.confint_item)
            return [curve.avg_vertical.hull for curve in selected]

        def threshold_averaging():
            for curve in curves:
                graphics = curve.avg_threshold()
                self.plot.addItem(graphics.curve_item)
                self.plot.addItem(graphics.confint_item)
            return [curve.avg_threshold.hull for curve in selected]

        def no_averaging():
            for curve in curves:
                graphics = curve.folds()
                for fold in graphics:
                    self.plot.addItem(fold.curve_item)
                    if self.display_convex_curve:
                        self.plot.addItem(fold.hull_item)
            return [fold.hull for curve in selected for fold in curve.folds]

        averagings = {
            OWROCAnalysis.Merge: merge_averaging,
            OWROCAnalysis.Vertical: vertical_averaging,
            OWROCAnalysis.Threshold: threshold_averaging,
            OWROCAnalysis.NoAveraging: no_averaging
        }

        target = self.target_index
        selected = self.selected_classifiers

        curves = [self.plot_curves(target, i) for i in selected]
        selected = [self.curve_data(target, i) for i in selected]
        hull_curves = averagings[self.roc_averaging]()

        if self.display_convex_hull and hull_curves:
            hull = convex_hull(hull_curves)
            hull_pen = QPen(QColor(200, 200, 200, 100), 2)
            hull_pen.setCosmetic(True)
            item = self.plot.plot(hull.fpr,
                                  hull.tpr,
                                  pen=hull_pen,
                                  brush=QBrush(QColor(200, 200, 200, 50)),
                                  fillLevel=0)
            item.setZValue(-10000)

        pen = QPen(QColor(100, 100, 100, 100), 1, Qt.DashLine)
        pen.setCosmetic(True)
        self.plot.plot([0, 1], [0, 1], pen=pen, antialias=True)

        if self.roc_averaging == OWROCAnalysis.Merge:
            self._update_perf_line()

        self._update_axes_ticks()

        warning = ""
        if not all(c.is_valid for c in hull_curves):
            if any(c.is_valid for c in hull_curves):
                warning = "Some ROC curves are undefined"
            else:
                warning = "All ROC curves are undefined"
        self.warning(warning)
예제 #23
0
    def _setup_plot(self):
        target = self.target_index
        selected = self.selected_classifiers

        curves = [self.plot_curves(target, i) for i in selected]
        selected = [self.curve_data(target, i) for i in selected]

        if self.roc_averaging == OWROCAnalysis.Merge:
            for curve in curves:
                graphics = curve.merge()
                curve = graphics.curve
                self.plot.addItem(graphics.curve_item)

                if self.display_convex_curve:
                    self.plot.addItem(graphics.hull_item)

                if self.display_def_threshold and curve.is_valid:
                    points = curve.points
                    ind = numpy.argmin(numpy.abs(points.thresholds - 0.5))
                    item = pg.TextItem(
                        text="{:.3f}".format(points.thresholds[ind]),
                    )
                    item.setPos(points.fpr[ind], points.tpr[ind])
                    self.plot.addItem(item)

            hull_curves = [curve.merged.hull for curve in selected]
            if hull_curves:
                self._rocch = convex_hull(hull_curves)
                iso_pen = QPen(QColor(Qt.black), 1)
                iso_pen.setCosmetic(True)
                self._perf_line = InfiniteLine(pen=iso_pen, antialias=True)
                self.plot.addItem(self._perf_line)

        elif self.roc_averaging == OWROCAnalysis.Vertical:
            for curve in curves:
                graphics = curve.avg_vertical()

                self.plot.addItem(graphics.curve_item)
                self.plot.addItem(graphics.confint_item)

            hull_curves = [curve.avg_vertical.hull for curve in selected]

        elif self.roc_averaging == OWROCAnalysis.Threshold:
            for curve in curves:
                graphics = curve.avg_threshold()
                self.plot.addItem(graphics.curve_item)
                self.plot.addItem(graphics.confint_item)

            hull_curves = [curve.avg_threshold.hull for curve in selected]

        elif self.roc_averaging == OWROCAnalysis.NoAveraging:
            for curve in curves:
                graphics = curve.folds()
                for fold in graphics:
                    self.plot.addItem(fold.curve_item)
                    if self.display_convex_curve:
                        self.plot.addItem(fold.hull_item)
            hull_curves = [fold.hull for curve in selected for fold in curve.folds]
        else:
            assert False

        if self.display_convex_hull and hull_curves:
            hull = convex_hull(hull_curves)
            hull_pen = QPen(QColor(200, 200, 200, 100), 2)
            hull_pen.setCosmetic(True)
            item = self.plot.plot(
                hull.fpr, hull.tpr,
                pen=hull_pen,
                brush=QBrush(QColor(200, 200, 200, 50)),
                fillLevel=0)
            item.setZValue(-10000)

        pen = QPen(QColor(100, 100, 100, 100), 1, Qt.DashLine)
        pen.setCosmetic(True)
        self.plot.plot([0, 1], [0, 1], pen=pen, antialias=True)

        if self.roc_averaging == OWROCAnalysis.Merge:
            self._update_perf_line()

        warning = ""
        if not all(c.is_valid for c in hull_curves):
            if any(c.is_valid for c in hull_curves):
                warning = "Some ROC curves are undefined"
            else:
                warning = "All ROC curves are undefined"
        self.warning(warning)
예제 #24
0
 def make_pen(color, width):
     p = QPen(color, width)
     p.setCosmetic(True)
     return p
예제 #25
0
 def makeline(pos):
     pen = QPen(Qt.darkGray, 1)
     pen.setCosmetic(True)
     line = InfiniteLine(angle=90, pos=pos, pen=pen, movable=True)
     line.setCursor(Qt.SizeHorCursor)
     return line
예제 #26
0
    def display_contingency(self):
        """
        Set the contingency to display.
        """
        cont = self.contingencies
        var, cvar = self.var, self.cvar
        if cont is None or not len(cont):
            return
        self.plot.clear()
        self.plot_prob.clear()
        self._legend.clear()
        self.tooltip_items = []

        if self.show_prob:
            self.ploti.showAxis('right')
        else:
            self.ploti.hideAxis('right')

        bottomaxis = self.ploti.getAxis("bottom")
        bottomaxis.setLabel(var.name)
        bottomaxis.resizeEvent()

        cvar_values = cvar.values
        colors = [QColor(*col) for col in cvar.colors]

        if var and var.is_continuous:
            bottomaxis.setTicks(None)

            weights, cols, cvar_values, curves = [], [], [], []
            for i, dist in enumerate(cont):
                v, W = dist
                if len(v):
                    weights.append(numpy.sum(W))
                    cols.append(colors[i])
                    cvar_values.append(cvar.values[i])
                    curves.append(ash_curve(
                        dist, cont, m=OWDistributions.ASH_HIST,
                        smoothing_factor=self.smoothing_factor))
            weights = numpy.array(weights)
            sumw = numpy.sum(weights)
            weights /= sumw
            colors = cols
            curves = [(X, Y * w) for (X, Y), w in zip(curves, weights)]

            curvesline = [] #from histograms to lines
            for X, Y in curves:
                X = X + (X[1] - X[0])/2
                X = X[:-1]
                X = numpy.array(X)
                Y = numpy.array(Y)
                curvesline.append((X, Y))

            for t in ["fill", "line"]:
                curve_data = list(zip(curvesline, colors, weights, cvar_values))
                for (X, Y), color, w, cval in reversed(curve_data):
                    item = pg.PlotCurveItem()
                    pen = QPen(QBrush(color), 3)
                    pen.setCosmetic(True)
                    color = QColor(color)
                    color.setAlphaF(0.2)
                    item.setData(X, Y/(w if self.relative_freq else 1),
                                 antialias=True, stepMode=False,
                                 fillLevel=0 if t == "fill" else None,
                                 brush=QBrush(color), pen=pen)
                    self.plot.addItem(item)
                    if t == "line":
                        item.tooltip = "{}\n{}={}".format(
                            "Normalized density " if self.relative_freq else "Density ",
                            cvar.name, cval)
                        self.tooltip_items.append((self.plot, item))

            if self.show_prob:
                all_X = numpy.array(numpy.unique(numpy.hstack([X for X, _ in curvesline])))
                inter_X = numpy.array(numpy.linspace(all_X[0], all_X[-1], len(all_X)*2))
                curvesinterp = [numpy.interp(inter_X, X, Y) for (X, Y) in curvesline]
                sumprob = numpy.sum(curvesinterp, axis=0)
                legal = sumprob > 0.05 * numpy.max(sumprob)

                i = len(curvesinterp) + 1
                show_all = self.show_prob == i
                for Y, color, cval in reversed(list(zip(curvesinterp, colors, cvar_values))):
                    i -= 1
                    if show_all or self.show_prob == i:
                        item = pg.PlotCurveItem()
                        pen = QPen(QBrush(color), 3, style=Qt.DotLine)
                        pen.setCosmetic(True)
                        prob = Y[legal] / sumprob[legal]
                        item.setData(
                            inter_X[legal], prob, antialias=True, stepMode=False,
                            fillLevel=None, brush=None, pen=pen)
                        self.plot_prob.addItem(item)
                        item.tooltip = "Probability that \n" + cvar.name + "=" + cval
                        self.tooltip_items.append((self.plot_prob, item))

        elif var and var.is_discrete:
            bottomaxis.setTicks([list(enumerate(var.values))])

            cont = numpy.array(cont)

            maxh = 0 #maximal column height
            maxrh = 0 #maximal relative column height
            scvar = cont.sum(axis=1)
            #a cvar with sum=0 with allways have distribution counts 0,
            #therefore we can divide it by anything
            scvar[scvar == 0] = 1
            for i, (value, dist) in enumerate(zip(var.values, cont.T)):
                maxh = max(maxh, max(dist))
                maxrh = max(maxrh, max(dist/scvar))

            for i, (value, dist) in enumerate(zip(var.values, cont.T)):
                dsum = sum(dist)
                geom = QRectF(i - 0.333, 0, 0.666,
                              maxrh if self.relative_freq else maxh)
                if self.show_prob:
                    prob = dist / dsum
                    ci = 1.96 * numpy.sqrt(prob * (1 - prob) / dsum)
                else:
                    ci = None
                item = DistributionBarItem(geom, dist/scvar/maxrh
                                           if self.relative_freq
                                           else dist/maxh, colors)
                self.plot.addItem(item)
                tooltip = "\n".join(
                    "%s: %.*f" % (n, 3 if self.relative_freq else 1, v)
                    for n, v in zip(cvar_values, dist/scvar if self.relative_freq else dist))
                item.tooltip = "{} ({}={}):\n{}".format(
                    "Normalized frequency " if self.relative_freq else "Frequency ",
                    cvar.name, value, tooltip)
                self.tooltip_items.append((self.plot, item))

                if self.show_prob:
                    item.tooltip += "\n\nProbabilities:"
                    for ic, a in enumerate(dist):
                        if self.show_prob - 1 != ic and \
                                self.show_prob - 1 != len(dist):
                            continue
                        position = -0.333 + ((ic+0.5)*0.666/len(dist))
                        if dsum < 1e-6:
                            continue
                        prob = a / dsum
                        if not 1e-6 < prob < 1 - 1e-6:
                            continue
                        ci = 1.96 * sqrt(prob * (1 - prob) / dsum)
                        item.tooltip += "\n%s: %.3f ± %.3f" % (cvar_values[ic], prob, ci)
                        mark = pg.ScatterPlotItem()
                        errorbar = pg.ErrorBarItem()
                        pen = QPen(QBrush(QColor(0)), 1)
                        pen.setCosmetic(True)
                        errorbar.setData(x=[i+position], y=[prob],
                                         bottom=min(numpy.array([ci]), prob),
                                         top=min(numpy.array([ci]), 1 - prob),
                                         beam=numpy.array([0.05]),
                                         brush=QColor(1), pen=pen)
                        mark.setData([i+position], [prob], antialias=True, symbol="o",
                                     fillLevel=None, pxMode=True, size=10,
                                     brush=QColor(colors[ic]), pen=pen)
                        self.plot_prob.addItem(errorbar)
                        self.plot_prob.addItem(mark)

        for color, name in zip(colors, cvar_values):
            self._legend.addItem(
                ScatterPlotItem(pen=color, brush=color, size=10, shape="s"),
                escape(name)
            )
        self._legend.show()
예제 #27
0
    def display_contingency(self):
        """
        Set the contingency to display.
        """
        cont = self.contingencies
        var, cvar = self.var, self.cvar
        assert len(cont) > 0
        self.plot.clear()
        self.plot_prob.clear()
        self._legend.clear()
        self.tooltip_items = []

        if self.show_prob:
            self.ploti.showAxis('right')
        else:
            self.ploti.hideAxis('right')

        bottomaxis = self.ploti.getAxis("bottom")
        bottomaxis.setLabel(var.name)
        bottomaxis.resizeEvent()

        cvar_values = cvar.values
        colors = [QColor(*col) for col in cvar.colors]

        if var and var.is_continuous:
            bottomaxis.setTicks(None)

            weights, cols, cvar_values, curves = [], [], [], []
            for i, dist in enumerate(cont):
                v, W = dist
                if len(v):
                    weights.append(numpy.sum(W))
                    cols.append(colors[i])
                    cvar_values.append(cvar.values[i])
                    curves.append(
                        ash_curve(dist,
                                  cont,
                                  m=OWDistributions.ASH_HIST,
                                  smoothing_factor=self.smoothing_facs[
                                      self.smoothing_index]))
            weights = numpy.array(weights)
            sumw = numpy.sum(weights)
            weights /= sumw
            colors = cols
            curves = [(X, Y * w) for (X, Y), w in zip(curves, weights)]
            ncval = len(cvar_values)

            curvesline = []  #from histograms to lines
            for (X, Y) in curves:
                X = X + (X[1] - X[0]) / 2
                X = X[:-1]
                X = numpy.array(X)
                Y = numpy.array(Y)
                curvesline.append((X, Y))

            for t in ["fill", "line"]:
                for (X, Y), color, w, cval in reversed(
                        list(zip(curvesline, colors, weights, cvar_values))):
                    item = pg.PlotCurveItem()
                    pen = QPen(QBrush(color), 3)
                    pen.setCosmetic(True)
                    color = QColor(color)
                    color.setAlphaF(0.2)
                    item.setData(X,
                                 Y / (w if self.relative_freq else 1),
                                 antialias=True,
                                 stepMode=False,
                                 fillLevel=0 if t == "fill" else None,
                                 brush=QBrush(color),
                                 pen=pen)
                    self.plot.addItem(item)
                    if t == "line":
                        item.tooltip = ("Normalized density " if self.relative_freq else "Density ") \
                            + "\n"+ cvar.name + "=" + cval
                        self.tooltip_items.append((self.plot, item))

            if self.show_prob:
                M_EST = 5  #for M estimate
                all_X = numpy.array(
                    numpy.unique(numpy.hstack([X for X, _ in curvesline])))
                inter_X = numpy.array(
                    numpy.linspace(all_X[0], all_X[-1],
                                   len(all_X) * 2))
                curvesinterp = [
                    numpy.interp(inter_X, X, Y) for (X, Y) in curvesline
                ]
                sumprob = numpy.sum(curvesinterp, axis=0)
                # allcorrection = M_EST/sumw*numpy.sum(sumprob)/len(inter_X)
                legal = sumprob > 0.05 * numpy.max(sumprob)

                i = len(curvesinterp) + 1
                show_all = self.show_prob == i
                for Y, color, cval in reversed(
                        list(zip(curvesinterp, colors, cvar_values))):
                    i -= 1
                    if show_all or self.show_prob == i:
                        item = pg.PlotCurveItem()
                        pen = QPen(QBrush(color), 3, style=Qt.DotLine)
                        pen.setCosmetic(True)
                        #prob = (Y+allcorrection/ncval)/(sumprob+allcorrection)
                        prob = Y[legal] / sumprob[legal]
                        item.setData(inter_X[legal],
                                     prob,
                                     antialias=True,
                                     stepMode=False,
                                     fillLevel=None,
                                     brush=None,
                                     pen=pen)
                        self.plot_prob.addItem(item)
                        item.tooltip = "Probability that \n" + cvar.name + "=" + cval
                        self.tooltip_items.append((self.plot_prob, item))

        elif var and var.is_discrete:
            bottomaxis.setTicks([list(enumerate(var.values))])

            cont = numpy.array(cont)
            ncval = len(cvar_values)

            maxh = 0  #maximal column height
            maxrh = 0  #maximal relative column height
            scvar = cont.sum(axis=1)
            #a cvar with sum=0 with allways have distribution counts 0,
            #therefore we can divide it by anything
            scvar[scvar == 0] = 1
            for i, (value, dist) in enumerate(zip(var.values, cont.T)):
                maxh = max(maxh, max(dist))
                maxrh = max(maxrh, max(dist / scvar))

            for i, (value, dist) in enumerate(zip(var.values, cont.T)):
                dsum = sum(dist)
                geom = QRectF(i - 0.333, 0, 0.666,
                              maxrh if self.relative_freq else maxh)
                if self.show_prob:
                    prob = dist / dsum
                    ci = 1.96 * numpy.sqrt(prob * (1 - prob) / dsum)
                else:
                    ci = None
                item = DistributionBarItem(
                    geom, dist / scvar /
                    maxrh if self.relative_freq else dist / maxh, colors)
                self.plot.addItem(item)
                tooltip = "\n".join("%s: %.*f" %
                                    (n, 3 if self.relative_freq else 1, v)
                                    for n, v in zip(
                                        cvar_values, dist /
                                        scvar if self.relative_freq else dist))
                item.tooltip = ("Normalized frequency " if self.relative_freq else "Frequency ") \
                    + "(" + cvar.name + "=" + value + "):" \
                    + "\n" + tooltip
                self.tooltip_items.append((self.plot, item))

                if self.show_prob:
                    item.tooltip += "\n\nProbabilities:"
                    for ic, a in enumerate(dist):
                        if self.show_prob - 1 != ic and \
                                self.show_prob - 1 != len(dist):
                            continue
                        position = -0.333 + ((ic + 0.5) * 0.666 / len(dist))
                        if dsum < 1e-6:
                            continue
                        prob = a / dsum
                        if not 1e-6 < prob < 1 - 1e-6:
                            continue
                        ci = 1.96 * sqrt(prob * (1 - prob) / dsum)
                        item.tooltip += "\n%s: %.3f ± %.3f" % (cvar_values[ic],
                                                               prob, ci)
                        mark = pg.ScatterPlotItem()
                        bar = pg.ErrorBarItem()
                        pen = QPen(QBrush(QColor(0)), 1)
                        pen.setCosmetic(True)
                        bar.setData(x=[i + position],
                                    y=[prob],
                                    bottom=min(numpy.array([ci]), prob),
                                    top=min(numpy.array([ci]), 1 - prob),
                                    beam=numpy.array([0.05]),
                                    brush=QColor(1),
                                    pen=pen)
                        mark.setData([i + position], [prob],
                                     antialias=True,
                                     symbol="o",
                                     fillLevel=None,
                                     pxMode=True,
                                     size=10,
                                     brush=QColor(colors[ic]),
                                     pen=pen)
                        self.plot_prob.addItem(bar)
                        self.plot_prob.addItem(mark)

        for color, name in zip(colors, cvar_values):
            self._legend.addItem(
                ScatterPlotItem(pen=color, brush=color, size=10, shape="s"),
                escape(name))
        self._legend.show()
예제 #28
0
    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()
예제 #29
0
    def setData(self, data, nsamples, sample_range=None, color=Qt.magenta):
        assert np.all(np.isfinite(data))

        if data.size > 0:
            xmin, xmax = np.min(data), np.max(data)
        else:
            xmin = xmax = 0.0

        if sample_range is None:
            xrange = xmax - xmin
            sample_min = xmin - xrange * 0.025
            sample_max = xmax + xrange * 0.025
        else:
            sample_min, sample_max = sample_range

        sample = np.linspace(sample_min, sample_max, nsamples)
        if data.size < 2:
            est = np.full(
                sample.size,
                1. / sample.size,
            )
        else:
            try:
                density = stats.gaussian_kde(data)
                est = density.evaluate(sample)
            except np.linalg.LinAlgError:
                est = np.zeros(sample.size)

        item = QGraphicsPathItem(violin_shape(sample, est))
        color = QColor(color)
        color.setAlphaF(0.5)
        item.setBrush(QBrush(color))
        pen = QPen(self.palette().color(QPalette.Shadow))
        pen.setCosmetic(True)
        item.setPen(pen)
        est_max = np.max(est)

        x = np.random.RandomState(0xD06F00D).uniform(-est_max,
                                                     est_max,
                                                     size=data.size)
        dots = ScatterPlotItem(
            x=x,
            y=data,
            size=3,
        )
        dots.setVisible(self.__dataPointsVisible)
        pen = QPen(self.palette().color(QPalette.Shadow), 1)
        hoverPen = QPen(self.palette().color(QPalette.Highlight), 1.5)
        cmax = SelectionLine(angle=0,
                             pos=xmax,
                             movable=True,
                             bounds=(sample_min, sample_max),
                             pen=pen,
                             hoverPen=hoverPen)
        cmin = SelectionLine(angle=0,
                             pos=xmin,
                             movable=True,
                             bounds=(sample_min, sample_max),
                             pen=pen,
                             hoverPen=hoverPen)
        cmax.setCursor(Qt.SizeVerCursor)
        cmin.setCursor(Qt.SizeVerCursor)

        selection_item = QGraphicsRectItem(
            QRectF(-est_max, xmin, est_max * 2, xmax - xmin))
        selection_item.setPen(QPen(Qt.NoPen))
        selection_item.setBrush(QColor(0, 250, 0, 50))

        def update_selection_rect():
            mode = self.__selectionMode
            p = selection_item.parentItem()  # type: Optional[QGraphicsItem]
            while p is not None and not isinstance(p, pg.ViewBox):
                p = p.parentItem()
            if p is not None:
                viewbox = p  # type: pg.ViewBox
            else:
                viewbox = None
            rect = selection_item.rect()  # type: QRectF
            if mode & ViolinPlot.High:
                rect.setTop(cmax.value())
            elif viewbox is not None:
                rect.setTop(viewbox.viewRect().bottom())
            else:
                rect.setTop(cmax.maxRange[1])

            if mode & ViolinPlot.Low:
                rect.setBottom(cmin.value())
            elif viewbox is not None:
                rect.setBottom(viewbox.viewRect().top())
            else:
                rect.setBottom(cmin.maxRange[0])

            selection_item.setRect(rect.normalized())

        cmax.sigPositionChanged.connect(update_selection_rect)
        cmin.sigPositionChanged.connect(update_selection_rect)
        cmax.visibleChanged.connect(update_selection_rect)
        cmin.visibleChanged.connect(update_selection_rect)

        def setupper(line):
            ebound = self.__effectiveBoundary()
            elower, eupper = ebound
            mode = self.__selectionMode
            if not mode & ViolinPlot.High:
                return
            upper = line.value()
            lower = min(elower, upper)
            if lower != elower and mode & ViolinPlot.Low:
                self.__min = lower
                cmin.setValue(lower)

            if upper != eupper:
                self.__max = upper

            if ebound != self.__effectiveBoundary():
                self.selectionEdited.emit()
                self.selectionChanged.emit()

        def setlower(line):
            ebound = self.__effectiveBoundary()
            elower, eupper = ebound
            mode = self.__selectionMode
            if not mode & ViolinPlot.Low:
                return
            lower = line.value()
            upper = max(eupper, lower)
            if upper != eupper and mode & ViolinPlot.High:
                self.__max = upper
                cmax.setValue(upper)

            if lower != elower:
                self.__min = lower

            if ebound != self.__effectiveBoundary():
                self.selectionEdited.emit()
                self.selectionChanged.emit()

        cmax.sigPositionChanged.connect(setupper)
        cmin.sigPositionChanged.connect(setlower)
        selmode = self.__selectionMode
        cmax.setVisible(selmode & ViolinPlot.High)
        cmin.setVisible(selmode & ViolinPlot.Low)
        selection_item.setVisible(selmode)

        self.addItem(dots)
        self.addItem(item)
        self.addItem(cmax)
        self.addItem(cmin)
        self.addItem(selection_item)

        self.setRange(
            QRectF(-est_max, np.min(sample), est_max * 2, np.ptp(sample)))
        self._plotitems = SimpleNamespace(pointsitem=dots,
                                          densityitem=item,
                                          cmax=cmax,
                                          cmin=cmin,
                                          selection_item=selection_item)
        self.__min = xmin
        self.__max = xmax
예제 #30
0
    def _setup_plot(self):
        """Setup the plot with new curve data."""
        assert self.data is not None
        self.graph.clear()

        data, domain = self.data, self.data.domain
        var = domain[self.group_var]
        class_col_data, _ = data.get_column_view(var)
        group_indices = [
            np.flatnonzero(class_col_data == i)
            for i in range(len(self.classes))
        ]

        self.graph.getAxis('bottom').setTicks([[
            (i + 1, str(a)) for i, a in enumerate(self.graph_variables)
        ]])

        X = np.arange(1, len(self.graph_variables) + 1)
        groups = []

        for i, indices in enumerate(group_indices):
            if len(indices) == 0:
                groups.append(None)
            else:
                if self.classes:
                    color = self.class_colors[i]
                else:
                    color = QColor(Qt.darkGray)
                group_data = data[indices, self.graph_variables]
                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)

                curve = pg.PlotCurveItem(
                    x=plot_x,
                    y=plot_y,
                    connect=connect,
                    pen=lightpen,
                    symbolSize=2,
                    antialias=True,
                )
                self.graph.addItem(curve)

                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)
                self.graph.addItem(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,
                              mean=meancurve,
                              boxplot=errorbar))

        self.__groups = groups
        self.__update_visibility()
예제 #31
0
 def make_pen(color, width=1):
     pen = QPen(color, width)
     pen.setCosmetic(True)
     return pen