QT charts extremely slow - QLineSeries
-
@Witc
OK, so at least we understand how to/that you can go from QML to Python and back passing a series around.It might be that this is as good as it gets. However, you are still appending points one by one and this may be "expensive", we don't know.
There is an overload of
append()
which accepts a pre-built list of points: PySide2.QtCharts.QtCharts.QXYSeries.append(points). In C++ this is void QXYSeries::append(const QList<QPointF> &points).You should try this. So instead of
serie1.append(i, self.y[i])
you want to first build all the points into a list in the loop and then append them in one go afterwards. I would guess something like:points = [] for i in self.x: points.append(QPointF(i, self.y[i])) # filling points with my prepared data serie.append(points) # append list of points in one call
Does that make it any faster?
Even better, given that you start with no points you need to retain and just want the newly created points, might be serie.replace(points)
Note: This is much faster than replacing data points one by one, or first clearing all data, and then appending the new data. Emits QXYSeries::pointsReplaced() when the points have been replaced.
-
I concur with @JonB regarding appending multiple points at once, or replacing the data vs appending points one at a time. I found it made a massive difference.
One point at a time is slow in C++, but you will be paying a double penalty in Python as each individual call has to go through a wrapper layer. The Python overhead of the calls taking a list will mainly be the conversion of the Python list to the
QList
. I would hope that conversions like Pythonlist
toQList
are optimised as much as they can be as they will be pervasive operations in a Python Qt application. -
Your idea to serie1.append(points) had no improvement - it took also about 5 seconds, but your second idea with serie1.replace(points) has great result!
Solution in python:
start = time.time() points = [] for i in self.x: points.append(QPointF(i, self.y[i])) # filling points with my prepared data serie1.replace(points) # fill list of points in one call end = time.time() print(end - start)
for 50000 values it takes only 126 ms, for 5000 values it takes 13 ms
I think we can consider this thread as solved - or any other ideas?
Thank you all @JonB @Bob64 @fcarney for help! -
"append" causes a redraw. There is no way to disable the redraw that I can find. The QML api for charts is kinda crappy for adding data points. Which is why I had to use "replace" in C++. I have done thousands of points this way and it doesn't cause delays in the UI interface.
-
J JonB referenced this topic on
-
J JonB referenced this topic on
-
J JonB referenced this topic on