PDA

View Full Version : Rendering a qwt plot spectrogram



moijhd
22nd July 2013, 16:18
Hi,

I am trying to render a QwtPlotSpectrogram into a PDF file using a QwtPlotRenderer.

Here some code that does not get the result I expected :



int main()
{
QwtPlot *plot;
plot = new QwtPlot();
plot->setTitle("Plot");
plot->setAxisScale(QwtPlot::xBottom, 0, 10);
plot->setAxisScale(QwtPlot::yLeft, 0, 10);
plot->enableAxis(QwtPlot::yRight);
plot->setAxisScale(QwtPlot::yRight, 0, 100*100);
plot->show();

QVector<double> xData;
QVector<double> zData;
for(int i = 0; i < 100; i++)
{
zData.push_back(i*i);
xData.push_back(i);
}

QwtMatrixRasterData *matrix;
matrix = new QwtMatrixRasterData();
matrix->setValueMatrix(zData, 10);
matrix->setInterval(
Qt::XAxis,
QwtInterval(0, 10)
);
matrix->setInterval(
Qt::YAxis,
QwtInterval(0, 10)
);

matrix->setInterval(
Qt::ZAxis,
QwtInterval(0, 100*100)
);

QwtPlotSpectrogram *spectrogram;
spectrogram = new QwtPlotSpectrogram();
spectrogram->setData(
matrix
);
spectrogram->attach(plot);

QwtPlotCurve *curve;
curve = new QwtPlotCurve();
curve->setSamples(xData, zData);
curve->attach(plot);

QwtPlotRenderer *plotRenderer;
plotRenderer = new QwtPlotRenderer();
plotRenderer->setDiscardFlag(QwtPlotRenderer::DiscardBackground) ;
plotRenderer->setDiscardFlag(QwtPlotRenderer::DiscardCanvasBackg round);
plotRenderer->setDiscardFlag(QwtPlotRenderer::DiscardCanvasFrame );

plot->replot();

QPrinter printer;
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setOutputFileName("test01.pdf");
printer.setResolution(QPrinter::HighResolution);
printer.setColorMode(QPrinter::Color);
printer.setDuplex(QPrinter::DuplexAuto);
printer.setFullPage(true);
printer.setOrientation(QPrinter::Landscape);
printer.setPageMargins(0, 0, 0, 0, QPrinter::Millimeter);
printer.setPageOrder(QPrinter::FirstPageFirst);

QPainter *painter;
painter = new QPainter();
painter->begin(&printer);

plotRenderer->render(plot, painter, painter->viewport());

painter->end();

return 0;
}


Please see attachments to understand.

Thanks !

Added after 16 minutes:



printer.setResolution(QPrinter::HighResolution);


was the problem.

I removed it. And I guess I should prefer QPrinter::setResolution instead, if I want to increase the quality of the document.

moijhd
22nd July 2013, 16:31
This is quite not the end : the result is a JPG picture : how to get a vectoriel picture ?

Uwe
23rd July 2013, 08:04
The renderer should always create a correct image - even with a very low resolution. So the seconds screenshot looks like a bug to me - in Qwt or in your code. Please upload a small compilable demo, that shows the issue, that I can have a look at it.

Qt offers 2 types of scalable vector graphic formats: SVG and PDF. I recommend PDF as the SVG renderer ignores painter clipping and because of this not all plots are rendered properly. But even when using SVG or PDF - drawing a raster graphic ( a spectrogram is one ) to a format that is able to handle vector graphics doesn't make it a vector graphic.

Also note, that the resolution of the resulting image also depends on the resolution of your data !

Have a look at QwtPlotRenderer::renderDocument() or QwtPlotRenderer::exportTo(). These high level APIs should be more convenient for your use case.

Uwe

moijhd
23rd July 2013, 10:33
The second screenshot bug was due to "printer.setResolution(QPrinter::HighResolution);". I don't know why. I removed it and it rendered fine. The code I provided is compilable.

Regarding the raster graphic, there is no way to make it a vector graphic ?

Uwe
23rd July 2013, 11:06
Regarding the raster graphic, there is no way to make it a vector graphic ?
The reason why it is a raster graphic is because you are displaying raster data. "Vectorizing" data pixels to rectangles won't change anything.

What you could try to do is to enable QwtMatrixRasterData::BilinearInterpolation. It doesn't make your output scalable, but the image will always be rendered in device resolution ( not limited by the resolution of your data ). But note, that rendering the image will be slower then.

Uwe

PS: try to use "spectrogram->setRenderThreadCount( 0 );" to enable multithreaded rendering