def renderDocument(self, plot, filename, sizeMM=(300, 200), resolution=85, format_=None): """ Render a plot to a file The format of the document will be auto-detected from the suffix of the file name. :param qwt.plot.QwtPlot plot: Plot widget :param str fileName: Path of the file, where the document will be stored :param QSizeF sizeMM: Size for the document in millimeters :param int resolution: Resolution in dots per Inch (dpi) """ if isinstance(sizeMM, tuple): sizeMM = QSizeF(*sizeMM) if format_ is None: ext = osp.splitext(filename)[1] if not ext: raise TypeError( "Unable to determine target format from filename") format_ = ext[1:] if plot is None or sizeMM.isEmpty() or resolution <= 0: return title = plot.title().text() if not title: title = "Plot Document" mmToInch = 1.0 / 25.4 size = sizeMM * mmToInch * resolution documentRect = QRectF(0.0, 0.0, size.width(), size.height()) fmt = format_.lower() if fmt in ("pdf", "ps"): printer = QPrinter() if fmt == "pdf": printer.setOutputFormat(QPrinter.PdfFormat) else: printer.setOutputFormat(QPrinter.PostScriptFormat) printer.setColorMode(QPrinter.Color) printer.setFullPage(True) printer.setPaperSize(sizeMM, QPrinter.Millimeter) printer.setDocName(title) printer.setOutputFileName(filename) printer.setResolution(resolution) painter = QPainter(printer) self.render(plot, painter, documentRect) painter.end() elif fmt == "svg": generator = QSvgGenerator() generator.setTitle(title) generator.setFileName(filename) generator.setResolution(resolution) generator.setViewBox(documentRect) painter = QPainter(generator) self.render(plot, painter, documentRect) painter.end() elif fmt in QImageWriter.supportedImageFormats(): imageRect = documentRect.toRect() dotsPerMeter = int(round(resolution * mmToInch * 1000.0)) image = QImage(imageRect.size(), QImage.Format_ARGB32) image.setDotsPerMeterX(dotsPerMeter) image.setDotsPerMeterY(dotsPerMeter) image.fill(QColor(Qt.white).rgb()) painter = QPainter(image) self.render(plot, painter, imageRect) painter.end() image.save(filename, fmt) else: raise TypeError("Unsupported file format '%s'" % fmt)
def activate(self, plot, plotRect, options=0x00): """ Recalculate the geometry of all components. :param qwt.plot.QwtPlot plot: Plot to be layout :param QRectF plotRect: Rectangle where to place the components :param options: Layout options """ self.invalidate() rect = QRectF(plotRect) self.__data.layoutData.init(plot, rect) if (not (options & self.IgnoreLegend) and plot.legend() and not plot.legend().isEmpty()): self.__data.legendRect = self.layoutLegend(options, rect) region = QRegion(rect.toRect()) rect = region.subtracted(QRegion( self.__data.legendRect.toRect())).boundingRect() if self.__data.legendPos == QwtPlot.LeftLegend: rect.setLeft(rect.left() + self.__data.spacing) elif self.__data.legendPos == QwtPlot.RightLegend: rect.setRight(rect.right() - self.__data.spacing) elif self.__data.legendPos == QwtPlot.TopLegend: rect.setTop(rect.top() + self.__data.spacing) elif self.__data.legendPos == QwtPlot.BottomLegend: rect.setBottom(rect.bottom() - self.__data.spacing) # +---+-----------+---+ # | Title | # +---+-----------+---+ # | | Axis | | # +---+-----------+---+ # | A | | A | # | x | Canvas | x | # | i | | i | # | s | | s | # +---+-----------+---+ # | | Axis | | # +---+-----------+---+ # | Footer | # +---+-----------+---+ # title, footer and axes include text labels. The height of each # label depends on its line breaks, that depend on the width # for the label. A line break in a horizontal text will reduce # the available width for vertical texts and vice versa. # expandLineBreaks finds the height/width for title, footer and axes # including all line breaks. dimTitle, dimFooter, dimAxes = self.expandLineBreaks(options, rect) if dimTitle > 0: self.__data.titleRect.setRect(rect.left(), rect.top(), rect.width(), dimTitle) rect.setTop(self.__data.titleRect.bottom() + self.__data.spacing) if (self.__data.layoutData.scale[QwtPlot.yLeft].isEnabled != self.__data.layoutData.scale[QwtPlot.yRight].isEnabled): self.__data.titleRect.setX(rect.left() + dimAxes[QwtPlot.yLeft]) self.__data.titleRect.setWidth(rect.width() - dimAxes[QwtPlot.yLeft] - dimAxes[QwtPlot.yRight]) if dimFooter > 0: self.__data.footerRect.setRect(rect.left(), rect.bottom() - dimFooter, rect.width(), dimFooter) rect.setBottom(self.__data.footerRect.top() - self.__data.spacing) if (self.__data.layoutData.scale[QwtPlot.yLeft].isEnabled != self.__data.layoutData.scale[QwtPlot.yRight].isEnabled): self.__data.footerRect.setX(rect.left() + dimAxes[QwtPlot.yLeft]) self.__data.footerRect.setWidth(rect.width() - dimAxes[QwtPlot.yLeft] - dimAxes[QwtPlot.yRight]) self.__data.canvasRect.setRect( rect.x() + dimAxes[QwtPlot.yLeft], rect.y() + dimAxes[QwtPlot.xTop], rect.width() - dimAxes[QwtPlot.yRight] - dimAxes[QwtPlot.yLeft], rect.height() - dimAxes[QwtPlot.xBottom] - dimAxes[QwtPlot.xTop], ) for axis in QwtPlot.AXES: if dimAxes[axis]: dim = dimAxes[axis] scaleRect = self.__data.scaleRect[axis] scaleRect.setRect(*self.__data.canvasRect.getRect()) if axis == QwtPlot.yLeft: scaleRect.setX(self.__data.canvasRect.left() - dim) scaleRect.setWidth(dim) elif axis == QwtPlot.yRight: scaleRect.setX(self.__data.canvasRect.right()) scaleRect.setWidth(dim) elif axis == QwtPlot.xBottom: scaleRect.setY(self.__data.canvasRect.bottom()) scaleRect.setHeight(dim) elif axis == QwtPlot.xTop: scaleRect.setY(self.__data.canvasRect.top() - dim) scaleRect.setHeight(dim) scaleRect = scaleRect.normalized() # +---+-----------+---+ # | <- Axis -> | # +-^-+-----------+-^-+ # | | | | | | # | | | | # | A | | A | # | x | Canvas | x | # | i | | i | # | s | | s | # | | | | # | | | | | | # +-V-+-----------+-V-+ # | <- Axis -> | # +---+-----------+---+ # The ticks of the axes - not the labels above - should # be aligned to the canvas. So we try to use the empty # corners to extend the axes, so that the label texts # left/right of the min/max ticks are moved into them. self.alignScales(options, self.__data.canvasRect, self.__data.scaleRect) if not self.__data.legendRect.isEmpty(): self.__data.legendRect = self.alignLegend(self.__data.canvasRect, self.__data.legendRect)