PDA

View Full Version : QwtPlot: multiple curves with separate x-axis/-scales?



-=Freaky=-
28th August 2008, 14:55
hi everyone,
first i have to say, you have a great forum here!

even though i found alot of help here, there's an issue i couldn't solve yet, hope someone here can help me.

i have a class which is derived from QwtPlot to display curves (own class derived from QwtPlotCurve - and yeah i know they're actually just blocks, not curves :)).
http://img32.picoodle.com/data/img32/3/8/28/f_ibwiperplotm_9e562db.png

now i want to display multiple curves (unkown number), each with its own, separate x-axis (image made with gimp).
http://img28.picoodle.com/data/img28/3/8/28/f_ibwiperplotm_ed4d378.png

i have tried QwtPlotScaleItem and drawing all the curves "by hand", but i couldn't get it to work well, i didn't even manage to calculate the coordinates of the curves and scale items right ...

is there an easier way to do this or do i have to do all the calculations on my own?
if so, i don't really know how to ... e.g. how can i draw the curves according to different scales (e.g. if the first curve has a scale from 0.0 to 5.5 and the next one has a scale from 7.0 to 12.3)? afaik they are drawn according to the "main scale" of the plot widget ...

i'd really appreciate all help i can get here.
i hope you can understand what i'm trying to explain here since english isn't my first language. :)
thanks in advance!

sincerely,
julian

viridis
28th August 2008, 17:10
Take a look here :
http://www.qtcentre.org/forum/f-qwt-23/t-virtual-axis--14504.html

Maybe it can help.

-=Freaky=-
28th August 2008, 22:27
thanks for your hint viridis, i'll try it, looks good so far.
but i have another question: how do i find out the position (on y-axis) and height of one drawn curve (in scale coords)?

heightOfYAxis / numberOfCurves
doesn't work of course, because it doesn't consider the extra scale items at all ... but i don't know the height of a scale item and the height doesn't change when the yLeft-scale changes (e.g. when the whole window/widget is resized) ...

thanks in advance!
sincerely,
julian

viridis
29th August 2008, 09:21
Indeed, I just realized that what I was suggesting was wrong for you.
I was wondering if you could use only one axis, and switch its scale according to the selected curve. But, by looking at your picture, it seems you always have same scales so I misunderstood the problem !

Thus, why don't you use mulitple plots and sync them (when zooming/panning) ? It seems to me a really simple solution which do all you need.
You do not have to worry about axis height, curve positionning...

-=Freaky=-
29th August 2008, 11:46
no, you got me right first, the different x-axis can all have different scales.
in the image they're all the same because i was too lazy to change that too when creating it with the gimp ... :)
sorry for that.
and there have to be separate axis and scales for each of the curves drawn - because my boss wants so. :D

anyway, i thought about having multiple plots, but in the end i have to have one single widget ready to use and probably there's also going to be a designer-plugin for it.
so basically, i would have to rewrite almost the whole plot-widget i have now to cover multiple plots and control dem separately, or write a whole new class covering some of my plot-widgets ... however, it would be a lot of extra work, which i'm trying to avoid ...

big thanks for trying to help me though!

sincerely,
julian

-=Freaky=-
30th August 2008, 08:04
sorry for double posting, but just to make my question clear again:

i need to know how to get the height of a QwtPlotScaleItem in my code, in either pixel or scale coordinates (so i can calculate the positions of all the elements in my widget correctly).
does anyone know how to achieve that?

thanks in advance,
sincerely,
julian

-=Freaky=-
2nd September 2008, 17:46
hi again,

i found QwtPlotScaleDraw::extent, is that the right method for me to use if i need the scale's height?
if it is, i guess it's returning the height in pixel coordinates (because it's returning an integer).

i still have some problems, but either i didn't unterstand a lot and my whole code is crap and wrong, or i just somehow can't find my mistakes ... i'd really appreciate everyone who would take a look at my code below. thanks in advance! :)

