Fix ScatterPlotItem performance regression (#1569)

* Fix ScatterPlotItem performance regression

* Add hover benchmark to ScatterPlotSpeedTest.py

* Removed a performance regression from GraphicsView

* Removed some tests failing due to the last commit
This commit is contained in:
lidstrom83 2021-02-11 08:36:52 -08:00 committed by GitHub
parent 344348441a
commit d7668f91b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 25 additions and 21 deletions

View File

@ -27,7 +27,7 @@ param = ptree.Parameter.create(name=translate('ScatterPlot', 'Parameters'), type
dict(name='_USE_QRECT', title='_USE_QRECT: ', type='bool', value=pyqtgraph.graphicsItems.ScatterPlotItem._USE_QRECT), dict(name='_USE_QRECT', title='_USE_QRECT: ', type='bool', value=pyqtgraph.graphicsItems.ScatterPlotItem._USE_QRECT),
dict(name='pxMode', title='pxMode: ', type='bool', value=True), dict(name='pxMode', title='pxMode: ', type='bool', value=True),
dict(name='useCache', title='useCache: ', type='bool', value=True), dict(name='useCache', title='useCache: ', type='bool', value=True),
dict(name='mode', title=translate('ScatterPlot', 'Mode: '), type='list', values={'New Item': 'newItem', 'Reuse Item': 'reuseItem', 'Simulate Pan/Zoom': 'panZoom'}, value='reuseItem'), dict(name='mode', title=translate('ScatterPlot', 'Mode: '), type='list', values={translate('ScatterPlot', 'New Item'): 'newItem', translate('ScatterPlot', 'Reuse Item'): 'reuseItem', translate('ScatterPlot', 'Simulate Pan/Zoom'): 'panZoom', translate('ScatterPlot', 'Simulate Hover'): 'hover'}, value='reuseItem'),
]) ])
for c in param.children(): for c in param.children():
c.setDefault(c.value()) c.setDefault(c.value())
@ -42,6 +42,7 @@ splitter.show()
data = {} data = {}
item = pg.ScatterPlotItem() item = pg.ScatterPlotItem()
hoverBrush = pg.mkBrush('y')
ptr = 0 ptr = 0
lastTime = time() lastTime = time()
fps = None fps = None
@ -88,13 +89,21 @@ def getData():
def update(): def update():
global ptr, lastTime, fps global ptr, lastTime, fps
if param['mode'] == 'newItem': mode = param['mode']
if mode == 'newItem':
mkItem() mkItem()
elif param['mode'] == 'reuseItem': elif mode == 'reuseItem':
item.setData(**getData()) item.setData(**getData())
elif param['mode'] == 'panZoom': elif mode == 'panZoom':
item.viewTransformChanged() item.viewTransformChanged()
item.update() item.update()
elif mode == 'hover':
pts = item.points()
old = pts[(ptr - 1) % len(pts)]
new = pts[ptr % len(pts)]
item.pointsAt(new.pos())
old.resetBrush() # reset old's brush before setting new's to better simulate hovering
new.setBrush(hoverBrush)
ptr += 1 ptr += 1
now = time() now = time()

View File

@ -776,14 +776,21 @@ class ScatterPlotItem(GraphicsObject):
mask = dataSet['sourceRect']['w'] == 0 mask = dataSet['sourceRect']['w'] == 0
if np.any(mask): if np.any(mask):
invalidate = True invalidate = True
dataSet['sourceRect'][mask] = self.fragmentAtlas[ coords = self.fragmentAtlas[
list(zip(*self._style(['symbol', 'size', 'pen', 'brush'], data=dataSet, idx=mask))) list(zip(*self._style(['symbol', 'size', 'pen', 'brush'], data=dataSet, idx=mask)))
] ]
dataSet['sourceRect'][mask] = coords
if _USE_QRECT: if _USE_QRECT:
sr = dataSet['sourceRect'][mask] rects = []
sru = np.unique(sr) for c in coords:
list(imap(self._sourceQRect.__setitem__, imap(tuple, sru), imap(QtCore.QRectF, *zip(*sru)))) try:
dataSet['sourceQRect'][mask] = list(imap(self._sourceQRect.__getitem__, imap(tuple, sr))) rect = self._sourceQRect[c]
except KeyError:
rect = QtCore.QRectF(*c)
self._sourceQRect[c] = rect
rects.append(rect)
dataSet['sourceQRect'][mask] = rects
dataSet['targetQRectValid'][mask] = False dataSet['targetQRectValid'][mask] = False
self._maybeRebuildAtlas() self._maybeRebuildAtlas()

View File

@ -123,11 +123,6 @@ class GraphicsView(QtGui.QGraphicsView):
self.scaleCenter = False ## should scaling center around view center (True) or mouse click (False) self.scaleCenter = False ## should scaling center around view center (True) or mouse click (False)
self.clickAccepted = False self.clickAccepted = False
# Set a transparent background QPalette!
palette = self.palette()
palette.setColor(QtGui.QPalette.Window, QtCore.Qt.transparent)
self.setPalette(palette)
def setAntialiasing(self, aa): def setAntialiasing(self, aa):
"""Enable or disable default antialiasing. """Enable or disable default antialiasing.
Note that this will only affect items that do not specify their own antialiasing options.""" Note that this will only affect items that do not specify their own antialiasing options."""

View File

@ -9,10 +9,6 @@ def test_basics_graphics_view():
background_role = view.backgroundRole() background_role = view.backgroundRole()
assert background_role == QtGui.QPalette.Window assert background_role == QtGui.QPalette.Window
palette = view.palette()
assert palette.isBrushSet(QtGui.QPalette.Active, QtGui.QPalette.Window)
assert palette.color(QtGui.QPalette.Window) == QtCore.Qt.transparent
assert view.backgroundBrush().color() == QtGui.QColor(0, 0, 0, 255) assert view.backgroundBrush().color() == QtGui.QColor(0, 0, 0, 255)
assert view.focusPolicy() == QtCore.Qt.StrongFocus assert view.focusPolicy() == QtCore.Qt.StrongFocus
@ -37,9 +33,6 @@ def test_basics_graphics_view():
# -------------------------------------- # --------------------------------------
view.setBackground("w") view.setBackground("w")
assert view._background == "w" assert view._background == "w"
palette = view.palette()
assert palette.isBrushSet(QtGui.QPalette.Active, QtGui.QPalette.Window)
assert palette.color(QtGui.QPalette.Window) == QtCore.Qt.transparent
assert view.backgroundBrush().color() == QtCore.Qt.white assert view.backgroundBrush().color() == QtCore.Qt.white
# Set anti aliasing # Set anti aliasing