PDA

View Full Version : Plot the graph for real time data



swinetha
24th July 2013, 07:27
Hai,

I am newbie to QT as well as Qwt.

I am having QT 5.0.2, QT Creator 2.7.0 and Qwt 6.1.0.

My requirement is Plotting the graph for the data is continuous data in real time, this data is reding from background process.


According to my application, I am started the background process using QProcess that process is .exe file for C code. In this C code ther is a while(1) loop for reading Infinite data. In GUI I am able to read the data also.

Now I want to plot the graph for those values to find the deviation.

I have simple qwt code as below



float y[20], x[20];
int i;
for(i=0;i<20;i++)
{
x[i]=i;
y[i]=2*sin((x[i]));

}
QwtPlot *plot=new QwtPlot();
plot->setTitle( "Plot Demo" );
plot->setCanvasBackground( Qt::white );
//plot->setAxisScale( QwtPlot::yLeft, 0.0, 20.0);
// plot->setAxisScale(QwtPlot::xBottom, 0.0, 20.0);
plot->insertLegend( new QwtLegend() );
plot->setAxisTitle(QwtPlot::xBottom, "X Axis");
plot->setAxisTitle(QwtPlot::yLeft, "Y Axis");
QwtPlotGrid *grid = new QwtPlotGrid();
grid->attach( plot );
grid->setPen( Qt::gray, 0.0, Qt::DotLine );

QwtPlotCurve *curve = new QwtPlotCurve();
curve->setTitle( "Pixel Count" );
curve->setPen(QPen(Qt::blue, 3,Qt::SolidLine) ),
curve->setRenderHint( QwtPlotItem::RenderAntialiased, true);

QwtSymbol *symbol = new QwtSymbol( QwtSymbol::Ellipse,QBrush(Qt::yellow),QPen(Qt::red ,2),QSize(8,8));
curve->setSymbol(symbol );

QPolygonF points;
for(i=0;i<20;i++)
points<<QPointF(x[i],y[i]);//<<QPointF(x2,y2)<<QPointF(x3,y3)<<QPointF(x4,y4)<< QPointF(x5,y5);
curve->setSamples( points );
curve->attach(plot );
plot->replot();
plot->resize( 600, 400 );

plot->show();


and code for reading the background data




QByteArray b1;
QList<QByteArray> read_data;

b1= process->readAllStandardOutput();

read_data=b1.split('\n');
int i=0,n=read_data.count();
float y[100000];
for(i=0;i<n;i++)
{
QString result=read_data.at(i);
result.remove(0,10);
qDebug("%s",result.toLatin1().data());
y[i]=result.toLatin1().toFloat();
}


how can I send the data in y[i] to "QPolygonF points"

tried to send to QPolygonF but am not getting what I want.

any one can give suggetions to meet my requirment

Thanks in advance

alainstgt
24th July 2013, 16:10
you have the solution in your code already:



QwtPlot *plot=new QwtPlot();
plot->setTitle( "Plot Demo" );
plot->setCanvasBackground( Qt::white );
//plot->setAxisScale( QwtPlot::yLeft, 0.0, 20.0);
// plot->setAxisScale(QwtPlot::xBottom, 0.0, 20.0);
plot->insertLegend( new QwtLegend() );
plot->setAxisTitle(QwtPlot::xBottom, "X Axis");
plot->setAxisTitle(QwtPlot::yLeft, "Y Axis");
QwtPlotGrid *grid = new QwtPlotGrid();
grid->attach( plot );
grid->setPen( Qt::gray, 0.0, Qt::DotLine );

QwtPlotCurve *curve = new QwtPlotCurve();
curve->setTitle( "Pixel Count" );
curve->setPen(QPen(Qt::blue, 3,Qt::SolidLine) );
curve->setRenderHint( QwtPlotItem::RenderAntialiased, true);
QwtSymbol *symbol = new QwtSymbol( QwtSymbol::Ellipse,QBrush(Qt::yellow),QPen(Qt::red ,2),QSize(8,8));
curve->setSymbol(symbol );

QPolygonF points;
curve->setSamples( points );
curve->attach( plot );

QByteArray b1;
QList<QByteArray> read_data;
b1= process->readAllStandardOutput();
read_data=b1.split('\n');
int i=0, n=read_data.count();
float y[100000];

