Results 1 to 7 of 7

Thread: sync plot grid w/ external scale widget

  1. #1
    Join Date
    Dec 2009
    Location
    Citrus Heights
    Posts
    10
    Thanks
    2
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default sync plot grid w/ external scale widget

    I have 2 QwtPlot objects on the same widget and both plot will use same x-axis (it has to be two different plot, not overlap on the same one). Both plots will not have x-axis displayed and an external QwtScaleWidget will display the x-axis. I have all this in a grid layout.


    The issue I'm running into is:
    - The QwtPlot grid tick does not line up with the QwtScaleWidget ticks.

    Qt Code:
    1. void MyWidget::SyncScale ()
    2. {
    3. xAxis->setScaleDiv(m_pQwtPlot1->axisScaleEngine(QwtPlot::xBottom)->transformation(),
    4. m_pQwtPlot1->axisWidget(QwtPlot::xBottom)->scaleDraw()->scaleDiv());
    5. int start, end;
    6. m_pQwtPlot1->axisWidget(QwtPlot::xBottom)->getBorderDistHint(start, end);
    7. xAxis->setBorderDist(start, end);
    8.  
    9. }
    To copy to clipboard, switch view to plain text mode 

    Any support/help are greatly appreciated!

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

    Default Re: sync plot grid w/ external scale widget

    Hm , the scaleMaps depend on the hidden scales - so at least the borders need to be in sync with your custom scale widget !

    What you can do is to derive from QwtPlotGrid and reimplement YourPlotGrid::updateScaleDiv as nop. Then you can assign the ticks manually using QwtPlotGrid::setXDiv/setYDiv.

    Uwe

  3. #3
    Join Date
    Dec 2009
    Location
    Citrus Heights
    Posts
    10
    Thanks
    2
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: sync plot grid w/ external scale widget

    No luck so far... The attached is the screen of what I got.
    graph.JPG

    The x axis at bottom is the external widget and x axis on top is part of QwtPlot. I want the 2nd graph's grid line up w/ the external axis just like how the top grid is line up with internal axis.

    I have the class as you suggested.
    Qt Code:
    1. class MyPlotGrid : public QwtPlotGrid
    2. {
    3. public:
    4. MyPlotGrid () : QwtPlotGrid() {}
    5.  
    6. virtual void updateScaleDiv(const QwtScaleDiv &xMap, const QwtScaleDiv &yMap);
    7. };
    8.  
    9. void MyPlotGrid::updateScaleDiv(const QwtScaleDiv &xMap, const QwtScaleDiv &yMap)
    10. { }
    To copy to clipboard, switch view to plain text mode 

    The grid is created here
    Qt Code:
    1. grid = new MyPlotGrid;
    2. grid->enableXMin(true);
    3. grid->setMajPen(QPen(Qt::gray, 0, Qt::SolidLine));
    4. grid->setMinPen(QPen(Qt::white, 0 , Qt::SolidLine));
    5. grid->attach(m_pLowerPlot);
    To copy to clipboard, switch view to plain text mode 

    I am using the top graph's engine to generate division for the external widget. Here is the modified slot to handle sync
    Qt Code:
    1. void MyWidget::SyncScale ()
    2. {
    3. xAxis->setScaleDiv(m_pTopPlot->axisScaleEngine(QwtPlot::xBottom)->transformation(),
    4. m_pTopPlot->axisWidget(QwtPlot::xBottom)->scaleDraw()->scaleDiv());
    5. int start, end;
    6. xAxis->getBorderDistHint(start, end);
    7. xAxis->setBorderDist(start, end);
    8. m_pLowerPlot->axisWidget(QwtPlot::xBottom)->setBorderDist(start, end);
    9.  
    10. grid->setXDiv(xAxis->scaleDraw()->scaleDiv());
    11. grid2->setXDiv(xAxis->scaleDraw()->scaleDiv());
    12.  
    13. }
    To copy to clipboard, switch view to plain text mode 

    grid is attached to top plot and grid2 is attached to lower plot. It's interesting that top plot is lined up and lower one is not -.-

    Thank you again for your support.

  4. #4
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,277
    Thanked 871 Times in 819 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: sync plot grid w/ external scale widget

    Your external scale doesn't match the transformations of the plots ( which value is mapped to which pixel position). This is a problem of your main layout not of the grid.

    Uwe

  5. #5
    Join Date
    Dec 2009
    Location
    Citrus Heights
    Posts
    10
    Thanks
    2
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Lightbulb Re: sync plot grid w/ external scale widget

    Thanks for all your help, Uwe. I was able to resolve it with your suggestions.
    graph2.JPG

    What I did was:
    1. extend QwtPlot class to store reference to external scale widget
    2. overload canvasMap function to use external scale widget to calculate mapping.
    Qt Code:
    1. class MyQwtPlot : public QwtPlot
    2. {
    3. protected:
    4. QwtScaleWidget *m_pXAxis;
    5. QwtScaleWidget *m_pYAxis;
    6.  
    7. public:
    8. MyQwtPlot (QWidget *parent = NULL) :
    9. QwtPlot(parent), m_pXAxis(NULL), m_pYAxis(NULL)
    10. {
    11. enableAxis(QwtPlot::xBottom, false);
    12. enableAxis(QwtPlot::yLeft, false);
    13. }
    14.  
    15. virtual QwtScaleMap canvasMap (int axisId) const;
    16. void SetExternalScaleWidget(int axisId, QwtScaleWidget *scaleWidget);
    17. };
    18.  
    19. QwtScaleMap MyQwtPlot::canvasMap (int axisId) const
    20. {
    21. const QwtPlotCanvas *cv = canvas();
    22. if ( cv == NULL )
    23. return map;
    24.  
    25. if ( axisId == QwtPlot::xBottom && m_pXAxis != NULL )
    26. {
    27. map.setTransformation(axisScaleEngine(axisId)->transformation());
    28.  
    29. QwtScaleDiv sd = m_pXAxis->scaleDraw()->scaleDiv();
    30. map.setScaleInterval(sd.lowerBound(), sd.upperBound());
    31.  
    32. int x = axisWidget(axisId)->x() + m_pXAxis->startBorderDist() - cv->x();
    33. int w = m_pXAxis->width() - m_pXAxis->startBorderDist() - m_pXAxis->endBorderDist();
    34. map.setPaintInterval(x, x + w);
    35. } else if ( axisId == QwtPlot::yLeft && m_pYAxis != NULL )
    36. {
    37. map.setTransformation(axisScaleEngine(axisId)->transformation());
    38. QwtScaleDiv sd = m_pYAxis->scaleDraw()->scaleDiv();
    39. map.setScaleInterval(sd.lowerBound(), sd.upperBound());
    40.  
    41. int y = m_pYAxis->startBorderDist() - cv->y();
    42. int h = m_pYAxis->height() - m_pYAxis->startBorderDist() - m_pYAxis->endBorderDist();
    43. map.setPaintInterval(y + h, y);
    44. } else
    45. return QwtPlot::canvasMap(axisId);
    46.  
    47. return map;
    48. }
    To copy to clipboard, switch view to plain text mode 

    3. extend QwtPlotGrid class to remove updateScaleDiv function
    Qt Code:
    1. class MyPlotGrid : public QwtPlotGrid
    2. {
    3. public:
    4. GalilPlotGrid() : QwtPlotGrid() {}
    5. // take out auto update, use setXDiv, setYDiv to update divider tick
    6. virtual void updateScaleDiv(const QwtScaleDiv &xMap, const QwtScaleDiv &yMap) {}
    7. };
    To copy to clipboard, switch view to plain text mode 
    4. have SyncScale slot connect to scaleDivChanged

    Qt Code:
    1. connect(m_pLowerPlot->axisWidget(QwtPlot::xBottom), SIGNAL(scaleDivChanged()), this, SLOT(SyncScale()));
    2. connect(m_pTopPlot->axisWidget(QwtPlot::xBottom), SIGNAL(scaleDivChanged()), this, SLOT(SyncScale()));
    3. connect(m_pLowerPlot->axisWidget(QwtPlot::yLeft), SIGNAL(scaleDivChanged()), this, SLOT(SyncScale()));
    4. connect(m_pTopPlot->axisWidget(QwtPlot::yLeft), SIGNAL(scaleDivChanged()), this, SLOT(SyncScale()));
    5.  
    6. void MyWidget::SyncScale ()
    7. {
    8. int start, end;
    9.  
    10. m_pXAxis->setScaleDiv(m_pPlotMag->axisScaleEngine(QwtPlot::xBottom)->transformation(),
    11. m_pTopPlot->axisScaleDraw(QwtPlot::xBottom)->scaleDiv());
    12. m_pXAxis->getBorderDistHint(start, end);
    13. m_pXAxis->setBorderDist(start, end);
    14.  
    15. div = m_pXAxis->scaleDraw()->scaleDiv();
    16. m_pTopPlot->setXDiv(div);
    17. m_pLowerPlot->setXDiv(div);
    18.  
    19. m_pYTop->setScaleDiv(m_pTopPlot->axisScaleEngine(QwtPlot::yLeft)->transformation(),
    20. m_pTopPlot->axisScaleDraw(QwtPlot::yLeft)->scaleDiv());
    21. m_pYTop->getBorderDistHint(start, end);
    22. m_pYTop->setBorderDist(start, end);
    23.  
    24. div = m_pYTop->scaleDraw()->scaleDiv();
    25. m_pGridTop->setYDiv(div);
    26.  
    27. m_pYLower->setScaleDiv(m_pLowerPlot->axisScaleEngine(QwtPlot::yLeft)->transformation(),
    28. m_pLowerPlot->axisScaleDraw(QwtPlot::yLeft)->scaleDiv());
    29. m_pYLower->getBorderDistHint(start, end);
    30. m_pYLower->setBorderDist(start, end);
    31.  
    32. div = m_pYLower->scaleDraw()->scaleDiv();
    33. m_pGridLower->setYDiv(div);
    34. }
    To copy to clipboard, switch view to plain text mode 

    Thx again

  6. The following user says thank you to Kevin Ching for this useful post:

    alizadeh91 (14th August 2012)

  7. #6
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,277
    Thanked 871 Times in 819 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: sync plot grid w/ external scale widget

    Wouldn't it be easier to sync the hidden x axis of the upper plot to the visible x axis of the lower plot - instead of introducing an additional scale.Did you have a look at the plotmatrix example in SVN trunk ?

    Uwe

  8. #7
    Join Date
    Dec 2009
    Location
    Citrus Heights
    Posts
    10
    Thanks
    2
    Thanked 2 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: sync plot grid w/ external scale widget

    I did not look at the example in SVN. I'll look at it . Thanks for pointing to that.

Similar Threads

  1. Replies: 5
    Last Post: 5th November 2010, 17:26
  2. Replies: 2
    Last Post: 12th October 2009, 21:17
  3. qwp plot axis scale
    By Cal in forum Qwt
    Replies: 1
    Last Post: 11th May 2009, 17:10
  4. Qwt plot + grid huge pdf file
    By giusepped in forum Qwt
    Replies: 3
    Last Post: 17th December 2008, 13:53
  5. how to hide the scale in qwt plot
    By babu198649 in forum Qwt
    Replies: 2
    Last Post: 7th March 2008, 06:38

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.