Results 1 to 17 of 17

Thread: Check perfomance of QwtPlotCurve with setPaintAttribute for displaying large data

  1. #1
    Join Date
    Nov 2019
    Posts
    31
    Thanks
    8
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Check perfomance of QwtPlotCurve with setPaintAttribute for displaying large data

    Dear UWE,

    I'm testing QwtPlotCurve with "big data". Previously you said that in QWT SVN trunk there is QWT 6.2 where I can find QwtPlotCurve::FilterPointsAggressive to increase perfomance of plotting large data. So I use QWT 6.2 from SVN.
    I plotted curves in cycle up to 20000 and each curve has 1000 points. Plotted data takes about 300 megabytes RAM and takes to plot maybe 25 seconds (I didn't measure exactly but not bad as few second is spent for reading data from SSD disk).
    When I tried to add QwtPlotCurve::setPaintAttribute I didn't see any changes in perfomance. I tried to set MinimizeMemory/FilterPoints/FilterPointsAgressive to true/false with no luck. Maybe I do something wrong? Here is the code:
    Qt Code:
    1. for (quint64 j = 0; j < nTrc; j++){
    2. QwtPlotCurve *curve = new QwtPlotCurve();
    3. curve->setPen( Qt::blue, 1 );
    4. curve->setRenderHint( QwtPlotItem::RenderAntialiased, true );
    5. curve->setOrientation(Qt::Vertical);
    6. curve->setSamples(Col<float>(TRACE_DATA.col(j)+j).memptr(), t.memptr(), nSamp); // data from Armadillo matrix
    7. curve->setPaintAttribute(QwtPlotCurve::MinimizeMemory, true); // I tried to swap true/false everywhere...
    8. curve->setPaintAttribute(QwtPlotCurve::FilterPoints, true);
    9. curve->setPaintAttribute(QwtPlotCurve::FilterPointsAggressive, true);
    10. curve->attach( plotForm );
    11. }
    To copy to clipboard, switch view to plain text mode 
    Woud it help if I set curve->setRenderThreadCount(N); in my case (for hundreds and thousands curves)?

    Here is how it looks for 50 lines (I tried it up to 20000 lines):
    1.jpg

  2. #2
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,309
    Thanked 879 Times in 827 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Check perfomance of QwtPlotCurve with setPaintAttribute for displaying large data

    Antialisasing is a substantial performance killer and does not make much sense in your case - so the first thing you should do is to turn it of. Using a pen width > 1 is another well known problem - one that is not used in your code.

    A general way to improve rendering is to use a hardware accelerated paint engine. On Unix systems this is pretty easy by using the X11 paint engine, that is available in Qt4 or Qt >= 5.10. Unfortunately Qt development decided to make the slow software renderer being the default even on X11 systems, where you have a much better option. On Windows you have to use an OpenGL canvas - or at least have to use the QwtPlotCanvas::OpenGLBuffer option you can find in SVN trunk.

    The FilterPointsAgressive/FilterPoints flags make use of the fact, that when rendering a curve with many points many of them will end up at the same position as others. But for a plot with many curves of a limited number of points these flags won't help much.

    Enabling the MinimizeMemory flag is counterproductive in terms of performance and is of no value when having curves with only 1000 points.

    Uwe

  3. The following user says thank you to Uwe for this useful post:

    Vasya (26th March 2020)

  4. #3
    Join Date
    Nov 2019
    Posts
    31
    Thanks
    8
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Check perfomance of QwtPlotCurve with setPaintAttribute for displaying large data

    Uwe,

    I'm trying to explore QwtPlotOpenGLCanvas. I successfully built QWT 6.3.0 from SVN trunk.
    I found your discussion about perfomance and OpenGL issues: https://www.qtcentre.org/threads/666...ming-is-*SLOW*
    Now I can run your code from there. But when I change canvas to QwtPlotOpenGLCanvas *canvas = new QwtPlotOpenGLCanvas(); my launched application looks like green window (black or yellow on the picture) without curves. And there is a warning:
    DXGI WARNING: IDXGIFactory::CreateSwapChain: Blt-model swap effects (DXGI_SWAP_EFFECT_DISCARD and DXGI_SWAP_EFFECT_SEQUENTIAL) are legacy swap effects that are predominantly superceded by their flip-model counterparts (DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL and DXGI_SWAP_EFFECT_FLIP_DISCARD). Please consider updating your application to leverage flip-model swap effects to benefit from modern presentation enhancements. More information is available at http://aka.ms/dxgiflipmodel. [ MISCELLANEOUS WARNING #294: ]
    QSize(600, 400) 0

    Since I'm not quite familiar with graphics and OpenGL it is difficult to understand what is blamed for this app behaviour.
    If you know something that possibly could help with that please give me a hint.

    I'm on Windows 10 x64, DirectX 12, Qt 5.14.1, compilator MSVC 2017 x64.

    Here is the code that I use:
    Qt Code:
    1. #include <QApplication>
    2. #include <QElapsedTimer>
    3. #include <qwt_plot.h>
    4. #include <qwt_plot_curve.h>
    5. #include <qwt_plot_canvas.h>
    6. #include <qwt_plot_opengl_canvas.h>
    7. #include <QtMath>
    8. #include <QDebug>
    9. #include <QtOpenGL>
    10.  
    11. class MyPlot: public QwtPlot
    12. {
    13. public:
    14. MyPlot()
    15. {
    16. const int numPoints = 10;
    17.  
    18. //QwtPlotCanvas* canvas = new QwtPlotCanvas();
    19. QwtPlotOpenGLCanvas *canvas = new QwtPlotOpenGLCanvas(); // NEW OpenGL Canvas
    20. #if 0
    21. canvas->setPaintAttribute( QwtPlotCanvas::OpenGLBuffer, true );
    22. #endif
    23. setCanvas( canvas );
    24. setCanvasBackground( Qt::white );
    25. setAxisScale( QwtPlot::yLeft, -1.5, 1.5 );
    26. setAxisScale( QwtPlot::xBottom, 0.0, numPoints );
    27.  
    28. QwtPlotCurve *curve = new QwtPlotCurve();
    29. curve->setTitle( "Some Points" );
    30. curve->setPaintAttribute(QwtPlotCurve::FilterPointsAggressive, true);
    31.  
    32. QPolygonF points;
    33. for ( int i = 0; i < numPoints; i++ )
    34. points += QPointF( i, qSin( i ) );
    35.  
    36. curve->setSamples( points );
    37. curve->attach( this );
    38. }
    39.  
    40. virtual void drawCanvas( QPainter *painter )
    41. {
    42. QElapsedTimer timer;
    43. timer.start();
    44.  
    45. QwtPlot::drawCanvas( painter );
    46.  
    47. qDebug() << size() << timer.elapsed();
    48. }
    49. };
    50.  
    51. int main( int argc, char **argv )
    52. {
    53. QApplication a( argc, argv );
    54.  
    55. MyPlot plot;
    56.  
    57. plot.resize( 600, 400 );
    58. plot.show();
    59.  
    60. return a.exec();
    61. }
    To copy to clipboard, switch view to plain text mode 
    1.png
    Last edited by Vasya; 26th March 2020 at 23:14.

  5. #4
    Join Date
    Nov 2019
    Posts
    31
    Thanks
    8
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Check perfomance of QwtPlotCurve with setPaintAttribute for displaying large data

    Oh! Since I'm on the laptop I have two video cards: one is Intel (integrated and used most of the time by default but it is slow) and NVidea (additional, more powerful).
    So before that my application used to launch with integrated slow Intel video card but to run OpenGL I need NVidea. In NVidea contol panel I added my application and chosed NVidea videocard for this application.

    Now it looks good, I'm going to test qwt opengl for my issues
    1.jpg

  6. #5
    Join Date
    Nov 2019
    Posts
    31
    Thanks
    8
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Check perfomance of QwtPlotCurve with setPaintAttribute for displaying large data

    Uwe,

    I tested QwtPlotCanvas::OpenGLBuffer and for my task I don't any difference in perfomance wether I use canvas->setPaintAttribute( QwtPlotCanvas::OpenGLBuffer, true); or canvas->setPaintAttribute( QwtPlotCanvas::OpenGLBuffer, false );. Both of them takes about 20 seconds to plot 20000 curves each of 1000 points.
    I use the following settings:
    canvas->setPaintAttribute( QwtPlotCanvas::OpenGLBuffer, true ); // change from true to false
    curve->setPaintAttribute(QwtPlotCurve::MinimizeMemory, false);
    curve->setPaintAttribute(QwtPlotCurve::FilterPoints, false);
    curve->setPaintAttribute(QwtPlotCurve::FilterPointsAggre ssive, false);
    What do you think?
    I also tried to use QwtPlotOpenGLCanvas but I cannot handle zooming to work. No panning, no zooming

    But there is a maybe a bug in QwtPlotCanvas::OpenGLBuffer(true) when I need to fill the area between baseline and curve. In the pictures attached I demostrate that.
    By the way, QwtPlotOpenGLCanvas fills this area finely
    1.png
    2.png

  7. #6
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,309
    Thanked 879 Times in 827 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Check perfomance of QwtPlotCurve with setPaintAttribute for displaying large data

    You will never ever have a good performance with a plot of 20000 curves * 1000 points and to me it sound like you are taking the wrong approach.
    Are you sure, that your data is not more like something you would display as raster data.

    Uwe

  8. #7
    Join Date
    Nov 2019
    Posts
    31
    Thanks
    8
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Check perfomance of QwtPlotCurve with setPaintAttribute for displaying large data

    Uwe,

    Yes 20000 curves it is too much but I'm exploring QWT and after that I should decide how to design the application.
    There is a small free software that can plot more curves with quite good perfomance SEISEE https://mail.dmng.ru/freeware/?lang=en
    I can't understand how it works but if you are interested to test it I could find some data to use in SEISEE

  9. #8
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,309
    Thanked 879 Times in 827 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Check perfomance of QwtPlotCurve with setPaintAttribute for displaying large data

    In the end you have to understand what is going on. A curve usually ends up at QPainter::drawPolyline, Qwt can do a couple of optimizations, but that's it.
    For one curve with many points optimzations will be more successful, but for many curves with a limited number of points there is not that much that can be done.

    Maybe one optimzation, that comes to my mind is disabling autoscaling, so that the bounding rectangle of the curves has not to be done by iterating over all curves. But this has to be done only once.

  10. The following user says thank you to Uwe for this useful post:

    Vasya (30th March 2020)

  11. #9
    Join Date
    Nov 2019
    Posts
    31
    Thanks
    8
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Check perfomance of QwtPlotCurve with setPaintAttribute for displaying large data

    Thank you Uwe
    Even I started with C/C++ few month ago I feel that I'm starting to understand the philosophy of QWT. I still have some difficulties but it needs some time to understand.
    I already disabled autoscaling.
    Actually I think that QWT is fast enough to fit my needs.
    At least as I'm using Armadillo library I'm able to perform 2D interpolation before plotting in case when number of curves and number of of points in each curve significantly exceed heigh and width of canvas in pixels.

    Thank you!

  12. #10
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,309
    Thanked 879 Times in 827 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Check perfomance of QwtPlotCurve with setPaintAttribute for displaying large data

    Quote Originally Posted by Vasya View Post
    At least as I'm using Armadillo library I'm able to perform 2D interpolation before plotting in case when number of curves and number of of points in each curve significantly exceed heigh and width of canvas in pixels.
    Guess by interpolation you mean clipping the curves against the canvas boundaries. This is done by default ( QwtPlotCurve::ClipPolygons ) and doing it in advance does only make sense, when you do not have to deal with operations like zooming. There is also an implementation of Douglas Peucker available ( https://qwt.sourceforge.io/class_qwt...ve_fitter.html ), but as this is an expensive algo it should be done in advance - only passing the reduced number of points.

    Uwe

  13. #11
    Join Date
    Nov 2019
    Posts
    31
    Thanks
    8
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Check perfomance of QwtPlotCurve with setPaintAttribute for displaying large data

    I think I'm talking about something different.
    My plotted curves have some specific features. They are like deviation from some vertical baseline (and each curve has a baseline).
    Lets suppose that canvas width is 500 pixels. Every curve has QPen width equal to 1 and if all curves are settled equidistantly on the canvas then there is no much sense to plot more than 500 my "pseudovertical" curves.
    So if I try to plot 5000 curves then I can choose every tenth (0, 10, 20, ...) curve and then plot it.

    And the same for Y axis. Every point of every of my curves is settled equidistantly (Y axis of every point is something like : 0, 2, 4, 6, 8 ...). So linear interpolation is fast and could improve plot perfomance when number of points much bigger than canvas height

  14. #12
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,309
    Thanked 879 Times in 827 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Check perfomance of QwtPlotCurve with setPaintAttribute for displaying large data

    Quote Originally Posted by Vasya View Post
    Every curve has QPen width equal to 1 and if all curves are settled equidistantly on the canvas then there is no much sense to plot more than 500 my "pseudovertical" curves.
    So if I try to plot 5000 curves then I can choose every tenth (0, 10, 20, ...) curve and then plot it.
    Not sure if this is a type of optimization, that is common of enough to explicitely support it in Qwt - curve points are usually not only shifted by the distance of the baselines. But nobody prevents you from doing so - simply hide/show curves depending on scale ranges.

    Quote Originally Posted by Vasya View Post
    Every point of every of my curves is settled equidistantly (Y axis of every point is something like : 0, 2, 4, 6, 8 ...). So linear interpolation is fast and could improve plot perfomance when number of points much bigger than canvas height
    Being equidistant does not make anything faster and I'm not sure what you mean by "interpolation" here. But clipping ( skipping points being outside the canvas ) and making use of the fact, that you can unite points, that are mapped to the same position, when drawing to an integer coordinate based paint device ( screen ) can have an significant effect. But the second ( = QwtPlotCurve::FilterPointsAggressive ) optimization won't be very effective, when you only have 1000 points. Drawing 1000 points to a canvas having a height of 1000 pixels does not reduce the number of points significantly.

    Uwe

  15. The following user says thank you to Uwe for this useful post:

    Vasya (1st April 2020)

  16. #13
    Join Date
    Nov 2019
    Posts
    31
    Thanks
    8
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Check perfomance of QwtPlotCurve with setPaintAttribute for displaying large data

    Quote Originally Posted by Uwe View Post
    Not sure if this is a type of optimization, that is common of enough to explicitely support it in Qwt - curve points are usually not only shifted by the distance of the baselines. But nobody prevents you from doing so - simply hide/show curves depending on scale ranges.
    Yes thank you for the hint, I'm going to try to make optimization based on the show/hide (curve->setEnabled(true/false)) properties. That should not be much difficult.

    About vertical resolution:
    Probably that is not so necessary but depending on plotted data each curve may have up to 5000 points (usually it is 2000-5000 points but may vary). In this case QwtPlotCurve::FilterPointsAggressive may be useful I think (or at least it should not consume much time to execute if number of points is small, less than 1000, I'm going to test it).

    And what about vertical linear interpolation:
    I think in this case interpolation for curves that reduces the number of plotted points is inapropriate, sorry for confusing you. But sometime ago I found this algo in Matlab: https://www.mathworks.com/matlabcent...40790-plot-big
    But that time I needed something like that to plot 2D data (spectrogram) with the same 1000 by 20000 points (or more) in each direction (the data is the same as for my curves but plotted NOT as curves but as spectrogram). And I wrote matlab code that choses points in X and Y direction before plotting Z data. I think in QWT spectrogram with big data could be useful also. Maybe FilterPointsAggressive could find some application at spectrogram?
    This is just an idea wich came to my mind now but probably QWT already has something similar (I didn't work with QWT spectrogram yet but I'm going to).

  17. #14
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,309
    Thanked 879 Times in 827 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Check perfomance of QwtPlotCurve with setPaintAttribute for displaying large data

    Quote Originally Posted by Vasya View Post
    I think in QWT spectrogram with big data could be useful also.
    The impact of the data size depends on the type of resampling being used - for example with nearest neighbor ( = default ) the performance does not depend on the data size.
    But the opposite is true: when the resolution of the data is smaller, than the one on screen rendering will be faster as in situations, where you have to calculate all pixels.
    Quote Originally Posted by Vasya View Post
    Probably that is not so necessary but depending on plotted data each curve may have up to 5000 points (usually it is 2000-5000 points but may vary). In this case QwtPlotCurve::FilterPointsAggressive may be useful I think (or at least it should not consume much time to execute if number of points is small, less than 1000, I'm going to test it).
    The algo calculates 4 points for each pixel: enter, min, max, leave. So when having 5K points and 1K pixels you will have almost no effect in reducing the number of lines to be painted.
    But the algo is fast and should not hurt that much.

    HTH,
    Uwe
    Last edited by Uwe; 1st April 2020 at 15:09.

  18. #15
    Join Date
    Nov 2019
    Posts
    31
    Thanks
    8
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Check perfomance of QwtPlotCurve with setPaintAttribute for displaying large data

    I think I misunderstood something but this interesting to know
    Quote Originally Posted by Uwe View Post
    The impact of the data size depends on the type of resampling being used - for example with nearest neighbor ( = default ) the performance does not depend on the data size.
    Does this only concernes to the situation when number of pixels is more than number of data points (say canvas size = [500, 500] and data size = [100, 100])? In this case we have to apply nearest neighbor interpolation to resize our data from [100, 100] to [500, 500] does it correct?

    And the opposite, when canvas size [500, 500] and the data is [5000, 5000]. In this case we can only plot 10% of our data. I don't know wether such software like QWT does the resampling of our data before plotting or it shows all the 5000*5000 points on the 500*500 screen?

    I've always been interesting about that beacause in Matlab my nearest-neighbor resampling improoved the plotting perfomance compared to plotting raw data.
    In Matlab I was using this function after I resample the data: https://www.mathworks.com/help/matlab/ref/imagesc.html

  19. #16
    Join Date
    Feb 2006
    Location
    Munich, Germany
    Posts
    3,309
    Thanked 879 Times in 827 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Check perfomance of QwtPlotCurve with setPaintAttribute for displaying large data

    Does this only concernes to the situation when number of pixels is more than number of data points (say canvas size = [500, 500] and data size = [100, 100])? In this case we have to apply nearest neighbor interpolation to resize our data from [100, 100] to [500, 500] does it correct?
    In case of nearest neighbor Qwt would create a 100x100 image - scaling to the paint device resolution will happen later. Resizing the data is not necessary for no type of interpolation.

    And the opposite, when canvas size [500, 500] and the data is [5000, 5000]. In this case we can only plot 10% of our data. I don't know wether such software like QWT does the resampling of our data before plotting or it shows all the 5000*5000 points on the 500*500 screen?
    The application has full control over the resampling. Note, that there is a class specifically supporting data being stored as a 2x2 array ( https://qwt.sourceforge.io/class_qwt...ster_data.html ), but in general the data can be hold in any way. See the spectrogram example, that does not even store the data at all.

    I've always been interesting about that beacause in Matlab my nearest-neighbor resampling improoved the plotting perfomance compared to plotting raw data.
    QwtPlotSpectrogram does not iterate over the data - it iterates over the pixels of the image and for nearest neighbor it picks the corresponding values.

    When shrinking the size of the data below the resolution of the screen you will have an effect on the performance as Qwt would not create an image in a resolution, where no corresponding data exists and less pixels need to be calculated. Otherwise your type of resampling would have no effect on the performance - see above.

    You can enable DEBUG_RENDER in qwt_plot_spectrogram.cpp and do some tests with the spectrogram example. Actually the performance of plotting will heaviliy depend on your implementation of QwtPlotRasterData::value(). This one is called for every pixel of the resulting image ( this is the resampling ) and having expensive calculations there will slow down rendering.

    Uwe

  20. The following user says thank you to Uwe for this useful post:

    Vasya (2nd April 2020)

  21. #17
    Join Date
    Nov 2019
    Posts
    31
    Thanks
    8
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Check perfomance of QwtPlotCurve with setPaintAttribute for displaying large data

    Thank you for explanation. I need to practice it more and less question I will have.

Similar Threads

  1. Replies: 3
    Last Post: 15th February 2017, 10:57
  2. Storing and displaying "large" amount of data
    By FreddyKay in forum Qt Programming
    Replies: 4
    Last Post: 27th November 2014, 20:31
  3. Replies: 2
    Last Post: 3rd January 2012, 16:00
  4. Replies: 4
    Last Post: 18th August 2009, 20:53
  5. QScrollArea not displaying large number of images
    By lpkincaid in forum Qt Programming
    Replies: 1
    Last Post: 31st May 2009, 10:58

Tags for this Thread

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.