for( i=0; i<n; i++ )
{
QString result=read_data.at(i);
result.remove(0,10);
qDebug("%s",result.toLatin1().data());
y[i]=result.toLatin1().toFloat();
points << QPointF( i, y[i] );
// check wether curve is updated, if not do it here
plot->replot;
plot->show;
}

Qwt is not installed on the computer I am writing from, so I cannot check my code, but the solution might not be far from here.

Just a remark. Converting a byte array to a string and then to a float is heavy, there should be a better way to do that. How fast is your data input rate?

swinetha
25th July 2013, 05:18
Thank you for your reply,


Data input rate -the data is reading from c.exe file with in fraction of seconds I am able to read 40000 values.

I have doubt for your solution,

you place this code in loop



plot->replot;
plot->show;


so for every "i" value these to lines will be called so there is a possible to "i" no of windows are opened.

and my requirement is plotting the graph continuously.

for example if we take a sin wave form, it will gives the continuos graph. Like that I want continuous graph with those values

alainstgt
25th July 2013, 10:51
sorry, but I do not undestand what you are meaning.
In my example, the plot is actualized in real time, and plotted continuously. The question is just wether your hardware is fast enough to do that.
You might define what you mean with real time.
The strong interpretation is that you are able to display the data one by one as they are available, continuously without any data loss.
A weaker interpretation of real time ist that you are displaying the new data in blocks of several data, but still without data loss.

swinetha
26th July 2013, 05:09
sorry for my explanation. for the question

The question is just wether your hardware is fast enough to do that.

It is able to do as fast as much.


for( i=0; i<n; i++ )
{
QString result=read_data.at(i);
result.remove(0,10);
qDebug("%s",result.toLatin1().data());
y[i]=result.toLatin1().toFloat();
points << QPointF( i, y[i] );
// check wether curve is updated, if not do it here
plot->replot;
plot->show;
}

It is the part of your code. In this you write the code

plot->replot;
plot->show;

in for loop.
My question is, loop will execute for every i value till it reaches the count.

the code in the loop will excute for every "i" value so plot->show is also excute for every value.

means it will open the plot window for every i value.

I have tested your code, it will displaying so many no of windows

how to modify that code to plot the graph continuously.

Uwe
26th July 2013, 07:06
2 considerations, when implementing a realtime plot - especially when you expect to have many, many samples:



always decouple sample and refresh rate
decoupling the rates means, that you only add new samples to a buffer without repainting. The curve update depends on a timer that runs periodically triggering a replot only when something has changed in the last cycle.

consider to use incremental painting
incremental painting means, that you design your plot in a way, that it doesn't change for new samples - beside of drawing a couple of new lines ( the oscilloscope example is designed this way ). But this is only possible when you don't have to change the scales.


Nore that the oscilloscope example runs with heavy data and high refresh rates with low CPU usage - even on a device like the PI !

Uwe

swinetha
30th July 2013, 10:51
consider to use incremental painting
incremental painting means, that you design your plot in a way, that it doesn't change for new samples - beside of drawing a couple of new lines ( the oscilloscope example is designed this way ). But this is only possible when you don't have to change the scales.

Sorry I am a bit confused,

UWE said that
"incremental painting means, that you design your plot in a way, that it doesn't change for new samples"
that it doesn't change for new samples means every time It shows only previous samples only?
can you explain me

Uwe
30th July 2013, 10:57
Incremental in this context means that only the new parts of a curve are painted on top of the existing plot - without repainting from scratch.

Uwe

swinetha
30th July 2013, 11:30
thank you for reply,

in that Oscilloscope example there are so many .pri files were added. these files are needed or not???\

swinetha
31st July 2013, 05:16
UWE said that

the new parts of a curve are painted on top of the existing plot,,

means only top values are plotted?

Uwe
31st July 2013, 06:20
With QwtPlotDirectPainter you can draw any part of a curve on top of an existing plot - without repainting the plot. It is up to the application code which part you want to draw - but usually these are points, that are not painted already ( = new ).

Uwe

swinetha
31st July 2013, 06:59
I want each and every value from starting to ending. how it is possible? can you explain me

Uwe
31st July 2013, 19:29
QwtPlot::replot().

Uwe

swinetha
1st August 2013, 04:56
I want to clarify one doubt,

Can I use oscilloscope example as reference to my requirement?