Results 1 to 10 of 10

Thread: Is it possible to use a deque as plot data?

  1. #1
    Join Date
    Jun 2011
    Posts
    38
    Thanks
    8
    Thanked 1 Time in 1 Post

    Default Is it possible to use a deque as plot data?

    Hi everyone,

    I want to plot some data in realtime, so at the end new data is added and at the front data is removed.
    A perfect job for a deque.

    But setSamples does not accept a deque...

    So far I used a deque and before replotting, I copied all contents of the deque to a vector.
    This works, but it is quite inefficient.

    Is there a better way to do this?

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

    Default Re: Is it possible to use a deque as plot data?

    Sure use QwtPlotCurve::setData() and bind your deque to the curve using the QwtSeriesData API.

    Uwe

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

    P@u1 (25th July 2011)

  4. #3
    Join Date
    Jun 2011
    Posts
    38
    Thanks
    8
    Thanked 1 Time in 1 Post

    Default Re: Is it possible to use a deque as plot data?

    Thanks for your great help!

    One more question:
    if my values are in range x: [-10,10] y: [-100,100]
    How should boundingRect() look then?

    return QRectF(-10, -100, 20, 200);

    or

    return QRectF(-10, 100, 20, 200);
    ?

    it's a question of which coordinate system is used.

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

    Default Re: Is it possible to use a deque as plot data?

    Always in plot coordinates: QRectF(-10, -100, 20, 200);

    I'm not aware of any coordinate system, where QRectF(-10, 100, 20, 200) might make sense and the bounding rectangle of a set of points has nothing to with coordinate systems ( like a QPolygonF::boundingRect() ) at all.

    Uwe

  6. #5
    Join Date
    Jun 2011
    Posts
    38
    Thanks
    8
    Thanked 1 Time in 1 Post

    Default Re: Is it possible to use a deque as plot data?

    Thanks for your great help again!
    Btw are you the or an author of qwt?

    I think that many people might need a deque buffer for qwt plot data, so I will post it here for others to use.
    Also feel very welcome to make suggestions for improvement!

    PlotDataBuffer.h
    Qt Code:
    1. #ifndef PLOTDATABUFFER_H_
    2. #define PLOTDATABUFFER_H_
    3.  
    4. #include <deque>
    5. #include <QPointF>
    6. #include "qwt_series_data.h"
    7.  
    8. class PlotDataBuffer : public QwtSeriesData<QPointF>
    9. {
    10. public:
    11. PlotDataBuffer(int windowSize);
    12. void setWindowSize(int windowSize);
    13. double getMinX() const;
    14. double getMaxX() const;
    15. double getMinY() const;
    16. double getMaxY() const;
    17. void PlotDataBuffer::addData(double x, double y) {addData(QPointF(x, y));}
    18. void addData(const QPointF& p);
    19. void clear();
    20.  
    21. virtual size_t size() const {return deque_.size();}
    22. virtual QPointF sample (size_t i) const {return deque_[i];}
    23. virtual QRectF boundingRect() const;
    24.  
    25. private:
    26. void makeMinMaxValid() const;
    27.  
    28. int windowSize_;
    29. std::deque<QPointF> deque_;
    30. mutable double minX_;
    31. mutable double maxX_;
    32. mutable double minY_;
    33. mutable double maxY_;
    34. mutable bool minMaxValid_;
    35. };
    36.  
    37. #endif
    To copy to clipboard, switch view to plain text mode 

    PlotDataBuffer.cpp
    Qt Code:
    1. #include "PlotDataBuffer.h"
    2. #include <cmath>
    3. #include <algorithm>
    4.  
    5. using namespace std;
    6.  
    7. class MinMax
    8. {
    9. public:
    10. MinMax():
    11. minX_(0.0),
    12. maxX_(0.0),
    13. minY_(0.0),
    14. maxY_(0.0)
    15. {
    16.  
    17. }
    18.  
    19. void operator()(const QPointF& p)
    20. {
    21. minX_ = min(minX_, p.x());
    22. maxX_ = max(maxX_, p.x());
    23.  
    24. minY_ = min(minY_, p.y());
    25. maxY_ = max(maxY_, p.y());
    26. }
    27.  
    28. double getMinX() const
    29. {
    30. return minX_;
    31. }
    32.  
    33. double getMaxX() const
    34. {
    35. return maxX_;
    36. }
    37.  
    38. double getMinY() const
    39. {
    40. return minY_;
    41. }
    42.  
    43. double getMaxY() const
    44. {
    45. return minY_;
    46. }
    47.  
    48. private:
    49. double minX_;
    50. double maxX_;
    51.  
    52. double minY_;
    53. double maxY_;
    54. };
    55.  
    56. PlotDataBuffer::PlotDataBuffer(int windowSize):
    57. minX_(0.0),
    58. maxX_(0.0),
    59. minY_(0.0),
    60. maxY_(0.0),
    61. windowSize_(windowSize),
    62. minMaxValid_(true)
    63. {
    64.  
    65. }
    66.  
    67. void PlotDataBuffer::setWindowSize(int windowSize)
    68. {
    69. if(windowSize == windowSize_)
    70. {
    71. return;
    72. }
    73. windowSize_ = windowSize;
    74. while(deque_.size() > windowSize_)
    75. {
    76. deque_.pop_front();
    77. }
    78. minMaxValid_ = false;
    79. }
    80.  
    81. void PlotDataBuffer::clear()
    82. {
    83. deque_.clear();
    84. }
    85.  
    86. QRectF PlotDataBuffer::boundingRect() const
    87. {
    88. makeMinMaxValid();
    89. return QRectF(minX_, minY_, maxX_ - minX_, maxY_ - minY_);
    90. }
    91.  
    92. void PlotDataBuffer::addData(const QPointF& p)
    93. {
    94. deque_.push_back(p);
    95. while(deque_.size() > windowSize_)
    96. {
    97. deque_.pop_front();
    98. }
    99. minMaxValid_ = false;
    100. }
    101.  
    102. void PlotDataBuffer::makeMinMaxValid() const
    103. {
    104. if(!minMaxValid_)
    105. {
    106. MinMax m = for_each(deque_.begin(), deque_.end(), MinMax());
    107. minX_ = m.getMinX();
    108. maxX_ = m.getMaxX();
    109. minY_ = m.getMinY();
    110. maxY_ = m.getMaxY();
    111. minMaxValid_ = true;
    112. }
    113. }
    114.  
    115. double PlotDataBuffer::getMinX() const
    116. {
    117. makeMinMaxValid();
    118. return minX_;
    119. }
    120.  
    121. double PlotDataBuffer::getMaxX() const
    122. {
    123. makeMinMaxValid();
    124. return maxX_;
    125. }
    126.  
    127. double PlotDataBuffer::getMinY() const
    128. {
    129. makeMinMaxValid();
    130. return minY_;
    131. }
    132.  
    133. double PlotDataBuffer::getMaxY() const
    134. {
    135. makeMinMaxValid();
    136. return maxY_;
    137. }
    To copy to clipboard, switch view to plain text mode 

  7. #6
    Join Date
    Jun 2011
    Posts
    38
    Thanks
    8
    Thanked 1 Time in 1 Post

    Default Re: Is it possible to use a deque as plot data?

    there was a dangerous bug in PlotDataBuffer.cpp (initializing min and max with 0.0 instead of numerical limits).
    Also I wrote minY_ instead of maxY_ in one getter.

    Unfortuantely I cannot edit it anymore, so here is the new version, just in case that some1 wants to use it:

    PlotDataBuffer.cpp
    Qt Code:
    1. #include "PlotDataBuffer.h"
    2. #include <cmath>
    3. #include <algorithm>
    4. #include <limits>
    5.  
    6. using namespace std;
    7.  
    8. class MinMax
    9. {
    10. public:
    11. MinMax():
    12. minX_(numeric_limits<double>::max()),
    13. maxX_(numeric_limits<double>::min()),
    14. minY_(numeric_limits<double>::max()),
    15. maxY_(numeric_limits<double>::min()),
    16. empty_(true)
    17. {
    18.  
    19. }
    20.  
    21. void operator()(const QPointF& p)
    22. {
    23. empty_ = false;
    24. minX_ = min(minX_, p.x());
    25. maxX_ = max(maxX_, p.x());
    26.  
    27. minY_ = min(minY_, p.y());
    28. maxY_ = max(maxY_, p.y());
    29. }
    30.  
    31. double getMinX() const
    32. {
    33. if(empty_)
    34. {
    35. return 0.0;
    36. }
    37. return minX_;
    38. }
    39.  
    40. double getMaxX() const
    41. {
    42. if(empty_)
    43. {
    44. return 0.0;
    45. }
    46. return maxX_;
    47. }
    48.  
    49. double getMinY() const
    50. {
    51. if(empty_)
    52. {
    53. return 0.0;
    54. }
    55. return minY_;
    56. }
    57.  
    58. double getMaxY() const
    59. {
    60. if(empty_)
    61. {
    62. return 0.0;
    63. }
    64. return maxY_;
    65. }
    66.  
    67. private:
    68. double minX_;
    69. double maxX_;
    70.  
    71. double minY_;
    72. double maxY_;
    73.  
    74. bool empty_;
    75. };
    76.  
    77. PlotDataBuffer::PlotDataBuffer(int windowSize):
    78. minX_(0.0),
    79. maxX_(0.0),
    80. minY_(0.0),
    81. maxY_(0.0),
    82. windowSize_(windowSize),
    83. minMaxValid_(true)
    84. {
    85.  
    86. }
    87.  
    88. void PlotDataBuffer::setWindowSize(int windowSize)
    89. {
    90. if(windowSize == windowSize_)
    91. {
    92. return;
    93. }
    94. windowSize_ = windowSize;
    95. while(deque_.size() > windowSize_)
    96. {
    97. deque_.pop_front();
    98. }
    99. minMaxValid_ = false;
    100. }
    101.  
    102. void PlotDataBuffer::clear()
    103. {
    104. deque_.clear();
    105. }
    106.  
    107. QRectF PlotDataBuffer::boundingRect() const
    108. {
    109. makeMinMaxValid();
    110. return QRectF(minX_, minY_, maxX_ - minX_, maxY_ - minY_);
    111. }
    112.  
    113. void PlotDataBuffer::addData(const QPointF& p)
    114. {
    115. deque_.push_back(p);
    116. while(deque_.size() > windowSize_)
    117. {
    118. deque_.pop_front();
    119. }
    120. minMaxValid_ = false;
    121. }
    122.  
    123. void PlotDataBuffer::makeMinMaxValid() const
    124. {
    125. if(!minMaxValid_)
    126. {
    127. MinMax m = for_each(deque_.begin(), deque_.end(), MinMax());
    128. minX_ = m.getMinX();
    129. maxX_ = m.getMaxX();
    130. minY_ = m.getMinY();
    131. maxY_ = m.getMaxY();
    132. minMaxValid_ = true;
    133. }
    134. }
    135.  
    136. double PlotDataBuffer::getMinX() const
    137. {
    138. makeMinMaxValid();
    139. return minX_;
    140. }
    141.  
    142. double PlotDataBuffer::getMaxX() const
    143. {
    144. makeMinMaxValid();
    145. return maxX_;
    146. }
    147.  
    148. double PlotDataBuffer::getMinY() const
    149. {
    150. makeMinMaxValid();
    151. return minY_;
    152. }
    153.  
    154. double PlotDataBuffer::getMaxY() const
    155. {
    156. makeMinMaxValid();
    157. return maxY_;
    158. }
    To copy to clipboard, switch view to plain text mode 

    Edit: I discovered a serious problem with the QwtSeriesData API. It takes ownership of the data...
    I want to use one of my buffers for more than one plotcurve, which does not work with this ownership problem.
    I'm thinking of employing some kind of smart pointer and share the data of the PlotDataBuffer to work around this problem.

    Edit2: What does happen if first call setData and later call setRawSamples?
    Last edited by P@u1; 26th July 2011 at 13:26.

  8. #7
    Join Date
    Jun 2011
    Posts
    38
    Thanks
    8
    Thanked 1 Time in 1 Post

    Default Re: Is it possible to use a deque as plot data?

    Found another bug:


    Qt Code:
    1. minX_(numeric_limits<double>::max()),
    2. maxX_(numeric_limits<double>::min()),
    3. minY_(numeric_limits<double>::max()),
    4. maxY_(numeric_limits<double>::min()),
    To copy to clipboard, switch view to plain text mode 

    Has to be replaced with:

    Qt Code:
    1. minX_(numeric_limits<double>::max()),
    2. maxX_(-numeric_limits<double>::max()),
    3. minY_(numeric_limits<double>::max()),
    4. maxY_(-numeric_limits<double>::max()),
    To copy to clipboard, switch view to plain text mode 

    I think I will stop posting bugfixes here , except if some1 really is interested, because it always bumps the thread.

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

    Default Re: Is it possible to use a deque as plot data?

    Quote Originally Posted by P@u1 View Post
    Edit: I discovered a serious problem with the QwtSeriesData API. It takes ownership of the data...
    No you have discovered a problem in your class derived from QwtSeriesData.

    QwtSeriesData is just an interface - completely unrelated to how the application stores or shares its samples. In fact it is even possible to calculate samples on the fly storing nothing - like in QwtSyntheticPointData.

    Uwe

  10. #9
    Join Date
    Jun 2011
    Posts
    38
    Thanks
    8
    Thanked 1 Time in 1 Post

    Default Re: Is it possible to use a deque as plot data?

    I solved it by using a wrapper, which holds a reference to the actual data and does nothing in the destructor.

  11. #10
    Join Date
    Nov 2010
    Posts
    3
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Is it possible to use a deque as plot data?

    Could you elaborate more on your final solution?
    I am attempting the same feat

Similar Threads

  1. Data Plot Question
    By gokceng in forum Newbie
    Replies: 1
    Last Post: 18th July 2011, 16:06
  2. retrieving data from a QWT plot
    By mobucl in forum Qwt
    Replies: 1
    Last Post: 26th May 2011, 13:00
  3. Simple Plot after Inputing some Data
    By thebrute in forum Qwt
    Replies: 0
    Last Post: 18th August 2010, 14:29
  4. 2D array data plot!
    By kahramonj in forum Qwt
    Replies: 3
    Last Post: 21st March 2009, 11:48
  5. plot only subset of the data
    By pospiech in forum Qwt
    Replies: 3
    Last Post: 14th April 2008, 21:19

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.