Ejemplo n.º 1
0
    def plotContourFills(self, painter, posn, axes, clip):
        """Plot the traced contours on the painter."""

        s = self.settings

        # don't draw if there are no cached polygons
        if self._cachedpolygons is None or s.Fills.hide:
            return

        # iterate over each level, and list of lines
        for num, polylist in enumerate(self._cachedpolygons):

            # iterate over each complete line of the contour
            path = qt4.QPainterPath()
            for poly in polylist:
                # convert coordinates from graph to plotter
                xplt = axes[0].dataToPlotterCoords(posn, poly[:,0])
                yplt = axes[1].dataToPlotterCoords(posn, poly[:,1])

                pts = qt4.QPolygonF()
                utils.addNumpyToPolygonF(pts, xplt, yplt)

                clippedpoly = qt4.QPolygonF()
                utils.polygonClip(pts, clip, clippedpoly)
                path.addPolygon(clippedpoly)

            # fill polygons
            brush = s.Fills.get('fills').returnBrushExtended(num)
            utils.brushExtFillPath(painter, brush, path)
Ejemplo n.º 2
0
    def _drawBezierLine( self, painter, xvals, yvals, posn,
                         xdata, ydata):
        """Handle bezier lines and fills."""

        pts = self._getLinePoints(xvals, yvals, posn, xdata, ydata)
        if len(pts) < 2:
            return
        path = self._getBezierLine(pts)
        s = self.settings

        # See note in addSettings about names of FillAbove and FillBelow
        for fill in (s.FillBelow, s.FillAbove):
            if not fill.hide:
                temppath = qt4.QPainterPath(path)
                temppath.lineTo({
                    'bottom': qt4.QPointF(pts[-1].x(), posn[3]),
                    'top':    qt4.QPointF(pts[-1].x(), posn[1]),
                    'left':   qt4.QPointF(posn[0], pts[-1].y()),
                    'right':  qt4.QPointF(posn[2], pts[-1].y()),
                    }[fill.edge])
                temppath.lineTo({
                    'bottom': qt4.QPointF(pts[0].x(), posn[3]),
                    'top':    qt4.QPointF(pts[0].x(), posn[1]),
                    'left':   qt4.QPointF(posn[0], pts[0].y()),
                    'right':  qt4.QPointF(posn[2], pts[0].y()),
                    }[fill.edge])
                utils.brushExtFillPath(painter, fill, temppath)

        if not s.PlotLine.hide:
            painter.strokePath(path, s.PlotLine.makeQPen(painter))
Ejemplo n.º 3
0
    def draw(self, parentposn, painthelper, outerbounds=None):
        '''Update the margins before drawing.'''

        s = self.settings

        margins = (s.get('leftMargin').convert(painthelper),
                   s.get('topMargin').convert(painthelper),
                   s.get('rightMargin').convert(painthelper),
                   s.get('bottomMargin').convert(painthelper))

        bounds = self.computeBounds(parentposn, painthelper, margins=margins)
        maxbounds = self.computeBounds(parentposn, painthelper)

        # controls for adjusting graph margins
        painter = painthelper.painter(self, bounds)
        painthelper.setControlGraph(self, [
            controlgraph.ControlMarginBox(self, bounds, maxbounds, painthelper)
        ])

        # do no painting if hidden
        if s.hide:
            return bounds

        # set graph rectangle attributes
        path = qt4.QPainterPath()
        path.addRect(
            qt4.QRectF(qt4.QPointF(bounds[0], bounds[1]),
                       qt4.QPointF(bounds[2], bounds[3])))
        utils.brushExtFillPath(painter,
                               s.Background,
                               path,
                               stroke=s.Border.makeQPenWHide(painter))

        # do normal drawing of children
        # iterate over children in reverse order
        for c in reversed(self.children):
            c.draw(bounds, painthelper, outerbounds=outerbounds)

        # now need to find axes which aren't children, and draw those again
        axestodraw = set()
        childrennames = set()
        for c in self.children:
            childrennames.add(c.name)
            try:
                for axis in c.getAxesNames():
                    axestodraw.add(axis)
            except AttributeError:
                pass

        axestodraw = axestodraw - childrennames
        if axestodraw:
            # now redraw all these axes if they aren't children of us
            axeswidgets = self.getAxes(axestodraw)
            for w in axeswidgets:
                if w is not None:
                    w.draw(bounds, painthelper, outerbounds=outerbounds)

        return bounds
Ejemplo n.º 4
0
    def areaDrawStacked(self, painter, posns, maxwidth, dsvals,
                        axes, widgetposn, clip):
        """Draw a stacked area plot"""

        s = self.settings

        # get axis which values are plotted along
        ishorz = s.direction == 'horizontal'
        vaxis = axes[not ishorz]

        # compute stacked coordinates
        stackedvals, stackedcoords = self.calcStackedPoints(
            dsvals, vaxis, widgetposn)
        # coordinates of origin
        zerocoords = vaxis.dataToPlotterCoords(widgetposn, N.zeros(posns.shape))

        # draw areas (reverse order, so edges are plotted correctly)
        for dsnum, coords in izip( xrange(len(stackedcoords)-1, -1, -1),
                                   stackedcoords[::-1]):

            # add points at end to make polygon
            p1 = N.hstack( [ [zerocoords[0]], coords, [zerocoords[-1]] ] )
            p2 = N.hstack( [ [posns[0]], posns, [posns[-1]] ] )

            # construct polygon on path, clipped
            poly = qt4.QPolygonF()
            if ishorz:
                utils.addNumpyToPolygonF(poly, p1, p2)
            else:
                utils.addNumpyToPolygonF(poly, p2, p1)
            clippoly = qt4.QPolygonF()
            utils.polygonClip(poly, clip, clippoly)
            path = qt4.QPainterPath()
            path.addPolygon(clippoly)
            path.closeSubpath()

            # actually draw polygon
            brush = s.BarFill.get('fills').returnBrushExtended(dsnum)
            utils.brushExtFillPath(painter, brush, path)

            # now draw lines
            poly = qt4.QPolygonF()
            if ishorz:
                utils.addNumpyToPolygonF(poly, coords, posns)
            else:
                utils.addNumpyToPolygonF(poly, posns, coords)

            pen = s.BarLine.get('lines').makePen(painter, dsnum)
            painter.setPen(pen)
            utils.plotClippedPolyline(painter, clip, poly)

        # draw error bars
        barwidth = maxwidth * s.barfill
        for barval, dsval in izip(stackedvals, dsvals):
            self.drawErrorBars(painter, posns, barwidth,
                               barval, dsval,
                               axes, widgetposn)
