Comments (7)
I would guess that #2863 is the one affecting you.
- Are you able to bisect the code to confirm that #2863 is the relevant PR affecting you?
- Are you using a hi-dpi display? If yes, in the following lines, if you change self._dpr to your screen device pixel ratio, does it make a difference?
pyqtgraph/pyqtgraph/graphicsItems/ScatterPlotItem.py
Lines 151 to 153 in a4bf606
ScatterPlotItem
starts off assuming DPR=1.0, and if that turns out to be incorrect, it has to rebuild the symbol cache. Effectively, this means that the time to first render should be slower for users with a hi-dpi display.
Now, pyqtgraph
library could perhaps try to probe for the primary screen's DPR and use that. That, however, is not entirely foolproof, as the user may have multiple screens with different DPRs.
Indeed, ScatterPlotItem
does not know the screen on which it will display until just before painting occurs. And furthermore, even after being displayed, the user could drag the window to the other screen.
pyqtgraph/pyqtgraph/graphicsItems/ScatterPlotItem.py
Lines 959 to 966 in a4bf606
from pyqtgraph.
Thanks for the quick reply!
I am indeed on a hi-dpi display and that may explain the slow down on my machine. In general, I am supporting users on Windows, Linux and macOS with any number of screens, so I would indeed need to check for the DPI before I plot.
I will check that the pull request you mention is indeed the one that affects the rendering performance on my machine and come back to you asap.
from pyqtgraph.
The following script takes < 2.5 secs to run on a particular system with hidpi.
import time
import numpy as np
import pyqtgraph as pg
npoints = 200_000
nbrushes = 600
rng = np.random.default_rng(0)
xy = rng.standard_normal(size=(2, npoints))
unique_colors = rng.integers(256, size=(nbrushes, 3))
unique_brushes = [pg.mkBrush(*rgb) for rgb in unique_colors]
random_choice = rng.integers(nbrushes, size=npoints)
random_brushes = [unique_brushes[x] for x in random_choice]
pg.mkQApp()
scatter = pg.ScatterPlotItem(
size=5,
pen=pg.mkPen(None),
brush=pg.mkBrush(255, 255, 255, 128), # To be overridden in the next call depending on a setting
hoverable=True,
hoverSymbol="s",
hoverSize=5,
hoverPen=pg.mkPen("w", width=2),
hoverBrush=None,
)
t0 = time.perf_counter()
# scatter.addPoints(x=xy[0], y=xy[1], brush=random_choice) # SLOW
scatter.addPoints(x=xy[0], y=xy[1], brush=random_brushes) # FAST
t1 = time.perf_counter()
print(f'{t1 - t0:.3f}')
pg.mkQApp()
win = pg.PlotWidget()
win.show()
win.addItem(scatter)
pg.exec()
The following should explain why:
pyqtgraph/pyqtgraph/graphicsItems/ScatterPlotItem.py
Lines 125 to 130 in a4bf606
from pyqtgraph.
set PYQTGRAPHPROFILE="ScatterPlotItem.paint"
SLOW version (with dpi mismatch)
9.933
> Entering ScatterPlotItem.paint
prep: 11133.5924 ms
draw: 164.4934 ms
< Exiting ScatterPlotItem.paint, total time: 11298.1008 ms
FAST version (with dpi mismatch)
0.710
> Entering ScatterPlotItem.paint
prep: 369.4633 ms
draw: 47.4142 ms
< Exiting ScatterPlotItem.paint, total time: 416.8903 ms
FAST version (with dpi matched)
0.709
> Entering ScatterPlotItem.paint
prep: 31.1583 ms
draw: 48.1068 ms
< Exiting ScatterPlotItem.paint, total time: 79.2849 ms
In the FAST version, a matched dpi would have saved only ~340ms.
Is that worth optimizing for?
The optimization would be adding one line after the instantiation of SymbolAtlas
.
self.fragmentAtlas = SymbolAtlas()
self.fragmentAtlas.setDevicePixelRatio(QtGui.QGuiApplication.primaryScreen().devicePixelRatio())
from pyqtgraph.
Thanks a lot! I will try it out first thing on Monday.
from pyqtgraph.
Hi,
when using the suggested fast method (#2960 (comment)) to create just one QBrush per unique identifier and have all other points with the same id reference it, I get the following results:
pyQtGraph 0.13.3: 748 +/- 5ms
pyQtGraph 0.13.4: 748 +/- 6ms
down from ca. 19.6 seconds.
Additionally, If I change the device pixel ratio of SymbolAtlas
via self.fragmentAtlas.setDevicePixelRatio(QtGui.QGuiApplication.primaryScreen().devicePixelRatio())
(which on my machine maps to 1.5
), I get the following results:
pyQtGraph 0.13.4: 757 +/- 4ms
Apparently, changing the device pixel ratio even (very minimally) slows down the rendering.
All in all, reducing the number of QBrush object instantiations more than solves my performance issue with colouring points in the ScatterPlotItem (from 19 down to a quarter of a second), and any additional optimization seem to bring only negligible improvements (or even regressions).
from pyqtgraph.
I had a typo in my instructions (edited):
set PYQTGRAPHPROFILE="ScatterPlotItem.paint"
from pyqtgraph.
Related Issues (20)
- TypeError when adding items to histogram menu in 0.13.4 HOT 3
- Colormap plot scatter points HOT 2
- SyntaxWarnings HOT 1
- 'DateAxisItem' object has no attribute 'fontMetrics' HOT 3
- `DateAxisItem` renders correctly only for one plot if re-added HOT 1
- Errors encountered when running tests on risc-v platform HOT 4
- 'NoneType' object has no attribute 'removeItem' HOT 1
- ConsoleWidget.write() function missing HOT 6
- TypeError exception in ROI raiseContextMenu . QPoint being sent floats instead of ints HOT 14
- ParameterTree Example Generated Deprecation Warning HOT 1
- Test failure on test_PolyLineROI on arm64
- parameterTree contents are not displayed on the correct position when the parameterTree widget has scroll bars HOT 4
- GraphicsScene.mouseMoveEvent duplicates events
- Export to SVG with opacity on items
- Error when using FFT on data with one point HOT 1
- FillBetweenItems overflows the area between the target curves HOT 3
- Dynamically wrapped composed methods have no type hints HOT 5
- `PlotItem.scene()` has a `QGraphicsScene` type hint instead of a `pyqtgraph.GraphicsScene`
- Increasing Legend text generate a vertical misalignment with the sample.
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pyqtgraph.