PDA

View Full Version : Curve Fitting Not Always Applied



Mannion
10th March 2011, 16:32
Hi

Installation Information:
Qt Creator 2.0.1
Based on Qt 4.7.0 (32 bit)
Built on Aug 24 2010 at 11:00:55
From revision 97d831e3de


First of all thanks for Qwt. It has proved to be a very useful library for my Qt work.

I am currently having an intermittent problem with the QwtSplineCurveFitter class.
Sometimes the curve fitting does not seem to occur?

See attached example image. I have also attached my plot class constructor and my update plot slot.
The connected signal call is as follows:


void BytesProcessed(int size, double * xArray, double * yArray, double yMax, int BtNo, bool bResetScale);

emit BytesProcessed( ( scDPPtr->dQVPressure.data()[scDPPtr->GetCount()-1].size()-1),
scDPPtr->dQVTime.data(),
scDPPtr->dQVPressure.data()[scDPPtr->GetCount()-1].data(),
scDPPtr->dPeakRawPressure.data()[scDPPtr->GetBreathCount()-1],
scDPPtr->GetBreathCount()-1,bNew);

The arrays used in the signal are referenced from the following QVectors:


QVector < QVector <double> > dQVPressure;
QVector <double> dQVTime;
QVector <double> dPeakRawPressure;

My plots seem to perform fairly well in almost real time but if you have any advice on optimising my code it would be appreciated greatly.


Is there a limit to the number of splines or spline points that can be created? I am plotting up to 4 plots of 50 curves that are each curve fitted.

Is my Spline Size a problem? It seems to give better results than lower settings but does begin to inhibit performance with larger numbers of plots e.g. 4 X 20+ curves.


fitter[i]->setSplineSize(1000);


http://img46.imageshack.us/img46/7430/noncurvefitting.th.jpg (http://img46.imageshack.us/i/noncurvefitting.jpg/)


Plot::Plot(QWidget *parent, QString pTitle, QString pAxisX, QString pAxisY ) :
plotTitle(pTitle), plotAxisX(pAxisX), plotAxisY(pAxisY){
setTitle(plotTitle);
dyMaxMax = 0.0; dxMaxMax = 0.0;
BtIndex = 0;
bRefresh = true;
xBlank[0]=0.0;
yBlank[0]=0.0;
xBlank[1]=0.0;
yBlank[1]=0.0;
graphAxes = (graphType)0;
setAxisTitle(xBottom, plotAxisX + " (Bt " + QString::number(BtIndex) +")" );
setAxisScale(xBottom, 0.0, 0.001);
setAxisTitle(yLeft, plotAxisY);
setAxisScale(yLeft, 0.0, 0.001);
static const QColor qCol(255,255,255);
static const QColor qColA[50];
for (int i=0; i<50; i++){ qColArray[i]=(255,i*5,i*5) ; }
this->setCanvasBackground(qCol);

for (int i=0; i<50; i++) {
d_curve[i] = new QwtPlotCurve("Data Moving Right");
d_curveLin[i] = new QwtPlotCurve("Linear");
}

int colcount = 0;
for (int i=0; i<4; i++) {
for (int j=0; j<4; j++) {
for (int k=0; k<4; k++) {
if (colcount <50) {
d_Color[colcount] = new QColor(((3-i)*(140/3)),(j*(140/3)),(k*(140/3)));
d_Pen[colcount] = new QPen( *d_Color[colcount], 0, Qt::SolidLine ) ;
d_curve[colcount]->setPen(*d_Pen[colcount] ) ;
colcount++;
}else{ i=4; j=4; k=4; }
}
}
}
d_Pen[54] = new QPen( *d_Color[49], 0, Qt::DotLine) ;
for (int i=0; i<50; i++) { d_curveLin[i]->setPen(*d_Pen[54] ) ; }

for (int i=0; i<50; i++) {
fitter[i] = new QwtSplineCurveFitter();
fitter[i]->setSplineSize(1000);
d_curve[i]->setCurveAttribute(QwtPlotCurve::Fitted,true);
fitter[i]->setFitMode(QwtSplineCurveFitter::Spline);
d_curve[i]->setCurveFitter(fitter[i]);
bSmoothed[i]=true;
d_curveLin[i]->setCurveAttribute(QwtPlotCurve::Fitted,false);

d_curve[i]->setRenderHint(QwtPlotItem::RenderAntialiased);
d_curve[i]->setPaintAttribute( QwtPlotCurve::ClipPolygons, true );
d_curve[i]->attach(this);
d_curveLin[i]->setRenderHint(QwtPlotItem::RenderAntialiased);
d_curveLin[i]->setPaintAttribute( QwtPlotCurve::ClipPolygons, true );
d_curveLin[i]->attach(this);
}
}