Ejemplo n.º 5
0
    def areaDrawStacked(self, painter, posns, maxwidth, dsvals, axes,
                        widgetposn, clip):
        """Draw a stacked area plot"""

        s = self.settings

        # get axis which values are plotted along
        ishorz = s.direction == 'horizontal'
        vaxis = axes[not ishorz]

        # compute stacked coordinates
        stackedvals, stackedcoords = self.calcStackedPoints(
            dsvals, vaxis, widgetposn)
        # coordinates of origin
        zerocoords = vaxis.dataToPlotterCoords(widgetposn,
                                               N.zeros(posns.shape))

        # draw areas (reverse order, so edges are plotted correctly)
        for dsnum, coords in izip(xrange(len(stackedcoords) - 1, -1, -1),
                                  stackedcoords[::-1]):

            # add points at end to make polygon
            p1 = N.hstack([[zerocoords[0]], coords, [zerocoords[-1]]])
            p2 = N.hstack([[posns[0]], posns, [posns[-1]]])

            # construct polygon on path, clipped
            poly = qt4.QPolygonF()
            if ishorz:
                utils.addNumpyToPolygonF(poly, p1, p2)
            else:
                utils.addNumpyToPolygonF(poly, p2, p1)
            clippoly = qt4.QPolygonF()
            utils.polygonClip(poly, clip, clippoly)
            path = qt4.QPainterPath()
            path.addPolygon(clippoly)
            path.closeSubpath()

            # actually draw polygon
            brush = s.BarFill.get('fills').returnBrushExtended(dsnum)
            utils.brushExtFillPath(painter, brush, path)

            # now draw lines
            poly = qt4.QPolygonF()
            if ishorz:
                utils.addNumpyToPolygonF(poly, coords, posns)
            else:
                utils.addNumpyToPolygonF(poly, posns, coords)

            pen = s.BarLine.get('lines').makePen(painter, dsnum)
            painter.setPen(pen)
            utils.plotClippedPolyline(painter, clip, poly)

        # draw error bars
        barwidth = maxwidth * s.barfill
        for barval, dsval in izip(stackedvals, dsvals):
            self.drawErrorBars(painter, posns, barwidth, barval, dsval, axes,
                               widgetposn)
Ejemplo n.º 6
0
    def drawShape(self, painter, rect):
        s = self.settings
        path = qt4.QPainterPath()
        if s.rounding == 0:
            path.addRect(rect)
        else:
            path.addRoundedRect(rect, s.rounding, s.rounding)

        utils.brushExtFillPath(painter, s.Fill, path, stroke=painter.pen())
Ejemplo n.º 7
0
    def drawShape(self, painter, rect):
        s = self.settings
        path = qt4.QPainterPath()
        if s.rounding == 0:
            path.addRect(rect)
        else:
            path.addRoundedRect(rect, s.rounding, s.rounding)

        utils.brushExtFillPath(painter, s.Fill, path, stroke=painter.pen())
Ejemplo n.º 8
0
    def draw(self, parentposn, painthelper, outerbounds = None):
        '''Update the margins before drawing.'''

        s = self.settings

        margins = ( s.get('leftMargin').convert(painthelper),
                    s.get('topMargin').convert(painthelper),
                    s.get('rightMargin').convert(painthelper),
                    s.get('bottomMargin').convert(painthelper) )

        bounds = self.computeBounds(parentposn, painthelper, margins=margins)
        maxbounds = self.computeBounds(parentposn, painthelper)

        # controls for adjusting graph margins
        painter = painthelper.painter(self, bounds)
        painthelper.setControlGraph(self, [
                controlgraph.ControlMarginBox(self, bounds, maxbounds,
                                              painthelper) ])

        # do no painting if hidden
        if s.hide:
            return bounds

        # set graph rectangle attributes
        path = qt4.QPainterPath()
        path.addRect( qt4.QRectF(qt4.QPointF(bounds[0], bounds[1]),
                                 qt4.QPointF(bounds[2], bounds[3])) )
        utils.brushExtFillPath(painter, s.Background, path,
                               stroke=s.Border.makeQPenWHide(painter))

        # do normal drawing of children
        # iterate over children in reverse order
        for c in reversed(self.children):
            c.draw(bounds, painthelper, outerbounds=outerbounds)

        # now need to find axes which aren't children, and draw those again
        axestodraw = set()
        childrennames = set()
        for c in self.children:
            childrennames.add(c.name)
            try:
                for axis in c.getAxesNames():
                    axestodraw.add(axis)
            except AttributeError:
                pass

        axestodraw = axestodraw - childrennames
        if axestodraw:
            # now redraw all these axes if they aren't children of us
            axeswidgets = self.getAxes(axestodraw)
            for w in axeswidgets:
                if w is not None:
                    w.draw(bounds, painthelper, outerbounds=outerbounds)

        return bounds
