From 389dff42500998efc96118fb0f253ecb2a1478d3 Mon Sep 17 00:00:00 2001 From: lidstrom83 Date: Wed, 10 Feb 2021 09:25:31 -0800 Subject: [PATCH] Add more options to ScatterPlotSpeedTest (#1566) * Add more options to ScatterPlotSpeedTest * Fixed poor choice of variable names * Add simulated pan/zoom * Multilingual support --- examples/ScatterPlotSpeedTest.py | 132 ++++++++++++------ examples/ScatterPlotSpeedTestTemplate.ui | 59 -------- .../ScatterPlotSpeedTestTemplate_pyqt5.py | 44 ------ .../ScatterPlotSpeedTestTemplate_pyqt6.py | 44 ------ .../ScatterPlotSpeedTestTemplate_pyside2.py | 44 ------ .../ScatterPlotSpeedTestTemplate_pyside6.py | 63 --------- 6 files changed, 90 insertions(+), 296 deletions(-) delete mode 100644 examples/ScatterPlotSpeedTestTemplate.ui delete mode 100644 examples/ScatterPlotSpeedTestTemplate_pyqt5.py delete mode 100644 examples/ScatterPlotSpeedTestTemplate_pyqt6.py delete mode 100644 examples/ScatterPlotSpeedTestTemplate_pyside2.py delete mode 100644 examples/ScatterPlotSpeedTestTemplate_pyside6.py diff --git a/examples/ScatterPlotSpeedTest.py b/examples/ScatterPlotSpeedTest.py index cadc16a3..ef6483d7 100644 --- a/examples/ScatterPlotSpeedTest.py +++ b/examples/ScatterPlotSpeedTest.py @@ -6,75 +6,123 @@ For testing rapid updates of ScatterPlotItem under various conditions. (Scatter plots are still rather slow to draw; expect about 20fps) """ - - -## Add path to library (just for examples; you do not need this) +# Add path to library (just for examples; you do not need this) import initExample - -from pyqtgraph.Qt import QtGui, QtCore, QT_LIB import numpy as np import pyqtgraph as pg +from pyqtgraph.Qt import QtGui, QtCore, QtWidgets from pyqtgraph.ptime import time -#QtGui.QApplication.setGraphicsSystem('raster') -app = pg.mkQApp("Scatter Plot Speed Test") -#mw = QtGui.QMainWindow() -#mw.resize(800,800) -import importlib -ui_template = importlib.import_module( - f'ScatterPlotSpeedTestTemplate_{QT_LIB.lower()}') +import pyqtgraph.parametertree as ptree +import pyqtgraph.graphicsItems.ScatterPlotItem -win = QtGui.QWidget() -win.setWindowTitle('pyqtgraph example: ScatterPlotSpeedTest') -ui = ui_template.Ui_Form() -ui.setupUi(win) -win.show() +translate = QtCore.QCoreApplication.translate -p = ui.plot -p.setRange(xRange=[-500, 500], yRange=[-500, 500]) +app = pg.mkQApp() +param = ptree.Parameter.create(name=translate('ScatterPlot', 'Parameters'), type='group', children=[ + dict(name='paused', title=translate('ScatterPlot', 'Paused: '), type='bool', value=False), + dict(name='count', title=translate('ScatterPlot', 'Count: '), type='int', limits=[1, None], value=500, step=100), + dict(name='size', title=translate('ScatterPlot', 'Size: '), type='int', limits=[1, None], value=10), + dict(name='randomize', title=translate('ScatterPlot', 'Randomize: '), type='bool', value=False), + 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='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'), +]) +for c in param.children(): + c.setDefault(c.value()) -count = 500 -data = np.random.normal(size=(50,count), scale=100) -sizeArray = (np.random.random(count) * 20.).astype(int) -brushArray = [pg.mkBrush(x) for x in np.random.randint(0, 256, (count, 3))] +pt = ptree.ParameterTree(showHeader=False) +pt.setParameters(param) +p = pg.PlotWidget() +splitter = QtWidgets.QSplitter() +splitter.addWidget(pt) +splitter.addWidget(p) +splitter.show() + +data = {} +item = pg.ScatterPlotItem() ptr = 0 lastTime = time() fps = None +timer = QtCore.QTimer() + + +def mkDataAndItem(): + global data, fps + scale = 100 + data = { + 'pos': np.random.normal(size=(50, param['count']), scale=scale), + 'pen': [pg.mkPen(x) for x in np.random.randint(0, 256, (param['count'], 3))], + 'brush': [pg.mkBrush(x) for x in np.random.randint(0, 256, (param['count'], 3))], + 'size': (np.random.random(param['count']) * param['size']).astype(int) + } + data['pen'][0] = pg.mkPen('w') + data['size'][0] = param['size'] + data['brush'][0] = pg.mkBrush('b') + bound = 5 * scale + p.setRange(xRange=[-bound, bound], yRange=[-bound, bound]) + mkItem() + + +def mkItem(): + global item + pyqtgraph.graphicsItems.ScatterPlotItem._USE_QRECT = param['_USE_QRECT'] + item = pg.ScatterPlotItem(pxMode=param['pxMode'], **getData()) + item.opts['useCache'] = param['useCache'] + p.clear() + p.addItem(item) + + +def getData(): + pos = data['pos'] + pen = data['pen'] + size = data['size'] + brush = data['brush'] + if not param['randomize']: + pen = pen[0] + size = size[0] + brush = brush[0] + return dict(x=pos[ptr % 50], y=pos[(ptr + 1) % 50], pen=pen, brush=brush, size=size) def update(): - global curve, data, ptr, p, lastTime, fps - p.clear() - if ui.randCheck.isChecked(): - size = sizeArray - brush = brushArray - else: - size = ui.sizeSpin.value() - brush = 'b' - curve = pg.ScatterPlotItem(x=data[ptr % 50], y=data[(ptr+1) % 50], - pen='w', brush=brush, size=size, - pxMode=ui.pixelModeCheck.isChecked()) - p.addItem(curve) + global ptr, lastTime, fps + if param['mode'] == 'newItem': + mkItem() + elif param['mode'] == 'reuseItem': + item.setData(**getData()) + elif param['mode'] == 'panZoom': + item.viewTransformChanged() + item.update() + ptr += 1 now = time() dt = now - lastTime lastTime = now if fps is None: - fps = 1.0/dt + fps = 1.0 / dt else: - s = np.clip(dt*3., 0, 1) - fps = fps * (1-s) + (1.0/dt) * s + s = np.clip(dt * 3., 0, 1) + fps = fps * (1 - s) + (1.0 / dt) * s p.setTitle('%0.2f fps' % fps) p.repaint() - #app.processEvents() ## force complete redraw for every plot -timer = QtCore.QTimer() + # app.processEvents() # force complete redraw for every plot + + +mkDataAndItem() +for name in ['count', 'size']: + param.child(name).sigValueChanged.connect(mkDataAndItem) +for name in ['_USE_QRECT', 'useCache', 'pxMode', 'randomize']: + param.child(name).sigValueChanged.connect(mkItem) +param.child('paused').sigValueChanged.connect(lambda _, v: timer.stop() if v else timer.start()) timer.timeout.connect(update) timer.start(0) - -## Start Qt event loop unless running in interactive mode. +# Start Qt event loop unless running in interactive mode. if __name__ == '__main__': import sys + if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'): QtGui.QApplication.instance().exec_() diff --git a/examples/ScatterPlotSpeedTestTemplate.ui b/examples/ScatterPlotSpeedTestTemplate.ui deleted file mode 100644 index 5cdccf0f..00000000 --- a/examples/ScatterPlotSpeedTestTemplate.ui +++ /dev/null @@ -1,59 +0,0 @@ - - - Form - - - - 0 - 0 - 400 - 300 - - - - PyQtGraph - - - - - - 10 - - - - - - - pixel mode - - - - - - - Size - - - - - - - - - - Randomize - - - - - - - - PlotWidget - QGraphicsView -
pyqtgraph
-
-
- - -
diff --git a/examples/ScatterPlotSpeedTestTemplate_pyqt5.py b/examples/ScatterPlotSpeedTestTemplate_pyqt5.py deleted file mode 100644 index 66254a5a..00000000 --- a/examples/ScatterPlotSpeedTestTemplate_pyqt5.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- - -# Form implementation generated from reading ui file 'ScatterPlotSpeedTestTemplate.ui' -# -# Created: Sun Sep 18 19:21:36 2016 -# by: pyside2-uic running on PySide2 2.0.0~alpha0 -# -# WARNING! All changes made in this file will be lost! - -from PyQt5 import QtCore, QtGui, QtWidgets - -class Ui_Form(object): - def setupUi(self, Form): - Form.setObjectName("Form") - Form.resize(400, 300) - self.gridLayout = QtWidgets.QGridLayout(Form) - self.gridLayout.setObjectName("gridLayout") - self.sizeSpin = QtWidgets.QSpinBox(Form) - self.sizeSpin.setProperty("value", 10) - self.sizeSpin.setObjectName("sizeSpin") - self.gridLayout.addWidget(self.sizeSpin, 1, 1, 1, 1) - self.pixelModeCheck = QtWidgets.QCheckBox(Form) - self.pixelModeCheck.setObjectName("pixelModeCheck") - self.gridLayout.addWidget(self.pixelModeCheck, 1, 3, 1, 1) - self.label = QtWidgets.QLabel(Form) - self.label.setObjectName("label") - self.gridLayout.addWidget(self.label, 1, 0, 1, 1) - self.plot = PlotWidget(Form) - self.plot.setObjectName("plot") - self.gridLayout.addWidget(self.plot, 0, 0, 1, 4) - self.randCheck = QtWidgets.QCheckBox(Form) - self.randCheck.setObjectName("randCheck") - self.gridLayout.addWidget(self.randCheck, 1, 2, 1, 1) - - self.retranslateUi(Form) - QtCore.QMetaObject.connectSlotsByName(Form) - - def retranslateUi(self, Form): - Form.setWindowTitle(QtWidgets.QApplication.translate("Form", "Form", None, -1)) - self.pixelModeCheck.setText(QtWidgets.QApplication.translate("Form", "pixel mode", None, -1)) - self.label.setText(QtWidgets.QApplication.translate("Form", "Size", None, -1)) - self.randCheck.setText(QtWidgets.QApplication.translate("Form", "Randomize", None, -1)) - -from pyqtgraph import PlotWidget diff --git a/examples/ScatterPlotSpeedTestTemplate_pyqt6.py b/examples/ScatterPlotSpeedTestTemplate_pyqt6.py deleted file mode 100644 index d963d8fc..00000000 --- a/examples/ScatterPlotSpeedTestTemplate_pyqt6.py +++ /dev/null @@ -1,44 +0,0 @@ -# Form implementation generated from reading ui file 'examples\ScatterPlotSpeedTestTemplate.ui' -# -# Created by: PyQt6 UI code generator 6.0.0 -# -# WARNING: Any manual changes made to this file will be lost when pyuic6 is -# run again. Do not edit this file unless you know what you are doing. - - -from PyQt6 import QtCore, QtGui, QtWidgets - - -class Ui_Form(object): - def setupUi(self, Form): - Form.setObjectName("Form") - Form.resize(400, 300) - self.gridLayout = QtWidgets.QGridLayout(Form) - self.gridLayout.setObjectName("gridLayout") - self.sizeSpin = QtWidgets.QSpinBox(Form) - self.sizeSpin.setProperty("value", 10) - self.sizeSpin.setObjectName("sizeSpin") - self.gridLayout.addWidget(self.sizeSpin, 1, 1, 1, 1) - self.pixelModeCheck = QtWidgets.QCheckBox(Form) - self.pixelModeCheck.setObjectName("pixelModeCheck") - self.gridLayout.addWidget(self.pixelModeCheck, 1, 3, 1, 1) - self.label = QtWidgets.QLabel(Form) - self.label.setObjectName("label") - self.gridLayout.addWidget(self.label, 1, 0, 1, 1) - self.plot = PlotWidget(Form) - self.plot.setObjectName("plot") - self.gridLayout.addWidget(self.plot, 0, 0, 1, 4) - self.randCheck = QtWidgets.QCheckBox(Form) - self.randCheck.setObjectName("randCheck") - self.gridLayout.addWidget(self.randCheck, 1, 2, 1, 1) - - self.retranslateUi(Form) - QtCore.QMetaObject.connectSlotsByName(Form) - - def retranslateUi(self, Form): - _translate = QtCore.QCoreApplication.translate - Form.setWindowTitle(_translate("Form", "PyQtGraph")) - self.pixelModeCheck.setText(_translate("Form", "pixel mode")) - self.label.setText(_translate("Form", "Size")) - self.randCheck.setText(_translate("Form", "Randomize")) -from pyqtgraph import PlotWidget diff --git a/examples/ScatterPlotSpeedTestTemplate_pyside2.py b/examples/ScatterPlotSpeedTestTemplate_pyside2.py deleted file mode 100644 index b0e62814..00000000 --- a/examples/ScatterPlotSpeedTestTemplate_pyside2.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- - -# Form implementation generated from reading ui file 'ScatterPlotSpeedTestTemplate.ui' -# -# Created: Sun Sep 18 19:21:36 2016 -# by: pyside2-uic running on PySide2 2.0.0~alpha0 -# -# WARNING! All changes made in this file will be lost! - -from PySide2 import QtCore, QtGui, QtWidgets - -class Ui_Form(object): - def setupUi(self, Form): - Form.setObjectName("Form") - Form.resize(400, 300) - self.gridLayout = QtWidgets.QGridLayout(Form) - self.gridLayout.setObjectName("gridLayout") - self.sizeSpin = QtWidgets.QSpinBox(Form) - self.sizeSpin.setProperty("value", 10) - self.sizeSpin.setObjectName("sizeSpin") - self.gridLayout.addWidget(self.sizeSpin, 1, 1, 1, 1) - self.pixelModeCheck = QtWidgets.QCheckBox(Form) - self.pixelModeCheck.setObjectName("pixelModeCheck") - self.gridLayout.addWidget(self.pixelModeCheck, 1, 3, 1, 1) - self.label = QtWidgets.QLabel(Form) - self.label.setObjectName("label") - self.gridLayout.addWidget(self.label, 1, 0, 1, 1) - self.plot = PlotWidget(Form) - self.plot.setObjectName("plot") - self.gridLayout.addWidget(self.plot, 0, 0, 1, 4) - self.randCheck = QtWidgets.QCheckBox(Form) - self.randCheck.setObjectName("randCheck") - self.gridLayout.addWidget(self.randCheck, 1, 2, 1, 1) - - self.retranslateUi(Form) - QtCore.QMetaObject.connectSlotsByName(Form) - - def retranslateUi(self, Form): - Form.setWindowTitle(QtWidgets.QApplication.translate("Form", "Form", None, -1)) - self.pixelModeCheck.setText(QtWidgets.QApplication.translate("Form", "pixel mode", None, -1)) - self.label.setText(QtWidgets.QApplication.translate("Form", "Size", None, -1)) - self.randCheck.setText(QtWidgets.QApplication.translate("Form", "Randomize", None, -1)) - -from pyqtgraph import PlotWidget diff --git a/examples/ScatterPlotSpeedTestTemplate_pyside6.py b/examples/ScatterPlotSpeedTestTemplate_pyside6.py deleted file mode 100644 index c529b167..00000000 --- a/examples/ScatterPlotSpeedTestTemplate_pyside6.py +++ /dev/null @@ -1,63 +0,0 @@ -# -*- coding: utf-8 -*- - -################################################################################ -## Form generated from reading UI file 'ScatterPlotSpeedTestTemplate.ui' -## -## Created by: Qt User Interface Compiler version 6.0.0 -## -## WARNING! All changes made in this file will be lost when recompiling UI file! -################################################################################ - -from PySide6.QtCore import * -from PySide6.QtGui import * -from PySide6.QtWidgets import * - -from pyqtgraph import PlotWidget - - -class Ui_Form(object): - def setupUi(self, Form): - if not Form.objectName(): - Form.setObjectName(u"Form") - Form.resize(400, 300) - self.gridLayout = QGridLayout(Form) - self.gridLayout.setObjectName(u"gridLayout") - self.sizeSpin = QSpinBox(Form) - self.sizeSpin.setObjectName(u"sizeSpin") - self.sizeSpin.setValue(10) - - self.gridLayout.addWidget(self.sizeSpin, 1, 1, 1, 1) - - self.pixelModeCheck = QCheckBox(Form) - self.pixelModeCheck.setObjectName(u"pixelModeCheck") - - self.gridLayout.addWidget(self.pixelModeCheck, 1, 3, 1, 1) - - self.label = QLabel(Form) - self.label.setObjectName(u"label") - - self.gridLayout.addWidget(self.label, 1, 0, 1, 1) - - self.plot = PlotWidget(Form) - self.plot.setObjectName(u"plot") - - self.gridLayout.addWidget(self.plot, 0, 0, 1, 4) - - self.randCheck = QCheckBox(Form) - self.randCheck.setObjectName(u"randCheck") - - self.gridLayout.addWidget(self.randCheck, 1, 2, 1, 1) - - - self.retranslateUi(Form) - - QMetaObject.connectSlotsByName(Form) - # setupUi - - def retranslateUi(self, Form): - Form.setWindowTitle(QCoreApplication.translate("Form", u"PyQtGraph", None)) - self.pixelModeCheck.setText(QCoreApplication.translate("Form", u"pixel mode", None)) - self.label.setText(QCoreApplication.translate("Form", u"Size", None)) - self.randCheck.setText(QCoreApplication.translate("Form", u"Randomize", None)) - # retranslateUi -