QCustomPlot Discussion and Comments

How to draw polyline as fast as possible using QCustomPlotReturn to overview

It takes about 15 minutes to draw more than 100,000 polylines using the sample code as below.

        for (int i = 0; i < geBoom1X.size(); ++i)    //  the type of geBoom1X, geBoom2X, ..., geBoom4X is QVector.
        {
            QVector<double> x(6), y(6);

            x[0] = 1132.0;
            x[1] = geBoom1X[i];
            x[2] = geBoom2X[i];
            x[3] = geBoom3X[i];
            x[4] = geBoom4X[i];
            x[5] = geBucketX[i];

            y[0] = 910.0;
            y[1] = geBoom1Y[i];
            y[2] = geBoom2Y[i];
            y[3] = geBoom3Y[i];
            y[4] = geBoom4Y[i];
            y[5] = geBucketY[i];

            QCPCurve *curve = new QCPCurve(customPlot->xAxis, customPlot->yAxis);

            QVector<QCPCurveData> data(6);
            data[0] = QCPCurveData(0, x[0], y[0]);
            data[1] = QCPCurveData(1, x[1], y[1]);
            data[2] = QCPCurveData(2, x[2], y[2]);
            data[3] = QCPCurveData(3, x[3], y[3]);
            data[4] = QCPCurveData(4, x[4], y[4]);
            data[5] = QCPCurveData(5, x[5], y[5]);

            curve->data()->set(data, true);
            curve->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, 10));
        }

It takes about 3 seconds if I use QPainter, the sample codes is as follow.

        for (int i = 0; i < geBoom1X.size(); ++i)
        {
            QVector<double> x(6), y(6);

            x[0] = 1132.0;
            x[1] = geBoom1X[i];
            x[2] = geBoom2X[i];
            x[3] = geBoom3X[i];
            x[4] = geBoom4X[i];
            x[5] = geBucketX[i];

            y[0] = 910.0;
            y[1] = geBoom1Y[i];
            y[2] = geBoom2Y[i];
            y[3] = geBoom3Y[i];
            y[4] = geBoom4Y[i];
            y[5] = geBucketY[i];

            QPointF points[] = {
                QPointF(x[0], y[0]),
                QPointF(x[1], y[1]),
                QPointF(x[2], y[2]),
                QPointF(x[3], y[3]),
                QPointF(x[4], y[4]),
                QPointF(x[5], y[5])
            };
            painter.drawPolyline(points, 6);   // the type of painter is QPainter.
        }

May i ask how to draw thousands of polylines using QCustomPlot?

Thank you very much.

use QCPGraph instead of QCPCurve

You're not just drawing 100k polylines, you're creating 20k (or so) instances of QCPCurve every time.

Two suggestions: Use one QCPGraph if your use case allows (i.e. continuously increasing key coordinate across all polylines), or at least only one QCPCurve, and separate the data points of each line by one NaN-valued data point. This way they're not connected but can profit from QCP's optimizations.

Alternatively, and probably more appropriate, create your own plottable (QCPAbstractPlottable subclass) which you can optimize for your special use case, and there you can just draw with the painter as you did.

@lancelot

In fact, I tried using QCPGraph at first. But I have trouble with it. For example, if I have three points: p1(1.0, 1.0), p2(2.0, 5.0), p3(3.0, 3.0), and I want to get a polyline p1-->p3-->p2, not p1-->p2-->p3. So, the similar codes as below were used:

QVector x(3), y(3);
x[0] = 1.0, y[0] = 1.0; // p1
x[1] = 3.0, y[1] = 3.0; // p3
x[2] = 2.0, y[2] = 5.0; // p2
customPlot->graph(0)->setData(x, y);

I still get a polyline p1-->p2-->p3, it seems that the keys are sorted automatically.

Is it possible to get a polyline p1-->p3-->p2 with GCPGraph? I am newbie to QCustomPlot.

Thanks.

@Manu

The reason why I do not use QCPGraph, please see the reply to Lancelot.
I tried to use only one QCPCurve, but I did not get the result I needed.

Let me try to subclass QCPAbstractPlottable, thank you for giving the direction.

setData(x,y,true)

@ Manu

I created my own plottable, which is inherited from QCPAbstractPlottable. And I overrided the pure virtual functions in QCPAbstractPlottable.

But I did not get any graphs when running the program. The code in draw(QCPPainter *painter) function is as below.

void QCPPolyline::draw(QCPPainter *painter)
{
    QPen pen;
    pen.setWidth(40);
    pen.setColor(Qt::red);
    pen.setStyle(Qt::SolidLine);
    painter->setPen(pen);

    QVector<double>& geBoom1X = mReader->geBoom1X();
    QVector<double>& geBoom1Y = mReader->geBoom1Y();
    QVector<double>& geBoom2X = mReader->geBoom2X();
    QVector<double>& geBoom2Y = mReader->geBoom2Y();
    QVector<double>& geBoom3X = mReader->geBoom3X();
    QVector<double>& geBoom3Y = mReader->geBoom3Y();
    QVector<double>& geBoom4X = mReader->geBoom4X();
    QVector<double>& geBoom4Y = mReader->geBoom4Y();
    QVector<double>& geBucketX= mReader->geBucketX();
    QVector<double>& geBucketY= mReader->geBucketY();


    for (int i = 0; i < geBoom1X.size(); ++i)
    {
        QVector<double> x(6), y(6);

        x[0] = 1132.0;
        x[1] = geBoom1X[i];
        x[2] = geBoom2X[i];
        x[3] = geBoom3X[i];
        x[4] = geBoom4X[i];
        x[5] = geBucketX[i];

        y[0] = 910.0;
        y[1] = geBoom1Y[i];
        y[2] = geBoom2Y[i];
        y[3] = geBoom3Y[i];
        y[4] = geBoom4Y[i];
        y[5] = geBucketY[i];

        QPointF points[] = {
            QPointF(x[0], y[0]),
            QPointF(x[1], y[1]),
            QPointF(x[2], y[2]),
            QPointF(x[3], y[3]),
            QPointF(x[4], y[4]),
            QPointF(x[5], y[5])
        };

        painter->drawPolyline(points, 6);
    }
}

I don't know why it does not work. Are there any key points I did not get.

Thanks.