Results 1 to 13 of 13

Thread: QwtRasterData and values

  1. #1
    Join Date
    Jun 2008
    Posts
    7
    Thanks
    2
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default QwtRasterData and values

    Can someone explain to me why the QwtRasterData::value method (which returns the value at the specified raster position) has "doubles" as the x / y for the position. I think I understand that the position is the pixel position, but what is a fraction of a position? I am trying to map the value call to my data but I am not sure what the fractional positions are.

    For example, I am creating a 100 x 100 QwtRasterData. I want to have a 100x100 array with values in it. How do I map the "value" call to my array?

    By the way, I am using the Spectrogram example as a starting point.

    Thanks.

  2. #2
    Join Date
    Jul 2008
    Posts
    16
    Thanks
    2
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11

    Default Re: QwtRasterData and values

    Hi,
    as far as I’ve understood it, you’d give the boundaries when you’re initialising your subclassed QwtRasterData. Qwt would then call the value method with all numbers between those boundaries that are currently displayable. If you stretch the plot to a size of 200 pixels, this will mean that qwt asks for 200 values betwenn 0 and 100, so you will have to use a method to get appropriate integer numbers from those.

    Qt Code:
    1. class SpectrogramData: public QwtRasterData
    2. {
    3. public:
    4. SpectrogramData
    5. : QwtRasterData(QwtDoubleRect(0., 0., 100., 100.))
    6. {
    7. }
    8. virtual double value(double x, double y) const
    9. {
    10. return myDataArray[(unsigned int) floor(x)][(unsigned int) floor(y)];
    11. }
    12. };
    To copy to clipboard, switch view to plain text mode 

    You could also implement a QSize rasterHint() method which returns the maximal resolution possible, so that Qwt only asks for 100 values between 0 and 100 and not like 300-something or however large you drag your plot on screen.

    Unfortunately, I do have issues with the code as well (especially when rasterHint is implemented), so it can only serve you as a first idea.

    My problem is, that sometimes Qwt would call value(99,100) which of course yields an out-of-range value. And somehow the plot gets shifted in y-direction, too. Strangely, this does not happen in x direction, e.g. Qwt does not call value(100,99) or value(100,100). At least that is not what I observed.

    Hopefully, someone could post an insightful solution to this and hint how Qwt determines which arguments it passes to the value(x, y) method.

    Nontheless, I hope my first version is of some use for you anyway.

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

    DKL1972 (19th July 2008)

  4. #3
    Join Date
    Jun 2008
    Posts
    7
    Thanks
    2
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: QwtRasterData and values

    Thank you. This explains it well for me and is a great start!

  5. #4
    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: QwtRasterData and values

    Quote Originally Posted by DKL1972 View Post
    Can someone explain to me why the QwtRasterData::value method (which returns the value at the specified raster position) has "doubles" as the x / y for the position. I think I understand that the position is the pixel position, ...
    No - Qwt has already translated the pixel positions into the coordinate system from the current scales. So you have to do some resampling (next neighbour, aggregation, accumulation or whatever) inside of YourRasterData::value ( or rebuild your matrix in QwtRasterData::initRaster() ).

    Uwe

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

    DKL1972 (23rd July 2008)

  7. #5
    Join Date
    Aug 2008
    Posts
    5
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QwtRasterData and values

    Hello everyone. I have the same problem with value method like Debilski. parameters of value function are bigger than for eg. 10 even if i set
    Qt Code:
    1. QwtRasterData(QwtDoubleRect(0., 0., 10., 10.))
    To copy to clipboard, switch view to plain text mode 
    I tried to round somehow the parameters x and y but i failed.
    In manual for QwtRasterData::initRaster() there is written:
    Before the composition of an image QwtPlotSpectrogram calls initRaster, announcing the area and its resolution that will be requested. The default implementation does nothing, but for data sets that are stored in files, it might be good idea to reimplement initRaster, where the data is resampled and loaded into memory.
    Does someone will be so kinde and give me example of QwtRasterData which returns value from 2 dimensional array of double.

    Thank You very much.

  8. #6
    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: QwtRasterData and values

    Quote Originally Posted by shargath View Post
    I tried to round somehow the parameters x and y but i failed
    Your QwtRasterData implementation tells the spectrogram, that it has data in the area (0.0, 0.0, 10.0, 10.0). This is an area on the plot canvas according to the scales and has nothing to do with the resolution of your raster !

    Depending on the current scales and the resolution of your paint device the spectrogram requests values ( you don't know them in advance ! ) in this area from your data class. In most situations your data doesn't have a value for exactly this position. That's why you have to calculate one ( this is called resampling ) from the existing values.

    How to do it depends completely on the organization of your data and the type of resampling you prefer.

    Uwe

  9. #7
    Join Date
    Aug 2008
    Posts
    5
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QwtRasterData and values

    My data is stored in two dimensional array of doubles. In first version I want program to plot all values from this data array where cell [x][y] of array corespond to (x,y) pixel position on the canvas. What else and how should i implement besides QwtRasterData::value method.

    Thank You for reply.

  10. #8
    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: QwtRasterData and values

    Qt Code:
    1. YourRasterData::YourRasterData():
    2. QwtRasterData(QwtDoubleRect(0.0, 0.0, 9.0, 9.0)
    3. {
    4. ...
    5. }
    6.  
    7. double YourRasterData::value(double x, double y) const
    8. {
    9. int ix = qRound(x);
    10. int iy = qRound(y);
    11. if ( ix >= 0 && ix < 10 && iy >= 0 && iy < 10 )
    12. return _values[ix][iy];
    13.  
    14. return ...; // shouldn't happen
    15. }
    To copy to clipboard, switch view to plain text mode 

    But from your previous postings I'm not sure that you really want what QwtPlotSpectrogram offers.

    Uwe

  11. #9
    Join Date
    Aug 2008
    Posts
    5
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QwtRasterData and values

    Here is my code as simple as possible, also i applied your last suggestions but despite i got segmentation fault. Please help.

    1. Plot.h

    Qt Code:
    1. #ifndef PLOT_DATA_H
    2. #define PLOT_DATA_H
    3.  
    4. #include "qwt_raster_data.h"
    5.  
    6. class plot_data: public QwtRasterData
    7. {
    8.  
    9. private:
    10. double ** d_DataArray;
    11.  
    12. public:
    13. plot_data();
    14. ~plot_data();
    15.  
    16. virtual QwtRasterData *copy() const;
    17. virtual QwtDoubleInterval range() const;
    18. virtual double value(double x, double y) const;
    19. void setData();
    20. };
    21.  
    22. #endif // PLOT_DATA_H
    To copy to clipboard, switch view to plain text mode 

    1. Plot.cpp

    Qt Code:
    1. #include "plot_data.h"
    2. #include <QDebug>
    3. #include <cmath>
    4. plot_data::plot_data():
    5. QwtRasterData(QwtDoubleRect(0., 0., 9.0, 9.0))
    6. {
    7. d_DataArray = NULL;
    8. }
    9.  
    10. plot_data::~plot_data()
    11. {
    12. if (d_DataArray != NULL ){
    13. for(int i = 0; i < 10; i ++)
    14. {
    15. delete [] d_DataArray[i];
    16.  
    17. }
    18. delete [] d_DataArray;
    19. }
    20. }
    21.  
    22.  
    23. QwtDoubleInterval plot_data::range() const
    24. {
    25. return QwtDoubleInterval(0., 10);
    26.  
    27. }
    28.  
    29. QwtRasterData* plot_data::copy() const
    30. {
    31. plot_data *clone = new plot_data();
    32. return clone;
    33. }
    34.  
    35.  
    36. double plot_data::value(double x, double y) const
    37. {
    38.  
    39. int xpos = qRound(x);
    40. int ypos = qRound(y);
    41. if (xpos >= 0 || xpos < 10 || ypos >= 0 || ypos < 10 )
    42. {
    43. //here is still segmentation fault;
    44. return d_DataArray[xpos][ypos];
    45. }
    46. qDebug() << "it happened";
    47. return 0.0;
    48. }
    49.  
    50. void plot_data::setData()
    51. {
    52. //here i'm generating some test data.
    53. //help values to random data;
    54. int XMin = 0, XMax = 10, size = 100;
    55.  
    56.  
    57. if (d_DataArray != NULL )
    58. {
    59. for(int i = 0; i < 10; i ++)
    60. {
    61. delete [] d_DataArray[i];
    62. }
    63. delete [] d_DataArray;
    64. qDebug()<< "Deleted";
    65. }
    66.  
    67. d_DataArray = new double* [10];
    68. if (d_DataArray == NULL)
    69. {
    70. qDebug() << "BAd initialization";
    71. }
    72. for(int i = 0; i < 10; i ++)
    73. {
    74. d_DataArray[i] = new double [10];
    75. if (d_DataArray[i] == NULL)
    76. qDebug() << "Something Wrong with allocation";
    77. }
    78.  
    79. for(int x = 0; x < 10; x ++)
    80. for(int y = 0; y < 10; y ++){
    81. d_DataArray[x][y] = XMin + rand() * (XMax - XMin) / RAND_MAX;
    82.  
    83. //qDebug() << d_DataArray[0][9] << "\n";
    84. //WHEN I CALL HERE SOMETHING LIKE THIS IT ALSO YELDS SEGFAULT
    85. }
    86.  
    87. }
    To copy to clipboard, switch view to plain text mode 


    Regarding the way how i would like to use the SpectrogramPlot. I'm working on 2 dimmensional Lattice boltzman method, and i want to visualise my results using SpectrogramPlot. It is simulation of fluid over discrete space. Results are values of speed in each cell of space. So i want to represent the data in 2D array. I think it's natural

  12. #10
    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: QwtRasterData and values

    Your copy method returns a data object with an empty matrix. No surprise, that the (unprotected) value method runs into a segfault. I recommend to use one of the implicitely shared QTL containers, because it makes the implementation of the copy operation easier.

    Uwe

  13. #11
    Join Date
    Dec 2009
    Posts
    24
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QwtRasterData and values

    [EDIT]:
    aaaahh.. I should have wait a little more before posting that...
    turns out it's a similar problem as the op had...
    x ,y values being asked outside the container...
    SORRY....[/EDIT]

    Hi,
    I'm reviving an old thread... I just stumbled upon this while trying to solve a pb of mine using QwtRasterData...

    I have a QMap container filled with data created somewhere else in the program...
    the following class is used like this
    d_spectrogram->setData(SpectrogramData(&data));

    this code:
    Qt Code:
    1. class SpectrogramData: public QwtRasterData
    2. {
    3. public:
    4. SpectrogramData(QMap<int, double*>* points):
    5. QwtRasterData(QwtDoubleRect(0.0, 0.0, 1999.0, 1999.0))
    6. {
    7. datas = points;
    8. }
    9.  
    10. virtual SpectrogramData *copy() const
    11. {
    12. SpectrogramData* spec_data = new SpectrogramData(datas);
    13. return spec_data;
    14. }
    15.  
    16. virtual QwtDoubleInterval range() const
    17. {
    18. return QwtDoubleInterval(0.0, 1000.0);
    19. }
    20.  
    21. virtual double value(double x, double y) const
    22. {
    23.  
    24. int X = qRound(x);
    25. int Y = qRound(y);
    26. return (datas->value(X))[Y];
    27. }
    28.  
    29. private:
    30. QMap<int, double*> *datas;
    31.  
    32. };
    To copy to clipboard, switch view to plain text mode 

    This consistently giving a segentation fault...happening when the object returned by the copy method is used...
    Leave alone the fact that I dont understand why 2 SpectrogramData objects are used,

    it seems that the copied object will contain a non null pointer to a non-empty container, as its parent...

    If somebody can shed some light on the silly mistake I made!
    Last edited by jcox23; 9th March 2010 at 13:53.

  14. #12
    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: QwtRasterData and values

    The map is somewhere allocated in your application code. It's up to the application code to take care of its lifetime. Also check the indices before accessing your map and double arrays - without setting the bounding rect you can be sure to see requests for positions you don't have.

    Note, that SpectrogramData::value() is called very often ( for each pixel of your plot canvas: width * height ). So better don't use a QMap. Returning a rasterHint should be useful as well.

    Uwe

  15. #13
    Join Date
    Dec 2009
    Posts
    24
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QwtRasterData and values

    Quote Originally Posted by Uwe View Post
    The map is somewhere allocated in your application code. It's up to the application code to take care of its lifetime.
    Yes it is created outside the code, I cant afford copying it around, it can be big, and there's several of them...RAM usage could quickly explode...

    Quote Originally Posted by Uwe View Post
    Also check the indices before accessing your map and double arrays - without setting the bounding rect you can be sure to see requests for positions you don't have.
    Yes turns out it was just that, a position request was outside the boundaries of my map...

    Quote Originally Posted by Uwe View Post
    Note, that SpectrogramData::value() is called very often ( for each pixel of your plot canvas: width * height ). So better don't use a QMap. Returning a rasterHint should be useful as well.
    Uwe
    I know, but QMap is just very convenient in my case, i have series of vectors (double) keyed by integers that are not linearly increasing....
    QHash would be probably a bit faster, is that what you were thinking about or even going further than that by using a more low level container... like a long flatten array for example?

Tags for this Thread

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.