Results 1 to 7 of 7

Thread: Auto scaling y axis using QwtPlotPanner and QwtPlotMagnifier

  1. #1
    Join Date
    Feb 2013
    Posts
    3
    Thanks
    3
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default Auto scaling y axis using QwtPlotPanner and QwtPlotMagnifier

    Hello guys, I have been working with Qwt for the last weekends but the lack of tutorials is a little sad.
    I've searched a little but I didn't find any way ( mainly an easy way ) of doing this.

    Well, here is the problem:
    I have a QwtPlot and its canvas is given to a QwtPlotPanner and a QwtPlotMagnifier constructors.
    QwtPlotPanner is set to allow only horizontal movement( you cant go up or down), and QwtPlotMagnifier can be only scaled horizontally too.

    Whenever the graphics changes I want rescale y axis to show minimum and maximum value at screen instead of keeping the old scale and showing an flat version of curve.
    Here is what I mean:
    Screenshot from 2013-02-10 14:22:45.jpgScreenshot from 2013-02-10 14:22:56.jpgScreenshot from 2013-02-10 14:23:00.jpg

    How can I do that?

  2. #2
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,311
    Thanked 879 Times in 827 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Auto scaling y axis using QwtPlotPanner and QwtPlotMagnifier

    Quote Originally Posted by masterid View Post
    Whenever the graphics changes I want rescale y axis to show minimum and maximum value at screen instead of keeping the old scale and showing an flat version of curve.
    If your question is about how to re-enable autoscaling for the y axis:

    Qt Code:
    1. curve->setSamples( ... );
    2. plot->setAxisAutoScale( QwtPlot::yLeft );
    3. plot->replot();
    To copy to clipboard, switch view to plain text mode 

    For your understanding: a scale can be calculated by the autoscaler or is set manually by QwtPlot::setAxisScaleDiv ( or QwtPlot::setAxisScale() ). Magnifier, zoomer or panner use setAxisScale() and disable autoscaling each time they are in action. That's why you have to re-enable it, when you want to apply the autoscaler for a different series of values.

    The auto scaler is implemented in the scale engine of a scale ( QwtPlot::axisScaleEngine() ). The engine offers a couple of options to configure its algo: see QwtScaleEngine::Attribute. QwtScaleEngine::Floating has to be set, if you don't want to have the scale boundaries to be aligned to the step size.

    I agree, that more documentation is necessary, but when the lines above are really all you were looking for it should have been possible with reading the existing docs.

    Uwe

  3. The following user says thank you to Uwe for this useful post:

    masterid (12th February 2013)

  4. #3
    Join Date
    Nov 2012
    Posts
    34
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Auto scaling y axis using QwtPlotPanner and QwtPlotMagnifier

    Quote Originally Posted by masterid View Post
    Whenever the graphics changes I want rescale y axis to show minimum and maximum value at screen instead of keeping the old scale and showing an flat version of curve.
    Qt Code:
    1. // Don't use auto-scaling,
    2. QwtPlot::setAxisAutoScale(xBottom, false);
    3. // Get the lower-bound, upper-bound of the x axis,
    4. QwtPlot::axisScaleDiv(xBottom).lowerBound().
    5. QwtPlot::axisScaleDiv(xBottom).upperBound().
    6. // Calculate your min/max y values between the date bounds.
    7. double min;
    8. double max;
    9. // Set it,
    10. QwtPlot::setAxisScale(yLeft, min, max);
    To copy to clipboard, switch view to plain text mode 

  5. The following user says thank you to Seamus for this useful post:

    masterid (12th February 2013)

  6. #4
    Join Date
    Feb 2013
    Posts
    3
    Thanks
    3
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default Re: Auto scaling y axis using QwtPlotPanner and QwtPlotMagnifier

    Thanks for the answers guys, but unfortunately both methods don't work.
    That is because the lowerBound and upperBound (and auto scale) are global relative to data.
    If I know what points have been plotted to canvas, I can find their minimum and maximum, so I can resize the y scale. Is there an practical way of doing this?

    I'm researching how to do that, but once again, thanks.
    I will try to get xBottom scale div, walk through data and find minimum and maximum in that interval. Unfortunately there is no signal that is emitted when scale div changes, so I will have to inherit both QwtPlotPanner and QwtPlotMagnifier, which is painful, but ok...

    PS: I wanted to answer earlier but I couldn't, I'm sorry for that.

  7. #5
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,311
    Thanked 879 Times in 827 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Auto scaling y axis using QwtPlotPanner and QwtPlotMagnifier

    Quote Originally Posted by masterid View Post
    That is because the lowerBound and upperBound (and auto scale) are global relative to data.
    If I know what points have been plotted to canvas, I can find their minimum and maximum, so I can resize the y scale. Is there an practical way of doing this?
    Ah o.k. you want to align the y axis to the bounding interval of the points lying inside the current interval of the x axis.

    Quote Originally Posted by masterid View Post
    Unfortunately there is no signal that is emitted when scale div changes
    What about QwtScaleWidget::scaleDivChanged() ?

    Another approach is to overload QwtSeriesData<T>::setRectOfInterest() ( with Qwt 6.1 you have to enable QwtPlotItem::ScaleInterest ). - or QwtPlotCurve::updateScaleDiv(). Here you could adjust the y coordinates of the bounding rectangle - what is the interval that is used by the auto scaler.

    Uwe

  8. The following user says thank you to Uwe for this useful post:

    masterid (13th February 2013)

  9. #6
    Join Date
    Feb 2013
    Posts
    3
    Thanks
    3
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11

    Default Re: Auto scaling y axis using QwtPlotPanner and QwtPlotMagnifier

    Wonderful Uwe! Thanks a lot man.

    I was searching for signal in QwtScaleDiv, that's why nothing was found.
    I followed the first tip, using the signal and it worked great!

    Here is the the slot which scaleDivChanged() was connected
    (Study is just a QwtSeriesData<QPointF>)

    Qt Code:
    1. void GraphicView::updateYAxis(){
    2. QwtScaleDiv *xDiv =
    3. plotter->axisScaleDiv(QwtPlot::xBottom);
    4.  
    5. double min=99999999999999,max=-99999999999999;
    6.  
    7. for(Study* s: studies.values()){
    8. for(uint i = 0; i < s->size(); i++) {
    9. double x = s->sample(i).x();
    10. double y = s->sample(i).y();
    11.  
    12. if(xDiv->interval().contains(x)){
    13. max=qMax(max,y);
    14. min=qMin(min,y);
    15. }
    16. }
    17. }
    18.  
    19. plotter->axisScaleEngine(QwtPlot::yLeft)->divideScale(min,max,5,25,(max-min)/5);
    20.  
    21. plotter->setAxisScaleDiv(QwtPlot::yLeft,div);
    22.  
    23. plotter->replot();
    24.  
    25. }
    To copy to clipboard, switch view to plain text mode 

  10. #7
    Join Date
    Nov 2012
    Posts
    34
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Auto scaling y axis using QwtPlotPanner and QwtPlotMagnifier

    I will try to get xBottom scale div, walk through data and find minimum and maximum in that interval. Unfortunately there is no signal that is emitted when scale div changes, so I will have to inherit both QwtPlotPanner and QwtPlotMagnifier, which is painful, but ok...
    These connections may interest you, using only QwtScaleWidget::scaleDivChanged() didn't handle some plot movements, I don't recall why:
    Qt Code:
    1. connect(panner, SIGNAL(panned(int,int)),
    2. this, SLOT(updateYAxis()));
    3. connect(axisWidget(xBottom), SIGNAL(scaleDivChanged()),
    4. this, SLOT(updateYAxis()));
    To copy to clipboard, switch view to plain text mode 

    You shouldn't need two for loops, or to set the initial min max values. I've pasted in the function similar to what I currently use on a candle plot, I limit the iterations with the bounds values, If you have data from a higher time frame that could be used to avoid most iterations.
    Qt Code:
    1. void GraphicView::updateYAxis()
    2. {
    3. if (! m_samples.size() || axisAutoScale(yRight))
    4. return;
    5.  
    6. const double lowerBound = axisScaleDiv(xBottom).lowerBound();
    7. const double upperBound = axisScaleDiv(xBottom).upperBound();
    8.  
    9. double min, max, begin, end;
    10.  
    11. if (lowerBound < upperBound)
    12. {
    13. begin = lowerBound;
    14. end = upperBound;
    15. }
    16. else
    17. {
    18. begin = upperBound;
    19. end = lowerBound;
    20. }
    21.  
    22. if( begin < 0 )
    23. begin = 0;
    24. if( end < 0 )
    25. end = 0;
    26.  
    27. if( m_samples.size() < begin )
    28. return;
    29.  
    30. if( m_samples.size() < end )
    31. end = m_samples.size() - 1;
    32.  
    33. min = m_samples.low().at(begin);
    34. max = m_samples.high().at(begin);
    35.  
    36. for ( int i = begin + 1; i <= end; ++i )
    37. {
    38. min = qMin( min, m_samples.low().at(i) );
    39. max = qMax( max, m_samples.high().at(i) );
    40. }
    41. setAxisScale(yRight, min, max);
    42. }
    To copy to clipboard, switch view to plain text mode 

Similar Threads

  1. QwtSpectogram and scaling the Axis
    By revellix in forum Qwt
    Replies: 1
    Last Post: 25th August 2011, 09:36
  2. improve the auto scaling of axis
    By 21did21 in forum Qwt
    Replies: 7
    Last Post: 7th July 2011, 19:26
  3. Replies: 3
    Last Post: 18th May 2011, 20:33
  4. Y axis not auto scaling
    By pkj in forum Qwt
    Replies: 0
    Last Post: 12th May 2011, 16:05
  5. QLabel - auto font scaling possible?
    By Byngl in forum Qt Programming
    Replies: 1
    Last Post: 11th October 2007, 16:50

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.