Ejemplo n.º 9
0
def _errorBarsDiamondFilled(style, xmin, xmax, ymin, ymax, xplotter, yplotter,
                            s, painter, clip):
    """Draw diamond filled region inside error bars."""
    if None not in (xmin, xmax, ymin, ymax):
        if not s.FillBelow.hideerror:
            path = qt4.QPainterPath()
            utils.addNumpyPolygonToPath(path, clip, xmin, yplotter, xplotter,
                                        ymin, xmax, yplotter)
            utils.brushExtFillPath(painter, s.FillBelow, path, ignorehide=True)

        if not s.FillAbove.hideerror:
            path = qt4.QPainterPath()
            utils.addNumpyPolygonToPath(path, clip, xmin, yplotter, xplotter,
                                        ymax, xmax, yplotter)
            utils.brushExtFillPath(painter, s.FillAbove, path, ignorehide=True)
Ejemplo n.º 10
0
    def drawGraph(self, painter, bounds, datarange, outerbounds=None):
        '''Plot graph area and axes.'''

        s = self.settings

        xw, yw = bounds[2]-bounds[0], bounds[3]-bounds[1]

        d60 = 60./180.*math.pi
        ang = math.atan2(yw, xw/2.)
        if ang > d60:
            # taller than wider
            widthh = xw/2
            height = math.tan(d60) * widthh
        else:
            # wider than taller
            height = yw
            widthh = height / math.tan(d60)

        # box for equilateral triangle
        self._box = ( (bounds[2]+bounds[0])/2 - widthh,
                      (bounds[1]+bounds[3])/2 - height/2,
                      (bounds[2]+bounds[0])/2 + widthh,
                      (bounds[1]+bounds[3])/2 + height/2 )
        self._width = widthh*2
        self._height = height

        # triangle shaped polygon for graph
        self._tripoly = p = qt4.QPolygonF()
        p.append( qt4.QPointF(self._box[0], self._box[3]) )
        p.append( qt4.QPointF(self._box[0]+widthh, self._box[1]) )
        p.append( qt4.QPointF(self._box[2], self._box[3]) )

        path = qt4.QPainterPath()
        path.addPolygon(p)
        path.closeSubpath()
        utils.brushExtFillPath(painter, s.Background, path,
                               stroke=s.Border.makeQPenWHide(painter))

        # work out origins and size
        self._size = max(min(s.fracsize, 1.), 0.)

        # make sure we don't go past the ends of the allowed range
        # value of origin of left axis at top
        self._orgleft = min(s.originleft, 1.-self._size)
        # value of origin of bottom axis at left
        self._orgbot = min(s.originbottom, 1.-self._size)
        # origin of right axis at bottom
        self._orgright = 1. - self._orgleft - (self._orgbot + self._size)
Ejemplo n.º 11
0
    def drawGraph(self, painter, bounds, datarange, outerbounds=None):
        '''Plot graph area and axes.'''

        s = self.settings

        xw, yw = bounds[2]-bounds[0], bounds[3]-bounds[1]

        d60 = 60./180.*math.pi
        ang = math.atan2(yw, xw/2.)
        if ang > d60:
            # taller than wider
            widthh = xw/2
            height = math.tan(d60) * widthh
        else:
            # wider than taller
            height = yw
            widthh = height / math.tan(d60)

        # box for equilateral triangle
        self._box = ( (bounds[2]+bounds[0])/2 - widthh,
                      (bounds[1]+bounds[3])/2 - height/2,
                      (bounds[2]+bounds[0])/2 + widthh,
                      (bounds[1]+bounds[3])/2 + height/2 )
        self._width = widthh*2
        self._height = height

        # triangle shaped polygon for graph
        self._tripoly = p = qt4.QPolygonF()
        p.append( qt4.QPointF(self._box[0], self._box[3]) )
        p.append( qt4.QPointF(self._box[0]+widthh, self._box[1]) )
        p.append( qt4.QPointF(self._box[2], self._box[3]) )

        path = qt4.QPainterPath()
        path.addPolygon(p)
        path.closeSubpath()
        utils.brushExtFillPath(painter, s.Background, path,
                               stroke=s.Border.makeQPenWHide(painter))

        # work out origins and size
        self._size = max(min(s.fracsize, 1.), 0.)

        # make sure we don't go past the ends of the allowed range
        # value of origin of left axis at top
        self._orgleft = min(s.originleft, 1.-self._size)
        # value of origin of bottom axis at left
        self._orgbot = min(s.originbottom, 1.-self._size)
        # origin of right axis at bottom
        self._orgright = 1. - self._orgleft - (self._orgbot + self._size)
Ejemplo n.º 12
0
def _errorBarsDiamondFilled(style, xmin, xmax, ymin, ymax, xplotter, yplotter,
                            s, painter, clip):
    """Draw diamond filled region inside error bars."""
    if None not in (xmin, xmax, ymin, ymax):
        if not s.FillBelow.hideerror:
            path = qt4.QPainterPath()
            utils.addNumpyPolygonToPath(path, clip,
                                        xmin, yplotter, xplotter, ymin,
                                        xmax, yplotter)
            utils.brushExtFillPath(painter, s.FillBelow, path, ignorehide=True)

        if not s.FillAbove.hideerror:
            path = qt4.QPainterPath()
            utils.addNumpyPolygonToPath(path, clip,
                                        xmin, yplotter, xplotter, ymax,
                                        xmax, yplotter)
            utils.brushExtFillPath(painter, s.FillAbove, path, ignorehide=True)
Ejemplo n.º 13
0
    def plotBars(self, painter, s, dsnum, clip, corners):
        """Plot a set of boxes."""
        # get style
        brush = s.BarFill.get('fills').returnBrushExtended(dsnum)
        pen = s.BarLine.get('lines').makePen(painter, dsnum)
        lw = pen.widthF() * 2

        # make clip box bigger to avoid lines showing
        extclip = qt4.QRectF(qt4.QPointF(clip.left()-lw, clip.top()-lw),
                             qt4.QPointF(clip.right()+lw, clip.bottom()+lw))

        # plot bars
        path = qt4.QPainterPath()
        utils.addNumpyPolygonToPath(
            path, extclip, corners[0], corners[1], corners[2], corners[1],
            corners[2], corners[3], corners[0], corners[3])
        utils.brushExtFillPath(painter, brush, path, stroke=pen)
