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