QCustomPlot Discussion and Comments

QCustomPlot high CPU usageReturn to overview

Hello,

I managed to plot 4 graphs in real-time with an update of 1 Hz. Each plot contains only a few sets of points. When the program launched, the CPU usage increased gradually from 8% to 70%. Then the drag and drop of the graph became not very responsive though still working. May I know what might cause this high CPU usage and can improve? Thanks a lot.

Regards,
Eric

Basically, I draw arrows between each points and some simple texts around the points. But don't think that will hog the CPU... Thank you.

It could be that you forget to delete objects/data after you don't need it. Could you show some of your code so we could see where the problem lies instead of guessing.

Thank you. Below is the plot data part.

void MainWindow::plot_path()
{
QVector<double> x, y;
if (!path1.point.empty()) {
for (int i = 0; i < path1.nNum; i++) {
x.insert(i, path1.point.at(i).x);
y.insert(i, path1.point.at(i).y);
}
}

QVector<double> x2, y2;
if (!path2.point.empty()) {
for (int i = 0; i < path2.nNum; i++) {
x2.insert(i, path2.point.at(i).x);
y2.insert(i, path2.point.at(i).y);
}
}

QVector<double> x3, y3;
if (!_target.point.empty()) {
for (int i = 0; i < _target.nNum; i++) {
x3.insert(i, _target.point.at(i).x);
y3.insert(i, _target.point.at(i).y);
}
}

if (x.empty() || y.empty() || x2.empty() || y2.empty() || x3.empty() || y3.empty()) {
qDebug() << "Empty vector";
return;
}
ui->graphicsView_path->graph(0)->setPen(QPen(Qt::black, 2));
ui->graphicsView_path->graph(0)->setName("Path1");
for (int i = 0; i < path1.nNum - 1; i++) {
// Add the arrow
QCPItemLine *arrow = new QCPItemLine(ui->graphicsView_path);
ui->graphicsView_path->addItem(arrow);

arrow->start->setCoords(x.at(i), y.at(i));
arrow->end->setCoords(x.at(i+1), y.at(i+1));
arrow->setPen(QPen(Qt::black, 1, Qt::SolidLine));

arrow->setHead(QCPLineEnding::esSpikeArrow);

// Add the point number text label
QCPItemText *text = new QCPItemText(ui->graphicsView_path);
ui->graphicsView_path->addItem(text);
text->position->setCoords(x.at(i) + 0.2, y.at(i) + 0.5);
text->setText(QString::number(i));
text->setFont(QFont("times", 12));
text->setPen(QPen(Qt::black));
}

/// Plot the 2nd path points
ui->graphicsView_path->graph(1)->setPen(QPen(Qt::red, 2));
ui->graphicsView_path->graph(1)->setName("Path2");
for (int i = 0; i < path2.nNum - 1; i++) {
// Add the arrow
QCPItemLine *arrow2 = new QCPItemLine(ui->graphicsView_path);
ui->graphicsView_path->addItem(arrow2);

arrow2->start->setCoords(x2.at(i), y2.at(i));
arrow2->end->setCoords(x2.at(i+1), y2.at(i+1));

arrow2->setPen(QPen(Qt::red, 1, Qt::SolidLine));
arrow2->setHead(QCPLineEnding::esLineArrow);

// Add the point number text label
QCPItemText *text2 = new QCPItemText(ui->graphicsView_path);
ui->graphicsView_path->addItem(text2);
text2->position->setCoords(x2.at(i) - 0.2, y2.at(i) - 0.5);
text2->setFont(QFont(font().family(), 12));
text2->setColor(Qt::red);
text2->setText(QString::number(i));
text2->setPen(QPen(Qt::red));
}

/// Display the targets
ui->graphicsView_path->graph(2)->addData(y3, x3);
ui->graphicsView_path->graph(2)->setPen(QPen(Qt::blue));
ui->graphicsView_path->graph(2)->setLineStyle(QCPGraph::lsNone);
ui->graphicsView_path->graph(2)->setScatterStyle(QCPScatterStyle::ssTriangle);
ui->graphicsView_path->graph(2)->setName("Targets");

static bool bSetScale = false;
if (!bSetScale) {
ui->graphicsView_path->xAxis->setRange(-50, 50);
ui->graphicsView_path->yAxis->setRange(-50, 50);
bSetScale = true;
}

ui->graphicsView_path->replot();

x.clear(); y.clear();
x2.clear(); y2.clear();
x3.clear(); y3.clear();

path1.point.clear();
path2.point.clear();
_target.point.clear();
}

Well i can't see that you delete any objects only clear vectors.
Try to call int QCustomPlot::clearItems ( )
before you call methods that add new plottables(graphs, arrows, ect.)
And for future reference you can also delete specific plottables by passing pointer or index:

bool QCustomPlot::removeItem ( QCPAbstractItem *  item) 
bool QCustomPlot::removeItem ( int  index) 

Thanks, works perfect! Really handy APIs.

Regards,
Eric

However, recreating everything at each replot is also not ideal. It's better to create your needed plottables and items when you need them the first time (e.g. in a setup function), and in the update function you only modify them (add data to graphs, move item positions around, etc.)
See the realtime data demo as example.

Thanks for the suggestion! The example is also quite informative..
Just a bit amazed at the resources such as arrows used in my program that would cause such a high CPU burden after running for a while..