def _fillRegion(self, painter, pxpts, pypts, bounds, belowleft, clip): """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 s = self.settings 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) # actually do the filling utils.plotClippedPolygon(painter, clip, pts)
def _plotContours(self, painter, posn, axes, linestyles, contours, showlabels, hidelines, clip): """Plot a set of contours. """ s = self.settings # no lines cached as no line styles if contours is None: return # iterate over each level, and list of lines for num, linelist in enumerate(contours): # move to the next line style painter.setPen(linestyles.makePen(painter, num)) # iterate over each complete line of the contour for curve in linelist: # convert coordinates from graph to plotter xplt = axes[0].dataToPlotterCoords(posn, curve[:,0]) yplt = axes[1].dataToPlotterCoords(posn, curve[:,1]) pts = qt4.QPolygonF() utils.addNumpyToPolygonF(pts, xplt, yplt) if showlabels: self.plotContourLabel(painter, s.levelsOut[num], xplt, yplt, not hidelines) else: # actually draw the curve to the plotter if not hidelines: utils.plotClippedPolyline(painter, clip, pts)
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)
def drawFillPts(self, painter, brushext, cliprect, ptsx, ptsy): '''Draw points for plotting a fill.''' pts = qt4.QPolygonF() utils.addNumpyToPolygonF(pts, ptsx, ptsy) filltype = brushext.filltype # this is broken: FIXME if filltype == 'left': dyend = ptsy[-1]-self._box[1] pts.append( qt4.QPointF(ptsx[-1]-dyend*tan30, self._box[1]) ) dystart = ptsy[0]-self._box[1] pts.append( qt4.QPointF(ptsx[0]-dystart*tan30, self._box[1]) ) elif filltype == 'right': pts.append( qt4.QPointF(self._box[2], ptsy[-1]) ) pts.append( qt4.QPointF(self._box[2], ptsy[0]) ) elif filltype == 'bottom': dyend = self._box[3]-ptsy[-1] pts.append( qt4.QPointF(ptsx[-1]-dyend*tan30, self._box[3]) ) dystart = self._box[3]-ptsy[0] pts.append( qt4.QPointF(ptsx[0]-dystart*tan30, self._box[3]) ) elif filltype == 'polygon': pass else: pts = None if pts is not None: utils.brushExtFillPolygon(painter, brushext, cliprect, pts)
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 # ensure plotting of contours does not go outside the area painter.setPen(qt4.QPen(qt4.Qt.NoPen)) # iterate over each level, and list of lines for num, polylist in enumerate(self._cachedpolygons): # move to the next line style painter.setBrush(s.Fills.get('fills').makeBrush(num)) # iterate over each complete line of the contour 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) utils.plotClippedPolygon(painter, clip, pts)
def draw(self, parentposn, phelper, outerbounds=None): '''Plot the data on a plotter.''' posn = Widget.draw(self, parentposn, phelper, outerbounds=outerbounds) s = self.settings d = self.document # exit if hidden if s.hide: return d1 = s.get('data1').getData(d) d2 = s.get('data2').getData(d) dscale = s.get('scalePoints').getData(d) text = s.get('labels').getData(d, checknull=True) if not d1 or not d2: return x1, y1, x2, y2 = posn cliprect = qt4.QRectF( qt4.QPointF(x1, y1), qt4.QPointF(x2, y2) ) painter = phelper.painter(self, posn) self.parent.setClip(painter, posn) # split parts separated by NaNs for v1, v2, scalings, textitems in document.generateValidDatasetParts( d1, d2, dscale, text): # convert data (chopping down length) v1d, v2d = v1.data, v2.data minlen = min(v1d.shape[0], v2d.shape[0]) v1d, v2d = v1d[:minlen], v2d[:minlen] px, py = self.parent.graphToPlotCoords(v1d, v2d) # do fill1 (if any) if not s.Fill1.hide: self.parent.drawFillPts(painter, s.Fill1, cliprect, px, py) # do fill2 if not s.Fill2.hide: self.parent.drawFillPts(painter, s.Fill2, cliprect, px, py) # plot line if not s.PlotLine.hide: painter.setBrush( qt4.QBrush() ) painter.setPen(s.PlotLine.makeQPen(painter)) pts = qt4.QPolygonF() utils.addNumpyToPolygonF(pts, px, py) utils.plotClippedPolyline(painter, cliprect, pts) # markers markersize = s.get('markerSize').convert(painter) pscale = None if scalings: pscale = scalings.data self.plotMarkers(painter, px, py, pscale, markersize, cliprect) # finally plot any labels if textitems and not s.Label.hide: self.drawLabels(painter, px, py, textitems, markersize)
def plotContourLabel(self, painter, number, xplt, yplt, showline): """Draw a label on a contour. This clips when drawing the line, plotting the label on top. """ s = self.settings cl = s.get('ContourLabels') painter.save() # get text and font text = utils.formatNumber(number * cl.scale, cl.format, locale=self.document.locale) font = cl.makeQFont(painter) descent = utils.FontMetrics(font, painter.device()).descent() # work out where text lies half = len(xplt)/2 hx, hy = xplt[half], yplt[half] r = utils.Renderer(painter, font, hx, hy, text, alignhorz=0, alignvert=0, angle=0) bounds = r.getBounds() # heuristics of when to plot label # we try to only plot label if underlying line is long enough height = bounds[3]-bounds[1] showtext = ( height*1.5 < (yplt.max() - yplt.min()) or (height*4 < (xplt.max() - xplt.min())) ) if showtext: # clip region containing text oldclip = painter.clipRegion() cr = oldclip - qt4.QRegion( bounds[0]-descent, bounds[1]-descent, bounds[2]-bounds[0]+descent*2, bounds[3]-bounds[1]+descent*2 ) painter.setClipRegion(cr) # draw lines if showline: pts = qt4.QPolygonF() utils.addNumpyToPolygonF(pts, xplt, yplt) painter.drawPolyline(pts) # actually plot the label if showtext: painter.setClipRegion(oldclip) painter.setPen( cl.makeQPen() ) r.render() painter.restore()
def getPreviewPixmap(self, ds): """Get a preview pixmap for a dataset.""" size = (140, 70) if ds.dimensions != 1 or ds.datatype != "numeric": return None pixmap = qt4.QPixmap(*size) pixmap.fill(qt4.Qt.transparent) p = qt4.QPainter(pixmap) p.setRenderHint(qt4.QPainter.Antialiasing) # calculate data points try: if len(ds.data) < size[1]: y = ds.data else: intvl = len(ds.data)/size[1]+1 y = ds.data[::intvl] x = N.arange(len(y)) # plot data points on image minval, maxval = N.nanmin(y), N.nanmax(y) y = (y-minval) / (maxval-minval) * size[1] finite = N.isfinite(y) x, y = x[finite], y[finite] x = x * (1./len(x)) * size[0] poly = qt4.QPolygonF() utils.addNumpyToPolygonF(poly, x, size[1]-y) p.setPen( qt4.QPen(qt4.Qt.blue) ) p.drawPolyline(poly) # draw x axis if span 0 p.setPen( qt4.QPen(qt4.Qt.black) ) if minval <= 0 and maxval > 0: y0 = size[1] - (0-minval)/(maxval-minval)*size[1] p.drawLine(x[0], y0, x[-1], y0) else: p.drawLine(x[0], size[1], x[-1], size[1]) p.drawLine(x[0], 0, x[0], size[1]) except (ValueError, ZeroDivisionError): # zero sized array after filtering or min == max, so return None p.end() return None p.end() return pixmap
def getPreviewPixmap(self, ds): """Get a preview pixmap for a dataset.""" size = (140, 70) if ds.dimensions != 1 or ds.datatype != "numeric": return None pixmap = qt4.QPixmap(*size) pixmap.fill(qt4.Qt.transparent) p = qt4.QPainter(pixmap) p.setRenderHint(qt4.QPainter.Antialiasing) # calculate data points try: if len(ds.data) < size[1]: y = ds.data else: intvl = len(ds.data) / size[1] + 1 y = ds.data[::intvl] x = N.arange(len(y)) # plot data points on image minval, maxval = N.nanmin(y), N.nanmax(y) y = (y - minval) / (maxval - minval) * size[1] finite = N.isfinite(y) x, y = x[finite], y[finite] x = x * (1. / len(x)) * size[0] poly = qt4.QPolygonF() utils.addNumpyToPolygonF(poly, x, size[1] - y) p.setPen(qt4.QPen(qt4.Qt.blue)) p.drawPolyline(poly) # draw x axis if span 0 p.setPen(qt4.QPen(qt4.Qt.black)) if minval <= 0 and maxval > 0: y0 = size[1] - (0 - minval) / (maxval - minval) * size[1] p.drawLine(x[0], y0, x[-1], y0) else: p.drawLine(x[0], size[1], x[-1], size[1]) p.drawLine(x[0], 0, x[0], size[1]) except (ValueError, ZeroDivisionError): # zero sized array after filtering or min == max, so return None p.end() return None p.end() return pixmap
def drawFillPts(self, painter, cliprect, ptsx, ptsy, filltype): '''Draw points for plotting a fill.''' pts = qt4.QPolygonF() utils.addNumpyToPolygonF(pts, ptsx, ptsy) if filltype == 'center': pts.append( qt4.QPointF(self._xc, self._yc) ) utils.plotClippedPolygon(painter, cliprect, pts) elif filltype == 'outside': pp = qt4.QPainterPath() pp.moveTo(self._xc, self._yc) pp.arcTo(cliprect, 0, 360) pp.addPolygon(pts) painter.fillPath(pp, painter.brush()) elif filltype == 'polygon': utils.plotClippedPolygon(painter, cliprect, pts)
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)
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)
def _errorBarsFilled(style, xmin, xmax, ymin, ymax, xplotter, yplotter, s, painter, clip): """Draw filled region as error region.""" ptsabove = qt4.QPolygonF() ptsbelow = qt4.QPolygonF() hidevert = True # keep track of what's shown hidehorz = True if ('vert' in style and (ymin is not None and ymax is not None) and not s.ErrorBarLine.hideVert): hidevert = False # lines above/below points utils.addNumpyToPolygonF(ptsbelow, xplotter, ymin) utils.addNumpyToPolygonF(ptsabove, xplotter, ymax) elif ('horz' in style and (xmin is not None and xmax is not None) and not s.ErrorBarLine.hideHorz): hidehorz = False # lines left/right points utils.addNumpyToPolygonF(ptsbelow, xmin, yplotter) utils.addNumpyToPolygonF(ptsabove, xmax, yplotter) # draw filled regions above/left and below/right if 'fill' in style and not (hidehorz and hidevert): # construct points for error bar regions retnpts = qt4.QPolygonF() utils.addNumpyToPolygonF(retnpts, xplotter[::-1], yplotter[::-1]) # polygons consist of lines joining the points and continuing # back along the plot line (retnpts) if not s.FillBelow.hideerror: utils.brushExtFillPolygon(painter, s.FillBelow, clip, ptsbelow + retnpts, ignorehide=True) if not s.FillAbove.hideerror: utils.brushExtFillPolygon(painter, s.FillAbove, clip, ptsabove + retnpts, ignorehide=True) # draw optional line (on top of fill) utils.plotClippedPolyline(painter, clip, ptsabove) utils.plotClippedPolyline(painter, clip, ptsbelow)
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)
def _errorBarsFilled(style, xmin, xmax, ymin, ymax, xplotter, yplotter, s, painter, clip): """Draw filled region as error region.""" ptsabove = qt4.QPolygonF() ptsbelow = qt4.QPolygonF() hidevert = True # keep track of what's shown hidehorz = True if ( 'vert' in style and (ymin is not None and ymax is not None) and not s.ErrorBarLine.hideVert ): hidevert = False # lines above/below points utils.addNumpyToPolygonF(ptsbelow, xplotter, ymin) utils.addNumpyToPolygonF(ptsabove, xplotter, ymax) elif ( 'horz' in style and (xmin is not None and xmax is not None) and not s.ErrorBarLine.hideHorz ): hidehorz = False # lines left/right points utils.addNumpyToPolygonF(ptsbelow, xmin, yplotter) utils.addNumpyToPolygonF(ptsabove, xmax, yplotter) # draw filled regions above/left and below/right if 'fill' in style and not (hidehorz and hidevert): # construct points for error bar regions retnpts = qt4.QPolygonF() utils.addNumpyToPolygonF(retnpts, xplotter[::-1], yplotter[::-1]) # polygons consist of lines joining the points and continuing # back along the plot line (retnpts) if not s.FillBelow.hideerror: utils.brushExtFillPolygon(painter, s.FillBelow, clip, ptsbelow+retnpts, ignorehide=True) if not s.FillAbove.hideerror: utils.brushExtFillPolygon(painter, s.FillAbove, clip, ptsabove+retnpts, ignorehide=True) # draw optional line (on top of fill) utils.plotClippedPolyline(painter, clip, ptsabove) utils.plotClippedPolyline(painter, clip, ptsbelow)
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)
def _errorBarsFilled(style, xmin, xmax, ymin, ymax, xplotter, yplotter, s, painter, clip): """Draw filled region as error region.""" ptsabove = qt4.QPolygonF() ptsbelow = qt4.QPolygonF() hidevert = True # keep track of what's shown hidehorz = True if "vert" in style and (ymin is not None and ymax is not None) and not s.ErrorBarLine.hideVert: hidevert = False # lines above/below points utils.addNumpyToPolygonF(ptsbelow, xplotter, ymin) utils.addNumpyToPolygonF(ptsabove, xplotter, ymax) elif "horz" in style and (xmin is not None and xmax is not None) and not s.ErrorBarLine.hideHorz: hidehorz = False # lines left/right points utils.addNumpyToPolygonF(ptsbelow, xmin, yplotter) utils.addNumpyToPolygonF(ptsabove, xmax, yplotter) # draw filled regions above/left and below/right if "fill" in style and not (hidehorz and hidevert): # construct points for error bar regions retnpts = qt4.QPolygonF() utils.addNumpyToPolygonF(retnpts, xplotter[::-1], yplotter[::-1]) # polygons consist of lines joining the points and continuing # back along the plot line (retnpts) painter.save() painter.setPen(qt4.Qt.NoPen) if not s.FillBelow.hideerror: painter.setBrush(s.FillBelow.makeQBrush()) painter.drawPolygon(ptsbelow + retnpts) if not s.FillAbove.hideerror: painter.setBrush(s.FillAbove.makeQBrush()) painter.drawPolygon(ptsabove + retnpts) painter.restore() # draw optional line (on top of fill) utils.plotClippedPolyline(painter, clip, ptsabove) utils.plotClippedPolyline(painter, clip, ptsbelow)
def _errorBarsFilled(style, xmin, xmax, ymin, ymax, xplotter, yplotter, s, painter, clip): """Draw filled region as error region.""" ptsabove = qt4.QPolygonF() ptsbelow = qt4.QPolygonF() for orientation, edges, plotpts, minpts, maxpts, hideline in ( ('vert', ('top', 'bottom'), xplotter, ymin, ymax, s.ErrorBarLine.hideVert), ('horz', ('left', 'right'), yplotter, xmin, xmax, s.ErrorBarLine.hideHorz) ): if ( (orientation in style) and not hideline and (minpts is not None) and (maxpts is not None) ): utils.addNumpyToPolygonF(ptsbelow, plotpts, minpts) utils.addNumpyToPolygonF(ptsabove, plotpts, maxpts) if 'fill' in style: retnpts = qt4.QPolygonF() fillpts = { 'top': ptsabove, 'left': ptsabove, 'bottom': ptsbelow, 'right': ptsbelow } utils.addNumpyToPolygonF(retnpts, xplotter[::-1], yplotter[::-1]) # See note in addSettings about names of FillAbove and # FillBelow for fill in (s.FillAbove, s.FillBelow): # polygons consist of lines joining the points and # continuing back along the plot line (retnpts) if not fill.hideerror: utils.brushExtFillPolygon(painter, fill, clip, fillpts[fill.edge]+retnpts, ignorehide=True) utils.plotClippedPolyline(painter, clip, ptsabove) utils.plotClippedPolyline(painter, clip, ptsbelow)
def _drawAxisLine(self, painter): """Draw the line of the axis, indicating broken positions. We currently use a triangle to mark the broken position """ # these are x and y, or y and x coordinates p1 = [self.posstarts[0]] p2 = [0.] # mirror shape using this setting markdirn = -1 if self.coordReflected: markdirn = -markdirn # add shape for each break for start, stop in zip( self.posstarts[1:], self.posstops[:-1] ): p1 += [stop, (start+stop)*0.5, start] p2 += [0, markdirn*(start-stop)*0.5, 0] # end point p1.append(self.posstops[-1]) p2.append(0.) # scale points by length of axis and add correct origin scale = self.coordParr2 - self.coordParr1 p1 = N.array(p1) * scale + self.coordParr1 p2 = N.array(p2) * scale + self.coordPerp if self.settings.direction == 'vertical': p1, p2 = p2, p1 # convert to polygon and draw poly = qt4.QPolygonF() utils.addNumpyToPolygonF(poly, p1, p2) pen = self.settings.get('Line').makeQPen(painter) pen.setCapStyle(qt4.Qt.FlatCap) painter.setPen(pen) painter.drawPolyline(poly)
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)
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)
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)
try: self.checker.check(s.function, s.variable) except RuntimeError, e: self.logEvalError(e) return x1, y1, x2, y2 = posn cliprect = qt4.QRectF( qt4.QPointF(x1, y1), qt4.QPointF(x2, y2) ) painter = phelper.painter(self, posn) self.parent.setClip(painter, posn) apts, bpts = self.getFunctionPoints() px, py = self.parent.graphToPlotCoords(apts, bpts) # plot line painter.setBrush(qt4.QBrush()) painter.setPen( s.PlotLine.makeQPenWHide(painter) ) for x, y in utils.validLinePoints(px, py): if not s.Fill1.hide: self.parent.drawFillPts(painter, s.Fill1, cliprect, x, y) if not s.Fill2.hide: self.parent.drawFillPts(painter, s.Fill2, cliprect, x, y) if not s.PlotLine.hide: p = qt4.QPolygonF() utils.addNumpyToPolygonF(p, x, y) painter.setBrush(qt4.QBrush()) painter.setPen( s.PlotLine.makeQPen(painter) ) utils.plotClippedPolyline(painter, cliprect, p) document.thefactory.register( NonOrthFunction )
def _getLinePoints(self, xvals, yvals, posn, xdata, ydata): """Get the points corresponding to the line connecting the points.""" pts = qt4.QPolygonF() s = self.settings steps = s.PlotLine.steps # simple continuous line if steps == "off": utils.addNumpyToPolygonF(pts, xvals, yvals) # stepped line, with points on left elif steps == "left": x1 = xvals[:-1] x2 = xvals[1:] y1 = yvals[:-1] y2 = yvals[1:] utils.addNumpyToPolygonF(pts, x1, y1, x2, y1, x2, y2) # stepped line, with points on right elif steps == "right": x1 = xvals[:-1] x2 = xvals[1:] y1 = yvals[:-1] y2 = yvals[1:] utils.addNumpyToPolygonF(pts, x1, y1, x1, y2, x2, y2) # stepped line, with points in centre # this is complex as we can't use the mean of the plotter coords, # as the axis could be log elif steps == "centre": axes = self.parent.getAxes((s.xAxis, s.yAxis)) if xdata.hasErrors(): # Special case if error bars on x points: # here we use the error bars to define the steps xmin, xmax = xdata.getPointRanges() # this is duplicated from drawing error bars: bad # convert xmin and xmax to graph coordinates xmin = axes[0].dataToPlotterCoords(posn, xmin) xmax = axes[0].dataToPlotterCoords(posn, xmax) utils.addNumpyToPolygonF(pts, xmin, yvals, xmax, yvals) else: # we put the bin edges half way between the points # we assume this is the correct thing to do even in log space x1 = xvals[:-1] x2 = xvals[1:] y1 = yvals[:-1] y2 = yvals[1:] xc = 0.5 * (x1 + x2) utils.addNumpyToPolygonF(pts, x1, y1, xc, y1, xc, y2) if len(xvals) > 0: pts.append(qt4.QPointF(xvals[-1], yvals[-1])) else: assert False return pts
def _getLinePoints(self, xvals, yvals, posn, xdata, ydata): """Get the points corresponding to the line connecting the points.""" pts = qt4.QPolygonF() s = self.settings steps = s.PlotLine.steps # simple continuous line if steps == 'off': utils.addNumpyToPolygonF(pts, xvals, yvals) # stepped line, with points on left elif steps[:4] == 'left': x1 = xvals[:-1] x2 = xvals[1:] y1 = yvals[:-1] y2 = yvals[1:] utils.addNumpyToPolygonF(pts, x1, y1, x2, y1, x2, y2) # stepped line, with points on right elif steps[:5] == 'right': x1 = xvals[:-1] x2 = xvals[1:] y1 = yvals[:-1] y2 = yvals[1:] utils.addNumpyToPolygonF(pts, x1, y1, x1, y2, x2, y2) # stepped line, with points in centre # this is complex as we can't use the mean of the plotter coords, # as the axis could be log elif steps[:6] == 'centre': axes = self.parent.getAxes((s.xAxis, s.yAxis)) if xdata.hasErrors(): # Special case if error bars on x points: # here we use the error bars to define the steps xmin, xmax = xdata.getPointRanges() # this is duplicated from drawing error bars: bad # convert xmin and xmax to graph coordinates xmin = axes[0].dataToPlotterCoords(posn, xmin) xmax = axes[0].dataToPlotterCoords(posn, xmax) utils.addNumpyToPolygonF(pts, xmin, yvals, xmax, yvals) else: # we put the bin edges half way between the points # we assume this is the correct thing to do even in log space x1 = xvals[:-1] x2 = xvals[1:] y1 = yvals[:-1] y2 = yvals[1:] xc = 0.5 * (x1 + x2) utils.addNumpyToPolygonF(pts, x1, y1, xc, y1, xc, y2) if len(xvals) > 0: pts.append(qt4.QPointF(xvals[-1], yvals[-1])) else: assert False return pts