Ejemplo n.º 14
0
    def drawFillPts(self, painter, extfill, cliprect, ptsx, ptsy):
        '''Draw points for plotting a fill.'''
        pts = qt4.QPolygonF()
        utils.addNumpyToPolygonF(pts, ptsx, ptsy)

        filltype = extfill.filltype
        if filltype == 'center':
            pts.append(qt4.QPointF(self._xc, self._yc))
            utils.brushExtFillPolygon(painter, extfill, cliprect, pts)
        elif filltype == 'outside':
            pp = qt4.QPainterPath()
            pp.moveTo(self._xc, self._yc)
            pp.arcTo(cliprect, 0, 360)
            pp.addPolygon(pts)
            utils.brushExtFillPath(painter, extfill, pp)
        elif filltype == 'polygon':
            utils.brushExtFillPolygon(painter, extfill, cliprect, pts)
Ejemplo n.º 15
0
    def drawFillPts(self, painter, extfill, cliprect,
                    ptsx, ptsy):
        '''Draw points for plotting a fill.'''
        pts = qt4.QPolygonF()
        utils.addNumpyToPolygonF(pts, ptsx, ptsy)

        filltype = extfill.filltype
        if filltype == 'center':
            pts.append( qt4.QPointF(self._xc, self._yc) )
            utils.brushExtFillPolygon(painter, extfill, cliprect, pts)
        elif filltype == 'outside':
            pp = qt4.QPainterPath()
            pp.moveTo(self._xc, self._yc)
            pp.arcTo(cliprect, 0, 360)
            pp.addPolygon(pts)
            utils.brushExtFillPath(painter, extfill, pp)
        elif filltype == 'polygon':
            utils.brushExtFillPolygon(painter, extfill, cliprect, pts)
Ejemplo n.º 16
0
    def drawGraph(self, painter, bounds, datarange, outerbounds=None):
        '''Plot graph area and axes.'''

        s = self.settings
        if s.maxradius == 'Auto':
            self._maxradius = datarange[1]
        else:
            self._maxradius = s.maxradius
    
        self._xscale = (bounds[2]-bounds[0])*0.5
        self._yscale = (bounds[3]-bounds[1])*0.5
        self._xc = 0.5*(bounds[0]+bounds[2])
        self._yc = 0.5*(bounds[3]+bounds[1])

        path = qt4.QPainterPath()
        path.addEllipse( qt4.QRectF( qt4.QPointF(bounds[0], bounds[1]),
                                     qt4.QPointF(bounds[2], bounds[3]) ) )
        utils.brushExtFillPath(painter, s.Background, path,
                               stroke=s.Border.makeQPenWHide(painter))
Ejemplo n.º 17
0
    def _fillRegion(self, painter, pxpts, pypts, bounds, belowleft, clip,
                    brush):
        """Fill the region above/below or left/right of the points.

        belowleft fills below if the variable is 'x', or left if 'y'
        otherwise it fills above/right."""

        # find starting and ending points for the filled region
        x1, y1, x2, y2 = bounds

        # trimming can lead to too few points
        if len(pxpts) < 2 or len(pypts) < 2:
            return

        pts = qt4.QPolygonF()
        if self.settings.variable == 'x':
            if belowleft:
                pts.append(qt4.QPointF(pxpts[0], y2))
                endpt = qt4.QPointF(pxpts[-1], y2)
            else:
                pts.append(qt4.QPointF(pxpts[0], y1))
                endpt = qt4.QPointF(pxpts[-1], y1)
        else:
            if belowleft:
                pts.append(qt4.QPointF(x1, pypts[0]))
                endpt = qt4.QPointF(x1, pypts[-1])
            else:
                pts.append(qt4.QPointF(x2, pypts[0]))
                endpt = qt4.QPointF(x2, pypts[-1])

        # add the points between
        utils.addNumpyToPolygonF(pts, pxpts, pypts)

        # stick on the ending point
        pts.append(endpt)

        # draw the clipped polygon
        clipped = qt4.QPolygonF()
        utils.polygonClip(pts, clip, clipped)
        path = qt4.QPainterPath()
        path.addPolygon(clipped)
        utils.brushExtFillPath(painter, brush, path)
Ejemplo n.º 18
0
    def plotBars(self, painter, s, dsnum, clip, corners):
        """Plot a set of boxes."""
        # get style
        brush = s.BarFill.get('fills').returnBrushExtended(dsnum)
        pen = s.BarLine.get('lines').makePen(painter, dsnum)
        lw = pen.widthF() * 2

        # make clip box bigger to avoid lines showing
        extclip = qt4.QRectF(
            qt4.QPointF(clip.left() - lw,
                        clip.top() - lw),
            qt4.QPointF(clip.right() + lw,
                        clip.bottom() + lw))

        # plot bars
        path = qt4.QPainterPath()
        utils.addNumpyPolygonToPath(path, extclip, corners[0], corners[1],
                                    corners[2], corners[1], corners[2],
                                    corners[3], corners[0], corners[3])
        utils.brushExtFillPath(painter, brush, path, stroke=pen)
