QwtPlotSpectrogram 不起作用(没有 ImageMode 图)
QwtPlotSpectrogram doesn't work (no ImageMode plot)
我正在尝试使用 QwtPlotSpectogram 库创建一些 (x,y,value) 数据的简单彩色 "spectrogram" 样式图。源数据是双精度数组。我不需要轮廓线,只需要代表每个 x,y 点值的彩色像素网格。
我找到了一个例子here,我稍微修改了一下,我也写了一个类似的东西。在这两种情况下,我都遇到了同样的问题 - 我看到等高线(如果我使用 "setDisplayMode(QwtPlotSpectrogram::ContourMode, on)" ),但无论我设置什么(例如 "setDisplayMode(QwtPlotSpectrogram::ImageMode, on)" ),我都不会得到任何彩色频谱图。我确实得到了空轴和右侧的颜色条。在下面的示例中,当调用 "showContour(true)" 槽时我得到了一些轮廓,但是如果使用 "showContour(false)" 和 "showSpectrogram(true)" 则得到一个空图。
我在我的 QwtRasterData class 实现中添加了一些调试,以便在调用 "initRaster" 时收到一条消息 - 即当绘图引擎要求绘制数据时(我猜?)。启用轮廓时弹出此消息,但在仅启用 ImageMode 时从未显示 - 所以看起来根本没有尝试绘制我的数据!
我错过了什么吗?我查看了几个示例(数量不多,它们与我所拥有的相似)并通读了 QwtPlotSpectrogram reference 但无法弄清楚。请注意,我已经从示例中删除了缩放器和平移器,因为我不需要它们...希望它们不是必需的?
这是我的示例频谱图 class:
// TestSpectrogram.h
class SpectrogramData;
class TestSpectrogram: public QwtPlot
{
Q_OBJECT
public:
TestSpectrogram(QWidget * = NULL);
public slots:
void showContour(bool on);
void showSpectrogram(bool on);
private:
QwtPlotSpectrogram *d_spectrogram;
SpectrogramData *d_data;
QwtLinearColorMap *colorMap;
QwtScaleDraw *sd;
};
//---------------------------------
// TestSpectrogram.cpp
// ======= Raster Data ======================================================
class SpectrogramData: public QwtRasterData
{
public:
SpectrogramData():
QwtRasterData()
{
}
virtual QwtRasterData *copy() const
{
return new SpectrogramData();
}
virtual QwtInterval range() const
{
return QwtInterval(0.0, 10.0);
}
virtual double value(double x, double y) const
{
// Some fake data:
const double c = 0.842;
const double v1 = x * x + (y-c) * (y+c);
const double v2 = x * (y+c) + x * (y+c);
return 1.0 / (v1 * v1 + v2 * v2);
}
};
//========== Spectrogram Plot Example ====================================
TestSpectrogram::TestSpectrogram(QWidget *parent):
QwtPlot(parent)
{
d_spectrogram = new QwtPlotSpectrogram();
colorMap = new QwtLinearColorMap(Qt::darkCyan, Qt::red);
colorMap->addColorStop(0.1, Qt::cyan);
colorMap->addColorStop(0.6, Qt::green);
colorMap->addColorStop(0.95, Qt::yellow);
d_spectrogram->setColorMap( colorMap );
d_data = new SpectrogramData();
d_spectrogram->setData(d_data);
d_spectrogram->attach(this);
QList<double> contourLevels;
for ( double level = 0.0; level < 1.0; level += 0.5 ) contourLevels.append(level);
d_spectrogram->setContourLevels(contourLevels);
// A color bar on the right axis
QwtScaleWidget *rightAxis = axisWidget(QwtPlot::yRight);
rightAxis->setTitle("Intensity");
rightAxis->setColorBarEnabled(true);
rightAxis->setColorMap( d_data->range(), colorMap );
setAxisScale(QwtPlot::yRight, 0.0,10.0 );
enableAxis(QwtPlot::yRight);
plotLayout()->setAlignCanvasToScales(true);
replot();
}
void TestSpectrogram::showContour(bool on)
{
d_spectrogram->setDisplayMode(QwtPlotSpectrogram::ContourMode, on);
replot();
}
void TestSpectrogram::showSpectrogram(bool on)
{
d_spectrogram->setDisplayMode(QwtPlotSpectrogram::ImageMode, on);
d_spectrogram->setDefaultContourPen(on ? QPen() : QPen(Qt::NoPen));
replot();
}
在我的 UI 中,我有一个要在其中显示情节的框架,以及几个用于测试的复选框。我像这样设置绘图和复选框:
TestSpectrogram *d_plot; // In header.
d_plot = new TestSpectrogram( ui->framePlot );
connect( ui->checkTestImage, SIGNAL(toggled(bool)), d_plot, SLOT(showSpectrogram(bool)) );
connect( ui->checkTestContour, SIGNAL(toggled(bool)), d_plot, SLOT(showContour(bool)) );
其他信息:
Qt:5.4.0(MinGW 4.9 32 位)
Qwt:6.1.2
Windows7
我的解决办法原来是我没有调用setInterval方法
QwtRasterData 对象(上例中 SpectrogramData 的基础)。
我在 SpectrogramData 的构造函数中添加了以下内容,它起作用了(我得到了彩色频谱图):
setInterval( Qt::XAxis, QwtInterval(-1.0, 1.0) );
setInterval( Qt::YAxis, QwtInterval(-1.0, 1.0) );
setInterval( Qt::ZAxis, QwtInterval(0.0, 10.0) );
看来你需要告诉它z轴、y轴和z轴的轴距,否则它甚至不会尝试调用栅格数据对象的value方法- 至少在 Qwt 6.1.2 中 - 没有绘制任何东西。
我看了几个例子,只有一个使用了setInterval;此外,Qwt 文档非常模糊:"Set the bounding interval for the x, y or z coordinates." - 没有进一步解释为什么需要这样做。
我正在尝试使用 QwtPlotSpectogram 库创建一些 (x,y,value) 数据的简单彩色 "spectrogram" 样式图。源数据是双精度数组。我不需要轮廓线,只需要代表每个 x,y 点值的彩色像素网格。
我找到了一个例子here,我稍微修改了一下,我也写了一个类似的东西。在这两种情况下,我都遇到了同样的问题 - 我看到等高线(如果我使用 "setDisplayMode(QwtPlotSpectrogram::ContourMode, on)" ),但无论我设置什么(例如 "setDisplayMode(QwtPlotSpectrogram::ImageMode, on)" ),我都不会得到任何彩色频谱图。我确实得到了空轴和右侧的颜色条。在下面的示例中,当调用 "showContour(true)" 槽时我得到了一些轮廓,但是如果使用 "showContour(false)" 和 "showSpectrogram(true)" 则得到一个空图。
我在我的 QwtRasterData class 实现中添加了一些调试,以便在调用 "initRaster" 时收到一条消息 - 即当绘图引擎要求绘制数据时(我猜?)。启用轮廓时弹出此消息,但在仅启用 ImageMode 时从未显示 - 所以看起来根本没有尝试绘制我的数据!
我错过了什么吗?我查看了几个示例(数量不多,它们与我所拥有的相似)并通读了 QwtPlotSpectrogram reference 但无法弄清楚。请注意,我已经从示例中删除了缩放器和平移器,因为我不需要它们...希望它们不是必需的?
这是我的示例频谱图 class:
// TestSpectrogram.h
class SpectrogramData;
class TestSpectrogram: public QwtPlot
{
Q_OBJECT
public:
TestSpectrogram(QWidget * = NULL);
public slots:
void showContour(bool on);
void showSpectrogram(bool on);
private:
QwtPlotSpectrogram *d_spectrogram;
SpectrogramData *d_data;
QwtLinearColorMap *colorMap;
QwtScaleDraw *sd;
};
//---------------------------------
// TestSpectrogram.cpp
// ======= Raster Data ======================================================
class SpectrogramData: public QwtRasterData
{
public:
SpectrogramData():
QwtRasterData()
{
}
virtual QwtRasterData *copy() const
{
return new SpectrogramData();
}
virtual QwtInterval range() const
{
return QwtInterval(0.0, 10.0);
}
virtual double value(double x, double y) const
{
// Some fake data:
const double c = 0.842;
const double v1 = x * x + (y-c) * (y+c);
const double v2 = x * (y+c) + x * (y+c);
return 1.0 / (v1 * v1 + v2 * v2);
}
};
//========== Spectrogram Plot Example ====================================
TestSpectrogram::TestSpectrogram(QWidget *parent):
QwtPlot(parent)
{
d_spectrogram = new QwtPlotSpectrogram();
colorMap = new QwtLinearColorMap(Qt::darkCyan, Qt::red);
colorMap->addColorStop(0.1, Qt::cyan);
colorMap->addColorStop(0.6, Qt::green);
colorMap->addColorStop(0.95, Qt::yellow);
d_spectrogram->setColorMap( colorMap );
d_data = new SpectrogramData();
d_spectrogram->setData(d_data);
d_spectrogram->attach(this);
QList<double> contourLevels;
for ( double level = 0.0; level < 1.0; level += 0.5 ) contourLevels.append(level);
d_spectrogram->setContourLevels(contourLevels);
// A color bar on the right axis
QwtScaleWidget *rightAxis = axisWidget(QwtPlot::yRight);
rightAxis->setTitle("Intensity");
rightAxis->setColorBarEnabled(true);
rightAxis->setColorMap( d_data->range(), colorMap );
setAxisScale(QwtPlot::yRight, 0.0,10.0 );
enableAxis(QwtPlot::yRight);
plotLayout()->setAlignCanvasToScales(true);
replot();
}
void TestSpectrogram::showContour(bool on)
{
d_spectrogram->setDisplayMode(QwtPlotSpectrogram::ContourMode, on);
replot();
}
void TestSpectrogram::showSpectrogram(bool on)
{
d_spectrogram->setDisplayMode(QwtPlotSpectrogram::ImageMode, on);
d_spectrogram->setDefaultContourPen(on ? QPen() : QPen(Qt::NoPen));
replot();
}
在我的 UI 中,我有一个要在其中显示情节的框架,以及几个用于测试的复选框。我像这样设置绘图和复选框:
TestSpectrogram *d_plot; // In header.
d_plot = new TestSpectrogram( ui->framePlot );
connect( ui->checkTestImage, SIGNAL(toggled(bool)), d_plot, SLOT(showSpectrogram(bool)) );
connect( ui->checkTestContour, SIGNAL(toggled(bool)), d_plot, SLOT(showContour(bool)) );
其他信息: Qt:5.4.0(MinGW 4.9 32 位) Qwt:6.1.2 Windows7
我的解决办法原来是我没有调用setInterval方法 QwtRasterData 对象(上例中 SpectrogramData 的基础)。
我在 SpectrogramData 的构造函数中添加了以下内容,它起作用了(我得到了彩色频谱图):
setInterval( Qt::XAxis, QwtInterval(-1.0, 1.0) );
setInterval( Qt::YAxis, QwtInterval(-1.0, 1.0) );
setInterval( Qt::ZAxis, QwtInterval(0.0, 10.0) );
看来你需要告诉它z轴、y轴和z轴的轴距,否则它甚至不会尝试调用栅格数据对象的value方法- 至少在 Qwt 6.1.2 中 - 没有绘制任何东西。
我看了几个例子,只有一个使用了setInterval;此外,Qwt 文档非常模糊:"Set the bounding interval for the x, y or z coordinates." - 没有进一步解释为什么需要这样做。