Results 1 to 3 of 3

Thread: Spectrogram Plot Hints

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

    Default Spectrogram Plot Hints

    Hello. Since many days I'm trying to create spectrogram plot. I have data stored in two dimensional matrix. ThereI have double values which I want to plot. I have some problems as you can predict with value method in derived QwtRasterData class. With the current code I try to describe error I have. When I run the program and some times spectrogram is working and plot is shown. But sometimes when I resize window where is plotted I have error in value() out of range method in QwtRasterData. From what I have read I have to implement several methods.
    1. resampling the data I have in the matrix to the position on the spectrogram area
    2. implement RasterHint method.
    3. implement initRaster method.


    Please first explain me as simple as you can what excatly is the raster and raster data.
    for example in qwt initRaster documentation we have
    rect - Area of the raster - area of what ? of "colored picture" which spectrogram plot show.
    raster - Number of horizontal and vertical pixels - i suppose that is the resolution of this "colored picture". Maybe you know some hint how to get this values when i want to resize plot window by mouse.

    or for ex, in the value() method what means the value at a raster position.

    How to do next neighbour resampling as Uwe sometimes suggest?

    Where i have implement RasterHint and what should be inside.

    I know that there a lot of things to explain, but by myself I could not do this.
    Below i presented my code if plot and rasterdata classes I created.
    qwtspectrogramplot.h
    Qt Code:
    1. #ifndef QWTSPECTROGRAMPLOT_H
    2. #define QWTSPECTROGRAMPLOT_H
    3. #include <QtGui/QMainWindow>
    4. #include "ui_qwtspectrogramplot.h"
    5. #include <qwt_plot.h>
    6. #include <qwt_plot_spectrogram.h>
    7. #include <qwt_color_map.h>
    8. #include <qwt_plot_layout.h>
    9. #include <qwt_scale_widget.h>
    10. #include "spectrogramdata.h"
    11. #include "parameters.h"
    12. #include "obstacle.h"
    13. #include "Solver.h"
    14.  
    15. class QwtSpectrogramPlot : public QMainWindow
    16. {
    17. Q_OBJECT
    18.  
    19. public:
    20. QwtSpectrogramPlot(QWidget *parent = 0, Qt::WFlags flags = 0);
    21. ~QwtSpectrogramPlot();
    22.  
    23. /**
    24. Prepare the plot widget;
    25. */
    26. void SetupPlot(QMainWindow* QwtSpectrogramPolt_window);
    27.  
    28.  
    29. QHBoxLayout *hboxLayout;
    30.  
    31. enum colormap{ standard, gray };
    32.  
    33. private:
    34.  
    35. QwtLinearColorMap* m_colorMap;
    36.  
    37. QwtPlotSpectrogram* m_spectrogram;
    38.  
    39. /**
    40. Here i don't understand what is the dependency beetwen
    41. this variable (m_DataRange) which i use to create colormap
    42. and the method range() in SpectrogramData.
    43. */
    44. QwtDoubleInterval* m_DataRange;
    45.  
    46. SpectrogramData m_RasterData;
    47.  
    48. /**
    49. My solver which produce data for Spectrogram data.
    50. */
    51. Velocity2D velocity;
    52. Grid2D grid;
    53. Obstacle obstacle;
    54. Parameters param;
    55. Solver* solver;
    56.  
    57. colormap m_colormap;
    58.  
    59. void initColorMap();
    60.  
    61. void initSolver();
    62.  
    63. Ui::QwtSpectrogramPlotClass ui;
    64.  
    65. public:
    66. void setDataRange(double min, double max);
    67.  
    68. public slots:
    69. void setColorMap(colormap map);
    70. void rescale();
    71. void setDataMax(double max);
    72. void setDataMin(double min);
    73.  
    74. void SetData(Point2D<double>** newData, int size_x, int size_y);
    75.  
    76. private slots:
    77. void on_Solve_pushButton_clicked();
    78.  
    79. };
    80. #endif // QWTSPECTROGRAMPLOT_H
    To copy to clipboard, switch view to plain text mode 

    qwtspectrogramplot.cpp
    Qt Code:
    1. #include "qwtspectrogramplot.h"
    2. #include <fstream>
    3.  
    4. QwtSpectrogramPlot::QwtSpectrogramPlot(QWidget *parent, Qt::WFlags flags)
    5. : QMainWindow(parent, flags)
    6. {
    7. ui.setupUi(this);
    8. SetupPlot(this);
    9. initSolver();
    10. QObject::connect(solver,SIGNAL(sendData(Point2D<double>**, int, int)),
    11. this, SLOT(SetData(Point2D<double>**, int, int)) );
    12.  
    13. }
    14. QwtSpectrogramPlot::~QwtSpectrogramPlot()
    15. {
    16. delete hboxLayout;
    17. delete m_DataRange;
    18. delete m_colorMap;
    19. delete m_spectrogram;
    20. delete qwtPlot;
    21. }
    22. void QwtSpectrogramPlot::initSolver()
    23. {
    24. velocity.set(0.0,0.0);
    25. grid.set(150,50);
    26. obstacle.setSize(grid);
    27. obstacle.initializeTable();
    28. obstacle.readFromFile("ball.obs");
    29. param.setDensity(1.0);
    30. param.setOmega(1.85);
    31. param.setVelocity(velocity);
    32. param.setGridSize(grid);
    33. solver = new Solver(&param);
    34. }
    35. void QwtSpectrogramPlot::SetupPlot(QMainWindow *QwtSpectrogramPlot_window)
    36. {
    37. hboxLayout = new QHBoxLayout(this->ui.framePlot);
    38. qwtPlot = new QwtPlot(this->ui.framePlot);
    39. qwtPlot->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
    40. hboxLayout->addWidget(qwtPlot);
    41.  
    42. /**
    43. Here i don't understand what is the dependency beetwen
    44. this variable (m_DataRange) which i use to create colormap
    45. and the method range() in SpectrogramData.
    46.  
    47. I want on the scale to have range the same as the range of data i have
    48. in the SpectrogramData class, so from 0.0 to 0.2;
    49. */
    50. m_DataRange = new QwtDoubleInterval(0,0.2);
    51.  
    52. m_spectrogram = new QwtPlotSpectrogram();
    53. m_colorMap = NULL;
    54. setColorMap(standard);
    55. m_spectrogram->attach(qwtPlot);
    56. }
    57.  
    58. void QwtSpectrogramPlot::setDataRange(double min, double max)
    59. {
    60. m_DataRange->setInterval(min,max);
    61. }
    62.  
    63. void QwtSpectrogramPlot::setDataMax(double max)
    64. {
    65. m_DataRange->setMaxValue(max);
    66. }
    67.  
    68. void QwtSpectrogramPlot::setDataMin(double min)
    69. {
    70. m_DataRange->setMinValue(min);
    71. }
    72.  
    73. void QwtSpectrogramPlot::setColorMap(colormap map)
    74. {
    75. m_colormap = map;
    76. initColorMap();
    77. }
    78.  
    79. void QwtSpectrogramPlot::initColorMap()
    80. {
    81. if (m_colorMap != NULL) delete m_colorMap;
    82.  
    83. double half = (m_DataRange->maxValue() - m_DataRange->minValue() ) / 2.0;
    84.  
    85. switch (m_colormap)
    86. {
    87. case standard:
    88. m_colorMap = new QwtLinearColorMap(Qt::darkCyan, Qt::red);
    89. m_colorMap->addColorStop(m_DataRange->minValue(), Qt::cyan);
    90. m_colorMap->addColorStop(half, Qt::green);
    91. m_colorMap->addColorStop(m_DataRange->maxValue(), Qt::yellow);
    92. break;
    93. case gray:
    94. m_colorMap = new QwtLinearColorMap(Qt::black, Qt::white);
    95. break;
    96. }
    97. m_spectrogram->setColorMap( (*m_colorMap) );
    98. }
    99.  
    100. void QwtSpectrogramPlot::rescale()
    101. {
    102. initColorMap();
    103. }
    104.  
    105. void QwtSpectrogramPlot::SetData(Point2D<double>** newData, int size_x, int size_y)
    106. {
    107.  
    108. m_RasterData.setData(newData, size_x, size_y);
    109. m_spectrogram->setData(m_RasterData);
    110. qwtPlot->replot();
    111.  
    112. }
    113.  
    114. void QwtSpectrogramPlot::on_Solve_pushButton_clicked()
    115. {
    116. solver->initializeDensity(&param);
    117. for (int i = 0; i < 100; i++)
    118. solver->doSolve(&obstacle,&param);
    119. }
    To copy to clipboard, switch view to plain text mode 

    qwtspectrogramdata.h
    Qt Code:
    1. #ifndef SPECTROGRAMDATA_H
    2. #define SPECTROGRAMDATA_H
    3.  
    4. #include <QObject>
    5. #include "Point2D.h"
    6. #include "qwt_raster_data.h"
    7. #include <fstream>
    8.  
    9. typedef Point2D<double> Data;
    10.  
    11. class SpectrogramData : public QwtRasterData
    12. {
    13. public:
    14. SpectrogramData(QObject* parent = 0);
    15. /**
    16. size_x - x size of the data stored in matrix i want to display (matrix[x][y])
    17. size_y - y size of the data stored in matrix i want to dispaly
    18. */
    19. SpectrogramData(int size_x, int size_y, QObject* parent = 0);
    20. virtual QwtRasterData *copy() const;
    21. ~SpectrogramData();
    22.  
    23. void setXSize(int size_x);
    24. void setYSize(int size_y);
    25. int getXSize();
    26. int getYSize();
    27.  
    28. void setRange(QwtDoubleInterval range);
    29. void setRange(double min, double max);
    30.  
    31. /**
    32. Range od data i have in the matrix;
    33. They are not bigger than 0.2 so for now i
    34. hardcode it as return QwtDoubleInterval(0.0, 0.2);
    35. */
    36. virtual QwtDoubleInterval range() const;
    37.  
    38. /**
    39. How to do resampling to next neighboor there??
    40. */
    41. double value (double x, double y) const;
    42.  
    43. /**
    44. get newData and place it to the SpectrogramData matrix
    45. */
    46. void setData(Point2D<double>** newData, int size_x, int size_y);
    47.  
    48. private:
    49. /**
    50. My data, it is simply 2D table with some additional methods
    51. */
    52. Data** data;
    53. /**
    54. x and y size of the Data** data table;
    55. */
    56. int lx;
    57. int ly;
    58.  
    59. //?? data range sored in the Data** data table it is from 0 to 0.2;
    60. QwtDoubleInterval* dataRange;
    61.  
    62. void deleteTable();
    63. void createTable();
    64.  
    65. };
    66. #endif // SPECTROGRAMDATA_H
    To copy to clipboard, switch view to plain text mode 

    qwtspectrogramdata.cpp
    Qt Code:
    1. #include "spectrogramdata.h"
    2.  
    3. SpectrogramData::SpectrogramData(QObject* parent)
    4. : QwtRasterData(QwtDoubleRect(0.0,0.0,0.0,0.0))
    5. {
    6.  
    7. data = NULL;
    8. dataRange = new QwtDoubleInterval(0.0,0.0);
    9. lx = 0;
    10. ly = 0;
    11. }
    12.  
    13. SpectrogramData::SpectrogramData(int size_x, int size_y, QObject* parent)
    14. : QwtRasterData(QwtDoubleRect(0.0,0.0,
    15. static_cast<double>(size_x),
    16. static_cast<double>(size_y)))
    17. {
    18. data = NULL;
    19. dataRange = new QwtDoubleInterval(0.0,0.0);
    20. lx = size_x;
    21. ly = size_y;
    22. }
    23.  
    24. QwtRasterData* SpectrogramData::copy() const
    25. {
    26. SpectrogramData* clone = new SpectrogramData(lx, ly);
    27. clone->setData(data,lx,ly);
    28. clone->setRange(lx, ly);
    29. return clone;
    30. }
    31.  
    32. SpectrogramData::~SpectrogramData()
    33. {
    34. delete dataRange;
    35. }
    36.  
    37. QwtDoubleInterval SpectrogramData::range() const
    38. {
    39. return QwtDoubleInterval(0.0, 0.15);
    40. }
    41.  
    42. double SpectrogramData::value(double x, double y) const
    43. {
    44. /**
    45. How to do resampling ?
    46. */
    47. int x_pos = static_cast<int>(x);
    48. int y_pos = static_cast<int>(y);
    49. return data[x_pos][y_pos].getMagnitude();
    50.  
    51. }
    52.  
    53. void SpectrogramData::setData(Point2D<double> **newData, int size_x, int size_y)
    54. {
    55. lx = size_x;
    56. ly = size_y;
    57.  
    58. /**
    59. Just get the pointer to the new calculated values;
    60. */
    61. data = newData;
    62. }
    63.  
    64. /**
    65. My additional methods
    66. */
    67. }
    To copy to clipboard, switch view to plain text mode 

    Tahnk you very much for your any hints and help

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

    Default Re: Spectrogram Plot Hints

    Imagine a GIS application with the longitude/latitude as coordinate system. You have bought elevation data with a resolution of 100x100 m for your country and data with a higher resolution ( 10x10 m ) for your hometown.

    The user of the GIS application navigates across the whole world - also to places, where you don't have any values. So the elevation data object needs to tell the plot widget about the area, where it has values: QwtRasterData::boundingRect().

    Your elevation data is by far too much to load it in memory at once. So the raster data object needs to know the area, that is currently displayed in the plot widget to build its raster in memory. That's what QwtRasterData::initRaster/discardRaster is about.

    The image, that is rendered from the elevation data is also a raster - but one with different pixel positions and sizes ( depending on the size of the plot widget and the area, that is currently displayed ) Mapping raster data from one resolution into another is called resampling. The most easiest way of resampling is next neighbor ( using the value of the closest point in the source raster ), but f.e. you could also use the average value of the 4 neighbored points.

    It doesn't make sense to render an image in a higher resolution, than the elevation data can offer values. To avoid this the raster data object can recommend a resolution for a specific area with QwtRasterData::rasterHint. Think about printing your scene to a A0 plotter with 1200dpi and you will understand why this optimization might be important.

    Uwe

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

    Default Re: Spectrogram Plot Hints

    Thank you very much Uwe. Now spectrogram and its data is little bit more clear for me.

Similar Threads

  1. Put plot axis out of the plot
    By KosyakOFF in forum Qwt
    Replies: 7
    Last Post: 21st June 2013, 14:36
  2. Replies: 7
    Last Post: 22nd September 2008, 23:05
  3. Replies: 6
    Last Post: 17th June 2008, 08:28

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.