so, as i said, i have a class derived from QwtPlot and another one derived from QwtPlotCurve.
a third class is derived from QwtScaleDraw to provide easy access to some options like the label's font and the tick's and backbone's color.

in my scale draw, i implemented the extent method like this:

int MyScaleDraw::extent()
{
// m_labelsFont: font for labels - didn't expect this, huh? ;-)
return QwtScaleDraw::extent( QPen(), m_labelsFont );
}

in my plot class, i've got the addCurve method:

void MyPlot::addCurve( MyCurve *p_curve )
{
if( p_curve )
{
setAxisScale( xBottom, 0, 5, 1 ); // just for testing purposes

double scaleHeight = 0; // height of a scale item
p_curve->attach( this );
if( m_curves.count() > 0 ) // m_curves: QMap< MyCurve*, QwtScaleDraw* >
{
QwtPlotScaleItem *s = new QwtPlotScaleItem;
s->setScaleDraw( m_xScaleDraw );
s->attach( this );
m_curves.insert( p_curve, s );
// i'm not sure about the following:
// ( m_xScaleDraw: MyScaleDraw for xBottom scales)
if( m_xScaleDraw )
scaleHeight = canvasMap( yLeft ).invTransform(
m_xScaleDraw->extent() );
}
else
m_curves.insert( p_curve, NULL );

double curveHeight = ( 100 - ((m_curves.count() - 1)*scaleHeight))
/ (m_curves.count() );
QMap< MyCurve*, QwtPlotScaleItem* >::iterator it
= m_curves.begin();
int i = 0;
while( it != m_curves.end() )
{
if( it.key() )
{
// MyCurve has 2 new elements:
// height => height of the blocks
// yPos => position (top border) on y-axis
it.key()->setHeight( curveHeight );
it.key()->setYPos( ( (i + 1) * curveHeight )
+ ( i * scaleHeight ) );
}
if( it.value() )
it.value()->setPosition( it.key()->yPos()
- it.key()->height() );
it++;
i++;
}
replot();
}
}

i also tested the scaleHeight values with a message box and it seems that the scaleHeight is calculated wrongly, but i just don't know why, i tried it for so long and maybe i just need a break from this project ... but i have to get this done. :)

as i said, anyone willing to help here is appreciated, many thanks in advance!

// edit: added screenshots of how it looks now after adding 2 curves to the plot widget via addCurve
http://img33.picoodle.com/data/img33/3/9/2/f_myplotstuffm_6b5b8ea.png

sincerely,
julian

Uwe
11th September 2008, 10:23
anyway, i thought about having multiple plots, but in the end i have to have one single widget ready to use and probably there's also going to be a designer-plugin for it.
This is no argument against building your widget from several QwtPlot widgets. ( QwtPlot itsself is a composite widget ).
IMHO this is by far the most natural and easiest implementation for your problem.

Uwe

-=Freaky=-
12th September 2008, 20:10
hi uwe,
thanks for your reply!
i played around with the stuff i posted above alot and finally got it to work ... at least values were calculated right and everything was drawn right.
but it was pretty much work and you can easily have new mistakes in the code which cost alot of extra time (happened to me way too often so i really got sick of it :D).

that is basically why i'm now trying to do it the way you suggested.
i was just about to make a new class which inherits QWidget and put a QVBoxLayout inside which will be the parent for all the plot widgets.
is that how i should do it or is there something way better? :)

again, thanks in advance!

sincerely,
julian

Uwe
13th September 2008, 13:39
i was just about to make a new class which inherits QWidget and put a QVBoxLayout inside which will be the parent for all the plot widgets. is that how i should do it ?
Sure,
Uwe

-=Freaky=-
18th September 2008, 16:14
alright thanks to viridis and Uwe!
finally, i didn't need different scales for each curve, but putting QwtPlot objects together in a layout works really well so far.

sincerely,
julian