Ejemplo n.º 19
0
    def drawGraph(self, painter, bounds, datarange, outerbounds=None):
        '''Plot graph area and axes.'''

        s = self.settings

        if datarange is None:
            datarange = [0., 1., 0., 1.]

        if s.maxradius == 'Auto':
            self._maxradius = datarange[1]
        else:
            self._maxradius = s.maxradius

        if s.minradius == 'Auto':
            if s.log:
                if datarange[0] > 0.:
                    self._minradius = datarange[0]
                else:
                    self._minradius = self._maxradius / 100.
            else:
                self._minradius = 0.
        else:
            self._minradius = s.minradius

        # stop negative values
        if s.log:
            self._minradius = N.clip(self._minradius, 1e-99, 1e99)
            self._maxradius = N.clip(self._maxradius, 1e-99, 1e99)
        if self._minradius == self._maxradius:
            self._maxradius = self._minradius + 1

        self._xscale = (bounds[2]-bounds[0])*0.5
        self._yscale = (bounds[3]-bounds[1])*0.5
        self._xc = 0.5*(bounds[0]+bounds[2])
        self._yc = 0.5*(bounds[3]+bounds[1])

        path = qt4.QPainterPath()
        path.addEllipse( qt4.QRectF( qt4.QPointF(bounds[0], bounds[1]),
                                     qt4.QPointF(bounds[2], bounds[3]) ) )
        utils.brushExtFillPath(painter, s.Background, path,
                               stroke=s.Border.makeQPenWHide(painter))
Ejemplo n.º 20
0
    def drawGraph(self, painter, bounds, datarange, outerbounds=None):
        '''Plot graph area and axes.'''

        s = self.settings
        if s.maxradius == 'Auto':
            self._maxradius = datarange[1]
        else:
            self._maxradius = s.maxradius

        self._xscale = (bounds[2] - bounds[0]) * 0.5
        self._yscale = (bounds[3] - bounds[1]) * 0.5
        self._xc = 0.5 * (bounds[0] + bounds[2])
        self._yc = 0.5 * (bounds[3] + bounds[1])

        path = qt4.QPainterPath()
        path.addEllipse(
            qt4.QRectF(qt4.QPointF(bounds[0], bounds[1]),
                       qt4.QPointF(bounds[2], bounds[3])))
        utils.brushExtFillPath(painter,
                               s.Background,
                               path,
                               stroke=s.Border.makeQPenWHide(painter))
Ejemplo n.º 21
0
def _errorBarsBoxFilled(style, xmin, xmax, ymin, ymax, xplotter, yplotter,
                        s, painter, clip):
    """Draw box filled region inside error bars."""
    print "_errorBarsBoxFilled"
    print xplotter
    print yplotter
    if None not in (xmin, xmax, ymin, ymax):
        # filled region below
        if not s.FillBelow.hideerror:
            path = qt4.QPainterPath()
            utils.addNumpyPolygonToPath(path, clip,
                                        xmin, ymin, xmin, yplotter,
                                        xmax, yplotter, xmax, ymin)
            utils.brushExtFillPath(painter, s.FillBelow, path, ignorehide=True)

        # filled region above
        if not s.FillAbove.hideerror:
            path = qt4.QPainterPath()
            utils.addNumpyPolygonToPath(path, clip,
                                        xmin, yplotter, xmax, yplotter,
                                        xmax, ymax, xmin, ymax)
            utils.brushExtFillPath(painter, s.FillAbove, path, ignorehide=True)
Ejemplo n.º 22
0
    def _fillRegion(self, painter, pxpts, pypts, bounds, belowleft, clip,
                    brush):
        """Fill the region above/below or left/right of the points.

        belowleft fills below if the variable is 'x', or left if 'y'
        otherwise it fills above/right."""

        # find starting and ending points for the filled region
        x1, y1, x2, y2 = bounds

        pts = qt4.QPolygonF()
        if self.settings.variable == 'x':
            if belowleft:
                pts.append(qt4.QPointF(pxpts[0], y2))
                endpt = qt4.QPointF(pxpts[-1], y2)
            else:
                pts.append(qt4.QPointF(pxpts[0], y1))
                endpt = qt4.QPointF(pxpts[-1], y1)
        else:
            if belowleft:
                pts.append(qt4.QPointF(x1, pypts[0]))
                endpt = qt4.QPointF(x1, pypts[-1])
            else:
                pts.append(qt4.QPointF(x2, pypts[0]))
                endpt = qt4.QPointF(x2, pypts[-1])

        # add the points between
        utils.addNumpyToPolygonF(pts, pxpts, pypts)

        # stick on the ending point
        pts.append(endpt)

        # draw the clipped polygon
        clipped = qt4.QPolygonF()
        utils.polygonClip(pts, clip, clipped)
        path = qt4.QPainterPath()
        path.addPolygon(clipped)
        utils.brushExtFillPath(painter, brush, path)
Ejemplo n.º 23
0
    def _drawBezierLine(self, painter, xvals, yvals, posn, xdata, ydata):
        """Handle bezier lines and fills."""

        pts = self._getLinePoints(xvals, yvals, posn, xdata, ydata)
        if len(pts) < 2:
            return
        path = self._getBezierLine(pts)
        s = self.settings

        if not s.FillBelow.hide:
            temppath = qt4.QPainterPath(path)
            temppath.lineTo(pts[-1].x(), posn[3])
            temppath.lineTo(pts[0].x(), posn[3])
            utils.brushExtFillPath(painter, s.FillBelow, temppath)

        if not s.FillAbove.hide:
            temppath = qt4.QPainterPath(path)
            temppath.lineTo(pts[-1].x(), posn[1])
            temppath.lineTo(pts[0].x(), posn[1])
            utils.brushExtFillPath(painter, s.FillAbove, temppath)

        if not s.PlotLine.hide:
            painter.strokePath(path, s.PlotLine.makeQPen(painter))
