Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Resetting Plots in QCustomPlot



  • Hello,

    I am using the realtime plot example from QCustomPlot to plot my sensor readings. In my application there is the possibility to "reset" the plot without exiting the program. So when clicking on reset, the timer (QElapsedTimer) gets invalidate and the static lastPointKey is set to zero, else it would count further because it is static. So this slot is called everytime when new values are available (every one second):

    oid Plotter::updatePlots(float data){
     
        static double lastPointKey = 0;
         
        // This if statement is true, when the reset button is clicked 
        if(!timer.isValid()){
            timer.start();
            lastPointKey = 0;
        }
     
        //Calculate two new data points
        double key = timer.elapsed()/1000.0;
     
        if (key-lastPointKey > 0.002) // at most add point every 2 ms
        {
           // plotting the points here
           // [...]
            lastPointKey = key;
        }
        ui->plot_acceleration->replot();
     
    }
    

    So, when the user hits the reset button, the plots (graphs) are deleted, and I set the timer to invalidate like this timer.invalidate();

    When I start the program for the first time, everything is fine and the plot looks like this.
    However, when I reset the plot i.e. after 1 minute and then start again, it seems that the plotted points are plotted more then once and it loks like that, but it should be looking like the first screenshot. The weird thing is now,
    After the one minute has passed (duration of the first plot), the plot is displayed correctly again. So I think it could be the variable lastPointKey or my timer. Does anyone have an idea what the problem might be?



  • Okay, I could fix the issue. The problem was my statement for resetting the plot.
    I used the following:

        for( int g=0; g<3; g++ )
        {
            ui->plot_acceleration->graph(g)->data().clear();
        }
    
        ui->plot_acceleration->replot();
    

    Then I tried the following like it is mentioned here:

    pq_plot->graph(g)->data().data().clear();
    

    But then the error occurs:

    error: member reference type 'QCPDataContainer<QCPGraphData> *' is a pointer; did you mean to use '->'?
    

    Then I used the autocorrection of Qt creator ('->' instead of ' . ')

        for( int g=0; g<3; g++ )
        {
            ui->plot_acceleration->graph(g)->data().data()->clear();
        }
    
        ui->plot_acceleration->replot();
    

    And it is working now. Still don't know what exactly happens with the plot, when I use the first statement... When I use the first statement the plots are also gone after clicking on reset...


  • Lifetime Qt Champion

    Hi,

    Why use a static variable for that ?
    What does trigger that method ?



  • @SGaist Hey,

    I uses this as static as in the example from the official QCustomPlot. I think this is used to make sure that points are plotted not too often (maximum every 2 ms). But I made a test and removed the whole variable - and the problem still appears, so either it has to do something with the timer or it is a QCustomPlot issue.

    Well, when I receive the raw data, I calculate the correct values and put them in a Map, after that I call the following SLOT, to print the numerical values in my QTableWidget and in this slot I call my updatePlots function to plot these values:

    void PlotterController::updateData(QMap<QString, float> data){
    
        ui->dataTable->setItem(0,0, new QTableWidgetItem(QString::number(data["acc_x"])));
        ui->dataTable->setItem(1,0, new QTableWidgetItem(QString::number(data["acc_y"])));
        ui->dataTable->setItem(2,0, new QTableWidgetItem(QString::number(data["acc_z"])));
    
        updatePlots(data);
    }
    
    Sorry, in the above code of my first post i worte "float data" as the functions parameter for easying the issue, but actually it is a map..
    
    
    
    

  • Lifetime Qt Champion

    Is that data coming from a different thread ?



  • @SGaist No, I do not use any extra threads.. I do not know why this issue only appears when I click on the reset button and start again... When I exit the application every time and start again, everything's fine. This is how I reset the plot, but I don't think that this causes the issue:

        for( int g=0; g<3; g++ )
        {
            ui->plot_acceleration->graph(g)->data().clear();
        }
    
        ui->plot_acceleration->replot();
        ui->dataTable->clearContents();
    

    EDIT: Btw, here is the example of QCusttomPlot real time plot



  • Okay, I could fix the issue. The problem was my statement for resetting the plot.
    I used the following:

        for( int g=0; g<3; g++ )
        {
            ui->plot_acceleration->graph(g)->data().clear();
        }
    
        ui->plot_acceleration->replot();
    

    Then I tried the following like it is mentioned here:

    pq_plot->graph(g)->data().data().clear();
    

    But then the error occurs:

    error: member reference type 'QCPDataContainer<QCPGraphData> *' is a pointer; did you mean to use '->'?
    

    Then I used the autocorrection of Qt creator ('->' instead of ' . ')

        for( int g=0; g<3; g++ )
        {
            ui->plot_acceleration->graph(g)->data().data()->clear();
        }
    
        ui->plot_acceleration->replot();
    

    And it is working now. Still don't know what exactly happens with the plot, when I use the first statement... When I use the first statement the plots are also gone after clicking on reset...