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.
- resampling the data I have in the matrix to the position on the spectrogram area
- implement RasterHint method.
- 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
#ifndef QWTSPECTROGRAMPLOT_H
#define QWTSPECTROGRAMPLOT_H
#include <QtGui/QMainWindow>
#include "ui_qwtspectrogramplot.h"
#include <qwt_plot.h>
#include <qwt_plot_spectrogram.h>
#include <qwt_color_map.h>
#include <qwt_plot_layout.h>
#include <qwt_scale_widget.h>
#include "spectrogramdata.h"
#include "parameters.h"
#include "obstacle.h"
#include "Solver.h"
{
Q_OBJECT
public:
QwtSpectrogramPlot
(QWidget *parent
= 0, Qt
::WFlags flags
= 0);
~QwtSpectrogramPlot();
/**
Prepare the plot widget;
*/
void SetupPlot
(QMainWindow* QwtSpectrogramPolt_window
);
enum colormap{ standard, gray };
private:
/**
Here i don't understand what is the dependency beetwen
this variable (m_DataRange) which i use to create colormap
and the method range() in SpectrogramData.
*/
SpectrogramData m_RasterData;
/**
My solver which produce data for Spectrogram data.
*/
Velocity2D velocity;
Grid2D grid;
Obstacle obstacle;
Parameters param;
Solver* solver;
colormap m_colormap;
void initColorMap();
void initSolver();
Ui::QwtSpectrogramPlotClass ui;
public:
void setDataRange(double min, double max);
public slots:
void setColorMap(colormap map);
void rescale();
void setDataMax(double max);
void setDataMin(double min);
void SetData(Point2D<double>** newData, int size_x, int size_y);
private slots:
void on_Solve_pushButton_clicked();
};
#endif // QWTSPECTROGRAMPLOT_H
#ifndef QWTSPECTROGRAMPLOT_H
#define QWTSPECTROGRAMPLOT_H
#include <QtGui/QMainWindow>
#include "ui_qwtspectrogramplot.h"
#include <qwt_plot.h>
#include <qwt_plot_spectrogram.h>
#include <qwt_color_map.h>
#include <qwt_plot_layout.h>
#include <qwt_scale_widget.h>
#include "spectrogramdata.h"
#include "parameters.h"
#include "obstacle.h"
#include "Solver.h"
class QwtSpectrogramPlot : public QMainWindow
{
Q_OBJECT
public:
QwtSpectrogramPlot(QWidget *parent = 0, Qt::WFlags flags = 0);
~QwtSpectrogramPlot();
/**
Prepare the plot widget;
*/
void SetupPlot(QMainWindow* QwtSpectrogramPolt_window);
QwtPlot *qwtPlot;
QHBoxLayout *hboxLayout;
enum colormap{ standard, gray };
private:
QwtLinearColorMap* m_colorMap;
QwtPlotSpectrogram* m_spectrogram;
/**
Here i don't understand what is the dependency beetwen
this variable (m_DataRange) which i use to create colormap
and the method range() in SpectrogramData.
*/
QwtDoubleInterval* m_DataRange;
SpectrogramData m_RasterData;
/**
My solver which produce data for Spectrogram data.
*/
Velocity2D velocity;
Grid2D grid;
Obstacle obstacle;
Parameters param;
Solver* solver;
colormap m_colormap;
void initColorMap();
void initSolver();
Ui::QwtSpectrogramPlotClass ui;
public:
void setDataRange(double min, double max);
public slots:
void setColorMap(colormap map);
void rescale();
void setDataMax(double max);
void setDataMin(double min);
void SetData(Point2D<double>** newData, int size_x, int size_y);
private slots:
void on_Solve_pushButton_clicked();
};
#endif // QWTSPECTROGRAMPLOT_H
To copy to clipboard, switch view to plain text mode
qwtspectrogramplot.cpp
#include "qwtspectrogramplot.h"
#include <fstream>
QwtSpectrogramPlot
::QwtSpectrogramPlot(QWidget *parent, Qt
::WFlags flags
){
ui.setupUi(this);
SetupPlot(this);
initSolver();
QObject::connect(solver,
SIGNAL(sendData
(Point2D<double>
**,
int,
int)),
this, SLOT(SetData(Point2D<double>**, int, int)) );
}
QwtSpectrogramPlot::~QwtSpectrogramPlot()
{
delete hboxLayout;
delete m_DataRange;
delete m_colorMap;
delete m_spectrogram;
}
void QwtSpectrogramPlot::initSolver()
{
velocity.set(0.0,0.0);
grid.set(150,50);
obstacle.setSize(grid);
obstacle.initializeTable();
obstacle.readFromFile("ball.obs");
param.setDensity(1.0);
param.setOmega(1.85);
param.setVelocity(velocity);
param.setGridSize(grid);
solver = new Solver(¶m);
}
void QwtSpectrogramPlot
::SetupPlot(QMainWindow *QwtSpectrogramPlot_window
) {
/**
Here i don't understand what is the dependency beetwen
this variable (m_DataRange) which i use to create colormap
and the method range() in SpectrogramData.
I want on the scale to have range the same as the range of data i have
in the SpectrogramData class, so from 0.0 to 0.2;
*/
m_colorMap = NULL;
setColorMap(standard);
}
void QwtSpectrogramPlot::setDataRange(double min, double max)
{
m_DataRange->setInterval(min,max);
}
void QwtSpectrogramPlot::setDataMax(double max)
{
m_DataRange->setMaxValue(max);
}
void QwtSpectrogramPlot::setDataMin(double min)
{
m_DataRange->setMinValue(min);
}
void QwtSpectrogramPlot::setColorMap(colormap map)
{
m_colormap = map;
initColorMap();
}
void QwtSpectrogramPlot::initColorMap()
{
if (m_colorMap != NULL) delete m_colorMap;
double half = (m_DataRange->maxValue() - m_DataRange->minValue() ) / 2.0;
switch (m_colormap)
{
case standard:
m_colorMap->addColorStop(m_DataRange->minValue(), Qt::cyan);
m_colorMap->addColorStop(half, Qt::green);
m_colorMap->addColorStop(m_DataRange->maxValue(), Qt::yellow);
break;
case gray:
break;
}
m_spectrogram->setColorMap( (*m_colorMap) );
}
void QwtSpectrogramPlot::rescale()
{
initColorMap();
}
void QwtSpectrogramPlot::SetData(Point2D<double>** newData, int size_x, int size_y)
{
m_RasterData.setData(newData, size_x, size_y);
m_spectrogram->setData(m_RasterData);
qwtPlot->replot();
}
void QwtSpectrogramPlot::on_Solve_pushButton_clicked()
{
solver->initializeDensity(¶m);
for (int i = 0; i < 100; i++)
solver->doSolve(&obstacle,¶m);
}
#include "qwtspectrogramplot.h"
#include <fstream>
QwtSpectrogramPlot::QwtSpectrogramPlot(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);
SetupPlot(this);
initSolver();
QObject::connect(solver,SIGNAL(sendData(Point2D<double>**, int, int)),
this, SLOT(SetData(Point2D<double>**, int, int)) );
}
QwtSpectrogramPlot::~QwtSpectrogramPlot()
{
delete hboxLayout;
delete m_DataRange;
delete m_colorMap;
delete m_spectrogram;
delete qwtPlot;
}
void QwtSpectrogramPlot::initSolver()
{
velocity.set(0.0,0.0);
grid.set(150,50);
obstacle.setSize(grid);
obstacle.initializeTable();
obstacle.readFromFile("ball.obs");
param.setDensity(1.0);
param.setOmega(1.85);
param.setVelocity(velocity);
param.setGridSize(grid);
solver = new Solver(¶m);
}
void QwtSpectrogramPlot::SetupPlot(QMainWindow *QwtSpectrogramPlot_window)
{
hboxLayout = new QHBoxLayout(this->ui.framePlot);
qwtPlot = new QwtPlot(this->ui.framePlot);
qwtPlot->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
hboxLayout->addWidget(qwtPlot);
/**
Here i don't understand what is the dependency beetwen
this variable (m_DataRange) which i use to create colormap
and the method range() in SpectrogramData.
I want on the scale to have range the same as the range of data i have
in the SpectrogramData class, so from 0.0 to 0.2;
*/
m_DataRange = new QwtDoubleInterval(0,0.2);
m_spectrogram = new QwtPlotSpectrogram();
m_colorMap = NULL;
setColorMap(standard);
m_spectrogram->attach(qwtPlot);
}
void QwtSpectrogramPlot::setDataRange(double min, double max)
{
m_DataRange->setInterval(min,max);
}
void QwtSpectrogramPlot::setDataMax(double max)
{
m_DataRange->setMaxValue(max);
}
void QwtSpectrogramPlot::setDataMin(double min)
{
m_DataRange->setMinValue(min);
}
void QwtSpectrogramPlot::setColorMap(colormap map)
{
m_colormap = map;
initColorMap();
}
void QwtSpectrogramPlot::initColorMap()
{
if (m_colorMap != NULL) delete m_colorMap;
double half = (m_DataRange->maxValue() - m_DataRange->minValue() ) / 2.0;
switch (m_colormap)
{
case standard:
m_colorMap = new QwtLinearColorMap(Qt::darkCyan, Qt::red);
m_colorMap->addColorStop(m_DataRange->minValue(), Qt::cyan);
m_colorMap->addColorStop(half, Qt::green);
m_colorMap->addColorStop(m_DataRange->maxValue(), Qt::yellow);
break;
case gray:
m_colorMap = new QwtLinearColorMap(Qt::black, Qt::white);
break;
}
m_spectrogram->setColorMap( (*m_colorMap) );
}
void QwtSpectrogramPlot::rescale()
{
initColorMap();
}
void QwtSpectrogramPlot::SetData(Point2D<double>** newData, int size_x, int size_y)
{
m_RasterData.setData(newData, size_x, size_y);
m_spectrogram->setData(m_RasterData);
qwtPlot->replot();
}
void QwtSpectrogramPlot::on_Solve_pushButton_clicked()
{
solver->initializeDensity(¶m);
for (int i = 0; i < 100; i++)
solver->doSolve(&obstacle,¶m);
}
To copy to clipboard, switch view to plain text mode
qwtspectrogramdata.h
#ifndef SPECTROGRAMDATA_H
#define SPECTROGRAMDATA_H
#include <QObject>
#include "Point2D.h"
#include "qwt_raster_data.h"
#include <fstream>
typedef Point2D<double> Data;
{
public:
SpectrogramData
(QObject* parent
= 0);
/**
size_x - x size of the data stored in matrix i want to display (matrix[x][y])
size_y - y size of the data stored in matrix i want to dispaly
*/
SpectrogramData
(int size_x,
int size_y,
QObject* parent
= 0);
~SpectrogramData();
void setXSize(int size_x);
void setYSize(int size_y);
int getXSize();
int getYSize();
void setRange(double min, double max);
/**
Range od data i have in the matrix;
They are not bigger than 0.2 so for now i
hardcode it as return QwtDoubleInterval(0.0, 0.2);
*/
/**
How to do resampling to next neighboor there??
*/
double value (double x, double y) const;
/**
get newData and place it to the SpectrogramData matrix
*/
void setData(Point2D<double>** newData, int size_x, int size_y);
private:
/**
My data, it is simply 2D table with some additional methods
*/
Data** data;
/**
x and y size of the Data** data table;
*/
int lx;
int ly;
//?? data range sored in the Data** data table it is from 0 to 0.2;
void deleteTable();
void createTable();
};
#endif // SPECTROGRAMDATA_H
#ifndef SPECTROGRAMDATA_H
#define SPECTROGRAMDATA_H
#include <QObject>
#include "Point2D.h"
#include "qwt_raster_data.h"
#include <fstream>
typedef Point2D<double> Data;
class SpectrogramData : public QwtRasterData
{
public:
SpectrogramData(QObject* parent = 0);
/**
size_x - x size of the data stored in matrix i want to display (matrix[x][y])
size_y - y size of the data stored in matrix i want to dispaly
*/
SpectrogramData(int size_x, int size_y, QObject* parent = 0);
virtual QwtRasterData *copy() const;
~SpectrogramData();
void setXSize(int size_x);
void setYSize(int size_y);
int getXSize();
int getYSize();
void setRange(QwtDoubleInterval range);
void setRange(double min, double max);
/**
Range od data i have in the matrix;
They are not bigger than 0.2 so for now i
hardcode it as return QwtDoubleInterval(0.0, 0.2);
*/
virtual QwtDoubleInterval range() const;
/**
How to do resampling to next neighboor there??
*/
double value (double x, double y) const;
/**
get newData and place it to the SpectrogramData matrix
*/
void setData(Point2D<double>** newData, int size_x, int size_y);
private:
/**
My data, it is simply 2D table with some additional methods
*/
Data** data;
/**
x and y size of the Data** data table;
*/
int lx;
int ly;
//?? data range sored in the Data** data table it is from 0 to 0.2;
QwtDoubleInterval* dataRange;
void deleteTable();
void createTable();
};
#endif // SPECTROGRAMDATA_H
To copy to clipboard, switch view to plain text mode
qwtspectrogramdata.cpp
#include "spectrogramdata.h"
SpectrogramData
::SpectrogramData(QObject* parent
){
data = NULL;
lx = 0;
ly = 0;
}
SpectrogramData
::SpectrogramData(int size_x,
int size_y,
QObject* parent
) static_cast<double>(size_x),
static_cast<double>(size_y)))
{
data = NULL;
lx = size_x;
ly = size_y;
}
{
SpectrogramData* clone = new SpectrogramData(lx, ly);
clone->setData(data,lx,ly);
clone->setRange(lx, ly);
return clone;
}
SpectrogramData::~SpectrogramData()
{
delete dataRange;
}
{
}
double SpectrogramData::value(double x, double y) const
{
/**
How to do resampling ?
*/
int x_pos = static_cast<int>(x);
int y_pos = static_cast<int>(y);
return data[x_pos][y_pos].getMagnitude();
}
void SpectrogramData::setData(Point2D<double> **newData, int size_x, int size_y)
{
lx = size_x;
ly = size_y;
/**
Just get the pointer to the new calculated values;
*/
data = newData;
}
/**
My additional methods
*/
}
#include "spectrogramdata.h"
SpectrogramData::SpectrogramData(QObject* parent)
: QwtRasterData(QwtDoubleRect(0.0,0.0,0.0,0.0))
{
data = NULL;
dataRange = new QwtDoubleInterval(0.0,0.0);
lx = 0;
ly = 0;
}
SpectrogramData::SpectrogramData(int size_x, int size_y, QObject* parent)
: QwtRasterData(QwtDoubleRect(0.0,0.0,
static_cast<double>(size_x),
static_cast<double>(size_y)))
{
data = NULL;
dataRange = new QwtDoubleInterval(0.0,0.0);
lx = size_x;
ly = size_y;
}
QwtRasterData* SpectrogramData::copy() const
{
SpectrogramData* clone = new SpectrogramData(lx, ly);
clone->setData(data,lx,ly);
clone->setRange(lx, ly);
return clone;
}
SpectrogramData::~SpectrogramData()
{
delete dataRange;
}
QwtDoubleInterval SpectrogramData::range() const
{
return QwtDoubleInterval(0.0, 0.15);
}
double SpectrogramData::value(double x, double y) const
{
/**
How to do resampling ?
*/
int x_pos = static_cast<int>(x);
int y_pos = static_cast<int>(y);
return data[x_pos][y_pos].getMagnitude();
}
void SpectrogramData::setData(Point2D<double> **newData, int size_x, int size_y)
{
lx = size_x;
ly = size_y;
/**
Just get the pointer to the new calculated values;
*/
data = newData;
}
/**
My additional methods
*/
}
To copy to clipboard, switch view to plain text mode
Tahnk you very much for your any hints and help
Bookmarks