Ejemplo n.º 24
0
    def draw(self, posn, phelper, outerbounds=None):
        """Plot the data on a plotter."""

        s = self.settings

        # exit if hidden
        if s.hide:
            return

        # get points in plotter coordinates
        xp, yp = self._getPlotterCoords(posn)
        if xp is None or yp is None:
            # we can't calculate coordinates
            return

        x1, y1, x2, y2 = posn
        cliprect = qt4.QRectF( qt4.QPointF(x1, y1), qt4.QPointF(x2, y2) )
        painter = phelper.painter(self, posn, clip=cliprect)

        pen = s.Line.makeQPenWHide(painter)
        pw = pen.widthF()*2
        lineclip = qt4.QRectF( qt4.QPointF(x1-pw, y1-pw),
                               qt4.QPointF(x2+pw, y2+pw) )

        # this is a hack as we generate temporary fake datasets
        path = qt4.QPainterPath()
        for xvals, yvals in document.generateValidDatasetParts(
            document.Dataset(xp), document.Dataset(yp)):

            poly = qt4.QPolygonF()
            utils.addNumpyToPolygonF(poly, xvals.data, yvals.data)
            clippedpoly = qt4.QPolygonF()
            utils.polygonClip(poly, lineclip, clippedpoly)
            path.addPolygon(clippedpoly)
            path.closeSubpath()

        utils.brushExtFillPath(painter, s.Fill, path, stroke=pen)
Ejemplo n.º 25
0
    def draw(self, posn, phelper, outerbounds=None):
        """Plot the data on a plotter."""

        s = self.settings

        # exit if hidden
        if s.hide:
            return

        # get points in plotter coordinates
        xp, yp = self._getPlotterCoords(posn)
        if xp is None or yp is None:
            # we can't calculate coordinates
            return

        x1, y1, x2, y2 = posn
        cliprect = qt4.QRectF(qt4.QPointF(x1, y1), qt4.QPointF(x2, y2))
        painter = phelper.painter(self, posn, clip=cliprect)

        pen = s.Line.makeQPenWHide(painter)
        pw = pen.widthF() * 2
        lineclip = qt4.QRectF(qt4.QPointF(x1 - pw, y1 - pw),
                              qt4.QPointF(x2 + pw, y2 + pw))

        # this is a hack as we generate temporary fake datasets
        path = qt4.QPainterPath()
        for xvals, yvals in document.generateValidDatasetParts(
                document.Dataset(xp), document.Dataset(yp)):

            poly = qt4.QPolygonF()
            utils.addNumpyToPolygonF(poly, xvals.data, yvals.data)
            clippedpoly = qt4.QPolygonF()
            utils.polygonClip(poly, lineclip, clippedpoly)
            path.addPolygon(clippedpoly)
            path.closeSubpath()

        utils.brushExtFillPath(painter, s.Fill, path, stroke=pen)
Ejemplo n.º 26
0
    def _drawBezierLine( self, painter, xvals, yvals, posn,
                         xdata, ydata):
        """Handle bezier lines and fills."""

        pts = self._getLinePoints(xvals, yvals, posn, xdata, ydata)
        if len(pts) < 2:
            return
        path = self._getBezierLine(pts)
        s = self.settings

        if not s.FillBelow.hide:
            temppath = qt4.QPainterPath(path)
            temppath.lineTo(pts[-1].x(), posn[3])
            temppath.lineTo(pts[0].x(), posn[3])
            utils.brushExtFillPath(painter, s.FillBelow, temppath)

        if not s.FillAbove.hide:
            temppath = qt4.QPainterPath(path)
            temppath.lineTo(pts[-1].x(), posn[1])
            temppath.lineTo(pts[0].x(), posn[1])
            utils.brushExtFillPath(painter, s.FillAbove, temppath)

        if not s.PlotLine.hide:
            painter.strokePath(path, s.PlotLine.makeQPen(painter))
Ejemplo n.º 27
0
    def draw(self, parentposn, phelper, outerbounds = None):
        """Plot the key on a plotter."""

        s = self.settings
        if s.hide:
            return

        painter = phelper.painter(self, parentposn)

        font = s.get('Text').makeQFont(painter)
        painter.setFont(font)
        height = utils.FontMetrics(font, painter.device()).height()
        margin = s.marginSize * height

        showtext = not s.Text.hide

        # maximum width of text required
        maxwidth = 1
        # total number of layout lines required
        totallines = 0

        # reserve space for the title
        titlewidth, titleheight = 0, 0
        if s.title != '':
            titlefont = qt4.QFont(font)
            titlefont.setPointSize(max(font.pointSize() * 1.2, font.pointSize() + 2))
            titlewidth, titleheight = utils.Renderer(painter, titlefont,
                                            0, 0, s.title).getDimensions()
            titleheight += 0.5*margin
            maxwidth = titlewidth

        entries = []
        # iterate over children and find widgets which are suitable
        for c in self.parent.children:
            try:
                num = c.getNumberKeys()
            except AttributeError:
                continue
            if not c.settings.hide:
                # add an entry for each key entry for each widget
                for i in xrange(num):
                    lines = 1
                    if showtext:
                        w, h = utils.Renderer(painter, font, 0, 0,
                                              c.getKeyText(i)).getDimensions()
                        maxwidth = max(maxwidth, w)
                        lines = max(1, math.ceil(float(h)/float(height)))
                    
                    totallines += lines
                    entries.append( (c, i, lines) )

        # layout the box
        layout, (numrows, numcols) = self._layout(entries, totallines)

        # total size of box
        symbolwidth = s.get('keyLength').convert(painter)
        totalwidth = ( (maxwidth + height + symbolwidth)*numcols +
                       height*(numcols-1) )
        totalheight = numrows * height + titleheight
        if not s.Border.hide:
            totalwidth += 2*margin
            totalheight += margin

        # work out horizontal position
        h = s.horzPosn
        if h == 'left':
            x = parentposn[0] + height
        elif h == 'right':
            x = parentposn[2] - height - totalwidth
        elif h == 'centre':
            x = ( parentposn[0] +
                  0.5*(parentposn[2] - parentposn[0] - totalwidth) )
        elif h == 'manual':
            x = parentposn[0] + (parentposn[2]-parentposn[0])*s.horzManual

        # work out vertical position
        v = s.vertPosn
        if v == 'top':
            y = parentposn[1] + height
        elif v == 'bottom':
            y = parentposn[3] - totalheight - height
        elif v == 'centre':
            y = ( parentposn[1] +
                  0.5*(parentposn[3] - parentposn[1] - totalheight) )
        elif v == 'manual':
            y = ( parentposn[3] -
                  (parentposn[3]-parentposn[1])*s.vertManual - totalheight )

        # for controlgraph
        boxposn = (x, y)
        boxdims = (totalwidth, totalheight)

        # draw surrounding box
        boxpath = qt4.QPainterPath()
        boxpath.addRect(qt4.QRectF(x, y, totalwidth, totalheight))
        if not s.Background.hide:
            utils.brushExtFillPath(painter, s.Background, boxpath)
        if not s.Border.hide:
            painter.strokePath(boxpath, s.get('Border').makeQPen(painter) )
            x += margin
            y += margin*0.5

        # center and draw the title
        if s.title:
            xpos = x + 0.5*(totalwidth - (0 if s.Border.hide else 2*margin) - titlewidth)
            utils.Renderer(painter, titlefont, xpos, y, s.title, alignvert=1).render()
            y += titleheight

        textpen = s.get('Text').makeQPen()

        # plot dataset entries
        for (plotter, num, xp, yp, lines) in layout:
            xpos = x + xp*(maxwidth+2*height+symbolwidth)
            ypos = y + yp*height

            # plot key symbol
            painter.save()
            keyoffset = 0
            if s.keyAlign == 'centre':
                keyoffset = (lines-1)*height/2.0
            elif s.keyAlign == 'bottom':
                keyoffset = (lines-1)*height
            
            plotter.drawKeySymbol(num, painter, xpos, ypos+keyoffset,
                                  symbolwidth, height)
            painter.restore()

            # write key text
            if showtext:
                painter.setPen(textpen)
                utils.Renderer(painter, font,
                               xpos + height + symbolwidth, ypos,
                               plotter.getKeyText(num),
                               -1, 1).render()

        phelper.setControlGraph(
            self, [ControlKey(self, parentposn, boxposn, boxdims, height)] )
