I want to draw a spectrogram with size 2000*2000. However, i don't want the axis scale numbers to be from 0 to 2000, but rather a linear transformation, where 2000 is mapped to a certain number (e.g. 120), and the rest of the values are mapped accordingly.
I declare a
QwtPlotSpectrogram * spectrogram
To copy to clipboard, switch view to plain text mode
instance, and i use setData() function to pass a SpectrogramData instance:
private:
std::vector<std::vector<double>> data_;
public:
SpectrogramData();
~SpectrogramData();
void setData(std::vector<std::vector<double>> & data) { data_ = data; }
virtual double value(double x, double y) const{ return data_[x][y]; }
};
class SpectrogramData : public QwtMatrixRasterData, public QwtLinearScaleEngine {
private:
std::vector<std::vector<double>> data_;
public:
SpectrogramData();
~SpectrogramData();
void setData(std::vector<std::vector<double>> & data) { data_ = data; }
virtual double value(double x, double y) const{ return data_[x][y]; }
};
To copy to clipboard, switch view to plain text mode
Then i initialize the QwtPlot:
...
spectrogram_data_ = new SpectrogramData();
...
spectrogram_->setData(spectrogram_data_);
spectrogram_->attach(plot_);
plot_ = new QwtPlot(this);
...
spectrogram_ = new QwtPlotSpectrogram();
spectrogram_data_ = new SpectrogramData();
...
spectrogram_->setData(spectrogram_data_);
spectrogram_->attach(plot_);
To copy to clipboard, switch view to plain text mode
The problem is that when i draw something, i have to use setInterval() on the spectrogram_data object, but the values 0 and 2000, for min and max, that i pass in order to fully draw the 2000*2000 matrix, set the axis to 0-2000 as well. If i give smaller values to setInterval() then part of the matrix is not drawn.
What i tried is to use QwtTranform, since i want a linear transformation, but as i am given to understand, it does not behave the way i want:
class AxisTransformation : public QwtTransform {
private:
double prev_start_, prev_end_;
double new_start_, new_end_;
public:
AxisTransformation(double prev_start, double prev_end, double new_start, double new_end) : prev_start_(prev_start), prev_end_(prev_end), new_start_(new_start), new_end_(new_end) {}
virtual double transform(double value) const {
return new_value = new_start_ + (new_end_ - new_start_) * (value - prev_start_) / (prev_end_ - prev_start_);
}
virtual double invTransform(double value) const {
return new_value = prev_start_ + (prev_end_ - prev_start_) * (value - new_start_) / (new_end_ - new_start_);
}
AxisTransformation * copy() const {
return new AxisTransformation(*this);
}
};
class AxisTransformation : public QwtTransform {
private:
double prev_start_, prev_end_;
double new_start_, new_end_;
public:
AxisTransformation(double prev_start, double prev_end, double new_start, double new_end) : prev_start_(prev_start), prev_end_(prev_end), new_start_(new_start), new_end_(new_end) {}
virtual double transform(double value) const {
return new_value = new_start_ + (new_end_ - new_start_) * (value - prev_start_) / (prev_end_ - prev_start_);
}
virtual double invTransform(double value) const {
return new_value = prev_start_ + (prev_end_ - prev_start_) * (value - new_start_) / (new_end_ - new_start_);
}
AxisTransformation * copy() const {
return new AxisTransformation(*this);
}
};
To copy to clipboard, switch view to plain text mode
along with
AxisTransformation * t = new AxisTransformation(0, 2000, 0, 120);
axis_x_bottom->setTransformation(t);
AxisTransformation * t = new AxisTransformation(0, 2000, 0, 120);
QwtScaleWidget * axis_x_bottom = plot_->axisWidget(QwtPlot::xBottom);
axis_x_bottom->setTransformation(t);
To copy to clipboard, switch view to plain text mode
So how can i fully draw the 2000*2000 matrix, but specifying the axis numbers displayed to be from 0 to 120?
Bookmarks