void Plot::UpdatePlotTest(int firstIndex, int lastIndex, double dyMax, double * dxarray, double * dyarray, int BtNo, bool bResetScale){
if (BtIndex!= BtNo ) {
BtIndex = BtNo;
setAxisTitle(xBottom, plotAxisX + " (Bt " + QString::number(BtIndex+1) + ")" ); }
if (this->bRefresh){ dyMaxMax = 0.001; dxMaxMax = 0.001; }
if (dyMaxMax < dyMax) { dyMaxMax = dyMax; setAxisScale(yLeft, 0, (dyMaxMax*1.05) ); }
if (dxMaxMax < dxarray[lastIndex]) {
dxMaxMax = dxarray[lastIndex];
setAxisScale(xBottom, dxarray[firstIndex], dxMaxMax); }
d_Pen[BtNo]->setWidth(4);
d_Pen[BtNo]->setColor(d_Color[0]->rgb());
d_curve[BtNo]->setCurveAttribute(QwtPlotCurve::Fitted,false);
fitter[BtNo]=NULL;
d_curve[BtNo]->setCurveFitter(NULL);
d_curve[BtNo]->setPen(*d_Pen[BtNo] ) ;
bSmoothed[BtNo] = false;
if (BtNo>0){
for (int jj = 0; jj<=49; jj++){
if (jj!=BtNo){
if (bSmoothed[jj] == false){
d_Pen[jj]->setWidth(0);
d_Pen[jj]->setColor(d_Color[jj]->rgb());
fitter[jj] = new QwtSplineCurveFitter();
fitter[jj]->setSplineSize(1000);
d_curve[jj]->setCurveAttribute(QwtPlotCurve::Fitted,true);
fitter[jj]->setFitMode(QwtSplineCurveFitter::Spline);
d_curve[jj]->setCurveFitter(fitter[jj]);
d_curve[jj]->setPen(*d_Pen[jj] ) ;
bSmoothed[jj]= true;
}
}
}
}
d_curve[BtNo]->setRawSamples(dxarray,dyarray,((lastIndex-firstIndex)+1) );
d_curveLin[BtNo]->setRawSamples(dxarray,dyarray,((lastIndex-firstIndex)+1) );
if (bResetScale == true){
for (int jj = 0; jj<=BtNo; jj++){
if (bSmoothed[jj] == false){
d_Pen[jj]->setWidth(0);
d_Pen[jj]->setColor(d_Color[jj]->rgb());
fitter[jj] = new QwtSplineCurveFitter();
fitter[jj]->setSplineSize(1000);
d_curve[jj]->setCurveAttribute(QwtPlotCurve::Fitted,true);
fitter[jj]->setFitMode(QwtSplineCurveFitter::Spline);
d_curve[jj]->setCurveFitter(fitter[jj]);
d_curve[jj]->setPen(*d_Pen[jj] ) ;
bSmoothed[jj]= true;
}
}
this->replot();
this->repaint();
}
this->bRefresh = false;
}

void Plot::RePlot(){this->replot();}

Uwe
11th March 2011, 10:35
Sometimes the curve fitting does not seem to occur?
When you isolate the problem to a small demo application I will have a look at it.


My plots seem to perform fairly well in almost real time but if you have any advice on optimising my code it would be appreciated greatly.
Well most optimizations have to do with introducing the characteristics of your specific data/plot into the algorithms. Without knowing them it is hard to tell you something useful.

In general spline interpolation is an expensive operation and in your application it is done every time the curve is repainted for the translated points in pixel coordinates. Maybe it is possible to interpolate the points in plot coordinates before you pass them to the curve.

Often the key for improving performance is to reduce the number of points, that need to be painted. In Qwt 6.0 you find an implementation of the Douglas Peucker algorithm ( QwtWeedingCurveFitter ) that might be useful.

Uwe

pkj
16th March 2011, 06:51
Hi Mannion...
While using QwtSplineCurveFitter in qwt6 i found out that it works beautifully for integers but has problems with doubles. Why don't you check by making the x and y var. integers(like multiply em by 1000).. c if it works...

Uwe
16th March 2011, 08:11
Or use some version from SVN, where this issue has been resolved.

Uwe