QwtPlotSpectrogram не работает (без графика ImageMode)

Я пытаюсь создать простой цветной график в стиле "спектрограмма" для некоторых (x,y,value) данных, используя библиотеку QwtPlotSpectogram. Исходные данные представляют собой массив значений типа double. Мне не нужны контурные линии, просто сетка цветных пикселей, представляющая значение в каждой точке x, y.

Я нашел здесь пример, который я немного изменил, и я также написал свою собственную похожую вещь. В обоих случаях я получаю одну и ту же проблему - я вижу контурные линии (если я использую "setDisplayMode(QwtPlotSpectrogram::ContourMode, on)"), но я никогда не получаю никакого цветного графика спектрограммы, независимо от того, что я установил (например, setDisplayMode (QwtPlotSpectrogram)::ImageMode, on)"). Я получаю пустые топоры и цветную полосу справа. В приведенном ниже примере я получаю некоторые контуры, когда вызывается слот "showContour(true)", но пустой график, если используются "showContour(false)" и "showSpectrogram(true)".

Я добавил некоторую отладку в мою реализацию класса QwtRasterData, так что я получил сообщение, когда вызывался "initRaster" - то есть, когда механизм печати запрашивал данные для построения (я полагаю?). Это сообщение выскочило, когда были включены контуры, но НИКОГДА не показывалось, когда был включен только ImageMode - так что похоже, что нет никакой попытки построить мои данные вообще!

Я что-то пропустил? Я просмотрел несколько примеров (их не так много, и они похожи на те, что есть у меня) и прочитал ссылку на QwtPlotSpectrogram, но не могу понять это. Обратите внимание, что я удалил zoomer и panner из примера, так как они мне не нужны... надеюсь, они не нужны?

Вот мой пример класса спектрограммы:

// 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();
}

В моем пользовательском интерфейсе есть рамка, в которой я хочу показать график, плюс несколько флажков для тестирования. Я установил сюжет и флажки так:

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 bit) Qwt: 6.1.2 Windows 7

1 ответ

Моим решением оказалось то, что я не вызывал метод 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, в противном случае он даже не пытается вызвать метод значения объекта растровых данных - по крайней мере, в Qwt 6.1.2 - и ничего не отображается.

Я посмотрел на несколько примеров, и только один из них использовал setInterval; также документы Qwt довольно расплывчаты: "Установите ограничивающий интервал для координат x, y или z". - нет дальнейшего объяснения того, зачем это нужно.

Другие вопросы по тегам