QCustomPlot Discussion and Comments

Slow drag response when many points are visible on the plotReturn to overview

I want to understand how can I optimize the QCustomPlot to render many points showing on the plot at the same time.

For this particular example, I have plotted 600 000 points each on 2 seperate graphs (in total 1 200 000) points.

In my .h file, I have 2 vectors declared that hold information about all points:

QVector<double> qv_x,qv_y;
QVector<double> qv_x_voltage,qv_y_voltage;


And in my .cpp, I have the following:

    
//Append list of qv_x and qv_y which contains all current meaurement points
void MainWindow::addPoint_current(double x, double y)
{
    qv_x.append(x);
    qv_y.append(y);
}


//Append list of qv_x_voltage and qv_y_voltage which contains all voltage measuremen points
void MainWindow::addPoint_voltage(double x, double y)
{
    qv_x_voltage.append(x);
    qv_y_voltage.append(y);
}


void MainWindow::setup_graph(QCustomPlot *customPlot)
{
    current_upper_limit = 1;
    current_lower_limit = 0;

    voltage_upper_limit = 3;
    voltage_lower_limit = 0;

    QColor accentColor = QColor(Qt::red);
    QColor themeColor = QColor(Qt::white);
    QColor themeBackgroundColor = QColor(55, 57, 53);


    foreach (QCPAxisRect *rect, customPlot->axisRects())
    {
        foreach (QCPAxis *axis, rect->axes())
        {
            axis->setLabelColor(themeColor);
            axis->setBasePen(QPen(themeColor, 0));
            axis->setTickPen(QPen(themeColor, 0));
            axis->setSubTickPen(QPen(themeColor, 0));
            axis->setTickLabelColor(themeColor);
            axis->grid()->setPen(QPen(themeColor, 0.0, Qt::DotLine));
            axis->grid()->setSubGridVisible(false);

            axis->setSelectedTickLabelColor(accentColor);
            axis->setSelectedLabelColor(accentColor);
            axis->setSelectedBasePen(QPen(accentColor, 0));
            axis->setSelectedSubTickPen(QPen(accentColor, 0));
            axis->setSelectedTickPen(QPen(accentColor, 0));
        }
      }



    customPlot->setBackground(QBrush(themeBackgroundColor));

    // SETUP GRAPH 0 for Current
    customPlot->addGraph();
    customPlot->graph(0)->setScatterStyle(QCPScatterStyle::ssCircle);
    customPlot->graph(0)->setLineStyle(QCPGraph::lsLine);
    QPen pen_current;
    pen_current.setWidth(0);
    pen_current.setColor(QColor(80, 200, 120));
    customPlot->graph(0)->setPen(pen_current);



    // SETUP GRAPH 1 for Voltage
    customPlot->addGraph(customPlot->xAxis, customPlot->yAxis2);
    customPlot->graph(1)->setScatterStyle(QCPScatterStyle::ssCross);
    customPlot->graph(1)->setLineStyle(QCPGraph::lsLine);
    QPen pen_voltage;
    pen_voltage.setWidth(0);
    pen_voltage.setColor(QColor(225,225,50));
    customPlot->graph(1)->setPen(pen_voltage);


    customPlot->xAxis->setLabel("Time(h:m:s)");
    QSharedPointer<CustomTimeTicker> customTicker(new CustomTimeTicker);
    customPlot->xAxis->setTicker(customTicker);

    customPlot->yAxis->setLabel("Current (mA)");
    customPlot->yAxis->setRange(current_lower_limit, current_upper_limit);
    customPlot->yAxis2->setVisible(true);
    customPlot->yAxis2->setLabel("Voltage (V)");
    customPlot->yAxis2->setRange(voltage_lower_limit, voltage_upper_limit);

    connect(ui->customPlot->xAxis, SIGNAL(rangeChanged(QCPRange)), this, SLOT(xAxisChanged(QCPRange)));



    customPlot->legend->setVisible(true);
    customPlot->graph(0)->setName("Current");
    customPlot->graph(1)->setName("Voltage");


    customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom | QCP::iSelectPlottables | QCP::iMultiSelect);
    customPlot->setSelectionRectMode(QCP::srmSelect);

    customPlot->graph(0)->setSelectable(QCP::stDataRange);
    customPlot->graph(1)->setSelectable(QCP::stDataRange);

    customPlot->setNoAntialiasingOnDrag(true);

    foreach (QCPAxisRect *rect, customPlot->axisRects())
    {
        rect->setRangeDrag(Qt::Horizontal);
        rect->setRangeZoom(Qt::Horizontal);
    }

    for (double i = 0; i < 30000; i=i+0.05)
     {
      addPoint_voltage((i),1.0f);
      addPoint_current((i),2.0f);
     }

     customPlot->graph(1)->addData(qv_x_voltage,qv_y_voltage);
     customPlot->graph(0)->addData(qv_x,qv_y);
     customPlot->replot();
}




As you can see from the setup code above, I have the drag enabled for the xAxis. The problem that I am having is very slow and laggy response when I am trying to drag the Plot left/right. As I move my mouse around, the plot is lagging for like 3-4 seconds. If I zoom in on the plot to ensure only 1000 or so points are visible, the dragging works without any issues. It only becomes problem as I zoom out so all the plotted points are visible at once, then the QCustomPlot cannot keep up with rendering so many points as the graph is being moved.

I would like to get some advice on how to reduce the lag and slow response of plot dragging when there are many points visible on the graph.

Perhaps there is a smart way to combine some of the points to a single point when the graph is zoomed out? For example, if there are many samples on the X axis that have same or simmillar Y value, they can be all combined into a 2-3 points "averaged". This way it would be possible to significantly reduce the number of points showing on the graph.