Qwt realtime plotting using QwtPlotDirectPainter
Hi,
This is my first post on this forum. First, I shall start off by saying that I'm a first year Electrical Engineering student, and am learning Qt, I'm not by any means, a pro at Qt (or C++) for that matter.
I made a program that receives and digital voltages read from this device connect to the serial port. Now I have to plot it.
I've managed to make basic plots, like sine waves and stuff like that. I would like to plot in realtime though. I know that the Oscilloscope and Realtime examples provided in Qwt 6.0.1 illustrate how to do this. I've read the DOC a lot as well. I'm having trouble understanding how to perform this realtime plotting.
I've made a trivial program to illustrate my issue. The points (-5, 5), (8, 7)... having nothing to do with anything. I just arbitrarily chose them as an example.
Code:
{
ui.setupUi(this);
ui.
qwtPlot->setAxisScale
(QwtPlot::xBottom,
-10,
10);
ui.
qwtPlot->setAxisScale
(QwtPlot::yLeft,
-10,
10);
painter = new QwtPlotDirectPainter();
std::vector<double> times1;
std::vector<double> times2;
std::vector<double> data1;
std::vector<double> data2;
times1.push_back(-5);
times1.push_back(8);
data1.push_back(5);
data1.push_back(7);
curve1->setSamples(×1.front(), &data1.front(), data1.size());
times2.push_back(0);
times2.push_back(3);
data2.push_back(2);
data2.push_back(3);
painter->drawSeries(curve1, 0, 1);
}
I don't understand why 'drawSeries' doesn't seem to do anything. All I would like to do is, add some more points (connected by a line) to the plot. Perhaps I'm going completely incorrectly about this; perhaps I just have a small error -- I have no idea. I will be plotting hundreds of thousands of points very often, and would like to augment to the plot rather than 'replot()' (which I believe is expensive, as it plots the whole thing) the whole thing.
If someone could point me in the right direct, that'd be great.
Thank you for your time.
Re: Qwt realtime plotting using QwtPlotDirectPainter
By Qt design it is not possible to erase something on a widget - the only way to do so its to replot.
QwtPlotDirectPainter is an optimization made for situations, where you draw something on top of an existing scene.
The code above doesn't make much sense as you can't draw to a widget before it is shown.
Uwe
Re: Qwt realtime plotting using QwtPlotDirectPainter
Thank you for your reply.
I'm not sure what you mean by 'erase something on a widget'. I didn't want to erase anything; I just wanted to add to my plot.
If I understand you correctly though, QwtPlotDirectPainter basically draws on top of a widget, and since the widget is not yet created (because I'm using Qt Designer, which creates the widget after my code has run), it doesn't paint anywhere... So the only way to update a plot if I'm using Qt Designer is to do a replot?
Thanks again for your time.
Re: Qwt realtime plotting using QwtPlotDirectPainter
I wonder why you want to draw anything yourself when QwtPlot does it for you?
Just create a plot as you do now, attach a curve to it, set data on it (remember that data should be alive as long as the curve is) and call replot when the data changes.
Simples :)
Edit:
I may have missed your point.
If you worry about performance you can subclass curve to cache itself when it's plotted.
Then next time you replot the plot curve should check what have changed since last time, use the part of cache that's the same and draw only extra points ,then cache new pixmap again.
Another solution may be sampling.
As you screen resolution will not be as great as amout of points you want to display, smart sampling algorithm can reduce amout of points needed to be drawn to just several hundreds speeding up the redraw.
Re: Qwt realtime plotting using QwtPlotDirectPainter
Hi,
Thanks for the suggestions, I will certainly take that on board. I was worried with performance issues, and didn't know about the whole cacheing thing. I will definately look into cacheing. The reason why I thought that QwtPlotDirectPainter::dataSeries(...) should be used is because I read in the DOC that it's faster than a replot, and that it's used to plot a subset of points. Also, in the Realtime and Oscilloscope example, QwtPlotDirectPainter::dataSeries(...) seems to have been used.
Re: Qwt realtime plotting using QwtPlotDirectPainter
Quote:
Originally Posted by
Spitfire
II may have missed your point.
If you worry about performance you can subclass curve to cache itself when it's plotted.
Then next time you replot the plot curve should check what have changed since last time, use the part of cache that's the same and draw only extra points ,then cache new pixmap again.
Drawing a pixmap is usually too slow for "realtime" conditions. Using such a cache might make sense for very few situations ( stable scales and a fixed size of the plot canvas ).
I would recommend to study the realtime example first as it is much simpler than the oscilloscope. It simply appends points to the end of the curve data and then uses QwtPlotDirectPointer to paint only these points on top of the existing plot. Guess you could use the code of the IncrementalPlot class like it is - beside some modifications, when you want to draw lines and not only symbols:
Code:
void IncrementalPlot
::appendPoint( const QPointF &point
) {
CurveData *data = static_cast<CurveData *>( d_curve->data() );
data->append( point );
int from = qMin( data->size() - 2, 0 );
d_directPainter->drawSeries( d_curve, from, data->size() - 1 );
}
Uwe
Re: Qwt realtime plotting using QwtPlotDirectPainter
I'll look into the Realtime example some more. I assume you meant QwtPlotDirectPainter. I was actually trying to do what you did in your code, in the code that I attached; however, I see that I'm trying to paint an object that does not yet exist when I run my code. Does this mean that I cannot use Qt Designer for the plot?
Re: Qwt realtime plotting using QwtPlotDirectPainter
Important is when the code is executed - this has nothing to do with the tool you are using to write your code.
The designer is no compiler and won't execute any C++ code at all.
Uwe
Re: Qwt realtime plotting using QwtPlotDirectPainter
Thank you for your help. I have gotten it to work.
Re: Qwt realtime plotting using QwtPlotDirectPainter
Hi,
I am a newbie to Qt/Qwt; but find it very useful; I am having similar question as Jean-Luc; I have been studying Qwt examples: Oscilloscope, Refreshtest, and Curvedemo2.
Oscilloscope does a 'replot" so the plot is restarted at the beginning of the plot window, Refreshtest does a "scroll" to the data; I would like to do a "erase bar" to the wave; so very similar to Oscilloscope but does NOT clear the plot window; I can stop the refresh by not doing "replot" after the interval; but I can't seem to create the "simple" erase bar; ie. deleting the previous plot(eg. 5 points in the future) and replacing them with the new points(as currently done in the examples); I am thinking of doing the "brute force method" of using similar brush as background color; but thought, there maybe a better solution or even a simpler solution.
Appreciate any suggestion to do this.
Thanks.
Lee
Re: Qwt realtime plotting using QwtPlotDirectPainter
In earlier Qt releases ( Qt 3 ) it was possible to erase something by drawing in XOR mode, but this feature is lost since Qt 4.0. So the answer is simple, you can't erase something from a widget ( by Qt design ).
Uwe