Results 1 to 10 of 10

Thread: QChart slow when plotting large data signals

  1. #1
    Join Date
    Feb 2018
    Posts
    22
    Thanks
    4
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Windows

    Default QChart slow when plotting large data signals

    Hello.
    I have a problem with QChart.
    When i plot >3000 samples it goes incredibly slow. I tried plotting a signal with 16000 samples, which took 13 seconds to plot.

    Here is the bit that is causing problems:

    Qt Code:
    1. QLineSeries *lineseries = new QLineSeries();
    2. QScatterSeries *scatterseries = new QScatterSeries();
    3. QTime mytimer;
    4. mytimer.start();
    5. lineseries->append(ali[bandnr].toList()); // QVector<QPointF>
    6. scatterseries->append(ali[bandnr].toList());
    7. chart_->addSeries(lineseries);
    8. chart_->addSeries(scatterseries);
    9. qDebug() << "time: " << mytimer.elapsed();
    10.  
    11. scatterseries->setMarkerSize(8);
    12. scatterseries->setPen(Qt::NoPen); // do not make border around points
    13. QString name = "hello";
    14. connect(scatterseries, &QScatterSeries::clicked, this, &LinePlot::keepCallout_);
    15. connect(scatterseries, &QScatterSeries::hovered, [=](QPointF point, bool state) {this->tooltip_(point, state, name); });
    To copy to clipboard, switch view to plain text mode 
    "ali" is just a QVector<QVector<QPointF>>
    I read somewhere that appending the data to the QLineSeries/QScatterSeries before adding them to QChart would improve speed. But its the same.
    I also read that using "replace" instead of "append" should increase the speed. But it doesn't change anything.

    The reason i also add a QScatterSeries is to make my "hover" tooltip only appear on actual data points.

    I also tried QCustomPlot instead, which uses 0.142 seconds to plot the same data. Why is QChart that much slower? Is there a solution to make it faster?

    Best Regards
    DAVC

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QChart slow when plotting large data signals

    Quote Originally Posted by DAVC View Post
    I also read that using "replace" instead of "append" should increase the speed. But it doesn't change anything.
    Did you measure the time between these two steps?
    The code you posted only checks the total.


    Quote Originally Posted by DAVC View Post
    I also tried QCustomPlot instead, which uses 0.142 seconds to plot the same data. Why is QChart that much slower? Is there a solution to make it faster?
    Would probably require some profiling to see where the time is actually spent.

    Cheers,
    _

  3. #3
    Join Date
    Feb 2018
    Posts
    22
    Thanks
    4
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QChart slow when plotting large data signals

    Thank you for your reply anda_skoa!

    I think i might have misunderstood your request to begin with, but it actually returned some interesting results. I tried time the "addSeries" individually.

    Qt Code:
    1. QLineSeries *lineseries = new QLineSeries();
    2. QScatterSeries *scatterseries = new QScatterSeries();
    3. QTime mytimer;
    4. mytimer.start();
    5. lineseries->append(ali[bandnr].toList()); // QVector<QPointF>
    6. scatterseries->append(ali[bandnr].toList());
    7. qDebug() << "pre add: " << mytimer.elapsed();
    8. chart_->addSeries(lineseries);
    9. qDebug() << "series: " << mytimer.elapsed();
    10. chart_->addSeries(scatterseries);
    11. qDebug() << "scatter: " << mytimer.elapsed();
    12.  
    13. scatterseries->setMarkerSize(8);
    14. scatterseries->setPen(Qt::NoPen); // do not make border around points
    15. QString name = "hello";
    16. connect(scatterseries, &QScatterSeries::clicked, this, &LinePlot::keepCallout_);
    17. connect(scatterseries, &QScatterSeries::hovered, [=](QPointF point, bool state) {this->tooltip_(point, state, name); });
    To copy to clipboard, switch view to plain text mode 

    And to my surprise:
    Adding the QLineseries actually only takes 0.181 seconds.
    adding the QScatterseries, however, takes 13.654 seconds.

    It is QScatterSeries that is the culprit. Or maybe the fact that i am adding a second series to the same chart? I'll try switching it around.

    EDIT:
    I just tried to comment the line where i add QLineSeries. Adding QScatterSeries still takes about 13 seconds. Why does the two differ so much?

    Damn, i thought i was being smart by making my hover signal attached to the QScatterSeries. I guess i'll have to find another way of doing it.


    Best Regards DAVC
    Last edited by DAVC; 22nd February 2019 at 15:10.

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QChart slow when plotting large data signals

    Damn, i thought i was being smart by making my hover signal attached to the QScatterSeries. I guess i'll have to find another way of doing it.
    Just a guess, but QScatterSeries might check every point to determine where the mouse is hovering, whereas QLineSeries might just check the bounding rectangle for the entire line.

    BTW, QCustomPlot is really the way to go if you want to be able to customize anything about your plots. The way the QChart library is designed, there is absolutely no way to extend it to do something different from what its authors wrote. There are no virtual methods, so you can't derive something new from QScatterSeries, for example, to override the method to change the default behavior. You can't add a new plot type if the standard line, scatter, and other series don't work for your needs. What you see is what you get, and that's all you get.

    QCustomPlot is completely customizable. I needed a scatter plot where each dot could have a different size, shape, and color, and where I could supply the data through a QAbstractItemModel without making a copy. I could do all of that with QCustomPlot and none of it with QChart.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  5. #5
    Join Date
    Feb 2018
    Posts
    22
    Thanks
    4
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QChart slow when plotting large data signals

    Thank you for your reply d_stranz!

    However, with QLineSeries and QCustomPlot, I have the same issue with "hovering". That as soon as i just hover the line i get an arbitrary point. I only want to print exact data points, as in, plotted data is by sample. It doesn't make sense to plot y-value for sample 3.5 for example.

    Do you have any good ideas for QCustomPlot to only make the tooltip appear when hovering an actual sample?

    Best regards
    DAVC

    Thank you for your reply d_stranz!

    However, with QLineSeries and QCustomPlot, I have the same issue with "hovering". That as soon as i just hover the line i get an arbitrary point. I only want to print exact data points, as in, plotted data is by sample. It doesn't make sense to plot y-value for sample 3.5 for example.

    Do you have any good ideas for QCustomPlot to only make the tooltip appear when hovering an actual sample?

    Best regards
    DAVC


    Added after 1 15 minutes:


    Okay, so to anyone reading this with the sample problem: You want to plot large data signals and when you hover a given signal, you want a tooltip to appear with the value for an actual sample.

    Do not use QScatterSeries. It is super slow. I don't know why.
    Use QLineSeries.

    Attach its "hovered" signal to a lambda function, like so:
    Qt Code:
    1. connect(lineseries, &QLineSeries::hovered, [=](QPointF point, bool state) {this->tooltip_(point, state, name, ali[bandnr]); });
    To copy to clipboard, switch view to plain text mode 
    This allows you to capture the default parameters from &QLineSeries::hovered, and provide any other values you might want. I want the name and the data as well. My tooptip function looks like this:

    Qt Code:
    1. void LinePlot::tooltip_(QPointF point, bool state, QString name, QVector<QPointF> data)
    2. {
    3. if (m_tooltip == 0)
    4. m_tooltip = new Callout(chart_);
    5.  
    6. if (state) {
    7. auto x = data[qRound(point.x())].x();
    8. auto y = data[qRound(point.x())].y();
    9. m_tooltip->setText(name + "\nX: " + QString::number(x) + " \nY: " + QString::number(y));
    10. m_tooltip->setAnchor(point);
    11. m_tooltip->setZValue(11);
    12. m_tooltip->updateGeometry();
    13. m_tooltip->setParentItem(chart_);
    14. m_tooltip->show();
    15. m_tooltip->update();
    16. }
    17. else {
    18. m_tooltip->hide();
    19. }
    20. }
    To copy to clipboard, switch view to plain text mode 

    you can see the callout class here:
    https://doc.qt.io/qt-5/qtcharts-call...llout-cpp.html

    This makes a tool tip appear when you hover an actual data point. It is a bit sluggish, tough, as the tooltip only disappears when you stop hovering the line and there is a timer for this. I'll see if i can remove that somehow.

    I tried setting lineserie.SetPointsVisible(true) but that turns the plotting insanely slow again.

    As for QCustomPlot. It is highly customizable, but when you're a rookie like me, it also becomes a bit overwhelming.

    Best Regards
    DAVC
    Last edited by DAVC; 25th February 2019 at 09:35.

  6. #6
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QChart slow when plotting large data signals

    Glad you solved it.

    As for QCustomPlot. It is highly customizable, but when you're a rookie like me, it also becomes a bit overwhelming.
    With great power comes great responsibility... and a learning curve. But Emanuel Eichhammer did a great job in designing an open and flexible widget that doesn't box you in to a fixed model. I just wish there was something similar for 3D plotting.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  7. #7
    Join Date
    Feb 2018
    Posts
    22
    Thanks
    4
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QChart slow when plotting large data signals

    With great power comes great responsibility... and a learning curve.
    I was actually surprised at how quickly I got a plot. Documentation and forums are quite extensive. I did have a look at IM GUI (Immediate Mode GUI). Couldn't even figure out how to get a basic window after two days. Though that probably says more about me.

    I would like to update my tooltip function:

    Qt Code:
    1. void LinePlot::tooltip_(QPointF point, bool state, QString name, QVector<QPointF> data)
    2. {
    3. if (m_tooltip == 0)
    4. m_tooltip = new Callout(chart_);
    5.  
    6. int x;
    7. double y;
    8. if (point.x() > 0){
    9. x = data[qRound(point.x())].x();
    10. y = data[x].y();
    11. }
    12. else {
    13. x = 0;
    14. y = data[x].y();
    15. }
    16. m_tooltip->setText(name + "\nX: " + QString::number(x) + " \nY: " + QString::number(y));
    17. m_tooltip->setAnchor(QPointF(x,y));
    18. m_tooltip->setZValue(11);
    19. m_tooltip->updateGeometry();
    20. m_tooltip->setParentItem(chart_);
    21. m_tooltip->show();
    22. m_tooltip->update();
    23.  
    24. if(!state) {
    25. m_tooltip->hide();
    26. }
    27. }
    To copy to clipboard, switch view to plain text mode 

    It makes the tooltip more responsive. Now we print the tooltip as soon as we hover the line. Only print sample values. We anchor the tooltip to the sample values. We also update the tooltip while moving the mouse along the line.

    Hope this helps someone.

    Best regards
    Davc

  8. The following user says thank you to DAVC for this useful post:

    d_stranz (26th February 2019)

  9. #8
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QChart slow when plotting large data signals

    I was actually surprised at how quickly I got a plot.
    Yes, if you want something standard, it is pretty simple. I have found that using OpenGL mode seems to have some problems. It could be my misunderstanding, but I had trouble getting plots to appear if I set the OpenGL flag.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  10. #9
    Join Date
    Jan 2020
    Posts
    1
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    MacOS X Windows Android

    Default Re: QChart slow when plotting large data signals

    Hi,

    another way how to solve this is the following "dirty" trick.
    You can modify the QT source code for QLineSeries.
    Search for "linechartitem.cpp", function "LineChartItem:aint".
    Comment the line:

    painter->drawLine(m_linePoints.at(i - 1), m_linePoints.at(i));

    and add the following line instead:

    painter->drawPoint( m_linePoints.at(i));

    Then recompile the QT.
    As the result you should get a scatter plot for QLineSeries which works fast ;-)

    --
    Cheers,
    Garfungiloops

  11. #10
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QChart slow when plotting large data signals

    As the result you should get a scatter plot for QLineSeries which works fast ;-)
    Why on earth would you want to do that? You could -never- create a true line plot where the points were connected by lines, you would always have a scatter plot no matter what. The only time this would look good is if your points occupied one x- and y-pixel after another. As soon as the x or y points were more than one pixel apart, you'd get a bunch of disconnected dots.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

Similar Threads

  1. How to scroll a QChart as realtime data come in
    By mustermann.klaus@gmx.de in forum Qt Programming
    Replies: 12
    Last Post: 5th January 2018, 10:45
  2. Slow plotting of spectrogram
    By Anton1 in forum Qwt
    Replies: 10
    Last Post: 28th December 2016, 17:30
  3. Replies: 5
    Last Post: 2nd July 2012, 21:49
  4. Replies: 1
    Last Post: 23rd September 2010, 06:45
  5. Replies: 9
    Last Post: 30th July 2010, 10:13

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.