Ejemplo n.º 28
0
    def plotBox(self, painter, axes, boxposn, posn, width, clip, stats):
        """Draw box for dataset."""

        if not N.isfinite(stats.median):
            # skip bad datapoints
            return

        s = self.settings
        horz = (s.direction == 'horizontal')

        # convert quartiles, top and bottom whiskers to plotter
        medplt, botplt, topplt, botwhisplt, topwhisplt = tuple(
            axes[not horz].dataToPlotterCoords(
                posn,
                N.array([
                    stats.median, stats.botquart, stats.topquart,
                    stats.botwhisker, stats.topwhisker
                ])))

        # draw whisker top to bottom
        p = s.Whisker.makeQPenWHide(painter)
        p.setCapStyle(qt4.Qt.FlatCap)
        painter.setPen(p)
        swapline(painter, boxposn, topwhisplt, boxposn, botwhisplt, horz)
        # draw ends of whiskers
        endsize = width / 2
        swapline(painter, boxposn - endsize / 2, topwhisplt,
                 boxposn + endsize / 2, topwhisplt, horz)
        swapline(painter, boxposn - endsize / 2, botwhisplt,
                 boxposn + endsize / 2, botwhisplt, horz)

        # draw box fill
        boxpath = qt4.QPainterPath()
        boxpath.addRect(
            swapbox(painter, boxposn - width / 2, botplt, boxposn + width / 2,
                    topplt, horz))
        utils.brushExtFillPath(painter, s.Fill, boxpath)

        # draw line across box
        p = s.Whisker.makeQPenWHide(painter)
        p.setCapStyle(qt4.Qt.FlatCap)
        painter.setPen(p)
        swapline(painter, boxposn - width / 2, medplt, boxposn + width / 2,
                 medplt, horz)

        # draw box
        painter.strokePath(boxpath, s.Border.makeQPenWHide(painter))

        # draw outliers
        painter.setPen(s.MarkersLine.makeQPenWHide(painter))
        painter.setBrush(s.MarkersFill.makeQBrushWHide())
        markersize = s.get('markerSize').convert(painter)
        if stats.outliers.shape[0] != 0:
            pltvals = axes[not horz].dataToPlotterCoords(posn, stats.outliers)
            otherpos = N.zeros(pltvals.shape) + boxposn
            if horz:
                x, y = pltvals, otherpos
            else:
                x, y = otherpos, pltvals

            utils.plotMarkers(painter,
                              x,
                              y,
                              s.outliersmarker,
                              markersize,
                              clip=clip)

        # draw mean
        meanplt = axes[not horz].dataToPlotterCoords(posn,
                                                     N.array([stats.mean]))[0]
        if horz:
            x, y = meanplt, boxposn
        else:
            x, y = boxposn, meanplt
        utils.plotMarker(painter, x, y, s.meanmarker, markersize)
Ejemplo n.º 29
0
 def drawShape(self, painter, rect):
     s = self.settings
     path = qt4.QPainterPath()
     path.addEllipse(rect)
     utils.brushExtFillPath(painter, s.Fill, path, stroke=painter.pen())
Ejemplo n.º 30
0
 def drawShape(self, painter, rect):
     s = self.settings
     path = qt4.QPainterPath()
     path.addEllipse(rect)
     utils.brushExtFillPath(painter, s.Fill, path, stroke=painter.pen())
