QCustomPlot Discussion and Comments

Overlaping plotsReturn to overview

Hi !

I have multiple independents plots that are, for the moment, one below the other in a vertical layout. Nothing special.

Now, I want to have the same organization, but allow the plot to be partially on top of each other. I think an example would be better to explain: https://en.wikipedia.org/wiki/Electroencephalography#/media/File:Spike-waves.png

Here, the plot all start at fixed positions relative to the window, but the data can be draw over the data of other plot.

My actual plots already have a transparent background. But I don't know how to allow multiple plots to overlap each other. I don't know if it's even possible...
Do you have any tips to achieve something like this ?

Quick proposition :
- each graph must have its own value axis and share the same key axis
- you will have to estimate the range of each value axis based on the default initial range (expected normal values), and the graph index (vertical position)

Let's say you have 4 graphs, each with a default initial range between 0 and 1, the real ranges would be :
Top graph - index 3 - [-3,1]
graph - index 2 - [-2,2]
graph - index 1 - [-1,3]
Bottom graph - index 0 - [0,3]

So put all graph in the same plot but shifting one of their axis ? That could work.
In that case, if I use addGraph() for each dataset, how do I shift the axis in the plot ?

For each graph :
- add an axis
- create a graph linked to this axis and the key axis

// get the axis rect
QCPAxisRect *axisRect= mPlot->axisRect();
// create a new value axis
QCPAxis *myAxis = axisRect->addAxis(QCPAxis::atLeft);
// create a graph
QCPGraph *newGraph = new QCPGraph(myAxis , axisRect->axis(QCPAxis::atBottom));

Small test based on plot-examples.pro

void MainWindow::setupRealtimeDataDemo(QCustomPlot *customPlot)
    demoName = "Real Time Data Demo";

    int nbGraphs = 8;
    QCPRange defaultRange(-1.,1.);
    for(int i=0; i< nbGraphs; i++) {
        QCPAxis *axis = customPlot->axisRect()->addAxis(QCPAxis::atLeft);
        axis->setRange(defaultRange.lower - (nbGraphs - 1 - i) * defaultRange.size(),
                       defaultRange.upper + i*defaultRange.size());
        QCPGraph *graph = new QCPGraph( customPlot->xAxis, axis);

        QCPItemText *text = new QCPItemText(customPlot);
        text->setText(QString("Graph %1").arg(i));
        text->position->setAxes(nullptr, axis);
        text->position->setCoords(0, defaultRange.center());
        text->setPadding(QMargins(3, 0, 3, 0));

        double currentHueAngle = 137.50776 * i;
        int h = int( fmod( currentHueAngle, 360.0 ) );
        int s = 127;
        int v = 242;
        graph->setPen(QPen(QColor::fromHsv( h, s, v )));

    QSharedPointer<QCPAxisTickerDateTime> timeTicker(new QCPAxisTickerDateTime);


    connect(&dataTimer, SIGNAL(timeout()), this, SLOT(realtimeDataSlot()));
    dataTimer.start(20); // 50Hz

void MainWindow::realtimeDataSlot()
    double key = QDateTime::currentMSecsSinceEpoch()/1000.0;

    for(int i=0; i< ui->customPlot->graphCount(); i++) {
        ui->customPlot->graph(i)->addData(key, qSin(key + (i%4 * M_PI_4)) + QRandomGenerator::global()->generateDouble());
        ui->customPlot->graph(i)->data()->removeBefore(key - 30.);

    ui->customPlot->axisRect()->axis(QCPAxis::atBottom)->setRange(key - 30., key);