Ejemplo n.º 31
0
    def draw(self, parentposn, painthelper, outerbounds = None):
        '''Update the margins before drawing.'''

        # yuck, avoid circular imports
        import axisbroken

        s = self.settings

        bounds = self.computeBounds(parentposn, painthelper)
        maxbounds = self.computeBounds(parentposn, painthelper, withmargin=False)

        # do no painting if hidden
        if s.hide:
            return bounds

        # controls for adjusting graph margins
        painter = painthelper.painter(self, bounds)
        painthelper.setControlGraph(self, [
                controlgraph.ControlMarginBox(self, bounds, maxbounds,
                                              painthelper) ])

        with painter:
            # set graph rectangle attributes
            path = qt4.QPainterPath()
            path.addRect( qt4.QRectF(qt4.QPointF(bounds[0], bounds[1]),
                                     qt4.QPointF(bounds[2], bounds[3])) )
            utils.brushExtFillPath(painter, s.Background, path,
                                   stroke=s.Border.makeQPenWHide(painter))

        # child drawing algorithm is a bit complex due to axes
        # being shared between graphs and broken axes

        # this is a map of axis names to plot to axis widgets
        axestodraw = {}
        # axes widgets for each plotter (precalculated by Page)
        axesofwidget = painthelper.plotteraxismap
        for c in self.children:
            try:
                for a in axesofwidget[c]:
                    axestodraw[a.name] = a
            except (KeyError, AttributeError):
                if hasattr(c, 'isaxis'):
                    axestodraw[c.name] = c

        # grid lines are normally plotted before other child widgets
        axisdrawlist = sorted(axestodraw.items(), reverse=True)
        for aname, awidget in axisdrawlist:
            awidget.updateAxisLocation(bounds)
            awidget.computePlottedRange()
            awidget.drawGrid(bounds, painthelper, outerbounds=outerbounds,
                             ontop=False)

        # broken axis handling
        brokenaxes = set()
        for name, axis in axestodraw.iteritems():
            if isinstance(axis, axisbroken.AxisBroken):
                brokenaxes.add(axis)

        # do normal drawing of children
        # iterate over children in reverse order
        for c in reversed(self.children):

            if hasattr(c, 'isaxis'):
                continue

            axes = axesofwidget.get(c, None)
            if axes is not None and any((a in brokenaxes for a in axes)):
                # handle broken axes
                childbrokenaxes = sorted([ (a.name, a) for a in axes
                                           if a in brokenaxes ])
                childbrokenaxes.sort()
                def iteratebrokenaxes(b):
                    """Recursively iterate over each broken axis and redraw
                    child for each.
                    We might have more than one broken axis per child, so
                    hence this rather strange iteration.
                    """
                    ax = b[0][1]
                    for i in xrange(ax.breakvnum):
                        ax.switchBreak(i, bounds)
                        if len(b) == 1:
                            c.draw(bounds, painthelper, outerbounds=outerbounds)
                        else:
                            iteratebrokenaxes(b[1:])
                    ax.switchBreak(None, bounds)
                iteratebrokenaxes(childbrokenaxes)

            else:
                # standard non broken axis drawing
                c.draw(bounds, painthelper, outerbounds=outerbounds)

        # then for grid lines on top
        for aname, awidget in axisdrawlist:
            axis.drawGrid(bounds, painthelper, outerbounds=outerbounds,
                          ontop=True)

        # draw axes on top of grid lines
        for aname, awidget in axisdrawlist:
            awidget.draw(bounds, painthelper, outerbounds=outerbounds)

        return bounds
Ejemplo n.º 32
0
    def plotBox(self, painter, axes, boxposn, posn, width, clip, stats):
        """Draw box for dataset."""

        s = self.settings
        horz = (s.direction == 'horizontal')

        # convert quartiles, top and bottom whiskers to plotter
        medplt, botplt, topplt, botwhisplt, topwhisplt = tuple(
            axes[not horz].dataToPlotterCoords(
                posn,
                N.array([ stats.median, stats.botquart, stats.topquart,
                          stats.botwhisker, stats.topwhisker ]))
            )

        # draw whisker top to bottom
        p = s.Whisker.makeQPenWHide(painter)
        p.setCapStyle(qt4.Qt.FlatCap)
        painter.setPen(p)
        swapline(painter, boxposn, topwhisplt, boxposn, botwhisplt, horz)
        # draw ends of whiskers
        endsize = width/2
        swapline(painter, boxposn-endsize/2, topwhisplt,
                 boxposn+endsize/2, topwhisplt, horz)
        swapline(painter, boxposn-endsize/2, botwhisplt,
                 boxposn+endsize/2, botwhisplt, horz)

        # draw box fill
        boxpath = qt4.QPainterPath()
        boxpath.addRect( swapbox(painter, boxposn-width/2, botplt,
                                 boxposn+width/2, topplt, horz) )
        utils.brushExtFillPath(painter, s.Fill, boxpath)

        # draw line across box
        p = s.Whisker.makeQPenWHide(painter)
        p.setCapStyle(qt4.Qt.FlatCap)
        painter.setPen(p)
        swapline(painter, boxposn-width/2, medplt,
                 boxposn+width/2, medplt, horz)

        # draw box
        painter.strokePath(boxpath, s.Border.makeQPenWHide(painter) )

        # draw outliers
        painter.setPen( s.MarkersLine.makeQPenWHide(painter) )
        painter.setBrush( s.MarkersFill.makeQBrushWHide() )
        markersize = s.get('markerSize').convert(painter)
        if stats.outliers.shape[0] != 0:
            pltvals = axes[not horz].dataToPlotterCoords(posn, stats.outliers)
            otherpos = N.zeros(pltvals.shape) + boxposn
            if horz:
                x, y = pltvals, otherpos
            else:
                x, y = otherpos, pltvals

            utils.plotMarkers( painter, x, y, s.outliersmarker,
                               markersize, clip=clip )

        # draw mean
        meanplt = axes[not horz].dataToPlotterCoords(
            posn, N.array([stats.mean]))[0]
        if horz:
            x, y = meanplt, boxposn
        else:
            x, y = boxposn, meanplt
        utils.plotMarker( painter, x, y, s.meanmarker, markersize )