diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
new file mode 100644
index 00000000..0974fe1f
--- /dev/null
+++ b/.github/workflows/codeql-analysis.yml
@@ -0,0 +1,55 @@
+name: codeql
+
+on: [push, pull_request]
+
+jobs:
+ analyze:
+ name: analyze
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v2
+ with:
+ # We must fetch at least the immediate parents so that if this is
+ # a pull request then we can checkout the head.
+ fetch-depth: 2
+ - name: Setup Python
+ uses: actions/setup-python@v2
+ with:
+ python-version: '3.9'
+ - name: Install Dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install PyQt5 numpy scipy
+ echo "CODEQL_PYTHON=$(which python)" >> $GITHUB_ENV
+
+ # Initializes the CodeQL tools for scanning.
+ - name: Initialize CodeQL
+ uses: github/codeql-action/init@v1
+ with:
+ languages: 'python'
+ # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
+ # If you wish to specify custom queries, you can do so here or in a config file.
+ # By default, queries listed here will override any specified in a config file.
+ # Prefix the list here with "+" to use these queries and those in the config file.
+ queries: +security-and-quality
+ setup-python-dependencies: false
+
+ # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
+ # If this step fails, then you should remove it and run the build manually (see below)
+ - name: Autobuild
+ uses: github/codeql-action/autobuild@v1
+
+ # ℹ️ Command-line programs to run using the OS shell.
+ # 📚 https://git.io/JvXDl
+
+ # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
+ # and modify them (or add more) to build your code if your project
+ # uses a compiled language
+
+ #- run: |
+ # make bootstrap
+ # make release
+
+ - name: Perform CodeQL Analysis
+ uses: github/codeql-action/analyze@v1
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 00000000..781aeebb
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,155 @@
+name: main
+
+on: [push, pull_request]
+
+jobs:
+ test:
+ runs-on: ${{ matrix.os }}
+ timeout-minutes: 30
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ubuntu-20.04 , windows-latest, macos-latest]
+ qt-lib: [pyqt, pyside]
+ python-version: [3.7, 3.8, 3.9]
+ include:
+ - python-version: "3.7"
+ qt-lib: "pyqt"
+ qt-version: "PyQt5~=5.12.0"
+ numpy-version: "~=1.17.0"
+ - python-version: "3.7"
+ qt-lib: "pyside"
+ qt-version: "PySide2~=5.12.0"
+ numpy-version: "~=1.17.0"
+ - python-version: "3.8"
+ qt-lib: "pyqt"
+ qt-version: "PyQt5~=5.15.0"
+ numpy-version: "~=1.19.0"
+ - python-version: "3.8"
+ qt-lib: "pyside"
+ qt-version: "PySide2~=5.15.0"
+ numpy-version: "~=1.19.0"
+ - python-version: "3.9"
+ qt-lib: "pyqt"
+ qt-version: "PyQt6"
+ numpy-version: "~=1.19.0"
+ - python-version: "3.9"
+ qt-lib: "pyside"
+ qt-version: "PySide6"
+ numpy-version: "~=1.19.0"
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ - name: Checkout test-data
+ uses: actions/checkout@v2
+ with:
+ repository: pyqtgraph/test-data
+ path: .pyqtgraph/test-data
+ - name: Setup Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v2
+ with:
+ # Semantic version range syntax or exact version of a Python version
+ python-version: ${{ matrix.python-version }}
+ - name: "Install Windows-Mesa OpenGL DLL"
+ if: runner.os == 'Windows'
+ run: |
+ curl -LJO https://github.com/pal1000/mesa-dist-win/releases/download/19.2.7/mesa3d-19.2.7-release-msvc.7z
+ 7z x mesa3d-19.2.7-release-msvc.7z
+ cd x64
+ xcopy opengl32.dll C:\windows\system32\mesadrv.dll*
+ xcopy opengl32.dll C:\windows\syswow64\mesadrv.dll*
+ REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\OpenGLDrivers\MSOGL" /v DLL /t REG_SZ /d "mesadrv.dll" /f
+ REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\OpenGLDrivers\MSOGL" /v DriverVersion /t REG_DWORD /d 1 /f
+ REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\OpenGLDrivers\MSOGL" /v Flags /t REG_DWORD /d 1 /f
+ REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\OpenGLDrivers\MSOGL" /v Version /t REG_DWORD /d 2 /f
+ REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\OpenGLDrivers\MSOGL" /v DLL /t REG_SZ /d "mesadrv.dll" /f
+ REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\OpenGLDrivers\MSOGL" /v DriverVersion /t REG_DWORD /d 1 /f
+ REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\OpenGLDrivers\MSOGL" /v Flags /t REG_DWORD /d 1 /f
+ REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\OpenGLDrivers\MSOGL" /v Version /t REG_DWORD /d 2 /f
+ shell: cmd
+ - name: Install Dependencies
+ run: |
+ pip install --upgrade pip
+ pip install ${{ matrix.qt-version }} numpy${{ matrix.numpy-version }} scipy pyopengl h5py matplotlib
+ pip install .
+ pip install pytest pytest-cov pytest-xdist coverage
+ - name: "Install Linux VirtualDisplay"
+ if: runner.os == 'Linux'
+ run: |
+ sudo apt-get update -y
+ sudo apt-get install -y libxkbcommon-x11-0 x11-utils
+ sudo apt-get install --no-install-recommends -y libyaml-dev libegl1-mesa libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0
+ sudo apt-get install -y libopengl0
+ pip install pytest-xvfb
+ - name: 'Debug Info'
+ run: |
+ echo python location: `which python`
+ echo python version: `python --version`
+ echo pytest location: `which pytest`
+ echo installed packages
+ pip list
+ echo pyqtgraph system info
+ python -c "import pyqtgraph as pg; pg.systemInfo()"
+ shell: bash
+ env:
+ QT_DEBUG_PLUGINS: 1
+ - name: 'XVFB Display Info'
+ run: |
+ xvfb-run --server-args="-screen 0, 1920x1200x24 -ac +extension GLX +render -noreset" python -c "from pyqtgraph.opengl.glInfo import GLTest"
+ xvfb-run --server-args="-screen 0, 1920x1200x24 -ac +extension GLX +render -noreset" python -m pyqtgraph.util.get_resolution
+ if: runner.os == 'Linux'
+ - name: 'Display Info'
+ run: |
+ python -c "from pyqtgraph.opengl.glInfo import GLTest"
+ python -m pyqtgraph.util.get_resolution
+ if: runner.os != 'Linux'
+ - name: Run Tests
+ run: |
+ mkdir $SCREENSHOT_DIR
+ pytest . -v \
+ -n auto \
+ --junitxml pytest.xml \
+ --cov pyqtgraph --cov-report=xml --cov-report=html
+ shell: bash
+ - name: Upload Screenshots
+ uses: actions/upload-artifact@v2
+ with:
+ name: Screenshots (Python ${{ matrix.python-version }} - Qt-Bindings ${{ matrix.qt-lib }} - OS ${{ matrix.os }})
+ path: $SCREENSHOT_DIR
+ if-no-files-found: ignore
+ env:
+ SCREENSHOT_DIR: ./screenshots
+
+ build-docs:
+ name: build docs
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Setup Python 3.9
+ uses: actions/setup-python@v2
+ with:
+ python-version: '3.9'
+ - name: Install Dependencies
+ run: |
+ cd doc
+ python -m pip install -r requirements.txt
+ - name: Build Documentation
+ run: |
+ cd doc
+ make html SPHINXOPTS='-W --keep-going -v'
+
+ build-wheel:
+ name: build wheel
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Setup Python 3.9
+ uses: actions/setup-python@v2
+ with:
+ python-version: '3.9'
+ - name: Build Wheel
+ run: |
+ python -m pip install setuptools wheel
+ python setup.py bdist_wheel
diff --git a/.gitignore b/.gitignore
index 78309170..8a81fee3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -107,3 +107,4 @@ rtr.cvs
# ctags
.tags*
+.asv/
diff --git a/CHANGELOG b/CHANGELOG
index efc3ee3b..d4f65c89 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,169 @@
+pyqtgraph-0.11.1
+
+ New Features:
+ - #800 Legend for bar graphs
+ - #1244 Arrow scatter symbols
+ - #161 Allow hiding individulal points in scatter plot
+ - #395 LegendItem display options
+ - #1310 Added `Pa` to Units
+ - #1310 `debug.ThreadTrace` add support for thread names
+ - #117 Flow Chart Nodes now resized based on number of inputs/outputs
+ - #1154 `DateAxisItem`
+ - #1285 Improve control over ROI/handle pens
+ - #1273 `PColorMeshItem`
+ - #1397 `LegendItem` enable customization of label text size
+ - #1422 Permit entry of non-finite values into float `SpinBox`
+ - #1442 `TickSliderItem.allowRemote` property added
+ - #1441 `Tick.removeAllowed` is now a regular property and used with `TickSliderItem`
+ - #1388 Emit a signal when `GraphicsScene` `addItem` or `removeItem` methods called
+
+ Performance enhancement:
+ - #1240/#345 GLImageItem clear need update flag
+ - #977 Faster computation option for pseudoscatter
+ - #1297 Improve ArrowItem performance
+ - #1296 Update `h5py` deps in metaarray
+ - #1295 Improve TextItem performance
+ - #1283 Performance improvements to arrayToQPath
+ - #816 Avoid constructing shadow pens when no shadow pen is set
+ - #1311 HistogramLUTItem detect trivial gradients
+ - #1312 avoid extra work when setLabelAngle would have no effect
+ - #1391 cache viewRect of `GraphicsItem` to reduce CPU load
+ - #150 Slight speedup to ViewBox panning
+ - #1420 Many ScatterPlot Improvements
+
+ API/Behavior Change:
+ - #496 Always antialias lines between gradient and region in HistogramLUTItem
+ - #385 Add headWidth parameter to arrows
+ - #551 fps variable on ImageView
+ - #1251 Allow explict utcOffset timezone in DateAxisItem
+ - #1310 Add `SignalProxy.block` for temporary disabling of signal forwarding
+ - #1310 `InfiniteLine.setPos` add support for array argument
+ - #1310 Rate-limit Qt event processing in ProgressDialog if it is modal
+ - #1289 Disable autoSIPrefix for DateAxisItem by default
+ - #1274 Add tickAlpha to AxisItem Style Options
+ - #402 Added `clear()` method to `GLViewWidget`
+ - #1264 Added exception to checkOpenGLVersion to highlight OpenGL ES incompatability
+ - #1257 Make painter tick font dependent for AxisItem
+ - #1256 Added `setState`, `setState` and `saveState` to `ROI`
+ - #1324 Pass through kwargs from MultiPlotItem.plot to PlotItem.plot
+ - #1387 ScatterPlotItem: Make + and x symbols thicker
+ - #1362 Make flowchart.Terminal sortable
+ - #1360 Add "left" and "right" step Modes to PlotCurveItem and PlotDataItem
+ - #1414 Emit event with mouse clicks for some items
+ - #1413 `InfiniteLine.viewTransformChanged` now calls superclass-method
+ - #1411 Hide `WidgetParameterItem.defaultBtn` if param has no default
+ - #1410 add fontSize kwarg to `Dock`
+ - #159 Add wrapping option to `SpinBox`
+ - #330 Set parameter default button `autoDefault` value to `False`
+ - #157 Provide `WidgetGroupInterface` to `GradientWidget`
+ - #151 Optional provide custom `PlotItem` to `PlotWidget`
+ - #1140 Dynamic range limiting in `PlotDataItem`
+ - #1383 GraphicsView set a transparent background palette
+ - #1428 Add default color for `ColorMap` type in `ColorMapWidget`
+
+ Bug Fixes:
+ - #1239 Avoid adding PlotItem twice
+ - #508 siScale precision
+ - #503 Fix butg in RawImageWidget which resulted in mirrored image
+ - #1242,#1267 Add the mouse event to the sigClicked signal in PlotCurveItem
+ - #1247 Restore the now-deprecated PlotWindow and ImageWindow classes
+ - #1249 Remove ScatterPlotItem's SpotItems during addItem call
+ - #1252 Fix incorrect tick text boundaries calculation on axis by setting the font
+ - #1310 Fixed `Vector.__init__` when used with `QVector3D` argument
+ - #1310 Fix console exception filtering for python3
+ - #1310 BusyCursor only restore cursor after all nested levels have exited
+ - #1310 `SimpleParameter.setValue` coerces argument to int if parameter type is int
+ - #1307 Fixed `reload` methods for python3
+ - #1294 Various console fixes
+ - #1293 Various Python3 code fixes
+ - #1282 Handle Axis SI prefix scaling in MatplotlibExporter
+ - #1276 Fix problems with high frequency gaming mice
+ - #1270 Various fixes with AxisItem space being taken
+ - #1272 `LegendItem.clear()` fixed
+ - #1268 Check for container before setting dock orientation
+ - #1312 Avoid divide by 0 condition in TargetItem
+ - #1309 Properly retain and use hoverPen argument in _PolyLineSegment
+ - #1371 Explicitly set line width in PlotCurveItem when using OpenGL
+ - #1319 don't automatically reload modules without pyc
+ - #1319 make ptime.time on py3 return precision wall-clock time
+ - #1334 Edge case detection in PlotCurveItem
+ - #1339 fix handling of QVector3D args in Vector.__init__
+ - #1336 Make `parent` an explicit kwarg of ArrowItem.__init__, avoid passing into setStyle
+ - #1368 Disconnect from correct slots in Flowchart
+ - #1364 fix log scaling
+ - #963 Allow last image in stack to be selected by slider in ImageView
+ - #1045 Raise AttributeError in __getattr__ in TabWindow
+ - #960 Work around PySide setOverrideCursor bug in BusyCursor
+ - #309 Encode QPropertyAnimation property name if not passed as bytes
+ - #1072 Fix storing of ragged curves in HDF5Exporter
+ - #1275 Fix Parameter.hasDefault
+ - #1291 Get ImageView ROI working with both row and col major data
+ - #1377 Consolidate and fix downsample factor computation in ImageItem
+ - #1376 Fix PlotItem.setAxisItems
+ - #1392 SignalProxy: Correct initialization without slot argument
+ - #1306 Fix incorrect rendering of overlapping object in renderToArray()
+ - #1349 Avoid calling method on undefined attribute
+ - #1367 AxisItem: Account for empty strings in the visibility of text and units
+ - #1356 Fix `ParameterTree` tree name and title handling
+ - #1419 Fix `DataTreeWidget` dict sorting crash
+ - #1408 Fix mouse interaction issues with `DockLabel`
+ - #329 Fix bug where `int` and `float` parameter limits are not always set
+ - #158 Make `DockArea` compatible with Qt Designer
+ - #1405 Fix name setting in `ScatterPlotItem` options
+ - #1403 Do not apply transparent background to Qt4
+ - #1468 Allow zero step in `ImageItem`
+ - #1464 Remove `ViewBox.childGroup`'s `ItemClipsChildrenToShape` flag
+ - #1461 arrayToQPath revert to old behavior of `connect=ndarray` parameter
+ - #1459 Fix `TickSliderItem` to avoid ghost ticks
+ - #1456 Resolve issue with `PlotCurveItem` with merging PRs in an incorrect order
+ - #1287 Fill in non-finite plot values for Qt versions >= 5.12.3
+ - #1447 Clipped AxisItem tick value labels to prevent drawing artifacts
+ - #1435 Fix autosize not taking to the correct range with `TextItem` in view
+ - #1452 merge `InfiniteLine` caching calls
+ - #1446 Fix `PlotDataItem.setData([], [])`
+ - #1443 Fix Viewbox axis zoom in RectMode
+ - #1439 Fix `TickSliderItem.setTickValue` when it references a `GradientEditorItem` method
+ - #1361 Prevent item duplication in `Node` context menu
+ - #1423 Fix typo in `kwargs` for `GridItem.setTextPen`
+ - #1401 Fix width, height and background in SVG exporter
+ - #1416 Handle case in `ROI` when `shape`, `vectors`, or `origin` keywords are passed in
+
+ Maintenance:
+ - #389 Revert workaround for upstream QT bug regarding mouse events
+ - #1243 Ensure setPos in ROI is initialized correctly
+ - #1241 Pin pytest-xvfb version on py2
+ - #1310 Added tests for `functions.subArray`
+ - #1307 Add `ThreadSafeTimer` to `__init__.py`
+ - #467 derivatePlots cleanup
+ - #400 `ImageView.Timeline` better visibility
+ - #1265 Make the documentation reproducible
+ - #1319 clean up exception messages in console
+ - #356 Fix some NumPy warnings
+ - #1326 Improve docs for MultiPlotWidget and MultiPlotItem
+ - #1331 Migrate imports of PyQt5's sip module to new namespace
+ - #1370 Fix deprecation warning in multiprocess module
+ - #308 Fix opt name for SpinBox: range -> bounds in UnsharpMaskNode example
+ - #887 Update collections.abc imports
+ - #1142 Miscellaneous doc fixups
+ - #1169 Avoid using mutable default argument value
+ - #1073 Python3 fixes
+ - #1284 Update doc strings to clarify getArrayRegion API for ROI subclasses
+ - #1042 Close windows at the end of test functions
+ - #1374 Test warnings cleanup
+ - #1375 Add targeted Vector test coverage
+ - #1384 GLViewWidget.pan docstring typo
+ - #1382 Autoformat LegendItem
+ - #1396 Add tests for GraphicsView
+ - #1399 Disable mouse rate limiting on test_ROI
+ - #1409 Prepend conda-forge channel prior to env creation in CI
+ - #1302 Fix Example app now works with Qt4/Python2
+ - #1402 Handle case of version string having no `+`
+ - #1400 Fix sphinx warnings on `PColorMeshItem`
+ - #1328 Add docs build job to CI
+ - #1464 Use `conda-forge` on pyside2+linux
+ - #1448 Fixes for `examples/CustomPlot.py`
+ - #1432 ExampleApp fix to use `pg` module from directory
+
pyqtgraph-0.11.0
NOTICE: This is the _last_ feature release to support Python 2 and Qt 4 (PyQt4 or pyside 1)
diff --git a/README.md b/README.md
index a1043fbb..d92402d2 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,15 @@
-
-[![Build Status](https://pyqtgraph.visualstudio.com/pyqtgraph/_apis/build/status/pyqtgraph.pyqtgraph?branchName=master)](https://pyqtgraph.visualstudio.com/pyqtgraph/_build/latest?definitionId=17&branchName=master)
-[![Documentation Status](https://readthedocs.org/projects/pyqtgraph/badge/?version=latest)](https://pyqtgraph.readthedocs.io/en/latest/?badge=latest)
-
PyQtGraph
=========
-A pure-Python graphics library for PyQt/PySide/PyQt5/PySide2
+[![PyPi](https://img.shields.io/pypi/v/pyqtgraph.svg)](https://pypi.org/project/pyqtgraph/)
+[![conda-forge](https://img.shields.io/conda/vn/conda-forge/pyqtgraph.svg)](https://anaconda.org/conda-forge/pyqtgraph)
+[![Build Status](https://github.com/pyqtgraph/pyqtgraph/workflows/main/badge.svg)](https://github.com/pyqtgraph/pyqtgraph/actions/?query=workflow%3Amain)
+[![CodeQL Status](https://github.com/pyqtgraph/pyqtgraph/workflows/codeql/badge.svg)](https://github.com/pyqtgraph/pyqtgraph/actions/?query=workflow%3Acodeql)
+[![Documentation Status](https://readthedocs.org/projects/pyqtgraph/badge/?version=latest)](https://pyqtgraph.readthedocs.io/en/latest/?badge=latest)
+[![Total alerts](https://img.shields.io/lgtm/alerts/g/pyqtgraph/pyqtgraph.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/pyqtgraph/pyqtgraph/alerts/)
+[![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/pyqtgraph/pyqtgraph.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/pyqtgraph/pyqtgraph/context:python)
+
+A pure-Python graphics library for PyQt5/PyQt6/PySide2/PySide6
Copyright 2020 Luke Campagnola, University of North Carolina at Chapel Hill
@@ -19,31 +23,43 @@ heavy leverage of numpy for number crunching, Qt's GraphicsView framework for
Requirements
------------
-* Python 2.7, or 3.x
+pyqtgraph has adopted [NEP 29](https://numpy.org/neps/nep-0029-deprecation_policy.html).
+
+This project supports:
+
+* All minor versions of Python released 42 months prior to the project, and at minimum the two latest minor versions.
+* All minor versions of numpy released in the 24 months prior to the project, and at minimum the last three minor versions.
+* All minor versions of Qt 5 and Qt 6 currently supported by upstream Qt
+
+Currently this means:
+
+* Python 3.7+
+* Qt 5.12-6.0
* Required
- * PyQt 4.8+, PySide, PyQt5, or PySide2
- * `numpy`
+ * PyQt5, PyQt6, PySide2 or PySide6
+ * `numpy` 1.17+
* Optional
* `scipy` for image processing
* `pyopengl` for 3D graphics
+ * `pyopengl` on macOS Big Sur only works with python 3.9.1+
* `hdf5` for large hdf5 binary format support
+ * `colorcet` for supplemental colormaps
+ * [`cupy`](https://docs.cupy.dev/en/stable/install.html) for CUDA-enhanced image processing
+ * On Windows, CUDA toolkit must be >= 11.1
Qt Bindings Test Matrix
-----------------------
-The following table represents the python environments we test in our CI system. Our CI system uses Ubuntu 18.04, Windows Server 2019, and macOS 10.15 base images.
+The following table represents the python environments we test in our CI system. Our CI system uses Ubuntu 20.04, Windows Server 2019, and macOS 10.15 base images.
-| Qt-Bindings | Python 2.7 | Python 3.6 | Python 3.7 | Python 3.8 |
-| :------------- | :----------------: | :----------------: | :----------------: | :----------------: |
-| PyQt-4 | :white_check_mark: | :x: | :x: | :x: |
-| PySide1 | :white_check_mark: | :x: | :x: | :x: |
-| PyQt5-5.9 | :x: | :white_check_mark: | :x: | :x: |
-| PySide2-5.13 | :x: | :x: | :white_check_mark: | :x: |
-| PyQt5-Latest | :x: | :x: | :x: | :white_check_mark: |
-| PySide2-Latest | :x: | :x: | :x: | :white_check_mark: |
-
-* pyqtgraph has had some incompatibilities with PySide2 versions 5.6-5.11, and we recommend you avoid those versions if possible
-* on macOS with Python 2.7 and Qt4 bindings (PyQt4 or PySide) the openGL related visualizations do not work reliably
+| Qt-Bindings | Python 3.7 | Python 3.8 | Python 3.9 |
+| :------------- | :----------------: | :----------------: | :----------------: |
+| PySide2-5.12 | :white_check_mark: | :x: | :x: |
+| PyQt5-5.12 | :white_check_mark: | :x: | :x: |
+| PySide2-5.15 | :x: | :white_check_mark: | :x: |
+| PyQt5-5.15 | :x: | :white_check_mark: | :x: |
+| PySide6-6.0 | :x: | :x: | :white_check_mark: |
+| PyQt6-6.0 | :x: | :x: | :white_check_mark: |
Support
-------
@@ -67,6 +83,6 @@ Installation Methods
Documentation
-------------
-The official documentation lives at https://pyqtgraph.readthedocs.io
+The official documentation lives at [pyqtgraph.readthedocs.io](https://pyqtgraph.readthedocs.io)
The easiest way to learn pyqtgraph is to browse through the examples; run `python -m pyqtgraph.examples` to launch the examples application.
diff --git a/asv.conf.json b/asv.conf.json
new file mode 100644
index 00000000..bb7d805d
--- /dev/null
+++ b/asv.conf.json
@@ -0,0 +1,140 @@
+{
+ // The version of the config file format. Do not change, unless
+ // you know what you are doing.
+ "version": 1,
+
+ // The name of the project being benchmarked
+ "project": "pyqtgraph",
+
+ // The project's homepage
+ "project_url": "http://pyqtgraph.org/",
+
+ // The URL or local path of the source code repository for the
+ // project being benchmarked
+ "repo": ".",
+
+ // List of branches to benchmark. If not provided, defaults to "master"
+ // (for git) or "default" (for mercurial).
+ "branches": ["master"], // for git
+ // "branches": ["default"], // for mercurial
+
+ // The DVCS being used. If not set, it will be automatically
+ // determined from "repo" by looking at the protocol in the URL
+ // (if remote), or by looking for special directories, such as
+ // ".git" (if local).
+ // "dvcs": "git",
+
+ // The tool to use to create environments. May be "conda",
+ // "virtualenv" or other value depending on the plugins in use.
+ // If missing or the empty string, the tool will be automatically
+ // determined by looking for tools on the PATH environment
+ // variable.
+ "environment_type": "conda",
+
+ // timeout in seconds for installing any dependencies in environment
+ // defaults to 10 min
+ //"install_timeout": 600,
+
+ // the base URL to show a commit for the project.
+ "show_commit_url": "http://github.com/pyqtgraph/pyqtgraph/commit/",
+
+ // The Pythons you'd like to test against. If not provided, defaults
+ // to the current version of Python used to run `asv`.
+ "pythons": ["2.7", "3.8"],
+
+ // The matrix of dependencies to test. Each key is the name of a
+ // package (in PyPI) and the values are version numbers. An empty
+ // list or empty string indicates to just test against the default
+ // (latest) version. null indicates that the package is to not be
+ // installed. If the package to be tested is only available from
+ // PyPi, and the 'environment_type' is conda, then you can preface
+ // the package name by 'pip+', and the package will be installed via
+ // pip (with all the conda available packages installed first,
+ // followed by the pip installed packages).
+ //
+ "matrix": {
+ "numpy": [],
+ "numba": [],
+ "pyqt": ["4", "5"],
+ },
+
+ // Combinations of libraries/python versions can be excluded/included
+ // from the set to test. Each entry is a dictionary containing additional
+ // key-value pairs to include/exclude.
+ //
+ // An exclude entry excludes entries where all values match. The
+ // values are regexps that should match the whole string.
+ //
+ // An include entry adds an environment. Only the packages listed
+ // are installed. The 'python' key is required. The exclude rules
+ // do not apply to includes.
+ //
+ // In addition to package names, the following keys are available:
+ //
+ // - python
+ // Python version, as in the *pythons* variable above.
+ // - environment_type
+ // Environment type, as above.
+ // - sys_platform
+ // Platform, as in sys.platform. Possible values for the common
+ // cases: 'linux2', 'win32', 'cygwin', 'darwin'.
+ //
+ "exclude": [
+ {"python": "3.8", "pyqt": "4"},
+ ],
+ //
+ // "include": [
+ // // additional env for python2.7
+ // {"python": "2.7", "numpy": "1.8"},
+ // // additional env if run on windows+conda
+ // {"platform": "win32", "environment_type": "conda", "python": "2.7", "libpython": ""},
+ // ],
+
+ // The directory (relative to the current directory) that benchmarks are
+ // stored in. If not provided, defaults to "benchmarks"
+ "benchmark_dir": "benchmarks",
+
+ // The directory (relative to the current directory) to cache the Python
+ // environments in. If not provided, defaults to "env"
+ "env_dir": ".asv/env",
+
+ // The directory (relative to the current directory) that raw benchmark
+ // results are stored in. If not provided, defaults to "results".
+ "results_dir": ".asv/results",
+
+ // The directory (relative to the current directory) that the html tree
+ // should be written to. If not provided, defaults to "html".
+ "html_dir": ".asv/html",
+
+ // The number of characters to retain in the commit hashes.
+ // "hash_length": 8,
+
+ // `asv` will cache wheels of the recent builds in each
+ // environment, making them faster to install next time. This is
+ // number of builds to keep, per environment.
+ "build_cache_size": 5
+
+ // The commits after which the regression search in `asv publish`
+ // should start looking for regressions. Dictionary whose keys are
+ // regexps matching to benchmark names, and values corresponding to
+ // the commit (exclusive) after which to start looking for
+ // regressions. The default is to start from the first commit
+ // with results. If the commit is `null`, regression detection is
+ // skipped for the matching benchmark.
+ //
+ // "regressions_first_commits": {
+ // "some_benchmark": "352cdf", // Consider regressions only after this commit
+ // "another_benchmark": null, // Skip regression detection altogether
+ // }
+
+ // The thresholds for relative change in results, after which `asv
+ // publish` starts reporting regressions. Dictionary of the same
+ // form as in ``regressions_first_commits``, with values
+ // indicating the thresholds. If multiple entries match, the
+ // maximum is taken. If no entry matches, the default is 5%.
+ //
+ // "regressions_thresholds": {
+ // "some_benchmark": 0.01, // Threshold of 1%
+ // "another_benchmark": 0.5, // Threshold of 50%
+ // }
+}
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
deleted file mode 100644
index 5e87923e..00000000
--- a/azure-pipelines.yml
+++ /dev/null
@@ -1,113 +0,0 @@
-trigger:
- branches:
- include:
- - '*' # Build for all branches if they have a azure-pipelines.yml file.
- tags:
- include:
- - 'v*' # Ensure that we are building for tags starting with 'v' (Official Versions)
-
-# Build only for PRs for master branch
-pr:
- autoCancel: true
- branches:
- include:
- - master
- - develop
-
-variables:
- OFFICIAL_REPO: 'pyqtgraph/pyqtgraph'
- DEFAULT_MERGE_BRANCH: 'master'
- disable.coverage.autogenerate: 'true'
-
-stages:
-- stage: pre_build
- jobs:
- - job: check_diff_size
- pool:
- vmImage: 'Ubuntu 18.04'
- steps:
- - bash: |
- git config --global advice.detachedHead false
- mkdir ~/repo-clone && cd ~/repo-clone
- git init
-
- git remote add -t $(Build.SourceBranchName) origin $(Build.Repository.Uri)
- git remote add -t ${DEFAULT_MERGE_BRANCH} upstream https://github.com/${OFFICIAL_REPO}.git
-
- git fetch origin $(Build.SourceBranchName)
- git fetch upstream ${DEFAULT_MERGE_BRANCH}
-
- git checkout $(Build.SourceBranchName)
- MERGE_SIZE=`du -s . | sed -e "s/\t.*//"`
- echo -e "Merge Size ${MERGE_SIZE}"
-
- git checkout ${DEFAULT_MERGE_BRANCH}
- TARGET_SIZE=`du -s . | sed -e "s/\t.*//"`
- echo -e "Target Size ${TARGET_SIZE}"
-
- if [ "${MERGE_SIZE}" != "${TARGET_SIZE}" ]; then
- SIZE_DIFF=`expr \( ${MERGE_SIZE} - ${TARGET_SIZE} \)`;
- else
- SIZE_DIFF=0;
- fi;
- echo -e "Estimated content size difference = ${SIZE_DIFF} kB" &&
- test ${SIZE_DIFF} -lt 100;
- displayName: 'Diff Size Check'
- - job: "style_check"
- pool:
- vmImage: "Ubuntu 18.04"
- steps:
- - task: UsePythonVersion@0
- inputs:
- versionSpec: 3.7
- - bash: |
- pip install flake8
- python setup.py style
- displayName: 'flake8 check'
- - job: "build_docs"
- pool:
- vmImage: 'Ubuntu 18.04'
- steps:
- - task: UsePythonVersion@0
- inputs:
- versionSpec: 3.8
- - script: |
- cd doc
- python -m pip install -r requirements.txt
- make html SPHINXOPTS='-W -v'
- displayName: "Build docs"
-
-- stage: build
- dependsOn: []
- jobs:
- - job: "build_wheel"
- pool:
- vmImage: 'Ubuntu 18.04'
- steps:
- - task: UsePythonVersion@0
- inputs:
- versionSpec: 3.8
- - script: |
- python -m pip install setuptools wheel
- python setup.py bdist_wheel --universal
- displayName: "Build Python Wheel"
- continueOnError: false
- - publish: dist
- artifact: wheel
-
-- stage: test
- displayName: "Test Suite"
- dependsOn: build
- jobs:
- - template: azure-test-template.yml
- parameters:
- name: linux
- vmImage: 'Ubuntu 18.04'
- - template: azure-test-template.yml
- parameters:
- name: windows
- vmImage: 'windows-2019'
- - template: azure-test-template.yml
- parameters:
- name: macOS
- vmImage: 'macOS-10.15'
\ No newline at end of file
diff --git a/azure-test-template.yml b/azure-test-template.yml
deleted file mode 100644
index ad7b5d62..00000000
--- a/azure-test-template.yml
+++ /dev/null
@@ -1,216 +0,0 @@
-# Azure Pipelines CI job template for PyDM Tests
-# https://docs.microsoft.com/en-us/azure/devops/pipelines/languages/anaconda?view=azure-devops
-parameters:
- name: ''
- vmImage: ''
-
-jobs:
-- job: ${{ parameters.name }}
- pool:
- vmImage: ${{ parameters.vmImage }}
- strategy:
- matrix:
- Python27-PyQt4-4.8:
- python.version: '2.7'
- qt.bindings: "pyqt=4"
- install.method: "conda"
- Python27-PySide-4.8:
- python.version: '2.7'
- qt.bindings: "pyside"
- install.method: "conda"
- Python36-PyQt5-5.9:
- python.version: "3.6"
- qt.bindings: "pyqt"
- install.method: "conda"
- Python37-PySide2-5.13:
- python.version: "3.7"
- qt.bindings: "pyside2"
- install.method: "conda"
- Python38-PyQt5-Latest:
- python.version: '3.8'
- qt.bindings: "PyQt5"
- install.method: "pip"
- Python38-PySide2-Latest:
- python.version: '3.8'
- qt.bindings: "PySide2"
- install.method: "pip"
-
- steps:
- - task: DownloadPipelineArtifact@2
- inputs:
- source: 'current'
- artifact: wheel
- path: 'dist'
-
- - task: ScreenResolutionUtility@1
- inputs:
- displaySettings: 'specific'
- width: '1920'
- height: '1080'
- condition: eq(variables['agent.os'], 'Windows_NT' )
-
- - task: UsePythonVersion@0
- inputs:
- versionSpec: $(python.version)
- condition: eq(variables['install.method'], 'pip')
-
- - script: |
- curl -LJO https://github.com/pal1000/mesa-dist-win/releases/download/19.1.0/mesa3d-19.1.0-release-msvc.exe
- 7z x mesa3d-19.1.0-release-msvc.exe
- cd x64
- xcopy opengl32.dll C:\windows\system32\mesadrv.dll*
- xcopy opengl32.dll C:\windows\syswow64\mesadrv.dll*
- REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\OpenGLDrivers\MSOGL" /v DLL /t REG_SZ /d "mesadrv.dll" /f
- REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\OpenGLDrivers\MSOGL" /v DriverVersion /t REG_DWORD /d 1 /f
- REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\OpenGLDrivers\MSOGL" /v Flags /t REG_DWORD /d 1 /f
- REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\OpenGLDrivers\MSOGL" /v Version /t REG_DWORD /d 2 /f
- REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\OpenGLDrivers\MSOGL" /v DLL /t REG_SZ /d "mesadrv.dll" /f
- REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\OpenGLDrivers\MSOGL" /v DriverVersion /t REG_DWORD /d 1 /f
- REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\OpenGLDrivers\MSOGL" /v Flags /t REG_DWORD /d 1 /f
- REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\OpenGLDrivers\MSOGL" /v Version /t REG_DWORD /d 2 /f
- displayName: "Install Windows-Mesa OpenGL DLL"
- condition: eq(variables['agent.os'], 'Windows_NT')
-
- - bash: |
- if [ $(agent.os) == 'Linux' ]
- then
- echo "##vso[task.prependpath]$CONDA/bin"
- elif [ $(agent.os) == 'Darwin' ]
- then
- sudo chown -R $USER $CONDA
- echo "##vso[task.prependpath]$CONDA/bin"
- elif [ $(agent.os) == 'Windows_NT' ]
- then
- echo "##vso[task.prependpath]$CONDA/Scripts"
- else
- echo 'Just what OS are you using?'
- fi
- displayName: 'Add Conda To $PATH'
- condition: eq(variables['install.method'], 'conda' )
- continueOnError: false
-
- - bash: |
- if [ $(install.method) == "conda" ]
- then
- conda update --all --yes --quiet
- conda config --env --set always_yes true
- if [ $(python.version) == '2.7' ]
- then
- conda config --set restore_free_channel true
- fi
- if [ $(qt.bindings) == "pyside2" ] || ([ $(qt.bindings) == 'pyside' ] && [ $(agent.os) == 'Darwin' ])
- then
- conda config --prepend channels conda-forge
- fi
- conda create --name test-environment-$(python.version) python=$(python.version) --yes --quiet
- source activate test-environment-$(python.version)
- conda info
-
- if [ $(qt.bindings) == "pyside2" ]
- then
- conda install $(qt.bindings) --yes --quiet --strict-channel-priority
- else
- conda install $(qt.bindings) --yes --quiet
- fi
- conda install numpy scipy pyopengl h5py six --yes --quiet
- pip install matplotlib
- else
- pip install $(qt.bindings) numpy scipy pyopengl h5py six matplotlib
- fi
- pip install pytest pytest-cov coverage pytest-xdist
- if [ $(python.version) == "2.7" ]
- then
- pip install pytest-faulthandler==1.6.0
- export PYTEST_ADDOPTS="--faulthandler-timeout=15"
- else
- pip install pytest pytest-cov coverage
- fi
- displayName: "Install Dependencies"
-
- - bash: |
- if [ $(install.method) == "conda" ]
- then
- source activate test-environment-$(python.version)
- fi
- python -m pip install --no-index --find-links=dist pyqtgraph
- displayName: 'Install Wheel'
-
- - bash: |
- sudo apt-get install -y libxkbcommon-x11-dev
- # workaround for QTBUG-84489
- sudo apt-get install -y libxcb-xfixes0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0
- if [ $(install.method) == "conda" ]
- then
- source activate test-environment-$(python.version)
- fi
- if [ $(python.version) == "2.7" ]
- then
- pip install PyVirtualDisplay==0.2.5 pytest-xvfb==1.2.0
- else
- pip install pytest-xvfb
- fi
- displayName: "Virtual Display Setup"
- condition: eq(variables['agent.os'], 'Linux' )
-
- - bash: |
- export QT_DEBUG_PLUGINS=1
- if [ $(install.method) == "conda" ]
- then
- source activate test-environment-$(python.version)
- fi
- echo python location: `which python`
- echo python version: `python --version`
- echo pytest location: `which pytest`
- echo installed packages
- pip list
- echo pyqtgraph system info
- python -c "import pyqtgraph as pg; pg.systemInfo()"
- echo display information
- if [ $(agent.os) == 'Linux' ]
- then
- export DISPLAY=:99.0
- Xvfb :99 -screen 0 1920x1200x24 -ac +extension GLX +render -noreset &
- sleep 3
- fi
- python -m pyqtgraph.util.get_resolution
- echo openGL information
- python -c "from pyqtgraph.opengl.glInfo import GLTest"
- displayName: 'Debug Info'
- continueOnError: false
-
- - bash: |
- if [ $(install.method) == "conda" ]
- then
- source activate test-environment-$(python.version)
- fi
- mkdir -p "$SCREENSHOT_DIR"
- # echo "If Screenshots are generated, they may be downloaded from:"
- # echo "https://dev.azure.com/pyqtgraph/pyqtgraph/_apis/build/builds/$(Build.BuildId)/artifacts?artifactName=Screenshots&api-version=5.0"
- pytest . -v \
- -n 1 \
- --junitxml=junit/test-results.xml \
- --cov pyqtgraph --cov-report=xml --cov-report=html
- displayName: 'Unit tests'
- env:
- AZURE: 1
- SCREENSHOT_DIR: $(Build.ArtifactStagingDirectory)/screenshots
-
- - task: PublishBuildArtifacts@1
- displayName: 'Publish Screenshots'
- condition: failed()
- inputs:
- pathtoPublish: $(Build.ArtifactStagingDirectory)/screenshots
- artifactName: Screenshots
-
- - task: PublishTestResults@2
- condition: succeededOrFailed()
- inputs:
- testResultsFiles: '**/test-*.xml'
- testRunTitle: 'Test Results for $(agent.os) - $(python.version) - $(qt.bindings) - $(install.method)'
- publishRunAttachments: true
-
- - task: PublishCodeCoverageResults@1
- inputs:
- codeCoverageTool: Cobertura
- summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/coverage.xml'
- reportDirectory: '$(System.DefaultWorkingDirectory)/**/htmlcov'
diff --git a/benchmarks/__init__.py b/benchmarks/__init__.py
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/benchmarks/__init__.py
@@ -0,0 +1 @@
+
diff --git a/benchmarks/makeARGB.py b/benchmarks/makeARGB.py
new file mode 100644
index 00000000..48656c52
--- /dev/null
+++ b/benchmarks/makeARGB.py
@@ -0,0 +1,72 @@
+import numpy as np
+
+from pyqtgraph.functions import makeARGB
+
+
+class TimeSuite(object):
+ def __init__(self):
+ self.c_map = None
+ self.float_data = None
+ self.uint8_data = None
+ self.uint8_lut = None
+ self.uint16_data = None
+ self.uint16_lut = None
+
+ def setup(self):
+ size = (500, 500)
+
+ self.float_data = {
+ 'data': np.random.normal(size=size),
+ 'levels': [-4., 4.],
+ }
+
+ self.uint16_data = {
+ 'data': np.random.randint(100, 4500, size=size).astype('uint16'),
+ 'levels': [250, 3000],
+ }
+
+ self.uint8_data = {
+ 'data': np.random.randint(0, 255, size=size).astype('ubyte'),
+ 'levels': [20, 220],
+ }
+
+ self.c_map = np.array([
+ [-500., 255.],
+ [-255., 255.],
+ [0., 500.],
+ ])
+
+ self.uint8_lut = np.zeros((256, 4), dtype='ubyte')
+ for i in range(3):
+ self.uint8_lut[:, i] = np.clip(np.linspace(self.c_map[i][0], self.c_map[i][1], 256), 0, 255)
+ self.uint8_lut[:, 3] = 255
+
+ self.uint16_lut = np.zeros((2 ** 16, 4), dtype='ubyte')
+ for i in range(3):
+ self.uint16_lut[:, i] = np.clip(np.linspace(self.c_map[i][0], self.c_map[i][1], 2 ** 16), 0, 255)
+ self.uint16_lut[:, 3] = 255
+
+
+def make_test(dtype, use_levels, lut_name, func_name):
+ def time_test(self):
+ data = getattr(self, dtype + '_data')
+ makeARGB(
+ data['data'],
+ lut=getattr(self, lut_name + '_lut', None),
+ levels=use_levels and data['levels'],
+ )
+
+ time_test.__name__ = func_name
+ return time_test
+
+
+for dt in ['float', 'uint16', 'uint8']:
+ for levels in [True, False]:
+ for ln in [None, 'uint8', 'uint16']:
+ name = f'time_makeARGB_{dt}_{"" if levels else "no"}levels_{ln or "no"}lut'
+ setattr(TimeSuite, name, make_test(dt, levels, ln, name))
+
+
+if __name__ == "__main__":
+ ts = TimeSuite()
+ ts.setup()
diff --git a/doc/source/apireference.rst b/doc/source/apireference.rst
index c52c8df1..2392a65e 100644
--- a/doc/source/apireference.rst
+++ b/doc/source/apireference.rst
@@ -12,7 +12,7 @@ Contents:
widgets/index
3dgraphics/index
colormap
- parametertree/index
+ parametertree/apiref
dockarea
graphicsscene/index
flowchart/index
diff --git a/doc/source/config_options.rst b/doc/source/config_options.rst
index 61b64499..797404c6 100644
--- a/doc/source/config_options.rst
+++ b/doc/source/config_options.rst
@@ -30,6 +30,8 @@ useWeave bool False Use weave to speed up
weaveDebug bool False Print full error message if weave compile fails.
useOpenGL bool False Enable OpenGL in GraphicsView. This can have unpredictable effects on stability
and performance.
+useCupy bool False Use cupy to perform calculations on the GPU. Only currently applies to
+ ImageItem and its associated functions.
enableExperimental bool False Enable experimental features (the curious can search for this key in the code).
crashWarning bool False If True, print warnings about situations that may result in a crash.
================== =================== ================== ================================================================================
diff --git a/doc/source/how_to_use.rst b/doc/source/how_to_use.rst
index e4424374..1c8880d0 100644
--- a/doc/source/how_to_use.rst
+++ b/doc/source/how_to_use.rst
@@ -51,7 +51,29 @@ For the serious application developer, all of the functionality in pyqtgraph is
#. Under "Header file", enter "pyqtgraph".
#. Click "Add", then click "Promote".
-See the designer documentation for more information on promoting widgets. The "VideoSpeedTest" and "ScatterPlotSpeedTest" examples both demonstrate the use of .ui files that are compiled to .py modules using pyuic4 or pyside-uic. The "designerExample" example demonstrates dynamically generating python classes from .ui files (no pyuic4 / pyside-uic needed).
+See the designer documentation for more information on promoting widgets. The "VideoSpeedTest" and "ScatterPlotSpeedTest" examples both demonstrate the use of .ui files that are compiled to .py modules using pyuic5 or pyside-uic. The "designerExample" example demonstrates dynamically generating python classes from .ui files (no pyuic5 / pyside-uic needed).
+
+
+HiDPI Displays
+--------------
+
+PyQtGraph has a method :func:`mkQApp ` that by default sets what we have tested to be the best combination of options to support hidpi displays, when in combination with non-hidpi secondary displays. For your application, you may have instantiated ``QApplication`` yourself, in which case we advise setting these options *before* runing ``QApplication.exec_()``.
+
+For Qt6 bindings, this functionally "just works" without having to set any attributes.
+
+On Versions of Qt >= 5.14 and < 6; you can get ideal behavior with the following lines::
+
+ os.environ["QT_ENABLE_HIDPI_SCALING"] = "1"
+ QApplication.setHighDpiScaleFactorRoundingPolicy(QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
+
+If you are on Qt >= 5.6 and < 5.14; you can get near ideal behavior with the following lines::
+
+ QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
+ QApplication.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps)
+
+With the later, ideal behavior was not achieved.
+
+.. autofunction:: pyqtgraph.Qt.mkQApp
PyQt and PySide
@@ -61,15 +83,16 @@ PyQtGraph supports two popular python wrappers for the Qt library: PyQt and PySi
APIs and functionality, but for various reasons (discussed elsewhere) you may prefer to use one package or the other. When
pyqtgraph is first imported, it automatically determines which library to use by making the fillowing checks:
-#. If PyQt4 is already imported, use that
-#. Else, if PySide is already imported, use that
-#. Else, attempt to import PyQt4
-#. If that import fails, attempt to import PySide.
+#. If PyQt5 is already imported, use that
+#. Else, if PySide2 is already imported, use that
+#. Else, if PySide6 is already imported, use that
+#. Else, if PyQt6 is already imported, use that
+#. Else, attempt to import PyQt5, PySide2, PySide6, PyQt6, in that order.
If you have both libraries installed on your system and you wish to force pyqtgraph to use one or the other, simply
make sure it is imported before pyqtgraph::
- import PySide ## this will force pyqtgraph to use PySide instead of PyQt4
+ import PySide2 ## this will force pyqtgraph to use PySide2 instead of PyQt5
import pyqtgraph as pg
diff --git a/doc/source/installation.rst b/doc/source/installation.rst
index 9cf276d7..8f094bac 100644
--- a/doc/source/installation.rst
+++ b/doc/source/installation.rst
@@ -3,8 +3,8 @@ Installation
PyQtGraph depends on:
-* Python 2.7 or Python 3.x
-* A Qt library such as PyQt4, PyQt5, PySide, or PySide2
+* Python 3.7+
+* A Qt library such as PyQt5, or PySide2
* numpy
The easiest way to meet these dependencies is with ``pip`` or with a scientific
diff --git a/doc/source/parametertree/index.rst b/doc/source/parametertree/index.rst
index 94f590c3..1a6d5375 100644
--- a/doc/source/parametertree/index.rst
+++ b/doc/source/parametertree/index.rst
@@ -3,17 +3,22 @@
Parameter Trees
===============
+.. currentmodule:: pyqtgraph.parametertree
+
Parameter trees are a system for handling hierarchies of parameters while automatically generating one or more GUIs to display and interact with the parameters.
This feature is commonly seen, for example, in user interface design applications which display a list of editable properties for each widget.
-Parameters generally have a name, a data type (int, float, string, color, etc), and a value matching the data type. Parameters may be grouped and nested
-to form hierarchies and may be subclassed to provide custom behavior and display widgets.
+Parameters generally have a name, a data type (int, float, string, color, etc), and a value matching the data type. Parameters may be grouped and nested to form hierarchies and may be subclassed to provide custom behavior and display widgets.
-PyQtGraph's parameter tree system works similarly to the model-view architecture used by some components of Qt: Parameters are purely data-handling classes
-that exist independent of any graphical interface. A ParameterTree is a widget that automatically generates a graphical interface which represents
-the state of a haierarchy of Parameter objects and allows the user to edit the values within that hierarchy. This separation of data (model) and graphical
-interface (view) allows the same data to be represented multiple times and in a variety of different ways.
+PyQtGraph's parameter tree system works similarly to the model-view architecture used by some components of Qt:
-For more information, see the 'parametertree' example included with pyqtgraph and the API reference
+- A :class:`Parameter` is a purely data-handling class that exists independent of any graphical interface.
+- A :class:`ParameterItem` is an interactive graphical representation of a :class:`Parameter`.
+- A :class:`ParameterTree` is a widget that automatically generates a graphical interface which represents the state of a hierarchy of Parameter objects and allows the user to edit the values within that hierarchy.
+
+This separation of data (model) and graphical interface (view) allows the same data to be represented multiple times and in a variety of different ways.
+For example, a floating point number parameter could be represented by a slider or a spinbox, or both.
+
+For more information, see the 'parametertree' example included with pyqtgraph and the API reference:
.. toctree::
:maxdepth: 2
diff --git a/doc/source/parametertree/parameter.rst b/doc/source/parametertree/parameter.rst
index b5326b91..fed39f3d 100644
--- a/doc/source/parametertree/parameter.rst
+++ b/doc/source/parametertree/parameter.rst
@@ -1,8 +1,9 @@
Parameter
=========
+.. autofunction:: pyqtgraph.parametertree.registerParameterType
+
.. autoclass:: pyqtgraph.parametertree.Parameter
:members:
.. automethod:: pyqtgraph.parametertree.Parameter.__init__
-
diff --git a/doc/source/parametertree/parametertypes.rst b/doc/source/parametertree/parametertypes.rst
index 4344cee3..2ca29b37 100644
--- a/doc/source/parametertree/parametertypes.rst
+++ b/doc/source/parametertree/parametertypes.rst
@@ -1,6 +1,40 @@
Built-in Parameter Types
========================
-.. automodule:: pyqtgraph.parametertree.parameterTypes
- :members:
+.. currentmodule:: pyqtgraph.parametertree.parameterTypes
+Parameters
+----------
+
+.. autoclass:: SimpleParameter
+ :members:
+
+.. autoclass:: GroupParameter
+ :members:
+
+.. autoclass:: ListParameter
+ :members:
+
+.. autoclass:: TextParameter
+ :members:
+
+.. autoclass:: ActionParameter
+ :members:
+
+ParameterItems
+--------------
+
+.. autoclass:: WidgetParameterItem
+ :members:
+
+.. autoclass:: GroupParameterItem
+ :members:
+
+.. autoclass:: ListParameterItem
+ :members:
+
+.. autoclass:: TextParameterItem
+ :members:
+
+.. autoclass:: ActionParameterItem
+ :members:
diff --git a/doc/source/qtcrashcourse.rst b/doc/source/qtcrashcourse.rst
index 083a78ee..bc993974 100644
--- a/doc/source/qtcrashcourse.rst
+++ b/doc/source/qtcrashcourse.rst
@@ -17,7 +17,7 @@ PyQtGraph fits into this scheme by providing its own QWidget subclasses to be in
Example::
- from PyQt4 import QtGui # (the example applies equally well to PySide)
+ from PyQt5 import QtGui # (the example applies equally well to PySide2)
import pyqtgraph as pg
## Always start by initializing Qt (only once per application)
@@ -99,4 +99,3 @@ QTimer, Multi-Threading
Multi-threading vs Multi-processing in Qt
-----------------------------------------
-
diff --git a/examples/Arrow.py b/examples/Arrow.py
index 2a707fec..bd0b6b07 100644
--- a/examples/Arrow.py
+++ b/examples/Arrow.py
@@ -15,7 +15,7 @@ from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg
-app = QtGui.QApplication([])
+app = pg.mkQApp("Arrow Example")
w = QtGui.QMainWindow()
cw = pg.GraphicsLayoutWidget()
diff --git a/examples/ColorButton.py b/examples/ColorButton.py
index 321ee735..e9df9750 100644
--- a/examples/ColorButton.py
+++ b/examples/ColorButton.py
@@ -11,7 +11,7 @@ import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import numpy as np
-app = QtGui.QApplication([])
+app = pg.mkQApp("ColorButton Example")
win = QtGui.QMainWindow()
btn = pg.ColorButton()
win.setCentralWidget(btn)
diff --git a/examples/DataSlicing.py b/examples/DataSlicing.py
index d766e7e3..8bd1e04d 100644
--- a/examples/DataSlicing.py
+++ b/examples/DataSlicing.py
@@ -14,7 +14,7 @@ import numpy as np
from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph as pg
-app = QtGui.QApplication([])
+app = pg.mkQApp("Data Slicing Example")
## Create window with two ImageView widgets
win = QtGui.QMainWindow()
diff --git a/examples/DataTreeWidget.py b/examples/DataTreeWidget.py
index 70ac49bd..47a5f32b 100644
--- a/examples/DataTreeWidget.py
+++ b/examples/DataTreeWidget.py
@@ -22,7 +22,7 @@ def some_func2():
return sys.exc_info()[2]
-app = QtGui.QApplication([])
+app = pg.mkQApp("DataTreeWidget Example")
d = {
'a list': [1,2,3,4,5,6, {'nested1': 'aaaaa', 'nested2': 'bbbbb'}, "seven"],
'a dict': {
diff --git a/examples/DateAxisItem.py b/examples/DateAxisItem.py
index 7bbaafff..d789308d 100644
--- a/examples/DateAxisItem.py
+++ b/examples/DateAxisItem.py
@@ -12,7 +12,7 @@ import numpy as np
import pyqtgraph as pg
from pyqtgraph.Qt import QtGui
-app = QtGui.QApplication([])
+app = pg.mkQApp("DateAxisItem Example")
# Create a plot with a date-time axis
w = pg.PlotWidget(axisItems = {'bottom': pg.DateAxisItem()})
diff --git a/examples/DateAxisItem_QtDesigner.py b/examples/DateAxisItem_QtDesigner.py
index f6f17489..d92a7503 100644
--- a/examples/DateAxisItem_QtDesigner.py
+++ b/examples/DateAxisItem_QtDesigner.py
@@ -9,17 +9,20 @@ import initExample ## Add path to library (just for examples; you do not need th
import sys
import time
+import os
import numpy as np
-from PyQt5 import QtWidgets, QtCore, uic
import pyqtgraph as pg
+from pyqtgraph.Qt import QtWidgets, QtCore, loadUiType
pg.setConfigOption('background', 'w')
pg.setConfigOption('foreground', 'k')
BLUE = pg.mkPen('#1f77b4')
-Design, _ = uic.loadUiType('DateAxisItem_QtDesigner.ui')
+path = os.path.dirname(os.path.abspath(__file__))
+uiFile = os.path.join(path, 'DateAxisItem_QtDesigner.ui')
+Design, _ = loadUiType(uiFile)
class ExampleApp(QtWidgets.QMainWindow, Design):
def __init__(self):
@@ -34,9 +37,7 @@ class ExampleApp(QtWidgets.QMainWindow, Design):
self.plotWidget.setAxisItems({'bottom': pg.DateAxisItem()})
self.plotWidget.showGrid(x=True, y=True)
-app = QtWidgets.QApplication(sys.argv)
-app.setStyle(QtWidgets.QStyleFactory.create('Fusion'))
-app.setPalette(QtWidgets.QApplication.style().standardPalette())
+app = pg.mkQApp("DateAxisItem_QtDesigner Example")
window = ExampleApp()
window.setWindowTitle('pyqtgraph example: DateAxisItem_QtDesigner')
window.show()
diff --git a/examples/DiffTreeWidget.py b/examples/DiffTreeWidget.py
index fa57a356..780e1eaf 100644
--- a/examples/DiffTreeWidget.py
+++ b/examples/DiffTreeWidget.py
@@ -12,7 +12,7 @@ from pyqtgraph.Qt import QtCore, QtGui
import numpy as np
-app = QtGui.QApplication([])
+app = pg.mkQApp("DiffTreeWidget Example")
A = {
'a list': [1,2,2,4,5,6, {'nested1': 'aaaa', 'nested2': 'bbbbb'}, "seven"],
'a dict': {
diff --git a/examples/Draw.py b/examples/Draw.py
index cc137db3..1401c398 100644
--- a/examples/Draw.py
+++ b/examples/Draw.py
@@ -12,7 +12,7 @@ from pyqtgraph.Qt import QtCore, QtGui
import numpy as np
import pyqtgraph as pg
-app = QtGui.QApplication([])
+app = pg.mkQApp("Draw Example")
## Create window with GraphicsView widget
w = pg.GraphicsView()
diff --git a/examples/ExampleApp.py b/examples/ExampleApp.py
index ea98373f..cb57e3d0 100644
--- a/examples/ExampleApp.py
+++ b/examples/ExampleApp.py
@@ -1,110 +1,26 @@
+import keyword
import os
+import re
import sys
import subprocess
+from argparse import Namespace
import pyqtgraph as pg
-from pyqtgraph.python2_3 import basestring
from pyqtgraph.Qt import QtGui, QtCore, QT_LIB
from pyqtgraph.pgcollections import OrderedDict
+from .utils import examples
path = os.path.abspath(os.path.dirname(__file__))
sys.path.insert(0, path)
app = pg.mkQApp()
-if QT_LIB == 'PySide':
- from exampleLoaderTemplate_pyside import Ui_Form
-elif QT_LIB == 'PySide2':
- from exampleLoaderTemplate_pyside2 import Ui_Form
-elif QT_LIB == 'PyQt5':
- from exampleLoaderTemplate_pyqt5 import Ui_Form
-else:
- from exampleLoaderTemplate_pyqt import Ui_Form
-
-examples = OrderedDict([
- ('Command-line usage', 'CLIexample.py'),
- ('Basic Plotting', 'Plotting.py'),
- ('ImageView', 'ImageView.py'),
- ('ParameterTree', 'parametertree.py'),
- ('Crosshair / Mouse interaction', 'crosshair.py'),
- ('Data Slicing', 'DataSlicing.py'),
- ('Plot Customization', 'customPlot.py'),
- ('Timestamps on x axis', 'DateAxisItem.py'),
- ('Image Analysis', 'imageAnalysis.py'),
- ('ViewBox Features', 'ViewBoxFeatures.py'),
- ('Dock widgets', 'dockarea.py'),
- ('Console', 'ConsoleWidget.py'),
- ('Histograms', 'histogram.py'),
- ('Beeswarm plot', 'beeswarm.py'),
- ('Symbols', 'Symbols.py'),
- ('Auto-range', 'PlotAutoRange.py'),
- ('Remote Plotting', 'RemoteSpeedTest.py'),
- ('Scrolling plots', 'scrollingPlots.py'),
- ('HDF5 big data', 'hdf5.py'),
- ('Demos', OrderedDict([
- ('Optics', 'optics_demos.py'),
- ('Special relativity', 'relativity_demo.py'),
- ('Verlet chain', 'verlet_chain_demo.py'),
- ('Koch Fractal', 'fractal.py'),
- ])),
- ('GraphicsItems', OrderedDict([
- ('Scatter Plot', 'ScatterPlot.py'),
- #('PlotItem', 'PlotItem.py'),
- ('IsocurveItem', 'isocurve.py'),
- ('GraphItem', 'GraphItem.py'),
- ('ErrorBarItem', 'ErrorBarItem.py'),
- ('FillBetweenItem', 'FillBetweenItem.py'),
- ('ImageItem - video', 'ImageItem.py'),
- ('ImageItem - draw', 'Draw.py'),
- ('Region-of-Interest', 'ROIExamples.py'),
- ('Bar Graph', 'BarGraphItem.py'),
- ('GraphicsLayout', 'GraphicsLayout.py'),
- ('LegendItem', 'Legend.py'),
- ('Text Item', 'text.py'),
- ('Linked Views', 'linkedViews.py'),
- ('Arrow', 'Arrow.py'),
- ('ViewBox', 'ViewBoxFeatures.py'),
- ('Custom Graphics', 'customGraphicsItem.py'),
- ('Labeled Graph', 'CustomGraphItem.py'),
- ])),
- ('Benchmarks', OrderedDict([
- ('Video speed test', 'VideoSpeedTest.py'),
- ('Line Plot update', 'PlotSpeedTest.py'),
- ('Scatter Plot update', 'ScatterPlotSpeedTest.py'),
- ('Multiple plots', 'MultiPlotSpeedTest.py'),
- ])),
- ('3D Graphics', OrderedDict([
- ('Volumetric', 'GLVolumeItem.py'),
- ('Isosurface', 'GLIsosurface.py'),
- ('Surface Plot', 'GLSurfacePlot.py'),
- ('Scatter Plot', 'GLScatterPlotItem.py'),
- ('Shaders', 'GLshaders.py'),
- ('Line Plot', 'GLLinePlotItem.py'),
- ('Mesh', 'GLMeshItem.py'),
- ('Image', 'GLImageItem.py'),
- ])),
- ('Widgets', OrderedDict([
- ('PlotWidget', 'PlotWidget.py'),
- ('SpinBox', 'SpinBox.py'),
- ('ConsoleWidget', 'ConsoleWidget.py'),
- ('Histogram / lookup table', 'HistogramLUT.py'),
- ('TreeWidget', 'TreeWidget.py'),
- ('ScatterPlotWidget', 'ScatterPlotWidget.py'),
- ('DataTreeWidget', 'DataTreeWidget.py'),
- ('GradientWidget', 'GradientWidget.py'),
- ('TableWidget', 'TableWidget.py'),
- ('ColorButton', 'ColorButton.py'),
- #('CheckTable', '../widgets/CheckTable.py'),
- #('VerticalLabel', '../widgets/VerticalLabel.py'),
- ('JoystickButton', 'JoystickButton.py'),
- ])),
- ('Flowcharts', 'Flowchart.py'),
- ('Custom Flowchart Nodes', 'FlowchartCustomNode.py'),
-])
-
+import importlib
+ui_template = importlib.import_module(
+ f'exampleLoaderTemplate_{QT_LIB.lower()}')
# based on https://github.com/art1415926535/PyQt5-syntax-highlighting
-QRegExp = QtCore.QRegExp
+QRegularExpression = QtCore.QRegularExpression
QFont = QtGui.QFont
QColor = QtGui.QColor
@@ -208,55 +124,45 @@ class PythonHighlighter(QSyntaxHighlighter):
"""Syntax highlighter for the Python language.
"""
# Python keywords
- keywords = [
- 'and', 'assert', 'break', 'class', 'continue', 'def',
- 'del', 'elif', 'else', 'except', 'exec', 'finally',
- 'for', 'from', 'global', 'if', 'import', 'in',
- 'is', 'lambda', 'not', 'or', 'pass', 'print',
- 'raise', 'return', 'try', 'while', 'yield',
- 'None', 'True', 'False', 'async', 'await',
- ]
+ keywords = keyword.kwlist
# Python operators
operators = [
- '=',
+ r'=',
# Comparison
- '==', '!=', '<', '<=', '>', '>=',
+ r'==', r'!=', r'<', r'<=', r'>', r'>=',
# Arithmetic
- '\+', '-', '\*', '/', '//', '\%', '\*\*',
+ r'\+', r"-", r'\*', r'/', r'//', r'%', r'\*\*',
# In-place
- '\+=', '-=', '\*=', '/=', '\%=',
+ r'\+=', r'-=', r'\*=', r'/=', r'\%=',
# Bitwise
- '\^', '\|', '\&', '\~', '>>', '<<',
+ r'\^', r'\|', r'&', r'~', r'>>', r'<<',
]
# Python braces
braces = [
- '\{', '\}', '\(', '\)', '\[', '\]',
+ r'\{', r'\}', r'\(', r'\)', r'\[', r'\]',
]
def __init__(self, document):
QSyntaxHighlighter.__init__(self, document)
# Multi-line strings (expression, flag, style)
- # FIXME: The triple-quotes in these two lines will mess up the
- # syntax highlighting from this point onward
- self.tri_single = (QRegExp("'''"), 1, 'string2')
- self.tri_double = (QRegExp('"""'), 2, 'string2')
+ self.tri_single = (QRegularExpression("'''"), 1, 'string2')
+ self.tri_double = (QRegularExpression('"""'), 2, 'string2')
rules = []
# Keyword, operator, and brace rules
rules += [(r'\b%s\b' % w, 0, 'keyword')
for w in PythonHighlighter.keywords]
- rules += [(r'%s' % o, 0, 'operator')
+ rules += [(o, 0, 'operator')
for o in PythonHighlighter.operators]
- rules += [(r'%s' % b, 0, 'brace')
+ rules += [(b, 0, 'brace')
for b in PythonHighlighter.braces]
# All other rules
rules += [
-
# 'self'
(r'\bself\b', 0, 'self'),
@@ -277,12 +183,8 @@ class PythonHighlighter(QSyntaxHighlighter):
# From '#' until a newline
(r'#[^\n]*', 0, 'comment'),
-
]
-
- # Build a QRegExp for each pattern
- self.rules = [(QRegExp(pat), index, fmt)
- for (pat, index, fmt) in rules]
+ self.rules = rules
@property
def styles(self):
@@ -294,16 +196,14 @@ class PythonHighlighter(QSyntaxHighlighter):
"""
# Do other syntax formatting
for expression, nth, format in self.rules:
- index = expression.indexIn(text, 0)
format = self.styles[format]
- while index >= 0:
- # We actually want the index of the nth match
- index = expression.pos(nth)
- length = len(expression.cap(nth))
- self.setFormat(index, length, format)
- index = expression.indexIn(text, index + length)
-
+ for n, match in enumerate(re.finditer(expression, text)):
+ if n < nth:
+ continue
+ start = match.start()
+ length = match.end() - start
+ self.setFormat(start, length, format)
self.setCurrentBlockState(0)
# Do multi-line strings
@@ -312,11 +212,16 @@ class PythonHighlighter(QSyntaxHighlighter):
in_multiline = self.match_multiline(text, *self.tri_double)
def match_multiline(self, text, delimiter, in_state, style):
- """Do highlighting of multi-line strings. ``delimiter`` should be a
- ``QRegExp`` for triple-single-quotes or triple-double-quotes, and
- ``in_state`` should be a unique integer to represent the corresponding
- state changes when inside those strings. Returns True if we're still
- inside a multi-line string when this function is finished.
+ """Do highlighting of multi-line strings.
+
+ =========== ==========================================================
+ delimiter (QRegularExpression) for triple-single-quotes or
+ triple-double-quotes
+ in_state (int) to represent the corresponding state changes when
+ inside those strings. Returns True if we're still inside a
+ multi-line string when this function is finished.
+ style (str) representation of the kind of style to use
+ =========== ==========================================================
"""
# If inside triple-single quotes, start at 0
if self.previousBlockState() == in_state:
@@ -324,17 +229,19 @@ class PythonHighlighter(QSyntaxHighlighter):
add = 0
# Otherwise, look for the delimiter on this line
else:
- start = delimiter.indexIn(text)
+ match = delimiter.match(text)
+ start = match.capturedStart()
# Move past this match
- add = delimiter.matchedLength()
+ add = match.capturedLength()
# As long as there's a delimiter match on this line...
while start >= 0:
# Look for the ending delimiter
- end = delimiter.indexIn(text, start + add)
+ match = delimiter.match(text, start + add)
+ end = match.capturedEnd()
# Ending delimiter on this line?
if end >= add:
- length = end - start + add + delimiter.matchedLength()
+ length = end - start + add + match.capturedLength()
self.setCurrentBlockState(0)
# No; multi-line string
else:
@@ -343,7 +250,8 @@ class PythonHighlighter(QSyntaxHighlighter):
# Apply formatting
self.setFormat(start, length, self.styles[style])
# Look for the next match
- start = delimiter.indexIn(text, start + length)
+ match = delimiter.match(text, start + length)
+ start = match.capturedStart()
# Return True if still inside a multi-line string, False otherwise
if self.currentBlockState() == in_state:
@@ -356,7 +264,7 @@ class PythonHighlighter(QSyntaxHighlighter):
class ExampleLoader(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
- self.ui = Ui_Form()
+ self.ui = ui_template.Ui_Form()
self.cw = QtGui.QWidget()
self.setCentralWidget(self.cw)
self.ui.setupUi(self.cw)
@@ -366,9 +274,7 @@ class ExampleLoader(QtGui.QMainWindow):
self.ui.codeView.setLayout(self.codeLayout)
self.hl = PythonHighlighter(self.ui.codeView.document())
app = QtGui.QApplication.instance()
- if QT_LIB in ['PyQt5', 'PySide2']:
- # Qt4 does not have a paletteChanged signal
- app.paletteChanged.connect(self.updateTheme)
+ app.paletteChanged.connect(self.updateTheme)
self.codeLayout.addItem(QtGui.QSpacerItem(100,100,QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Expanding), 0, 0)
self.codeLayout.addWidget(self.codeBtn, 1, 1)
self.codeBtn.hide()
@@ -410,15 +316,23 @@ class ExampleLoader(QtGui.QMainWindow):
self.hl = PythonHighlighter(self.ui.codeView.document())
def populateTree(self, root, examples):
+ bold_font = None
for key, val in examples.items():
item = QtGui.QTreeWidgetItem([key])
self.itemCache.append(item) # PyQt 4.9.6 no longer keeps references to these wrappers,
# so we need to make an explicit reference or else the .file
# attribute will disappear.
- if isinstance(val, basestring):
- item.file = val
- else:
+ if isinstance(val, OrderedDict):
self.populateTree(item, val)
+ elif isinstance(val, Namespace):
+ item.file = val.filename
+ if 'recommended' in val:
+ if bold_font is None:
+ bold_font = item.font(0)
+ bold_font.setBold(True)
+ item.setFont(0, bold_font)
+ else:
+ item.file = val
root.addChild(item)
def currentFile(self):
diff --git a/examples/Flowchart.py b/examples/Flowchart.py
index b911cec8..45e833ce 100644
--- a/examples/Flowchart.py
+++ b/examples/Flowchart.py
@@ -19,7 +19,7 @@ import pyqtgraph as pg
import numpy as np
import pyqtgraph.metaarray as metaarray
-app = QtGui.QApplication([])
+app = pg.mkQApp("Flowchart Example")
## Create main window with grid layout
win = QtGui.QMainWindow()
diff --git a/examples/FlowchartCustomNode.py b/examples/FlowchartCustomNode.py
index 2b0819ab..dc1fd55f 100644
--- a/examples/FlowchartCustomNode.py
+++ b/examples/FlowchartCustomNode.py
@@ -13,7 +13,7 @@ from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg
import numpy as np
-app = QtGui.QApplication([])
+app = pg.mkQApp("Flowchart Custom Node Example")
## Create main window with a grid layout inside
win = QtGui.QMainWindow()
diff --git a/examples/GLBarGraphItem.py b/examples/GLBarGraphItem.py
index d14eba87..e593d54a 100644
--- a/examples/GLBarGraphItem.py
+++ b/examples/GLBarGraphItem.py
@@ -11,7 +11,7 @@ import pyqtgraph.opengl as gl
import pyqtgraph as pg
import numpy as np
-app = QtGui.QApplication([])
+app = pg.mkQApp("GLBarGraphItem Example")
w = gl.GLViewWidget()
w.opts['distance'] = 40
w.show()
diff --git a/examples/GLImageItem.py b/examples/GLImageItem.py
index 70bf5306..6a31c09a 100644
--- a/examples/GLImageItem.py
+++ b/examples/GLImageItem.py
@@ -13,7 +13,7 @@ import pyqtgraph.opengl as gl
import pyqtgraph as pg
import numpy as np
-app = QtGui.QApplication([])
+app = pg.mkQApp("GLImageItem Example")
w = gl.GLViewWidget()
w.opts['distance'] = 200
w.show()
diff --git a/examples/GLIsosurface.py b/examples/GLIsosurface.py
index a9403ffb..0beeea66 100644
--- a/examples/GLIsosurface.py
+++ b/examples/GLIsosurface.py
@@ -11,7 +11,7 @@ from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph as pg
import pyqtgraph.opengl as gl
-app = QtGui.QApplication([])
+app = pg.mkQApp("GLIsosurface Example")
w = gl.GLViewWidget()
w.show()
w.setWindowTitle('pyqtgraph example: GLIsosurface')
diff --git a/examples/GLLinePlotItem.py b/examples/GLLinePlotItem.py
index 1de07cff..0d07b153 100644
--- a/examples/GLLinePlotItem.py
+++ b/examples/GLLinePlotItem.py
@@ -11,7 +11,7 @@ import pyqtgraph.opengl as gl
import pyqtgraph as pg
import numpy as np
-app = QtGui.QApplication([])
+app = pg.mkQApp("GLLinePlotItem Example")
w = gl.GLViewWidget()
w.opts['distance'] = 40
w.show()
diff --git a/examples/GLMeshItem.py b/examples/GLMeshItem.py
index 1caa3490..692f8f8f 100644
--- a/examples/GLMeshItem.py
+++ b/examples/GLMeshItem.py
@@ -11,7 +11,7 @@ from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph as pg
import pyqtgraph.opengl as gl
-app = QtGui.QApplication([])
+app = pg.mkQApp("GLMeshItem Example")
w = gl.GLViewWidget()
w.show()
w.setWindowTitle('pyqtgraph example: GLMeshItem')
diff --git a/examples/GLScatterPlotItem.py b/examples/GLScatterPlotItem.py
index 53a9a752..b52e17b5 100644
--- a/examples/GLScatterPlotItem.py
+++ b/examples/GLScatterPlotItem.py
@@ -7,11 +7,12 @@ Demonstrates use of GLScatterPlotItem with rapidly-updating plots.
## Add path to library (just for examples; you do not need this)
import initExample
+import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph.opengl as gl
import numpy as np
-app = QtGui.QApplication([])
+app = pg.mkQApp("GLScatterPlotItem Example")
w = gl.GLViewWidget()
w.opts['distance'] = 20
w.show()
diff --git a/examples/GLSurfacePlot.py b/examples/GLSurfacePlot.py
index e9896e07..cac8d5fe 100644
--- a/examples/GLSurfacePlot.py
+++ b/examples/GLSurfacePlot.py
@@ -13,7 +13,7 @@ import pyqtgraph.opengl as gl
import numpy as np
## Create a GL View widget to display data
-app = QtGui.QApplication([])
+app = pg.mkQApp("GLSurfacePlot Example")
w = gl.GLViewWidget()
w.show()
w.setWindowTitle('pyqtgraph example: GLSurfacePlot')
diff --git a/examples/GLViewWidget.py b/examples/GLViewWidget.py
index a5207838..d06a6ed8 100644
--- a/examples/GLViewWidget.py
+++ b/examples/GLViewWidget.py
@@ -6,10 +6,10 @@ Very basic 3D graphics example; create a view widget and add a few items.
## Add path to library (just for examples; you do not need this)
import initExample
-from pyqtgraph.Qt import QtCore, QtGui
+from pyqtgraph.Qt import QtCore, QtGui, mkQApp
import pyqtgraph.opengl as gl
-app = QtGui.QApplication([])
+app = mkQApp("GLViewWidget Example")
w = gl.GLViewWidget()
w.opts['distance'] = 20
w.show()
diff --git a/examples/GLVolumeItem.py b/examples/GLVolumeItem.py
index ca20b127..628ee971 100644
--- a/examples/GLVolumeItem.py
+++ b/examples/GLVolumeItem.py
@@ -7,10 +7,11 @@ Demonstrates GLVolumeItem for displaying volumetric data.
## Add path to library (just for examples; you do not need this)
import initExample
+import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph.opengl as gl
-app = QtGui.QApplication([])
+app = pg.mkQApp("GLVolumeItem Example")
w = gl.GLViewWidget()
w.opts['distance'] = 200
w.show()
diff --git a/examples/GLshaders.py b/examples/GLshaders.py
index ce00fc7a..86719c6d 100644
--- a/examples/GLshaders.py
+++ b/examples/GLshaders.py
@@ -13,7 +13,7 @@ from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph as pg
import pyqtgraph.opengl as gl
-app = QtGui.QApplication([])
+app = pg.mkQApp("GLShaders Example")
w = gl.GLViewWidget()
w.show()
w.setWindowTitle('pyqtgraph example: GL Shaders')
diff --git a/examples/GradientEditor.py b/examples/GradientEditor.py
index 1bba4af1..ad8c8eee 100644
--- a/examples/GradientEditor.py
+++ b/examples/GradientEditor.py
@@ -7,7 +7,7 @@ from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg
-app = QtGui.QApplication([])
+app = pg.mkQApp("Gradiant Editor Example")
mw = pg.GraphicsView()
mw.resize(800,800)
mw.show()
diff --git a/examples/GradientWidget.py b/examples/GradientWidget.py
index d4ad22b8..623171b2 100644
--- a/examples/GradientWidget.py
+++ b/examples/GradientWidget.py
@@ -12,7 +12,7 @@ import numpy as np
-app = QtGui.QApplication([])
+app = pg.mkQApp("Gradiant Widget Example")
w = QtGui.QMainWindow()
w.show()
w.setWindowTitle('pyqtgraph example: GradientWidget')
diff --git a/examples/GraphicsLayout.py b/examples/GraphicsLayout.py
index 70da7e5c..74d61c10 100644
--- a/examples/GraphicsLayout.py
+++ b/examples/GraphicsLayout.py
@@ -12,7 +12,7 @@ from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg
import numpy as np
-app = QtGui.QApplication([])
+app = pg.mkQApp("Gradiant Layout Example")
view = pg.GraphicsView()
l = pg.GraphicsLayout(border=(100,100,100))
view.setCentralItem(l)
diff --git a/examples/GraphicsScene.py b/examples/GraphicsScene.py
index c8931444..69be5b53 100644
--- a/examples/GraphicsScene.py
+++ b/examples/GraphicsScene.py
@@ -6,7 +6,7 @@ from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph as pg
from pyqtgraph.GraphicsScene import GraphicsScene
-app = QtGui.QApplication([])
+app = pg.mkQApp("GraphicsScene Example")
win = pg.GraphicsView()
win.show()
diff --git a/examples/HistogramLUT.py b/examples/HistogramLUT.py
index 082a963c..4c9ef4cf 100644
--- a/examples/HistogramLUT.py
+++ b/examples/HistogramLUT.py
@@ -11,7 +11,7 @@ from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg
-app = QtGui.QApplication([])
+app = pg.mkQApp("Histogram Lookup Table Example")
win = QtGui.QMainWindow()
win.resize(800,600)
win.show()
diff --git a/examples/ImageItem.py b/examples/ImageItem.py
index a2dc7af3..9982d65c 100644
--- a/examples/ImageItem.py
+++ b/examples/ImageItem.py
@@ -11,7 +11,7 @@ import numpy as np
import pyqtgraph as pg
import pyqtgraph.ptime as ptime
-app = QtGui.QApplication([])
+app = pg.mkQApp("ImageItem Example")
## Create window with GraphicsView widget
win = pg.GraphicsLayoutWidget()
diff --git a/examples/ImageView.py b/examples/ImageView.py
index 3412f348..d2c3ebc0 100644
--- a/examples/ImageView.py
+++ b/examples/ImageView.py
@@ -20,7 +20,7 @@ import pyqtgraph as pg
# Interpret image data as row-major instead of col-major
pg.setConfigOptions(imageAxisOrder='row-major')
-app = QtGui.QApplication([])
+app = pg.mkQApp("ImageView Example")
## Create window with ImageView widget
win = QtGui.QMainWindow()
diff --git a/examples/InfiniteLine.py b/examples/InfiniteLine.py
index 55020776..d90ae143 100644
--- a/examples/InfiniteLine.py
+++ b/examples/InfiniteLine.py
@@ -9,7 +9,7 @@ import numpy as np
import pyqtgraph as pg
-app = QtGui.QApplication([])
+app = pg.mkQApp("InfiniteLine Example")
win = pg.GraphicsLayoutWidget(show=True, title="Plotting items examples")
win.resize(1000,600)
diff --git a/examples/JoystickButton.py b/examples/JoystickButton.py
index 03c79706..c6965900 100644
--- a/examples/JoystickButton.py
+++ b/examples/JoystickButton.py
@@ -12,7 +12,7 @@ from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg
-app = QtGui.QApplication([])
+app = pg.mkQApp("Joystick Button Example")
mw = QtGui.QMainWindow()
mw.resize(300,50)
mw.setWindowTitle('pyqtgraph example: JoystickButton')
diff --git a/examples/Legend.py b/examples/Legend.py
index 9239f1ae..5df9fb83 100644
--- a/examples/Legend.py
+++ b/examples/Legend.py
@@ -39,7 +39,6 @@ legend.addItem(c1, 'curve1')
legend.addItem(c2, 'curve2')
legend.addItem(s1, 'scatter')
-
## Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__':
import sys
diff --git a/examples/LogPlotTest.py b/examples/LogPlotTest.py
index 5ae9d17e..1e6bf669 100644
--- a/examples/LogPlotTest.py
+++ b/examples/LogPlotTest.py
@@ -10,7 +10,7 @@ from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg
-app = QtGui.QApplication([])
+app = pg.mkQApp("Log Plot Example")
win = pg.GraphicsLayoutWidget(show=True, title="Basic plotting examples")
win.resize(1000,600)
diff --git a/examples/MultiPlotSpeedTest.py b/examples/MultiPlotSpeedTest.py
index f4295687..e8f7ee85 100644
--- a/examples/MultiPlotSpeedTest.py
+++ b/examples/MultiPlotSpeedTest.py
@@ -12,7 +12,7 @@ from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg
from pyqtgraph.ptime import time
-app = QtGui.QApplication([])
+app = pg.mkQApp("MultiPlot Speed Test")
plot = pg.plot()
plot.setWindowTitle('pyqtgraph example: MultiPlotSpeedTest')
diff --git a/examples/MultiPlotWidget.py b/examples/MultiPlotWidget.py
index 2800ee44..4802a046 100644
--- a/examples/MultiPlotWidget.py
+++ b/examples/MultiPlotWidget.py
@@ -14,7 +14,7 @@ except:
print("MultiPlot is only used with MetaArray for now (and you do not have the metaarray package)")
exit()
-app = QtGui.QApplication([])
+app = pg.mkQApp("MultiPlot Widget Example")
mw = QtGui.QMainWindow()
mw.resize(800,800)
pw = MultiPlotWidget()
diff --git a/examples/NonUniformImage.py b/examples/NonUniformImage.py
new file mode 100644
index 00000000..9d13cc0b
--- /dev/null
+++ b/examples/NonUniformImage.py
@@ -0,0 +1,86 @@
+# -*- coding: utf-8 -*-
+"""
+Display a non-uniform image.
+This example displays 2-d data as an image with non-uniformly
+distributed sample points.
+"""
+
+import initExample ## Add path to library (just for examples; you do not need this)
+
+from pyqtgraph.Qt import QtGui, QtCore
+import pyqtgraph as pg
+import numpy as np
+from pyqtgraph.graphicsItems.GradientEditorItem import Gradients
+from pyqtgraph.graphicsItems.NonUniformImage import NonUniformImage
+
+
+RPM2RADS = 2 * np.pi / 60
+RADS2RPM = 1 / RPM2RADS
+
+kfric = 1 # [Ws/rad] angular damping coefficient [0;100]
+kfric3 = 1.5e-6 # [Ws3/rad3] angular damping coefficient (3rd order) [0;10-3]
+psi = 0.2 # [Vs] flux linkage [0.001;10]
+res = 5e-3 # [Ohm] resistance [0;100]
+v_ref = 200 # [V] reference DC voltage [0;1000]
+k_v = 5 # linear voltage coefficient [-100;100]
+
+# create the (non-uniform) scales
+tau = np.array([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 120, 140, 160, 180, 200, 220], dtype=np.float32)
+w = np.array([0, 250, 500, 750, 1000, 1500, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000], dtype=np.float32) * RPM2RADS
+v = 380
+
+# calculate the power losses
+TAU, W = np.meshgrid(tau, w, indexing='ij')
+V = np.ones_like(TAU) * v
+
+P_loss = kfric * W + kfric3 * W ** 3 + (res * (TAU / psi) ** 2) + k_v * (V - v_ref)
+
+P_mech = TAU * W
+P_loss[P_mech > 1.5e5] = np.NaN
+
+# green - orange - red
+Gradients['gor'] = {'ticks': [(0.0, (74, 158, 71)), (0.5, (255, 230, 0)), (1, (191, 79, 76))], 'mode': 'rgb'}
+
+app = pg.mkQApp("NonUniform Image Example")
+
+win = QtGui.QMainWindow()
+cw = pg.GraphicsLayoutWidget()
+win.show()
+win.resize(600, 400)
+win.setCentralWidget(cw)
+win.setWindowTitle('pyqtgraph example: Non-uniform Image')
+
+p = cw.addPlot(title="Power Losses [W]", row=0, col=0)
+
+lut = pg.HistogramLUTItem()
+
+p.setMouseEnabled(x=False, y=False)
+
+cw.addItem(lut)
+
+# load the gradient
+lut.gradient.loadPreset('gor')
+
+image = NonUniformImage(w * RADS2RPM, tau, P_loss.T)
+image.setLookupTable(lut, autoLevel=True)
+image.setZValue(-1)
+p.addItem(image)
+
+h = image.getHistogram()
+lut.plot.setData(*h)
+
+p.showGrid(x=True, y=True)
+
+p.setLabel(axis='bottom', text='Speed [rpm]')
+p.setLabel(axis='left', text='Torque [Nm]')
+
+# elevate the grid lines
+p.axes['bottom']['item'].setZValue(1000)
+p.axes['left']['item'].setZValue(1000)
+
+
+## Start Qt event loop unless running in interactive mode or using pyside.
+if __name__ == '__main__':
+ import sys
+ if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
+ QtGui.QApplication.instance().exec_()
diff --git a/examples/PColorMeshItem.py b/examples/PColorMeshItem.py
index 29e89db5..1e5f4e85 100644
--- a/examples/PColorMeshItem.py
+++ b/examples/PColorMeshItem.py
@@ -11,7 +11,7 @@ import numpy as np
import pyqtgraph as pg
import pyqtgraph.ptime as ptime
-app = QtGui.QApplication([])
+app = pg.mkQApp("PColorMesh Example")
## Create window with GraphicsView widget
win = pg.GraphicsLayoutWidget()
diff --git a/examples/PlotAutoRange.py b/examples/PlotAutoRange.py
index 0e3cd422..35ff72b6 100644
--- a/examples/PlotAutoRange.py
+++ b/examples/PlotAutoRange.py
@@ -12,7 +12,7 @@ import numpy as np
import pyqtgraph as pg
#QtGui.QApplication.setGraphicsSystem('raster')
-app = QtGui.QApplication([])
+app = pg.mkQApp("Plot Auto Range Example")
#mw = QtGui.QMainWindow()
#mw.resize(800,800)
diff --git a/examples/PlotSpeedTest.py b/examples/PlotSpeedTest.py
index 03c9537f..f5d630b4 100644
--- a/examples/PlotSpeedTest.py
+++ b/examples/PlotSpeedTest.py
@@ -12,7 +12,7 @@ from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg
from pyqtgraph.ptime import time
-app = QtGui.QApplication([])
+app = pg.mkQApp("Plot Speed Test")
p = pg.plot()
p.setWindowTitle('pyqtgraph example: PlotSpeedTest')
diff --git a/examples/Plotting.py b/examples/Plotting.py
index 130698a4..c3cf8b37 100644
--- a/examples/Plotting.py
+++ b/examples/Plotting.py
@@ -13,7 +13,7 @@ import numpy as np
import pyqtgraph as pg
#QtGui.QApplication.setGraphicsSystem('raster')
-app = QtGui.QApplication([])
+app = pg.mkQApp("Plotting Example")
#mw = QtGui.QMainWindow()
#mw.resize(800,800)
diff --git a/examples/ProgressDialog.py b/examples/ProgressDialog.py
index 141d2bb4..0fa9aa34 100644
--- a/examples/ProgressDialog.py
+++ b/examples/ProgressDialog.py
@@ -9,7 +9,7 @@ import time
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
-app = QtGui.QApplication([])
+app = pg.mkQApp("Progress Dialog Example")
def runStage(i):
diff --git a/examples/ROIExamples.py b/examples/ROIExamples.py
index fe3e4db8..17e55e98 100644
--- a/examples/ROIExamples.py
+++ b/examples/ROIExamples.py
@@ -32,7 +32,7 @@ arr[8:13, 44:46] = 10
## create GUI
-app = QtGui.QApplication([])
+app = pg.mkQApp("ROI Examples")
w = pg.GraphicsLayoutWidget(show=True, size=(1000,800), border=True)
w.setWindowTitle('pyqtgraph example: ROI Examples')
diff --git a/examples/ROItypes.py b/examples/ROItypes.py
index 4352f888..20a83dcb 100644
--- a/examples/ROItypes.py
+++ b/examples/ROItypes.py
@@ -11,7 +11,7 @@ import pyqtgraph as pg
pg.setConfigOptions(imageAxisOrder='row-major')
## create GUI
-app = QtGui.QApplication([])
+app = pg.mkQApp("ROI Types Examples")
w = pg.GraphicsLayoutWidget(show=True, size=(800,800), border=True)
v = w.addViewBox(colspan=2)
diff --git a/examples/RemoteSpeedTest.py b/examples/RemoteSpeedTest.py
index 03b4430b..8d8dd210 100644
--- a/examples/RemoteSpeedTest.py
+++ b/examples/RemoteSpeedTest.py
@@ -24,6 +24,8 @@ pg.setConfigOptions(antialias=True) ## this will be expensive for the local plo
view.pg.setConfigOptions(antialias=True) ## prettier plots at no cost to the main process!
view.setWindowTitle('pyqtgraph example: RemoteSpeedTest')
+app.aboutToQuit.connect(view.close)
+
label = QtGui.QLabel()
rcheck = QtGui.QCheckBox('plot remote')
rcheck.setChecked(True)
diff --git a/examples/ScatterPlot.py b/examples/ScatterPlot.py
index 295f76e9..070f21c5 100644
--- a/examples/ScatterPlot.py
+++ b/examples/ScatterPlot.py
@@ -14,7 +14,7 @@ import numpy as np
from collections import namedtuple
from itertools import chain
-app = QtGui.QApplication([])
+app = pg.mkQApp("Scatter Plot Item Example")
mw = QtGui.QMainWindow()
mw.resize(800,800)
view = pg.GraphicsLayoutWidget() ## GraphicsView with GraphicsLayout inserted by default
diff --git a/examples/ScatterPlotSpeedTest.py b/examples/ScatterPlotSpeedTest.py
index 7167b819..cadc16a3 100644
--- a/examples/ScatterPlotSpeedTest.py
+++ b/examples/ScatterPlotSpeedTest.py
@@ -17,21 +17,16 @@ import numpy as np
import pyqtgraph as pg
from pyqtgraph.ptime import time
#QtGui.QApplication.setGraphicsSystem('raster')
-app = QtGui.QApplication([])
+app = pg.mkQApp("Scatter Plot Speed Test")
#mw = QtGui.QMainWindow()
#mw.resize(800,800)
-if QT_LIB == 'PySide':
- from ScatterPlotSpeedTestTemplate_pyside import Ui_Form
-elif QT_LIB == 'PySide2':
- from ScatterPlotSpeedTestTemplate_pyside2 import Ui_Form
-elif QT_LIB == 'PyQt5':
- from ScatterPlotSpeedTestTemplate_pyqt5 import Ui_Form
-else:
- from ScatterPlotSpeedTestTemplate_pyqt import Ui_Form
+import importlib
+ui_template = importlib.import_module(
+ f'ScatterPlotSpeedTestTemplate_{QT_LIB.lower()}')
win = QtGui.QWidget()
win.setWindowTitle('pyqtgraph example: ScatterPlotSpeedTest')
-ui = Ui_Form()
+ui = ui_template.Ui_Form()
ui.setupUi(win)
win.show()
diff --git a/examples/ScatterPlotSpeedTestTemplate_pyqt.py b/examples/ScatterPlotSpeedTestTemplate_pyqt.py
deleted file mode 100644
index 896525eb..00000000
--- a/examples/ScatterPlotSpeedTestTemplate_pyqt.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file './examples/ScatterPlotSpeedTestTemplate.ui'
-#
-# Created: Fri Sep 21 15:39:09 2012
-# by: PyQt4 UI code generator 4.9.1
-#
-# WARNING! All changes made in this file will be lost!
-
-from PyQt4 import QtCore, QtGui
-
-try:
- _fromUtf8 = QtCore.QString.fromUtf8
-except AttributeError:
- _fromUtf8 = lambda s: s
-
-class Ui_Form(object):
- def setupUi(self, Form):
- Form.setObjectName(_fromUtf8("Form"))
- Form.resize(400, 300)
- self.gridLayout = QtGui.QGridLayout(Form)
- self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
- self.sizeSpin = QtGui.QSpinBox(Form)
- self.sizeSpin.setProperty("value", 10)
- self.sizeSpin.setObjectName(_fromUtf8("sizeSpin"))
- self.gridLayout.addWidget(self.sizeSpin, 1, 1, 1, 1)
- self.pixelModeCheck = QtGui.QCheckBox(Form)
- self.pixelModeCheck.setObjectName(_fromUtf8("pixelModeCheck"))
- self.gridLayout.addWidget(self.pixelModeCheck, 1, 3, 1, 1)
- self.label = QtGui.QLabel(Form)
- self.label.setObjectName(_fromUtf8("label"))
- self.gridLayout.addWidget(self.label, 1, 0, 1, 1)
- self.plot = PlotWidget(Form)
- self.plot.setObjectName(_fromUtf8("plot"))
- self.gridLayout.addWidget(self.plot, 0, 0, 1, 4)
- self.randCheck = QtGui.QCheckBox(Form)
- self.randCheck.setObjectName(_fromUtf8("randCheck"))
- self.gridLayout.addWidget(self.randCheck, 1, 2, 1, 1)
-
- self.retranslateUi(Form)
- QtCore.QMetaObject.connectSlotsByName(Form)
-
- def retranslateUi(self, Form):
- Form.setWindowTitle(QtGui.QApplication.translate("Form", "PyQtGraph", None, QtGui.QApplication.UnicodeUTF8))
- self.pixelModeCheck.setText(QtGui.QApplication.translate("Form", "pixel mode", None, QtGui.QApplication.UnicodeUTF8))
- self.label.setText(QtGui.QApplication.translate("Form", "Size", None, QtGui.QApplication.UnicodeUTF8))
- self.randCheck.setText(QtGui.QApplication.translate("Form", "Randomize", None, QtGui.QApplication.UnicodeUTF8))
-
-from pyqtgraph import PlotWidget
diff --git a/examples/ScatterPlotSpeedTestTemplate_pyqt6.py b/examples/ScatterPlotSpeedTestTemplate_pyqt6.py
new file mode 100644
index 00000000..d963d8fc
--- /dev/null
+++ b/examples/ScatterPlotSpeedTestTemplate_pyqt6.py
@@ -0,0 +1,44 @@
+# 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_pyside.py b/examples/ScatterPlotSpeedTestTemplate_pyside.py
deleted file mode 100644
index 798ebccd..00000000
--- a/examples/ScatterPlotSpeedTestTemplate_pyside.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file './examples/ScatterPlotSpeedTestTemplate.ui'
-#
-# Created: Fri Sep 21 15:39:09 2012
-# by: pyside-uic 0.2.13 running on PySide 1.1.0
-#
-# WARNING! All changes made in this file will be lost!
-
-from PySide import QtCore, QtGui
-
-class Ui_Form(object):
- def setupUi(self, Form):
- Form.setObjectName("Form")
- Form.resize(400, 300)
- self.gridLayout = QtGui.QGridLayout(Form)
- self.gridLayout.setObjectName("gridLayout")
- self.sizeSpin = QtGui.QSpinBox(Form)
- self.sizeSpin.setProperty("value", 10)
- self.sizeSpin.setObjectName("sizeSpin")
- self.gridLayout.addWidget(self.sizeSpin, 1, 1, 1, 1)
- self.pixelModeCheck = QtGui.QCheckBox(Form)
- self.pixelModeCheck.setObjectName("pixelModeCheck")
- self.gridLayout.addWidget(self.pixelModeCheck, 1, 3, 1, 1)
- self.label = QtGui.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 = QtGui.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(QtGui.QApplication.translate("Form", "PyQtGraph", None, QtGui.QApplication.UnicodeUTF8))
- self.pixelModeCheck.setText(QtGui.QApplication.translate("Form", "pixel mode", None, QtGui.QApplication.UnicodeUTF8))
- self.label.setText(QtGui.QApplication.translate("Form", "Size", None, QtGui.QApplication.UnicodeUTF8))
- self.randCheck.setText(QtGui.QApplication.translate("Form", "Randomize", None, QtGui.QApplication.UnicodeUTF8))
-
-from pyqtgraph import PlotWidget
diff --git a/examples/ScatterPlotSpeedTestTemplate_pyside6.py b/examples/ScatterPlotSpeedTestTemplate_pyside6.py
new file mode 100644
index 00000000..c529b167
--- /dev/null
+++ b/examples/ScatterPlotSpeedTestTemplate_pyside6.py
@@ -0,0 +1,63 @@
+# -*- 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
+
diff --git a/examples/SpinBox.py b/examples/SpinBox.py
index ae8f30bf..74695879 100644
--- a/examples/SpinBox.py
+++ b/examples/SpinBox.py
@@ -15,7 +15,7 @@ from pyqtgraph.Qt import QtCore, QtGui
import numpy as np
import ast
-app = QtGui.QApplication([])
+app = pg.mkQApp("SpinBox Example")
spins = [
diff --git a/examples/Symbols.py b/examples/Symbols.py
index a0c57f75..3a683e6d 100755
--- a/examples/Symbols.py
+++ b/examples/Symbols.py
@@ -10,7 +10,7 @@ import initExample ## Add path to library (just for examples; you do not need th
from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg
-app = QtGui.QApplication([])
+app = pg.mkQApp("Symbols Examples")
win = pg.GraphicsLayoutWidget(show=True, title="Scatter Plot Symbols")
win.resize(1000,600)
diff --git a/examples/TableWidget.py b/examples/TableWidget.py
index cfeac399..0fb1aae4 100644
--- a/examples/TableWidget.py
+++ b/examples/TableWidget.py
@@ -9,7 +9,7 @@ import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import numpy as np
-app = QtGui.QApplication([])
+app = pg.mkQApp("Table Widget Example")
w = pg.TableWidget()
w.show()
diff --git a/examples/TreeWidget.py b/examples/TreeWidget.py
index b1ad3847..56940316 100644
--- a/examples/TreeWidget.py
+++ b/examples/TreeWidget.py
@@ -10,7 +10,7 @@ from pyqtgraph.Qt import QtCore, QtGui
import numpy as np
-app = QtGui.QApplication([])
+app = pg.mkQApp("TreeWidget Example")
w = pg.TreeWidget()
w.setColumnCount(2)
diff --git a/examples/VideoSpeedTest.py b/examples/VideoSpeedTest.py
index 7131f9d1..9f7d5c7e 100644
--- a/examples/VideoSpeedTest.py
+++ b/examples/VideoSpeedTest.py
@@ -6,45 +6,89 @@ it is being scaled and/or converted by lookup table, and whether OpenGL
is used by the view widget
"""
+import argparse
+import sys
-import initExample ## Add path to library (just for examples; you do not need this)
-
-
-from pyqtgraph.Qt import QtGui, QtCore, QT_LIB
import numpy as np
+
import pyqtgraph as pg
import pyqtgraph.ptime as ptime
+from pyqtgraph.Qt import QtGui, QtCore, QT_LIB
-if QT_LIB == 'PySide':
- import VideoTemplate_pyside as VideoTemplate
-elif QT_LIB == 'PySide2':
- import VideoTemplate_pyside2 as VideoTemplate
-elif QT_LIB == 'PyQt5':
- import VideoTemplate_pyqt5 as VideoTemplate
-else:
- import VideoTemplate_pyqt as VideoTemplate
-
+import importlib
+ui_template = importlib.import_module(f'VideoTemplate_{QT_LIB.lower()}')
+
+try:
+ import cupy as cp
+ pg.setConfigOption("useCupy", True)
+ _has_cupy = True
+except ImportError:
+ cp = None
+ _has_cupy = False
+
+parser = argparse.ArgumentParser(description="Benchmark for testing video performance")
+parser.add_argument('--cuda', default=False, action='store_true', help="Use CUDA to process on the GPU", dest="cuda")
+parser.add_argument('--dtype', default='uint8', choices=['uint8', 'uint16', 'float'], help="Image dtype (uint8, uint16, or float)")
+parser.add_argument('--frames', default=3, type=int, help="Number of image frames to generate (default=3)")
+parser.add_argument('--image-mode', default='mono', choices=['mono', 'rgb'], help="Image data mode (mono or rgb)", dest='image_mode')
+parser.add_argument('--levels', default=None, type=lambda s: tuple([float(x) for x in s.split(',')]), help="min,max levels to scale monochromatic image dynamic range, or rmin,rmax,gmin,gmax,bmin,bmax to scale rgb")
+parser.add_argument('--lut', default=False, action='store_true', help="Use color lookup table")
+parser.add_argument('--lut-alpha', default=False, action='store_true', help="Use alpha color lookup table", dest='lut_alpha')
+parser.add_argument('--size', default='512x512', type=lambda s: tuple([int(x) for x in s.split('x')]), help="WxH image dimensions default='512x512'")
+args = parser.parse_args(sys.argv[1:])
#QtGui.QApplication.setGraphicsSystem('raster')
-app = QtGui.QApplication([])
+app = pg.mkQApp("Video Speed Test Example")
win = QtGui.QMainWindow()
win.setWindowTitle('pyqtgraph example: VideoSpeedTest')
-ui = VideoTemplate.Ui_MainWindow()
+ui = ui_template.Ui_MainWindow()
ui.setupUi(win)
win.show()
try:
from pyqtgraph.widgets.RawImageWidget import RawImageGLWidget
except ImportError:
+ RawImageGLWidget = None
ui.rawGLRadio.setEnabled(False)
ui.rawGLRadio.setText(ui.rawGLRadio.text() + " (OpenGL not available)")
else:
ui.rawGLImg = RawImageGLWidget()
ui.stack.addWidget(ui.rawGLImg)
+# read in CLI args
+ui.cudaCheck.setChecked(args.cuda and _has_cupy)
+ui.cudaCheck.setEnabled(_has_cupy)
+ui.framesSpin.setValue(args.frames)
+ui.widthSpin.setValue(args.size[0])
+ui.heightSpin.setValue(args.size[1])
+ui.dtypeCombo.setCurrentText(args.dtype)
+ui.rgbCheck.setChecked(args.image_mode=='rgb')
ui.maxSpin1.setOpts(value=255, step=1)
ui.minSpin1.setOpts(value=0, step=1)
+levelSpins = [ui.minSpin1, ui.maxSpin1, ui.minSpin2, ui.maxSpin2, ui.minSpin3, ui.maxSpin3]
+if args.cuda and _has_cupy:
+ xp = cp
+else:
+ xp = np
+if args.levels is None:
+ ui.scaleCheck.setChecked(False)
+ ui.rgbLevelsCheck.setChecked(False)
+else:
+ ui.scaleCheck.setChecked(True)
+ if len(args.levels) == 2:
+ ui.rgbLevelsCheck.setChecked(False)
+ ui.minSpin1.setValue(args.levels[0])
+ ui.maxSpin1.setValue(args.levels[1])
+ elif len(args.levels) == 6:
+ ui.rgbLevelsCheck.setChecked(True)
+ for spin,val in zip(levelSpins, args.levels):
+ spin.setValue(val)
+ else:
+ raise ValueError("levels argument must be 2 or 6 comma-separated values (got %r)" % (args.levels,))
+ui.lutCheck.setChecked(args.lut)
+ui.alphaCheck.setChecked(args.lut_alpha)
+
#ui.graphicsView.useOpenGL() ## buggy, but you can try it if you need extra speed.
@@ -53,7 +97,8 @@ ui.graphicsView.setCentralItem(vb)
vb.setAspectLocked()
img = pg.ImageItem()
vb.addItem(img)
-vb.setRange(QtCore.QRectF(0, 0, 512, 512))
+
+
LUT = None
def updateLUT():
@@ -64,74 +109,94 @@ def updateLUT():
else:
n = 4096
LUT = ui.gradient.getLookupTable(n, alpha=ui.alphaCheck.isChecked())
+ if _has_cupy and xp == cp:
+ LUT = cp.asarray(LUT)
ui.gradient.sigGradientChanged.connect(updateLUT)
updateLUT()
ui.alphaCheck.toggled.connect(updateLUT)
def updateScale():
- global ui
- spins = [ui.minSpin1, ui.maxSpin1, ui.minSpin2, ui.maxSpin2, ui.minSpin3, ui.maxSpin3]
+ global ui, levelSpins
if ui.rgbLevelsCheck.isChecked():
- for s in spins[2:]:
+ for s in levelSpins[2:]:
s.setEnabled(True)
else:
- for s in spins[2:]:
+ for s in levelSpins[2:]:
s.setEnabled(False)
+
+updateScale()
+
ui.rgbLevelsCheck.toggled.connect(updateScale)
-
+
cache = {}
def mkData():
with pg.BusyCursor():
- global data, cache, ui
+ global data, cache, ui, xp
frames = ui.framesSpin.value()
width = ui.widthSpin.value()
height = ui.heightSpin.value()
- dtype = (ui.dtypeCombo.currentText(), ui.rgbCheck.isChecked(), frames, width, height)
- if dtype not in cache:
- if dtype[0] == 'uint8':
- dt = np.uint8
+ cacheKey = (ui.dtypeCombo.currentText(), ui.rgbCheck.isChecked(), frames, width, height)
+ if cacheKey not in cache:
+ if cacheKey[0] == 'uint8':
+ dt = xp.uint8
loc = 128
scale = 64
mx = 255
- elif dtype[0] == 'uint16':
- dt = np.uint16
+ elif cacheKey[0] == 'uint16':
+ dt = xp.uint16
loc = 4096
scale = 1024
mx = 2**16
- elif dtype[0] == 'float':
- dt = np.float
+ elif cacheKey[0] == 'float':
+ dt = xp.float
loc = 1.0
scale = 0.1
mx = 1.0
+ else:
+ raise ValueError(f"unable to handle dtype: {cacheKey[0]}")
if ui.rgbCheck.isChecked():
- data = np.random.normal(size=(frames,width,height,3), loc=loc, scale=scale)
+ data = xp.random.normal(size=(frames,width,height,3), loc=loc, scale=scale)
data = pg.gaussianFilter(data, (0, 6, 6, 0))
else:
- data = np.random.normal(size=(frames,width,height), loc=loc, scale=scale)
+ data = xp.random.normal(size=(frames,width,height), loc=loc, scale=scale)
data = pg.gaussianFilter(data, (0, 6, 6))
- if dtype[0] != 'float':
- data = np.clip(data, 0, mx)
+ if cacheKey[0] != 'float':
+ data = xp.clip(data, 0, mx)
data = data.astype(dt)
data[:, 10, 10:50] = mx
data[:, 9:12, 48] = mx
data[:, 8:13, 47] = mx
- cache = {dtype: data} # clear to save memory (but keep one to prevent unnecessary regeneration)
-
- data = cache[dtype]
+ cache = {cacheKey: data} # clear to save memory (but keep one to prevent unnecessary regeneration)
+
+ data = cache[cacheKey]
updateLUT()
updateSize()
def updateSize():
- global ui
+ global ui, vb
frames = ui.framesSpin.value()
width = ui.widthSpin.value()
height = ui.heightSpin.value()
- dtype = np.dtype(str(ui.dtypeCombo.currentText()))
+ dtype = xp.dtype(str(ui.dtypeCombo.currentText()))
rgb = 3 if ui.rgbCheck.isChecked() else 1
ui.sizeLabel.setText('%d MB' % (frames * width * height * rgb * dtype.itemsize / 1e6))
-
+ vb.setRange(QtCore.QRectF(0, 0, width, height))
+
+
+def noticeCudaCheck():
+ global xp, cache
+ cache = {}
+ if ui.cudaCheck.isChecked():
+ if _has_cupy:
+ xp = cp
+ else:
+ xp = np
+ ui.cudaCheck.setChecked(False)
+ else:
+ xp = np
+ mkData()
mkData()
@@ -145,7 +210,7 @@ ui.framesSpin.editingFinished.connect(mkData)
ui.widthSpin.valueChanged.connect(updateSize)
ui.heightSpin.valueChanged.connect(updateSize)
ui.framesSpin.valueChanged.connect(updateSize)
-
+ui.cudaCheck.toggled.connect(noticeCudaCheck)
ptr = 0
@@ -157,14 +222,14 @@ def update():
useLut = LUT
else:
useLut = None
-
+
downsample = ui.downsampleCheck.isChecked()
if ui.scaleCheck.isChecked():
if ui.rgbLevelsCheck.isChecked():
useScale = [
- [ui.minSpin1.value(), ui.maxSpin1.value()],
- [ui.minSpin2.value(), ui.maxSpin2.value()],
+ [ui.minSpin1.value(), ui.maxSpin1.value()],
+ [ui.minSpin2.value(), ui.maxSpin2.value()],
[ui.minSpin3.value(), ui.maxSpin3.value()]]
else:
useScale = [ui.minSpin1.value(), ui.maxSpin1.value()]
@@ -181,7 +246,7 @@ def update():
img.setImage(data[ptr%data.shape[0]], autoLevels=False, levels=useScale, lut=useLut, autoDownsample=downsample)
ui.stack.setCurrentIndex(0)
#img.setImage(data[ptr%data.shape[0]], autoRange=False)
-
+
ptr += 1
now = ptime.time()
dt = now - lastTime
@@ -196,7 +261,7 @@ def update():
timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(0)
-
+
## Start Qt event loop unless running in interactive mode or using pyside.
diff --git a/examples/VideoTemplate.ui b/examples/VideoTemplate.ui
index 7da18327..5508442a 100644
--- a/examples/VideoTemplate.ui
+++ b/examples/VideoTemplate.ui
@@ -15,6 +15,13 @@
+ -
+
+
+ Use CUDA (GPU) if available
+
+
+
-
diff --git a/examples/VideoTemplate_pyqt.py b/examples/VideoTemplate_pyqt.py
deleted file mode 100644
index b93bedeb..00000000
--- a/examples/VideoTemplate_pyqt.py
+++ /dev/null
@@ -1,212 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file 'examples/VideoTemplate.ui'
-#
-# Created by: PyQt4 UI code generator 4.11.4
-#
-# WARNING! All changes made in this file will be lost!
-
-from PyQt4 import QtCore, QtGui
-
-try:
- _fromUtf8 = QtCore.QString.fromUtf8
-except AttributeError:
- def _fromUtf8(s):
- return s
-
-try:
- _encoding = QtGui.QApplication.UnicodeUTF8
- def _translate(context, text, disambig):
- return QtGui.QApplication.translate(context, text, disambig, _encoding)
-except AttributeError:
- def _translate(context, text, disambig):
- return QtGui.QApplication.translate(context, text, disambig)
-
-class Ui_MainWindow(object):
- def setupUi(self, MainWindow):
- MainWindow.setObjectName(_fromUtf8("MainWindow"))
- MainWindow.resize(695, 798)
- self.centralwidget = QtGui.QWidget(MainWindow)
- self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
- self.gridLayout_2 = QtGui.QGridLayout(self.centralwidget)
- self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2"))
- self.downsampleCheck = QtGui.QCheckBox(self.centralwidget)
- self.downsampleCheck.setObjectName(_fromUtf8("downsampleCheck"))
- self.gridLayout_2.addWidget(self.downsampleCheck, 8, 0, 1, 2)
- self.scaleCheck = QtGui.QCheckBox(self.centralwidget)
- self.scaleCheck.setObjectName(_fromUtf8("scaleCheck"))
- self.gridLayout_2.addWidget(self.scaleCheck, 4, 0, 1, 1)
- self.gridLayout = QtGui.QGridLayout()
- self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
- self.rawRadio = QtGui.QRadioButton(self.centralwidget)
- self.rawRadio.setObjectName(_fromUtf8("rawRadio"))
- self.gridLayout.addWidget(self.rawRadio, 3, 0, 1, 1)
- self.gfxRadio = QtGui.QRadioButton(self.centralwidget)
- self.gfxRadio.setChecked(True)
- self.gfxRadio.setObjectName(_fromUtf8("gfxRadio"))
- self.gridLayout.addWidget(self.gfxRadio, 2, 0, 1, 1)
- self.stack = QtGui.QStackedWidget(self.centralwidget)
- self.stack.setObjectName(_fromUtf8("stack"))
- self.page = QtGui.QWidget()
- self.page.setObjectName(_fromUtf8("page"))
- self.gridLayout_3 = QtGui.QGridLayout(self.page)
- self.gridLayout_3.setObjectName(_fromUtf8("gridLayout_3"))
- self.graphicsView = GraphicsView(self.page)
- self.graphicsView.setObjectName(_fromUtf8("graphicsView"))
- self.gridLayout_3.addWidget(self.graphicsView, 0, 0, 1, 1)
- self.stack.addWidget(self.page)
- self.page_2 = QtGui.QWidget()
- self.page_2.setObjectName(_fromUtf8("page_2"))
- self.gridLayout_4 = QtGui.QGridLayout(self.page_2)
- self.gridLayout_4.setObjectName(_fromUtf8("gridLayout_4"))
- self.rawImg = RawImageWidget(self.page_2)
- sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.rawImg.sizePolicy().hasHeightForWidth())
- self.rawImg.setSizePolicy(sizePolicy)
- self.rawImg.setObjectName(_fromUtf8("rawImg"))
- self.gridLayout_4.addWidget(self.rawImg, 0, 0, 1, 1)
- self.stack.addWidget(self.page_2)
- self.gridLayout.addWidget(self.stack, 0, 0, 1, 1)
- self.rawGLRadio = QtGui.QRadioButton(self.centralwidget)
- self.rawGLRadio.setObjectName(_fromUtf8("rawGLRadio"))
- self.gridLayout.addWidget(self.rawGLRadio, 4, 0, 1, 1)
- self.gridLayout_2.addLayout(self.gridLayout, 1, 0, 1, 4)
- self.dtypeCombo = QtGui.QComboBox(self.centralwidget)
- self.dtypeCombo.setObjectName(_fromUtf8("dtypeCombo"))
- self.dtypeCombo.addItem(_fromUtf8(""))
- self.dtypeCombo.addItem(_fromUtf8(""))
- self.dtypeCombo.addItem(_fromUtf8(""))
- self.gridLayout_2.addWidget(self.dtypeCombo, 3, 2, 1, 1)
- self.label = QtGui.QLabel(self.centralwidget)
- self.label.setObjectName(_fromUtf8("label"))
- self.gridLayout_2.addWidget(self.label, 3, 0, 1, 1)
- self.rgbLevelsCheck = QtGui.QCheckBox(self.centralwidget)
- self.rgbLevelsCheck.setObjectName(_fromUtf8("rgbLevelsCheck"))
- self.gridLayout_2.addWidget(self.rgbLevelsCheck, 4, 1, 1, 1)
- self.horizontalLayout_2 = QtGui.QHBoxLayout()
- self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2"))
- self.minSpin2 = SpinBox(self.centralwidget)
- self.minSpin2.setEnabled(False)
- self.minSpin2.setObjectName(_fromUtf8("minSpin2"))
- self.horizontalLayout_2.addWidget(self.minSpin2)
- self.label_3 = QtGui.QLabel(self.centralwidget)
- self.label_3.setAlignment(QtCore.Qt.AlignCenter)
- self.label_3.setObjectName(_fromUtf8("label_3"))
- self.horizontalLayout_2.addWidget(self.label_3)
- self.maxSpin2 = SpinBox(self.centralwidget)
- self.maxSpin2.setEnabled(False)
- self.maxSpin2.setObjectName(_fromUtf8("maxSpin2"))
- self.horizontalLayout_2.addWidget(self.maxSpin2)
- self.gridLayout_2.addLayout(self.horizontalLayout_2, 5, 2, 1, 1)
- self.horizontalLayout = QtGui.QHBoxLayout()
- self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
- self.minSpin1 = SpinBox(self.centralwidget)
- self.minSpin1.setObjectName(_fromUtf8("minSpin1"))
- self.horizontalLayout.addWidget(self.minSpin1)
- self.label_2 = QtGui.QLabel(self.centralwidget)
- self.label_2.setAlignment(QtCore.Qt.AlignCenter)
- self.label_2.setObjectName(_fromUtf8("label_2"))
- self.horizontalLayout.addWidget(self.label_2)
- self.maxSpin1 = SpinBox(self.centralwidget)
- self.maxSpin1.setObjectName(_fromUtf8("maxSpin1"))
- self.horizontalLayout.addWidget(self.maxSpin1)
- self.gridLayout_2.addLayout(self.horizontalLayout, 4, 2, 1, 1)
- self.horizontalLayout_3 = QtGui.QHBoxLayout()
- self.horizontalLayout_3.setObjectName(_fromUtf8("horizontalLayout_3"))
- self.minSpin3 = SpinBox(self.centralwidget)
- self.minSpin3.setEnabled(False)
- self.minSpin3.setObjectName(_fromUtf8("minSpin3"))
- self.horizontalLayout_3.addWidget(self.minSpin3)
- self.label_4 = QtGui.QLabel(self.centralwidget)
- self.label_4.setAlignment(QtCore.Qt.AlignCenter)
- self.label_4.setObjectName(_fromUtf8("label_4"))
- self.horizontalLayout_3.addWidget(self.label_4)
- self.maxSpin3 = SpinBox(self.centralwidget)
- self.maxSpin3.setEnabled(False)
- self.maxSpin3.setObjectName(_fromUtf8("maxSpin3"))
- self.horizontalLayout_3.addWidget(self.maxSpin3)
- self.gridLayout_2.addLayout(self.horizontalLayout_3, 6, 2, 1, 1)
- self.lutCheck = QtGui.QCheckBox(self.centralwidget)
- self.lutCheck.setObjectName(_fromUtf8("lutCheck"))
- self.gridLayout_2.addWidget(self.lutCheck, 7, 0, 1, 1)
- self.alphaCheck = QtGui.QCheckBox(self.centralwidget)
- self.alphaCheck.setObjectName(_fromUtf8("alphaCheck"))
- self.gridLayout_2.addWidget(self.alphaCheck, 7, 1, 1, 1)
- self.gradient = GradientWidget(self.centralwidget)
- sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.gradient.sizePolicy().hasHeightForWidth())
- self.gradient.setSizePolicy(sizePolicy)
- self.gradient.setObjectName(_fromUtf8("gradient"))
- self.gridLayout_2.addWidget(self.gradient, 7, 2, 1, 2)
- spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
- self.gridLayout_2.addItem(spacerItem, 3, 3, 1, 1)
- self.fpsLabel = QtGui.QLabel(self.centralwidget)
- font = QtGui.QFont()
- font.setPointSize(12)
- self.fpsLabel.setFont(font)
- self.fpsLabel.setAlignment(QtCore.Qt.AlignCenter)
- self.fpsLabel.setObjectName(_fromUtf8("fpsLabel"))
- self.gridLayout_2.addWidget(self.fpsLabel, 0, 0, 1, 4)
- self.rgbCheck = QtGui.QCheckBox(self.centralwidget)
- self.rgbCheck.setObjectName(_fromUtf8("rgbCheck"))
- self.gridLayout_2.addWidget(self.rgbCheck, 3, 1, 1, 1)
- self.label_5 = QtGui.QLabel(self.centralwidget)
- self.label_5.setObjectName(_fromUtf8("label_5"))
- self.gridLayout_2.addWidget(self.label_5, 2, 0, 1, 1)
- self.horizontalLayout_4 = QtGui.QHBoxLayout()
- self.horizontalLayout_4.setObjectName(_fromUtf8("horizontalLayout_4"))
- self.framesSpin = QtGui.QSpinBox(self.centralwidget)
- self.framesSpin.setButtonSymbols(QtGui.QAbstractSpinBox.NoButtons)
- self.framesSpin.setProperty("value", 10)
- self.framesSpin.setObjectName(_fromUtf8("framesSpin"))
- self.horizontalLayout_4.addWidget(self.framesSpin)
- self.widthSpin = QtGui.QSpinBox(self.centralwidget)
- self.widthSpin.setButtonSymbols(QtGui.QAbstractSpinBox.PlusMinus)
- self.widthSpin.setMaximum(10000)
- self.widthSpin.setProperty("value", 512)
- self.widthSpin.setObjectName(_fromUtf8("widthSpin"))
- self.horizontalLayout_4.addWidget(self.widthSpin)
- self.heightSpin = QtGui.QSpinBox(self.centralwidget)
- self.heightSpin.setButtonSymbols(QtGui.QAbstractSpinBox.NoButtons)
- self.heightSpin.setMaximum(10000)
- self.heightSpin.setProperty("value", 512)
- self.heightSpin.setObjectName(_fromUtf8("heightSpin"))
- self.horizontalLayout_4.addWidget(self.heightSpin)
- self.gridLayout_2.addLayout(self.horizontalLayout_4, 2, 1, 1, 2)
- self.sizeLabel = QtGui.QLabel(self.centralwidget)
- self.sizeLabel.setText(_fromUtf8(""))
- self.sizeLabel.setObjectName(_fromUtf8("sizeLabel"))
- self.gridLayout_2.addWidget(self.sizeLabel, 2, 3, 1, 1)
- MainWindow.setCentralWidget(self.centralwidget)
-
- self.retranslateUi(MainWindow)
- self.stack.setCurrentIndex(1)
- QtCore.QMetaObject.connectSlotsByName(MainWindow)
-
- def retranslateUi(self, MainWindow):
- MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
- self.downsampleCheck.setText(_translate("MainWindow", "Auto downsample", None))
- self.scaleCheck.setText(_translate("MainWindow", "Scale Data", None))
- self.rawRadio.setText(_translate("MainWindow", "RawImageWidget", None))
- self.gfxRadio.setText(_translate("MainWindow", "GraphicsView + ImageItem", None))
- self.rawGLRadio.setText(_translate("MainWindow", "RawGLImageWidget", None))
- self.dtypeCombo.setItemText(0, _translate("MainWindow", "uint8", None))
- self.dtypeCombo.setItemText(1, _translate("MainWindow", "uint16", None))
- self.dtypeCombo.setItemText(2, _translate("MainWindow", "float", None))
- self.label.setText(_translate("MainWindow", "Data type", None))
- self.rgbLevelsCheck.setText(_translate("MainWindow", "RGB", None))
- self.label_3.setText(_translate("MainWindow", "<--->", None))
- self.label_2.setText(_translate("MainWindow", "<--->", None))
- self.label_4.setText(_translate("MainWindow", "<--->", None))
- self.lutCheck.setText(_translate("MainWindow", "Use Lookup Table", None))
- self.alphaCheck.setText(_translate("MainWindow", "alpha", None))
- self.fpsLabel.setText(_translate("MainWindow", "FPS", None))
- self.rgbCheck.setText(_translate("MainWindow", "RGB", None))
- self.label_5.setText(_translate("MainWindow", "Image size", None))
-
-from pyqtgraph import GradientWidget, GraphicsView, SpinBox
-from pyqtgraph.widgets.RawImageWidget import RawImageWidget
diff --git a/examples/VideoTemplate_pyqt5.py b/examples/VideoTemplate_pyqt5.py
index 63153fb5..2a039ae7 100644
--- a/examples/VideoTemplate_pyqt5.py
+++ b/examples/VideoTemplate_pyqt5.py
@@ -2,12 +2,15 @@
# Form implementation generated from reading ui file 'examples/VideoTemplate.ui'
#
-# Created by: PyQt5 UI code generator 5.5.1
+# Created by: PyQt5 UI code generator 5.15.1
#
-# WARNING! All changes made in this file will be lost!
+# WARNING: Any manual changes made to this file will be lost when pyuic5 is
+# run again. Do not edit this file unless you know what you are doing.
+
from PyQt5 import QtCore, QtGui, QtWidgets
+
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
@@ -16,6 +19,9 @@ class Ui_MainWindow(object):
self.centralwidget.setObjectName("centralwidget")
self.gridLayout_2 = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout_2.setObjectName("gridLayout_2")
+ self.cudaCheck = QtWidgets.QCheckBox(self.centralwidget)
+ self.cudaCheck.setObjectName("cudaCheck")
+ self.gridLayout_2.addWidget(self.cudaCheck, 9, 0, 1, 2)
self.downsampleCheck = QtWidgets.QCheckBox(self.centralwidget)
self.downsampleCheck.setObjectName("downsampleCheck")
self.gridLayout_2.addWidget(self.downsampleCheck, 8, 0, 1, 2)
@@ -176,6 +182,7 @@ class Ui_MainWindow(object):
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
+ self.cudaCheck.setText(_translate("MainWindow", "Use CUDA (GPU) if available"))
self.downsampleCheck.setText(_translate("MainWindow", "Auto downsample"))
self.scaleCheck.setText(_translate("MainWindow", "Scale Data"))
self.rawRadio.setText(_translate("MainWindow", "RawImageWidget"))
@@ -194,6 +201,5 @@ class Ui_MainWindow(object):
self.fpsLabel.setText(_translate("MainWindow", "FPS"))
self.rgbCheck.setText(_translate("MainWindow", "RGB"))
self.label_5.setText(_translate("MainWindow", "Image size"))
-
from pyqtgraph import GradientWidget, GraphicsView, SpinBox
from pyqtgraph.widgets.RawImageWidget import RawImageWidget
diff --git a/examples/VideoTemplate_pyside.py b/examples/VideoTemplate_pyqt6.py
similarity index 54%
rename from examples/VideoTemplate_pyside.py
rename to examples/VideoTemplate_pyqt6.py
index 4af85249..f69ebe0f 100644
--- a/examples/VideoTemplate_pyside.py
+++ b/examples/VideoTemplate_pyqt6.py
@@ -1,53 +1,56 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file 'examples/VideoTemplate.ui'
+# Form implementation generated from reading ui file 'VideoTemplate.ui'
#
-# Created: Wed Oct 26 09:21:01 2016
-# by: pyside-uic 0.2.15 running on PySide 1.2.2
+# Created by: PyQt6 UI code generator 6.0.0
#
-# WARNING! All changes made in this file will be lost!
+# 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
-from PySide import QtCore, QtGui
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(695, 798)
- self.centralwidget = QtGui.QWidget(MainWindow)
+ self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
- self.gridLayout_2 = QtGui.QGridLayout(self.centralwidget)
+ self.gridLayout_2 = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout_2.setObjectName("gridLayout_2")
- self.downsampleCheck = QtGui.QCheckBox(self.centralwidget)
+ self.cudaCheck = QtWidgets.QCheckBox(self.centralwidget)
+ self.cudaCheck.setObjectName("cudaCheck")
+ self.gridLayout_2.addWidget(self.cudaCheck, 9, 0, 1, 2)
+ self.downsampleCheck = QtWidgets.QCheckBox(self.centralwidget)
self.downsampleCheck.setObjectName("downsampleCheck")
self.gridLayout_2.addWidget(self.downsampleCheck, 8, 0, 1, 2)
- self.scaleCheck = QtGui.QCheckBox(self.centralwidget)
+ self.scaleCheck = QtWidgets.QCheckBox(self.centralwidget)
self.scaleCheck.setObjectName("scaleCheck")
self.gridLayout_2.addWidget(self.scaleCheck, 4, 0, 1, 1)
- self.gridLayout = QtGui.QGridLayout()
+ self.gridLayout = QtWidgets.QGridLayout()
self.gridLayout.setObjectName("gridLayout")
- self.rawRadio = QtGui.QRadioButton(self.centralwidget)
+ self.rawRadio = QtWidgets.QRadioButton(self.centralwidget)
self.rawRadio.setObjectName("rawRadio")
self.gridLayout.addWidget(self.rawRadio, 3, 0, 1, 1)
- self.gfxRadio = QtGui.QRadioButton(self.centralwidget)
+ self.gfxRadio = QtWidgets.QRadioButton(self.centralwidget)
self.gfxRadio.setChecked(True)
self.gfxRadio.setObjectName("gfxRadio")
self.gridLayout.addWidget(self.gfxRadio, 2, 0, 1, 1)
- self.stack = QtGui.QStackedWidget(self.centralwidget)
+ self.stack = QtWidgets.QStackedWidget(self.centralwidget)
self.stack.setObjectName("stack")
- self.page = QtGui.QWidget()
+ self.page = QtWidgets.QWidget()
self.page.setObjectName("page")
- self.gridLayout_3 = QtGui.QGridLayout(self.page)
+ self.gridLayout_3 = QtWidgets.QGridLayout(self.page)
self.gridLayout_3.setObjectName("gridLayout_3")
self.graphicsView = GraphicsView(self.page)
self.graphicsView.setObjectName("graphicsView")
self.gridLayout_3.addWidget(self.graphicsView, 0, 0, 1, 1)
self.stack.addWidget(self.page)
- self.page_2 = QtGui.QWidget()
+ self.page_2 = QtWidgets.QWidget()
self.page_2.setObjectName("page_2")
- self.gridLayout_4 = QtGui.QGridLayout(self.page_2)
+ self.gridLayout_4 = QtWidgets.QGridLayout(self.page_2)
self.gridLayout_4.setObjectName("gridLayout_4")
self.rawImg = RawImageWidget(self.page_2)
- sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.rawImg.sizePolicy().hasHeightForWidth())
@@ -56,30 +59,30 @@ class Ui_MainWindow(object):
self.gridLayout_4.addWidget(self.rawImg, 0, 0, 1, 1)
self.stack.addWidget(self.page_2)
self.gridLayout.addWidget(self.stack, 0, 0, 1, 1)
- self.rawGLRadio = QtGui.QRadioButton(self.centralwidget)
+ self.rawGLRadio = QtWidgets.QRadioButton(self.centralwidget)
self.rawGLRadio.setObjectName("rawGLRadio")
self.gridLayout.addWidget(self.rawGLRadio, 4, 0, 1, 1)
self.gridLayout_2.addLayout(self.gridLayout, 1, 0, 1, 4)
- self.dtypeCombo = QtGui.QComboBox(self.centralwidget)
+ self.dtypeCombo = QtWidgets.QComboBox(self.centralwidget)
self.dtypeCombo.setObjectName("dtypeCombo")
self.dtypeCombo.addItem("")
self.dtypeCombo.addItem("")
self.dtypeCombo.addItem("")
self.gridLayout_2.addWidget(self.dtypeCombo, 3, 2, 1, 1)
- self.label = QtGui.QLabel(self.centralwidget)
+ self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setObjectName("label")
self.gridLayout_2.addWidget(self.label, 3, 0, 1, 1)
- self.rgbLevelsCheck = QtGui.QCheckBox(self.centralwidget)
+ self.rgbLevelsCheck = QtWidgets.QCheckBox(self.centralwidget)
self.rgbLevelsCheck.setObjectName("rgbLevelsCheck")
self.gridLayout_2.addWidget(self.rgbLevelsCheck, 4, 1, 1, 1)
- self.horizontalLayout_2 = QtGui.QHBoxLayout()
+ self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.minSpin2 = SpinBox(self.centralwidget)
self.minSpin2.setEnabled(False)
self.minSpin2.setObjectName("minSpin2")
self.horizontalLayout_2.addWidget(self.minSpin2)
- self.label_3 = QtGui.QLabel(self.centralwidget)
- self.label_3.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_3 = QtWidgets.QLabel(self.centralwidget)
+ self.label_3.setAlignment(QtCore.Qt.Alignment.AlignCenter)
self.label_3.setObjectName("label_3")
self.horizontalLayout_2.addWidget(self.label_3)
self.maxSpin2 = SpinBox(self.centralwidget)
@@ -87,27 +90,27 @@ class Ui_MainWindow(object):
self.maxSpin2.setObjectName("maxSpin2")
self.horizontalLayout_2.addWidget(self.maxSpin2)
self.gridLayout_2.addLayout(self.horizontalLayout_2, 5, 2, 1, 1)
- self.horizontalLayout = QtGui.QHBoxLayout()
+ self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.minSpin1 = SpinBox(self.centralwidget)
self.minSpin1.setObjectName("minSpin1")
self.horizontalLayout.addWidget(self.minSpin1)
- self.label_2 = QtGui.QLabel(self.centralwidget)
- self.label_2.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_2 = QtWidgets.QLabel(self.centralwidget)
+ self.label_2.setAlignment(QtCore.Qt.Alignment.AlignCenter)
self.label_2.setObjectName("label_2")
self.horizontalLayout.addWidget(self.label_2)
self.maxSpin1 = SpinBox(self.centralwidget)
self.maxSpin1.setObjectName("maxSpin1")
self.horizontalLayout.addWidget(self.maxSpin1)
self.gridLayout_2.addLayout(self.horizontalLayout, 4, 2, 1, 1)
- self.horizontalLayout_3 = QtGui.QHBoxLayout()
+ self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
self.minSpin3 = SpinBox(self.centralwidget)
self.minSpin3.setEnabled(False)
self.minSpin3.setObjectName("minSpin3")
self.horizontalLayout_3.addWidget(self.minSpin3)
- self.label_4 = QtGui.QLabel(self.centralwidget)
- self.label_4.setAlignment(QtCore.Qt.AlignCenter)
+ self.label_4 = QtWidgets.QLabel(self.centralwidget)
+ self.label_4.setAlignment(QtCore.Qt.Alignment.AlignCenter)
self.label_4.setObjectName("label_4")
self.horizontalLayout_3.addWidget(self.label_4)
self.maxSpin3 = SpinBox(self.centralwidget)
@@ -115,56 +118,56 @@ class Ui_MainWindow(object):
self.maxSpin3.setObjectName("maxSpin3")
self.horizontalLayout_3.addWidget(self.maxSpin3)
self.gridLayout_2.addLayout(self.horizontalLayout_3, 6, 2, 1, 1)
- self.lutCheck = QtGui.QCheckBox(self.centralwidget)
+ self.lutCheck = QtWidgets.QCheckBox(self.centralwidget)
self.lutCheck.setObjectName("lutCheck")
self.gridLayout_2.addWidget(self.lutCheck, 7, 0, 1, 1)
- self.alphaCheck = QtGui.QCheckBox(self.centralwidget)
+ self.alphaCheck = QtWidgets.QCheckBox(self.centralwidget)
self.alphaCheck.setObjectName("alphaCheck")
self.gridLayout_2.addWidget(self.alphaCheck, 7, 1, 1, 1)
self.gradient = GradientWidget(self.centralwidget)
- sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.gradient.sizePolicy().hasHeightForWidth())
self.gradient.setSizePolicy(sizePolicy)
self.gradient.setObjectName("gradient")
self.gridLayout_2.addWidget(self.gradient, 7, 2, 1, 2)
- spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
+ spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
self.gridLayout_2.addItem(spacerItem, 3, 3, 1, 1)
- self.fpsLabel = QtGui.QLabel(self.centralwidget)
+ self.fpsLabel = QtWidgets.QLabel(self.centralwidget)
font = QtGui.QFont()
font.setPointSize(12)
self.fpsLabel.setFont(font)
- self.fpsLabel.setAlignment(QtCore.Qt.AlignCenter)
+ self.fpsLabel.setAlignment(QtCore.Qt.Alignment.AlignCenter)
self.fpsLabel.setObjectName("fpsLabel")
self.gridLayout_2.addWidget(self.fpsLabel, 0, 0, 1, 4)
- self.rgbCheck = QtGui.QCheckBox(self.centralwidget)
+ self.rgbCheck = QtWidgets.QCheckBox(self.centralwidget)
self.rgbCheck.setObjectName("rgbCheck")
self.gridLayout_2.addWidget(self.rgbCheck, 3, 1, 1, 1)
- self.label_5 = QtGui.QLabel(self.centralwidget)
+ self.label_5 = QtWidgets.QLabel(self.centralwidget)
self.label_5.setObjectName("label_5")
self.gridLayout_2.addWidget(self.label_5, 2, 0, 1, 1)
- self.horizontalLayout_4 = QtGui.QHBoxLayout()
+ self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
self.horizontalLayout_4.setObjectName("horizontalLayout_4")
- self.framesSpin = QtGui.QSpinBox(self.centralwidget)
- self.framesSpin.setButtonSymbols(QtGui.QAbstractSpinBox.NoButtons)
+ self.framesSpin = QtWidgets.QSpinBox(self.centralwidget)
+ self.framesSpin.setButtonSymbols(QtWidgets.QAbstractSpinBox.ButtonSymbols.NoButtons)
self.framesSpin.setProperty("value", 10)
self.framesSpin.setObjectName("framesSpin")
self.horizontalLayout_4.addWidget(self.framesSpin)
- self.widthSpin = QtGui.QSpinBox(self.centralwidget)
- self.widthSpin.setButtonSymbols(QtGui.QAbstractSpinBox.PlusMinus)
+ self.widthSpin = QtWidgets.QSpinBox(self.centralwidget)
+ self.widthSpin.setButtonSymbols(QtWidgets.QAbstractSpinBox.ButtonSymbols.PlusMinus)
self.widthSpin.setMaximum(10000)
self.widthSpin.setProperty("value", 512)
self.widthSpin.setObjectName("widthSpin")
self.horizontalLayout_4.addWidget(self.widthSpin)
- self.heightSpin = QtGui.QSpinBox(self.centralwidget)
- self.heightSpin.setButtonSymbols(QtGui.QAbstractSpinBox.NoButtons)
+ self.heightSpin = QtWidgets.QSpinBox(self.centralwidget)
+ self.heightSpin.setButtonSymbols(QtWidgets.QAbstractSpinBox.ButtonSymbols.NoButtons)
self.heightSpin.setMaximum(10000)
self.heightSpin.setProperty("value", 512)
self.heightSpin.setObjectName("heightSpin")
self.horizontalLayout_4.addWidget(self.heightSpin)
self.gridLayout_2.addLayout(self.horizontalLayout_4, 2, 1, 1, 2)
- self.sizeLabel = QtGui.QLabel(self.centralwidget)
+ self.sizeLabel = QtWidgets.QLabel(self.centralwidget)
self.sizeLabel.setText("")
self.sizeLabel.setObjectName("sizeLabel")
self.gridLayout_2.addWidget(self.sizeLabel, 2, 3, 1, 1)
@@ -175,25 +178,26 @@ class Ui_MainWindow(object):
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
- MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
- self.downsampleCheck.setText(QtGui.QApplication.translate("MainWindow", "Auto downsample", None, QtGui.QApplication.UnicodeUTF8))
- self.scaleCheck.setText(QtGui.QApplication.translate("MainWindow", "Scale Data", None, QtGui.QApplication.UnicodeUTF8))
- self.rawRadio.setText(QtGui.QApplication.translate("MainWindow", "RawImageWidget", None, QtGui.QApplication.UnicodeUTF8))
- self.gfxRadio.setText(QtGui.QApplication.translate("MainWindow", "GraphicsView + ImageItem", None, QtGui.QApplication.UnicodeUTF8))
- self.rawGLRadio.setText(QtGui.QApplication.translate("MainWindow", "RawGLImageWidget", None, QtGui.QApplication.UnicodeUTF8))
- self.dtypeCombo.setItemText(0, QtGui.QApplication.translate("MainWindow", "uint8", None, QtGui.QApplication.UnicodeUTF8))
- self.dtypeCombo.setItemText(1, QtGui.QApplication.translate("MainWindow", "uint16", None, QtGui.QApplication.UnicodeUTF8))
- self.dtypeCombo.setItemText(2, QtGui.QApplication.translate("MainWindow", "float", None, QtGui.QApplication.UnicodeUTF8))
- self.label.setText(QtGui.QApplication.translate("MainWindow", "Data type", None, QtGui.QApplication.UnicodeUTF8))
- self.rgbLevelsCheck.setText(QtGui.QApplication.translate("MainWindow", "RGB", None, QtGui.QApplication.UnicodeUTF8))
- self.label_3.setText(QtGui.QApplication.translate("MainWindow", "<--->", None, QtGui.QApplication.UnicodeUTF8))
- self.label_2.setText(QtGui.QApplication.translate("MainWindow", "<--->", None, QtGui.QApplication.UnicodeUTF8))
- self.label_4.setText(QtGui.QApplication.translate("MainWindow", "<--->", None, QtGui.QApplication.UnicodeUTF8))
- self.lutCheck.setText(QtGui.QApplication.translate("MainWindow", "Use Lookup Table", None, QtGui.QApplication.UnicodeUTF8))
- self.alphaCheck.setText(QtGui.QApplication.translate("MainWindow", "alpha", None, QtGui.QApplication.UnicodeUTF8))
- self.fpsLabel.setText(QtGui.QApplication.translate("MainWindow", "FPS", None, QtGui.QApplication.UnicodeUTF8))
- self.rgbCheck.setText(QtGui.QApplication.translate("MainWindow", "RGB", None, QtGui.QApplication.UnicodeUTF8))
- self.label_5.setText(QtGui.QApplication.translate("MainWindow", "Image size", None, QtGui.QApplication.UnicodeUTF8))
-
+ _translate = QtCore.QCoreApplication.translate
+ MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
+ self.cudaCheck.setText(_translate("MainWindow", "Use CUDA (GPU) if available"))
+ self.downsampleCheck.setText(_translate("MainWindow", "Auto downsample"))
+ self.scaleCheck.setText(_translate("MainWindow", "Scale Data"))
+ self.rawRadio.setText(_translate("MainWindow", "RawImageWidget"))
+ self.gfxRadio.setText(_translate("MainWindow", "GraphicsView + ImageItem"))
+ self.rawGLRadio.setText(_translate("MainWindow", "RawGLImageWidget"))
+ self.dtypeCombo.setItemText(0, _translate("MainWindow", "uint8"))
+ self.dtypeCombo.setItemText(1, _translate("MainWindow", "uint16"))
+ self.dtypeCombo.setItemText(2, _translate("MainWindow", "float"))
+ self.label.setText(_translate("MainWindow", "Data type"))
+ self.rgbLevelsCheck.setText(_translate("MainWindow", "RGB"))
+ self.label_3.setText(_translate("MainWindow", "<--->"))
+ self.label_2.setText(_translate("MainWindow", "<--->"))
+ self.label_4.setText(_translate("MainWindow", "<--->"))
+ self.lutCheck.setText(_translate("MainWindow", "Use Lookup Table"))
+ self.alphaCheck.setText(_translate("MainWindow", "alpha"))
+ self.fpsLabel.setText(_translate("MainWindow", "FPS"))
+ self.rgbCheck.setText(_translate("MainWindow", "RGB"))
+ self.label_5.setText(_translate("MainWindow", "Image size"))
+from pyqtgraph import GradientWidget, GraphicsView, SpinBox
from pyqtgraph.widgets.RawImageWidget import RawImageWidget
-from pyqtgraph import SpinBox, GradientWidget, GraphicsView
diff --git a/examples/VideoTemplate_pyside2.py b/examples/VideoTemplate_pyside2.py
index 37b7d2e8..10d3cb6c 100644
--- a/examples/VideoTemplate_pyside2.py
+++ b/examples/VideoTemplate_pyside2.py
@@ -1,207 +1,288 @@
# -*- coding: utf-8 -*-
-# Form implementation generated from reading ui file 'VideoTemplate.ui'
-#
-# Created: Sun Sep 18 19:22:41 2016
-# by: pyside2-uic running on PySide2 2.0.0~alpha0
-#
-# WARNING! All changes made in this file will be lost!
+################################################################################
+## Form generated from reading UI file 'VideoTemplate.ui'
+##
+## Created by: Qt User Interface Compiler version 5.15.2
+##
+## WARNING! All changes made in this file will be lost when recompiling UI file!
+################################################################################
+
+from PySide2.QtCore import *
+from PySide2.QtGui import *
+from PySide2.QtWidgets import *
+
+from pyqtgraph import GraphicsView
+from pyqtgraph.widgets.RawImageWidget import RawImageWidget
+from pyqtgraph import GradientWidget
+from pyqtgraph import SpinBox
-from PySide2 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
- MainWindow.setObjectName("MainWindow")
+ if not MainWindow.objectName():
+ MainWindow.setObjectName(u"MainWindow")
MainWindow.resize(695, 798)
- self.centralwidget = QtWidgets.QWidget(MainWindow)
- self.centralwidget.setObjectName("centralwidget")
- self.gridLayout_2 = QtWidgets.QGridLayout(self.centralwidget)
- self.gridLayout_2.setObjectName("gridLayout_2")
- self.downsampleCheck = QtWidgets.QCheckBox(self.centralwidget)
- self.downsampleCheck.setObjectName("downsampleCheck")
+ self.centralwidget = QWidget(MainWindow)
+ self.centralwidget.setObjectName(u"centralwidget")
+ self.gridLayout_2 = QGridLayout(self.centralwidget)
+ self.gridLayout_2.setObjectName(u"gridLayout_2")
+ self.cudaCheck = QCheckBox(self.centralwidget)
+ self.cudaCheck.setObjectName(u"cudaCheck")
+
+ self.gridLayout_2.addWidget(self.cudaCheck, 9, 0, 1, 2)
+
+ self.downsampleCheck = QCheckBox(self.centralwidget)
+ self.downsampleCheck.setObjectName(u"downsampleCheck")
+
self.gridLayout_2.addWidget(self.downsampleCheck, 8, 0, 1, 2)
- self.scaleCheck = QtWidgets.QCheckBox(self.centralwidget)
- self.scaleCheck.setObjectName("scaleCheck")
+
+ self.scaleCheck = QCheckBox(self.centralwidget)
+ self.scaleCheck.setObjectName(u"scaleCheck")
+
self.gridLayout_2.addWidget(self.scaleCheck, 4, 0, 1, 1)
- self.gridLayout = QtWidgets.QGridLayout()
- self.gridLayout.setObjectName("gridLayout")
- self.rawRadio = QtWidgets.QRadioButton(self.centralwidget)
- self.rawRadio.setObjectName("rawRadio")
+
+ self.gridLayout = QGridLayout()
+ self.gridLayout.setObjectName(u"gridLayout")
+ self.rawRadio = QRadioButton(self.centralwidget)
+ self.rawRadio.setObjectName(u"rawRadio")
+
self.gridLayout.addWidget(self.rawRadio, 3, 0, 1, 1)
- self.gfxRadio = QtWidgets.QRadioButton(self.centralwidget)
+
+ self.gfxRadio = QRadioButton(self.centralwidget)
+ self.gfxRadio.setObjectName(u"gfxRadio")
self.gfxRadio.setChecked(True)
- self.gfxRadio.setObjectName("gfxRadio")
+
self.gridLayout.addWidget(self.gfxRadio, 2, 0, 1, 1)
- self.stack = QtWidgets.QStackedWidget(self.centralwidget)
- self.stack.setObjectName("stack")
- self.page = QtWidgets.QWidget()
- self.page.setObjectName("page")
- self.gridLayout_3 = QtWidgets.QGridLayout(self.page)
- self.gridLayout_3.setObjectName("gridLayout_3")
+
+ self.stack = QStackedWidget(self.centralwidget)
+ self.stack.setObjectName(u"stack")
+ self.page = QWidget()
+ self.page.setObjectName(u"page")
+ self.gridLayout_3 = QGridLayout(self.page)
+ self.gridLayout_3.setObjectName(u"gridLayout_3")
self.graphicsView = GraphicsView(self.page)
- self.graphicsView.setObjectName("graphicsView")
+ self.graphicsView.setObjectName(u"graphicsView")
+
self.gridLayout_3.addWidget(self.graphicsView, 0, 0, 1, 1)
+
self.stack.addWidget(self.page)
- self.page_2 = QtWidgets.QWidget()
- self.page_2.setObjectName("page_2")
- self.gridLayout_4 = QtWidgets.QGridLayout(self.page_2)
- self.gridLayout_4.setObjectName("gridLayout_4")
+ self.page_2 = QWidget()
+ self.page_2.setObjectName(u"page_2")
+ self.gridLayout_4 = QGridLayout(self.page_2)
+ self.gridLayout_4.setObjectName(u"gridLayout_4")
self.rawImg = RawImageWidget(self.page_2)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
+ self.rawImg.setObjectName(u"rawImg")
+ sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.rawImg.sizePolicy().hasHeightForWidth())
self.rawImg.setSizePolicy(sizePolicy)
- self.rawImg.setObjectName("rawImg")
+
self.gridLayout_4.addWidget(self.rawImg, 0, 0, 1, 1)
+
self.stack.addWidget(self.page_2)
- self.page_3 = QtWidgets.QWidget()
- self.page_3.setObjectName("page_3")
- self.gridLayout_5 = QtWidgets.QGridLayout(self.page_3)
- self.gridLayout_5.setObjectName("gridLayout_5")
- self.rawGLImg = RawImageGLWidget(self.page_3)
- self.rawGLImg.setObjectName("rawGLImg")
- self.gridLayout_5.addWidget(self.rawGLImg, 0, 0, 1, 1)
- self.stack.addWidget(self.page_3)
+
self.gridLayout.addWidget(self.stack, 0, 0, 1, 1)
- self.rawGLRadio = QtWidgets.QRadioButton(self.centralwidget)
- self.rawGLRadio.setObjectName("rawGLRadio")
+
+ self.rawGLRadio = QRadioButton(self.centralwidget)
+ self.rawGLRadio.setObjectName(u"rawGLRadio")
+
self.gridLayout.addWidget(self.rawGLRadio, 4, 0, 1, 1)
+
+
self.gridLayout_2.addLayout(self.gridLayout, 1, 0, 1, 4)
- self.dtypeCombo = QtWidgets.QComboBox(self.centralwidget)
- self.dtypeCombo.setObjectName("dtypeCombo")
+
+ self.dtypeCombo = QComboBox(self.centralwidget)
self.dtypeCombo.addItem("")
self.dtypeCombo.addItem("")
self.dtypeCombo.addItem("")
+ self.dtypeCombo.setObjectName(u"dtypeCombo")
+
self.gridLayout_2.addWidget(self.dtypeCombo, 3, 2, 1, 1)
- self.label = QtWidgets.QLabel(self.centralwidget)
- self.label.setObjectName("label")
+
+ self.label = QLabel(self.centralwidget)
+ self.label.setObjectName(u"label")
+
self.gridLayout_2.addWidget(self.label, 3, 0, 1, 1)
- self.rgbLevelsCheck = QtWidgets.QCheckBox(self.centralwidget)
- self.rgbLevelsCheck.setObjectName("rgbLevelsCheck")
+
+ self.rgbLevelsCheck = QCheckBox(self.centralwidget)
+ self.rgbLevelsCheck.setObjectName(u"rgbLevelsCheck")
+
self.gridLayout_2.addWidget(self.rgbLevelsCheck, 4, 1, 1, 1)
- self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
- self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+
+ self.horizontalLayout_2 = QHBoxLayout()
+ self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
self.minSpin2 = SpinBox(self.centralwidget)
+ self.minSpin2.setObjectName(u"minSpin2")
self.minSpin2.setEnabled(False)
- self.minSpin2.setObjectName("minSpin2")
+
self.horizontalLayout_2.addWidget(self.minSpin2)
- self.label_3 = QtWidgets.QLabel(self.centralwidget)
- self.label_3.setAlignment(QtCore.Qt.AlignCenter)
- self.label_3.setObjectName("label_3")
+
+ self.label_3 = QLabel(self.centralwidget)
+ self.label_3.setObjectName(u"label_3")
+ self.label_3.setAlignment(Qt.AlignCenter)
+
self.horizontalLayout_2.addWidget(self.label_3)
+
self.maxSpin2 = SpinBox(self.centralwidget)
+ self.maxSpin2.setObjectName(u"maxSpin2")
self.maxSpin2.setEnabled(False)
- self.maxSpin2.setObjectName("maxSpin2")
+
self.horizontalLayout_2.addWidget(self.maxSpin2)
+
+
self.gridLayout_2.addLayout(self.horizontalLayout_2, 5, 2, 1, 1)
- self.horizontalLayout = QtWidgets.QHBoxLayout()
- self.horizontalLayout.setObjectName("horizontalLayout")
+
+ self.horizontalLayout = QHBoxLayout()
+ self.horizontalLayout.setObjectName(u"horizontalLayout")
self.minSpin1 = SpinBox(self.centralwidget)
- self.minSpin1.setObjectName("minSpin1")
+ self.minSpin1.setObjectName(u"minSpin1")
+
self.horizontalLayout.addWidget(self.minSpin1)
- self.label_2 = QtWidgets.QLabel(self.centralwidget)
- self.label_2.setAlignment(QtCore.Qt.AlignCenter)
- self.label_2.setObjectName("label_2")
+
+ self.label_2 = QLabel(self.centralwidget)
+ self.label_2.setObjectName(u"label_2")
+ self.label_2.setAlignment(Qt.AlignCenter)
+
self.horizontalLayout.addWidget(self.label_2)
+
self.maxSpin1 = SpinBox(self.centralwidget)
- self.maxSpin1.setObjectName("maxSpin1")
+ self.maxSpin1.setObjectName(u"maxSpin1")
+
self.horizontalLayout.addWidget(self.maxSpin1)
+
+
self.gridLayout_2.addLayout(self.horizontalLayout, 4, 2, 1, 1)
- self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
- self.horizontalLayout_3.setObjectName("horizontalLayout_3")
+
+ self.horizontalLayout_3 = QHBoxLayout()
+ self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
self.minSpin3 = SpinBox(self.centralwidget)
+ self.minSpin3.setObjectName(u"minSpin3")
self.minSpin3.setEnabled(False)
- self.minSpin3.setObjectName("minSpin3")
+
self.horizontalLayout_3.addWidget(self.minSpin3)
- self.label_4 = QtWidgets.QLabel(self.centralwidget)
- self.label_4.setAlignment(QtCore.Qt.AlignCenter)
- self.label_4.setObjectName("label_4")
+
+ self.label_4 = QLabel(self.centralwidget)
+ self.label_4.setObjectName(u"label_4")
+ self.label_4.setAlignment(Qt.AlignCenter)
+
self.horizontalLayout_3.addWidget(self.label_4)
+
self.maxSpin3 = SpinBox(self.centralwidget)
+ self.maxSpin3.setObjectName(u"maxSpin3")
self.maxSpin3.setEnabled(False)
- self.maxSpin3.setObjectName("maxSpin3")
+
self.horizontalLayout_3.addWidget(self.maxSpin3)
+
+
self.gridLayout_2.addLayout(self.horizontalLayout_3, 6, 2, 1, 1)
- self.lutCheck = QtWidgets.QCheckBox(self.centralwidget)
- self.lutCheck.setObjectName("lutCheck")
+
+ self.lutCheck = QCheckBox(self.centralwidget)
+ self.lutCheck.setObjectName(u"lutCheck")
+
self.gridLayout_2.addWidget(self.lutCheck, 7, 0, 1, 1)
- self.alphaCheck = QtWidgets.QCheckBox(self.centralwidget)
- self.alphaCheck.setObjectName("alphaCheck")
+
+ self.alphaCheck = QCheckBox(self.centralwidget)
+ self.alphaCheck.setObjectName(u"alphaCheck")
+
self.gridLayout_2.addWidget(self.alphaCheck, 7, 1, 1, 1)
+
self.gradient = GradientWidget(self.centralwidget)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
+ self.gradient.setObjectName(u"gradient")
sizePolicy.setHeightForWidth(self.gradient.sizePolicy().hasHeightForWidth())
self.gradient.setSizePolicy(sizePolicy)
- self.gradient.setObjectName("gradient")
+
self.gridLayout_2.addWidget(self.gradient, 7, 2, 1, 2)
- spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
- self.gridLayout_2.addItem(spacerItem, 3, 3, 1, 1)
- self.fpsLabel = QtWidgets.QLabel(self.centralwidget)
- font = QtGui.QFont()
+
+ self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
+
+ self.gridLayout_2.addItem(self.horizontalSpacer, 3, 3, 1, 1)
+
+ self.fpsLabel = QLabel(self.centralwidget)
+ self.fpsLabel.setObjectName(u"fpsLabel")
+ font = QFont()
font.setPointSize(12)
self.fpsLabel.setFont(font)
- self.fpsLabel.setAlignment(QtCore.Qt.AlignCenter)
- self.fpsLabel.setObjectName("fpsLabel")
+ self.fpsLabel.setAlignment(Qt.AlignCenter)
+
self.gridLayout_2.addWidget(self.fpsLabel, 0, 0, 1, 4)
- self.rgbCheck = QtWidgets.QCheckBox(self.centralwidget)
- self.rgbCheck.setObjectName("rgbCheck")
+
+ self.rgbCheck = QCheckBox(self.centralwidget)
+ self.rgbCheck.setObjectName(u"rgbCheck")
+
self.gridLayout_2.addWidget(self.rgbCheck, 3, 1, 1, 1)
- self.label_5 = QtWidgets.QLabel(self.centralwidget)
- self.label_5.setObjectName("label_5")
+
+ self.label_5 = QLabel(self.centralwidget)
+ self.label_5.setObjectName(u"label_5")
+
self.gridLayout_2.addWidget(self.label_5, 2, 0, 1, 1)
- self.horizontalLayout_4 = QtWidgets.QHBoxLayout()
- self.horizontalLayout_4.setObjectName("horizontalLayout_4")
- self.framesSpin = QtWidgets.QSpinBox(self.centralwidget)
- self.framesSpin.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
- self.framesSpin.setProperty("value", 10)
- self.framesSpin.setObjectName("framesSpin")
+
+ self.horizontalLayout_4 = QHBoxLayout()
+ self.horizontalLayout_4.setObjectName(u"horizontalLayout_4")
+ self.framesSpin = QSpinBox(self.centralwidget)
+ self.framesSpin.setObjectName(u"framesSpin")
+ self.framesSpin.setButtonSymbols(QAbstractSpinBox.NoButtons)
+ self.framesSpin.setValue(10)
+
self.horizontalLayout_4.addWidget(self.framesSpin)
- self.widthSpin = QtWidgets.QSpinBox(self.centralwidget)
- self.widthSpin.setButtonSymbols(QtWidgets.QAbstractSpinBox.PlusMinus)
+
+ self.widthSpin = QSpinBox(self.centralwidget)
+ self.widthSpin.setObjectName(u"widthSpin")
+ self.widthSpin.setButtonSymbols(QAbstractSpinBox.PlusMinus)
self.widthSpin.setMaximum(10000)
- self.widthSpin.setProperty("value", 512)
- self.widthSpin.setObjectName("widthSpin")
+ self.widthSpin.setValue(512)
+
self.horizontalLayout_4.addWidget(self.widthSpin)
- self.heightSpin = QtWidgets.QSpinBox(self.centralwidget)
- self.heightSpin.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
+
+ self.heightSpin = QSpinBox(self.centralwidget)
+ self.heightSpin.setObjectName(u"heightSpin")
+ self.heightSpin.setButtonSymbols(QAbstractSpinBox.NoButtons)
self.heightSpin.setMaximum(10000)
- self.heightSpin.setProperty("value", 512)
- self.heightSpin.setObjectName("heightSpin")
+ self.heightSpin.setValue(512)
+
self.horizontalLayout_4.addWidget(self.heightSpin)
+
+
self.gridLayout_2.addLayout(self.horizontalLayout_4, 2, 1, 1, 2)
- self.sizeLabel = QtWidgets.QLabel(self.centralwidget)
- self.sizeLabel.setText("")
- self.sizeLabel.setObjectName("sizeLabel")
+
+ self.sizeLabel = QLabel(self.centralwidget)
+ self.sizeLabel.setObjectName(u"sizeLabel")
+
self.gridLayout_2.addWidget(self.sizeLabel, 2, 3, 1, 1)
+
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
- self.stack.setCurrentIndex(2)
- QtCore.QMetaObject.connectSlotsByName(MainWindow)
+
+ self.stack.setCurrentIndex(1)
+
+
+ QMetaObject.connectSlotsByName(MainWindow)
+ # setupUi
def retranslateUi(self, MainWindow):
- MainWindow.setWindowTitle(QtWidgets.QApplication.translate("MainWindow", "MainWindow", None, -1))
- self.downsampleCheck.setText(QtWidgets.QApplication.translate("MainWindow", "Auto downsample", None, -1))
- self.scaleCheck.setText(QtWidgets.QApplication.translate("MainWindow", "Scale Data", None, -1))
- self.rawRadio.setText(QtWidgets.QApplication.translate("MainWindow", "RawImageWidget", None, -1))
- self.gfxRadio.setText(QtWidgets.QApplication.translate("MainWindow", "GraphicsView + ImageItem", None, -1))
- self.rawGLRadio.setText(QtWidgets.QApplication.translate("MainWindow", "RawGLImageWidget", None, -1))
- self.dtypeCombo.setItemText(0, QtWidgets.QApplication.translate("MainWindow", "uint8", None, -1))
- self.dtypeCombo.setItemText(1, QtWidgets.QApplication.translate("MainWindow", "uint16", None, -1))
- self.dtypeCombo.setItemText(2, QtWidgets.QApplication.translate("MainWindow", "float", None, -1))
- self.label.setText(QtWidgets.QApplication.translate("MainWindow", "Data type", None, -1))
- self.rgbLevelsCheck.setText(QtWidgets.QApplication.translate("MainWindow", "RGB", None, -1))
- self.label_3.setText(QtWidgets.QApplication.translate("MainWindow", "<--->", None, -1))
- self.label_2.setText(QtWidgets.QApplication.translate("MainWindow", "<--->", None, -1))
- self.label_4.setText(QtWidgets.QApplication.translate("MainWindow", "<--->", None, -1))
- self.lutCheck.setText(QtWidgets.QApplication.translate("MainWindow", "Use Lookup Table", None, -1))
- self.alphaCheck.setText(QtWidgets.QApplication.translate("MainWindow", "alpha", None, -1))
- self.fpsLabel.setText(QtWidgets.QApplication.translate("MainWindow", "FPS", None, -1))
- self.rgbCheck.setText(QtWidgets.QApplication.translate("MainWindow", "RGB", None, -1))
- self.label_5.setText(QtWidgets.QApplication.translate("MainWindow", "Image size", None, -1))
+ MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
+ self.cudaCheck.setText(QCoreApplication.translate("MainWindow", u"Use CUDA (GPU) if available", None))
+ self.downsampleCheck.setText(QCoreApplication.translate("MainWindow", u"Auto downsample", None))
+ self.scaleCheck.setText(QCoreApplication.translate("MainWindow", u"Scale Data", None))
+ self.rawRadio.setText(QCoreApplication.translate("MainWindow", u"RawImageWidget", None))
+ self.gfxRadio.setText(QCoreApplication.translate("MainWindow", u"GraphicsView + ImageItem", None))
+ self.rawGLRadio.setText(QCoreApplication.translate("MainWindow", u"RawGLImageWidget", None))
+ self.dtypeCombo.setItemText(0, QCoreApplication.translate("MainWindow", u"uint8", None))
+ self.dtypeCombo.setItemText(1, QCoreApplication.translate("MainWindow", u"uint16", None))
+ self.dtypeCombo.setItemText(2, QCoreApplication.translate("MainWindow", u"float", None))
+
+ self.label.setText(QCoreApplication.translate("MainWindow", u"Data type", None))
+ self.rgbLevelsCheck.setText(QCoreApplication.translate("MainWindow", u"RGB", None))
+ self.label_3.setText(QCoreApplication.translate("MainWindow", u"<--->", None))
+ self.label_2.setText(QCoreApplication.translate("MainWindow", u"<--->", None))
+ self.label_4.setText(QCoreApplication.translate("MainWindow", u"<--->", None))
+ self.lutCheck.setText(QCoreApplication.translate("MainWindow", u"Use Lookup Table", None))
+ self.alphaCheck.setText(QCoreApplication.translate("MainWindow", u"alpha", None))
+ self.fpsLabel.setText(QCoreApplication.translate("MainWindow", u"FPS", None))
+ self.rgbCheck.setText(QCoreApplication.translate("MainWindow", u"RGB", None))
+ self.label_5.setText(QCoreApplication.translate("MainWindow", u"Image size", None))
+ self.sizeLabel.setText("")
+ # retranslateUi
-from pyqtgraph.widgets.RawImageWidget import RawImageGLWidget, RawImageWidget
-from pyqtgraph import GradientWidget, SpinBox, GraphicsView
diff --git a/examples/VideoTemplate_pyside6.py b/examples/VideoTemplate_pyside6.py
new file mode 100644
index 00000000..a9d386c8
--- /dev/null
+++ b/examples/VideoTemplate_pyside6.py
@@ -0,0 +1,288 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'VideoTemplate.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 GraphicsView
+from pyqtgraph.widgets.RawImageWidget import RawImageWidget
+from pyqtgraph import GradientWidget
+from pyqtgraph import SpinBox
+
+
+class Ui_MainWindow(object):
+ def setupUi(self, MainWindow):
+ if not MainWindow.objectName():
+ MainWindow.setObjectName(u"MainWindow")
+ MainWindow.resize(695, 798)
+ self.centralwidget = QWidget(MainWindow)
+ self.centralwidget.setObjectName(u"centralwidget")
+ self.gridLayout_2 = QGridLayout(self.centralwidget)
+ self.gridLayout_2.setObjectName(u"gridLayout_2")
+ self.cudaCheck = QCheckBox(self.centralwidget)
+ self.cudaCheck.setObjectName(u"cudaCheck")
+
+ self.gridLayout_2.addWidget(self.cudaCheck, 9, 0, 1, 2)
+
+ self.downsampleCheck = QCheckBox(self.centralwidget)
+ self.downsampleCheck.setObjectName(u"downsampleCheck")
+
+ self.gridLayout_2.addWidget(self.downsampleCheck, 8, 0, 1, 2)
+
+ self.scaleCheck = QCheckBox(self.centralwidget)
+ self.scaleCheck.setObjectName(u"scaleCheck")
+
+ self.gridLayout_2.addWidget(self.scaleCheck, 4, 0, 1, 1)
+
+ self.gridLayout = QGridLayout()
+ self.gridLayout.setObjectName(u"gridLayout")
+ self.rawRadio = QRadioButton(self.centralwidget)
+ self.rawRadio.setObjectName(u"rawRadio")
+
+ self.gridLayout.addWidget(self.rawRadio, 3, 0, 1, 1)
+
+ self.gfxRadio = QRadioButton(self.centralwidget)
+ self.gfxRadio.setObjectName(u"gfxRadio")
+ self.gfxRadio.setChecked(True)
+
+ self.gridLayout.addWidget(self.gfxRadio, 2, 0, 1, 1)
+
+ self.stack = QStackedWidget(self.centralwidget)
+ self.stack.setObjectName(u"stack")
+ self.page = QWidget()
+ self.page.setObjectName(u"page")
+ self.gridLayout_3 = QGridLayout(self.page)
+ self.gridLayout_3.setObjectName(u"gridLayout_3")
+ self.graphicsView = GraphicsView(self.page)
+ self.graphicsView.setObjectName(u"graphicsView")
+
+ self.gridLayout_3.addWidget(self.graphicsView, 0, 0, 1, 1)
+
+ self.stack.addWidget(self.page)
+ self.page_2 = QWidget()
+ self.page_2.setObjectName(u"page_2")
+ self.gridLayout_4 = QGridLayout(self.page_2)
+ self.gridLayout_4.setObjectName(u"gridLayout_4")
+ self.rawImg = RawImageWidget(self.page_2)
+ self.rawImg.setObjectName(u"rawImg")
+ sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(self.rawImg.sizePolicy().hasHeightForWidth())
+ self.rawImg.setSizePolicy(sizePolicy)
+
+ self.gridLayout_4.addWidget(self.rawImg, 0, 0, 1, 1)
+
+ self.stack.addWidget(self.page_2)
+
+ self.gridLayout.addWidget(self.stack, 0, 0, 1, 1)
+
+ self.rawGLRadio = QRadioButton(self.centralwidget)
+ self.rawGLRadio.setObjectName(u"rawGLRadio")
+
+ self.gridLayout.addWidget(self.rawGLRadio, 4, 0, 1, 1)
+
+
+ self.gridLayout_2.addLayout(self.gridLayout, 1, 0, 1, 4)
+
+ self.dtypeCombo = QComboBox(self.centralwidget)
+ self.dtypeCombo.addItem("")
+ self.dtypeCombo.addItem("")
+ self.dtypeCombo.addItem("")
+ self.dtypeCombo.setObjectName(u"dtypeCombo")
+
+ self.gridLayout_2.addWidget(self.dtypeCombo, 3, 2, 1, 1)
+
+ self.label = QLabel(self.centralwidget)
+ self.label.setObjectName(u"label")
+
+ self.gridLayout_2.addWidget(self.label, 3, 0, 1, 1)
+
+ self.rgbLevelsCheck = QCheckBox(self.centralwidget)
+ self.rgbLevelsCheck.setObjectName(u"rgbLevelsCheck")
+
+ self.gridLayout_2.addWidget(self.rgbLevelsCheck, 4, 1, 1, 1)
+
+ self.horizontalLayout_2 = QHBoxLayout()
+ self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
+ self.minSpin2 = SpinBox(self.centralwidget)
+ self.minSpin2.setObjectName(u"minSpin2")
+ self.minSpin2.setEnabled(False)
+
+ self.horizontalLayout_2.addWidget(self.minSpin2)
+
+ self.label_3 = QLabel(self.centralwidget)
+ self.label_3.setObjectName(u"label_3")
+ self.label_3.setAlignment(Qt.AlignCenter)
+
+ self.horizontalLayout_2.addWidget(self.label_3)
+
+ self.maxSpin2 = SpinBox(self.centralwidget)
+ self.maxSpin2.setObjectName(u"maxSpin2")
+ self.maxSpin2.setEnabled(False)
+
+ self.horizontalLayout_2.addWidget(self.maxSpin2)
+
+
+ self.gridLayout_2.addLayout(self.horizontalLayout_2, 5, 2, 1, 1)
+
+ self.horizontalLayout = QHBoxLayout()
+ self.horizontalLayout.setObjectName(u"horizontalLayout")
+ self.minSpin1 = SpinBox(self.centralwidget)
+ self.minSpin1.setObjectName(u"minSpin1")
+
+ self.horizontalLayout.addWidget(self.minSpin1)
+
+ self.label_2 = QLabel(self.centralwidget)
+ self.label_2.setObjectName(u"label_2")
+ self.label_2.setAlignment(Qt.AlignCenter)
+
+ self.horizontalLayout.addWidget(self.label_2)
+
+ self.maxSpin1 = SpinBox(self.centralwidget)
+ self.maxSpin1.setObjectName(u"maxSpin1")
+
+ self.horizontalLayout.addWidget(self.maxSpin1)
+
+
+ self.gridLayout_2.addLayout(self.horizontalLayout, 4, 2, 1, 1)
+
+ self.horizontalLayout_3 = QHBoxLayout()
+ self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
+ self.minSpin3 = SpinBox(self.centralwidget)
+ self.minSpin3.setObjectName(u"minSpin3")
+ self.minSpin3.setEnabled(False)
+
+ self.horizontalLayout_3.addWidget(self.minSpin3)
+
+ self.label_4 = QLabel(self.centralwidget)
+ self.label_4.setObjectName(u"label_4")
+ self.label_4.setAlignment(Qt.AlignCenter)
+
+ self.horizontalLayout_3.addWidget(self.label_4)
+
+ self.maxSpin3 = SpinBox(self.centralwidget)
+ self.maxSpin3.setObjectName(u"maxSpin3")
+ self.maxSpin3.setEnabled(False)
+
+ self.horizontalLayout_3.addWidget(self.maxSpin3)
+
+
+ self.gridLayout_2.addLayout(self.horizontalLayout_3, 6, 2, 1, 1)
+
+ self.lutCheck = QCheckBox(self.centralwidget)
+ self.lutCheck.setObjectName(u"lutCheck")
+
+ self.gridLayout_2.addWidget(self.lutCheck, 7, 0, 1, 1)
+
+ self.alphaCheck = QCheckBox(self.centralwidget)
+ self.alphaCheck.setObjectName(u"alphaCheck")
+
+ self.gridLayout_2.addWidget(self.alphaCheck, 7, 1, 1, 1)
+
+ self.gradient = GradientWidget(self.centralwidget)
+ self.gradient.setObjectName(u"gradient")
+ sizePolicy.setHeightForWidth(self.gradient.sizePolicy().hasHeightForWidth())
+ self.gradient.setSizePolicy(sizePolicy)
+
+ self.gridLayout_2.addWidget(self.gradient, 7, 2, 1, 2)
+
+ self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
+
+ self.gridLayout_2.addItem(self.horizontalSpacer, 3, 3, 1, 1)
+
+ self.fpsLabel = QLabel(self.centralwidget)
+ self.fpsLabel.setObjectName(u"fpsLabel")
+ font = QFont()
+ font.setPointSize(12)
+ self.fpsLabel.setFont(font)
+ self.fpsLabel.setAlignment(Qt.AlignCenter)
+
+ self.gridLayout_2.addWidget(self.fpsLabel, 0, 0, 1, 4)
+
+ self.rgbCheck = QCheckBox(self.centralwidget)
+ self.rgbCheck.setObjectName(u"rgbCheck")
+
+ self.gridLayout_2.addWidget(self.rgbCheck, 3, 1, 1, 1)
+
+ self.label_5 = QLabel(self.centralwidget)
+ self.label_5.setObjectName(u"label_5")
+
+ self.gridLayout_2.addWidget(self.label_5, 2, 0, 1, 1)
+
+ self.horizontalLayout_4 = QHBoxLayout()
+ self.horizontalLayout_4.setObjectName(u"horizontalLayout_4")
+ self.framesSpin = QSpinBox(self.centralwidget)
+ self.framesSpin.setObjectName(u"framesSpin")
+ self.framesSpin.setButtonSymbols(QAbstractSpinBox.NoButtons)
+ self.framesSpin.setValue(10)
+
+ self.horizontalLayout_4.addWidget(self.framesSpin)
+
+ self.widthSpin = QSpinBox(self.centralwidget)
+ self.widthSpin.setObjectName(u"widthSpin")
+ self.widthSpin.setButtonSymbols(QAbstractSpinBox.PlusMinus)
+ self.widthSpin.setMaximum(10000)
+ self.widthSpin.setValue(512)
+
+ self.horizontalLayout_4.addWidget(self.widthSpin)
+
+ self.heightSpin = QSpinBox(self.centralwidget)
+ self.heightSpin.setObjectName(u"heightSpin")
+ self.heightSpin.setButtonSymbols(QAbstractSpinBox.NoButtons)
+ self.heightSpin.setMaximum(10000)
+ self.heightSpin.setValue(512)
+
+ self.horizontalLayout_4.addWidget(self.heightSpin)
+
+
+ self.gridLayout_2.addLayout(self.horizontalLayout_4, 2, 1, 1, 2)
+
+ self.sizeLabel = QLabel(self.centralwidget)
+ self.sizeLabel.setObjectName(u"sizeLabel")
+
+ self.gridLayout_2.addWidget(self.sizeLabel, 2, 3, 1, 1)
+
+ MainWindow.setCentralWidget(self.centralwidget)
+
+ self.retranslateUi(MainWindow)
+
+ self.stack.setCurrentIndex(1)
+
+
+ QMetaObject.connectSlotsByName(MainWindow)
+ # setupUi
+
+ def retranslateUi(self, MainWindow):
+ MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
+ self.cudaCheck.setText(QCoreApplication.translate("MainWindow", u"Use CUDA (GPU) if available", None))
+ self.downsampleCheck.setText(QCoreApplication.translate("MainWindow", u"Auto downsample", None))
+ self.scaleCheck.setText(QCoreApplication.translate("MainWindow", u"Scale Data", None))
+ self.rawRadio.setText(QCoreApplication.translate("MainWindow", u"RawImageWidget", None))
+ self.gfxRadio.setText(QCoreApplication.translate("MainWindow", u"GraphicsView + ImageItem", None))
+ self.rawGLRadio.setText(QCoreApplication.translate("MainWindow", u"RawGLImageWidget", None))
+ self.dtypeCombo.setItemText(0, QCoreApplication.translate("MainWindow", u"uint8", None))
+ self.dtypeCombo.setItemText(1, QCoreApplication.translate("MainWindow", u"uint16", None))
+ self.dtypeCombo.setItemText(2, QCoreApplication.translate("MainWindow", u"float", None))
+
+ self.label.setText(QCoreApplication.translate("MainWindow", u"Data type", None))
+ self.rgbLevelsCheck.setText(QCoreApplication.translate("MainWindow", u"RGB", None))
+ self.label_3.setText(QCoreApplication.translate("MainWindow", u"<--->", None))
+ self.label_2.setText(QCoreApplication.translate("MainWindow", u"<--->", None))
+ self.label_4.setText(QCoreApplication.translate("MainWindow", u"<--->", None))
+ self.lutCheck.setText(QCoreApplication.translate("MainWindow", u"Use Lookup Table", None))
+ self.alphaCheck.setText(QCoreApplication.translate("MainWindow", u"alpha", None))
+ self.fpsLabel.setText(QCoreApplication.translate("MainWindow", u"FPS", None))
+ self.rgbCheck.setText(QCoreApplication.translate("MainWindow", u"RGB", None))
+ self.label_5.setText(QCoreApplication.translate("MainWindow", u"Image size", None))
+ self.sizeLabel.setText("")
+ # retranslateUi
+
diff --git a/examples/ViewBox.py b/examples/ViewBox.py
index 2ba2094c..f9dbac43 100644
--- a/examples/ViewBox.py
+++ b/examples/ViewBox.py
@@ -18,7 +18,7 @@ import numpy as np
from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg
-app = QtGui.QApplication([])
+app = pg.mkQApp("ViewBox Example")
mw = QtGui.QMainWindow()
mw.setWindowTitle('pyqtgraph example: ViewBox')
mw.show()
diff --git a/examples/colorMaps.py b/examples/colorMaps.py
new file mode 100644
index 00000000..fb648a66
--- /dev/null
+++ b/examples/colorMaps.py
@@ -0,0 +1,103 @@
+# -*- coding: utf-8 -*-
+"""
+This example demonstrates the use of ImageView, which is a high-level widget for
+displaying and analyzing 2D and 3D data. ImageView provides:
+
+ 1. A zoomable region (ViewBox) for displaying the image
+ 2. A combination histogram and gradient editor (HistogramLUTItem) for
+ controlling the visual appearance of the image
+ 3. A timeline for selecting the currently displayed frame (for 3D data only).
+ 4. Tools for very basic analysis of image data (see ROI and Norm buttons)
+
+"""
+## Add path to library (just for examples; you do not need this)
+import initExample
+
+import numpy as np
+from pyqtgraph.Qt import QtCore, QtGui
+import pyqtgraph as pg
+
+app = pg.mkQApp()
+
+## Create window with ImageView widget
+win = QtGui.QMainWindow()
+win.resize(1000,800)
+
+lw = pg.GraphicsLayoutWidget()
+lw.setFixedWidth(1000)
+lw.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
+
+scr = QtGui.QScrollArea()
+scr.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
+scr.setWidget(lw)
+win.setCentralWidget(scr)
+win.show()
+win.setWindowTitle('pyqtgraph example: Color maps')
+
+## Create color map test image
+width = 3*256
+height = 32
+img = np.zeros( (width, height) )
+gradient = np.linspace(0.05, 0.95, width)
+modulation = np.zeros(width)
+for idx in range(width):
+ modulation[idx] = -0.05 * np.sin( 200 * np.pi * idx/width )
+for idx in range(height):
+ img[:,idx] = gradient + (idx/(height-1)) * modulation
+
+num_bars = 0
+
+lw.addLabel('=== local color maps ===')
+num_bars += 1
+lw.nextRow()
+list_of_maps = pg.colormap.listMaps()
+for map_name in list_of_maps:
+ num_bars += 1
+ lw.addLabel(map_name)
+ cmap = pg.colormap.get(map_name)
+ imi = pg.ImageItem()
+ imi.setImage(img)
+ imi.setLookupTable( cmap.getLookupTable(alpha=True) )
+ vb = lw.addViewBox(lockAspect=True, enableMouse=False)
+ vb.addItem(imi)
+ lw.nextRow()
+
+lw.addLabel('=== Matplotlib import ===')
+num_bars += 1
+lw.nextRow()
+list_of_maps = pg.colormap.listMaps('matplotlib')
+for map_name in list_of_maps:
+ num_bars += 1
+ lw.addLabel(map_name)
+ cmap = pg.colormap.get(map_name, source='matplotlib', skipCache=True)
+ if cmap is not None:
+ imi = pg.ImageItem()
+ imi.setImage(img)
+ imi.setLookupTable( cmap.getLookupTable(alpha=True) )
+ vb = lw.addViewBox(lockAspect=True, enableMouse=False)
+ vb.addItem(imi)
+ lw.nextRow()
+
+lw.addLabel('=== ColorCET import ===')
+num_bars += 1
+lw.nextRow()
+list_of_maps = pg.colormap.listMaps('colorcet')
+for map_name in list_of_maps:
+ num_bars += 1
+ lw.addLabel(map_name)
+ cmap = pg.colormap.get(map_name, source='colorcet', skipCache=True)
+ if cmap is not None:
+ imi = pg.ImageItem()
+ imi.setImage(img)
+ imi.setLookupTable( cmap.getLookupTable(alpha=True) )
+ vb = lw.addViewBox(lockAspect=True, enableMouse=False)
+ vb.addItem(imi)
+ lw.nextRow()
+
+lw.setFixedHeight(num_bars * (height+5) )
+
+## 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/crosshair.py b/examples/crosshair.py
index 584eced8..150ed53d 100644
--- a/examples/crosshair.py
+++ b/examples/crosshair.py
@@ -12,7 +12,7 @@ from pyqtgraph.Qt import QtGui, QtCore
from pyqtgraph.Point import Point
#generate layout
-app = QtGui.QApplication([])
+app = pg.mkQApp("Crosshair Example")
win = pg.GraphicsLayoutWidget(show=True)
win.setWindowTitle('pyqtgraph example: crosshair')
label = pg.LabelItem(justify='right')
diff --git a/examples/designerExample_pyside2.py b/examples/designerExample_pyside2.py
deleted file mode 100644
index 1e04c1ac..00000000
--- a/examples/designerExample_pyside2.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file 'examples/designerExample.ui'
-#
-# Created: Fri Feb 16 20:31:04 2018
-# by: pyside2-uic 2.0.0 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.plotBtn = QtWidgets.QPushButton(Form)
- self.plotBtn.setObjectName("plotBtn")
- self.gridLayout.addWidget(self.plotBtn, 0, 0, 1, 1)
- self.plot = PlotWidget(Form)
- self.plot.setObjectName("plot")
- self.gridLayout.addWidget(self.plot, 1, 0, 1, 1)
-
- self.retranslateUi(Form)
- QtCore.QMetaObject.connectSlotsByName(Form)
-
- def retranslateUi(self, Form):
- Form.setWindowTitle(QtWidgets.QApplication.translate("Form", "Form", None, -1))
- self.plotBtn.setText(QtWidgets.QApplication.translate("Form", "Plot!", None, -1))
-
-from pyqtgraph import PlotWidget
diff --git a/examples/dockarea.py b/examples/dockarea.py
index 9cc79f1b..f87a8da3 100644
--- a/examples/dockarea.py
+++ b/examples/dockarea.py
@@ -24,7 +24,7 @@ import numpy as np
from pyqtgraph.dockarea import *
-app = QtGui.QApplication([])
+app = pg.mkQApp("DockArea Example")
win = QtGui.QMainWindow()
area = DockArea()
win.setCentralWidget(area)
diff --git a/examples/exampleLoaderTemplate.ui b/examples/exampleLoaderTemplate.ui
index a4d65e89..9d60ad4a 100644
--- a/examples/exampleLoaderTemplate.ui
+++ b/examples/exampleLoaderTemplate.ui
@@ -64,16 +64,6 @@
default
- -
-
- PyQt4
-
-
- -
-
- PySide
-
-
-
PyQt5
@@ -84,6 +74,16 @@
PySide2
+ -
+
+ PySide6
+
+
+ -
+
+ PyQt6
+
+
-
@@ -115,7 +115,6 @@
- 75
true
diff --git a/examples/exampleLoaderTemplate_pyqt.py b/examples/exampleLoaderTemplate_pyqt.py
deleted file mode 100644
index c76d0f51..00000000
--- a/examples/exampleLoaderTemplate_pyqt.py
+++ /dev/null
@@ -1,105 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file 'examples/exampleLoaderTemplate.ui'
-#
-# Created by: PyQt4 UI code generator 4.11.4
-#
-# WARNING! All changes made in this file will be lost!
-
-from PyQt4 import QtCore, QtGui
-
-try:
- _fromUtf8 = QtCore.QString.fromUtf8
-except AttributeError:
- def _fromUtf8(s):
- return s
-
-try:
- _encoding = QtGui.QApplication.UnicodeUTF8
- def _translate(context, text, disambig):
- return QtGui.QApplication.translate(context, text, disambig, _encoding)
-except AttributeError:
- def _translate(context, text, disambig):
- return QtGui.QApplication.translate(context, text, disambig)
-
-class Ui_Form(object):
- def setupUi(self, Form):
- Form.setObjectName(_fromUtf8("Form"))
- Form.resize(846, 552)
- self.gridLayout_2 = QtGui.QGridLayout(Form)
- self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2"))
- self.splitter = QtGui.QSplitter(Form)
- self.splitter.setOrientation(QtCore.Qt.Horizontal)
- self.splitter.setObjectName(_fromUtf8("splitter"))
- self.widget = QtGui.QWidget(self.splitter)
- self.widget.setObjectName(_fromUtf8("widget"))
- self.gridLayout = QtGui.QGridLayout(self.widget)
- self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
- self.exampleTree = QtGui.QTreeWidget(self.widget)
- self.exampleTree.setObjectName(_fromUtf8("exampleTree"))
- self.exampleTree.headerItem().setText(0, _fromUtf8("1"))
- self.exampleTree.header().setVisible(False)
- self.gridLayout.addWidget(self.exampleTree, 0, 0, 1, 2)
- self.graphicsSystemCombo = QtGui.QComboBox(self.widget)
- self.graphicsSystemCombo.setObjectName(_fromUtf8("graphicsSystemCombo"))
- self.graphicsSystemCombo.addItem(_fromUtf8(""))
- self.graphicsSystemCombo.addItem(_fromUtf8(""))
- self.graphicsSystemCombo.addItem(_fromUtf8(""))
- self.graphicsSystemCombo.addItem(_fromUtf8(""))
- self.gridLayout.addWidget(self.graphicsSystemCombo, 2, 1, 1, 1)
- self.qtLibCombo = QtGui.QComboBox(self.widget)
- self.qtLibCombo.setObjectName(_fromUtf8("qtLibCombo"))
- self.qtLibCombo.addItem(_fromUtf8(""))
- self.qtLibCombo.addItem(_fromUtf8(""))
- self.qtLibCombo.addItem(_fromUtf8(""))
- self.qtLibCombo.addItem(_fromUtf8(""))
- self.qtLibCombo.addItem(_fromUtf8(""))
- self.gridLayout.addWidget(self.qtLibCombo, 1, 1, 1, 1)
- self.label_2 = QtGui.QLabel(self.widget)
- self.label_2.setObjectName(_fromUtf8("label_2"))
- self.gridLayout.addWidget(self.label_2, 2, 0, 1, 1)
- self.label = QtGui.QLabel(self.widget)
- self.label.setObjectName(_fromUtf8("label"))
- self.gridLayout.addWidget(self.label, 1, 0, 1, 1)
- self.loadBtn = QtGui.QPushButton(self.widget)
- self.loadBtn.setObjectName(_fromUtf8("loadBtn"))
- self.gridLayout.addWidget(self.loadBtn, 3, 1, 1, 1)
- self.widget1 = QtGui.QWidget(self.splitter)
- self.widget1.setObjectName(_fromUtf8("widget1"))
- self.verticalLayout = QtGui.QVBoxLayout(self.widget1)
- self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
- self.loadedFileLabel = QtGui.QLabel(self.widget1)
- font = QtGui.QFont()
- font.setBold(True)
- font.setWeight(75)
- self.loadedFileLabel.setFont(font)
- self.loadedFileLabel.setText(_fromUtf8(""))
- self.loadedFileLabel.setAlignment(QtCore.Qt.AlignCenter)
- self.loadedFileLabel.setObjectName(_fromUtf8("loadedFileLabel"))
- self.verticalLayout.addWidget(self.loadedFileLabel)
- self.codeView = QtGui.QPlainTextEdit(self.widget1)
- font = QtGui.QFont()
- font.setFamily(_fromUtf8("Courier New"))
- self.codeView.setFont(font)
- self.codeView.setObjectName(_fromUtf8("codeView"))
- self.verticalLayout.addWidget(self.codeView)
- self.gridLayout_2.addWidget(self.splitter, 0, 0, 1, 1)
-
- self.retranslateUi(Form)
- QtCore.QMetaObject.connectSlotsByName(Form)
-
- def retranslateUi(self, Form):
- Form.setWindowTitle(_translate("Form", "PyQtGraph", None))
- self.graphicsSystemCombo.setItemText(0, _translate("Form", "default", None))
- self.graphicsSystemCombo.setItemText(1, _translate("Form", "native", None))
- self.graphicsSystemCombo.setItemText(2, _translate("Form", "raster", None))
- self.graphicsSystemCombo.setItemText(3, _translate("Form", "opengl", None))
- self.qtLibCombo.setItemText(0, _translate("Form", "default", None))
- self.qtLibCombo.setItemText(1, _translate("Form", "PyQt4", None))
- self.qtLibCombo.setItemText(2, _translate("Form", "PySide", None))
- self.qtLibCombo.setItemText(3, _translate("Form", "PyQt5", None))
- self.qtLibCombo.setItemText(4, _translate("Form", "PySide2", None))
- self.label_2.setText(_translate("Form", "Graphics System:", None))
- self.label.setText(_translate("Form", "Qt Library:", None))
- self.loadBtn.setText(_translate("Form", "Run Example", None))
-
diff --git a/examples/exampleLoaderTemplate_pyqt5.py b/examples/exampleLoaderTemplate_pyqt5.py
index 669e1f34..22c0d2c4 100644
--- a/examples/exampleLoaderTemplate_pyqt5.py
+++ b/examples/exampleLoaderTemplate_pyqt5.py
@@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'exampleLoaderTemplate.ui'
#
-# Created by: PyQt5 UI code generator 5.15.1
+# Created by: PyQt5 UI code generator 5.15.2
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
@@ -62,7 +62,6 @@ class Ui_Form(object):
self.loadedFileLabel = QtWidgets.QLabel(self.widget1)
font = QtGui.QFont()
font.setBold(True)
- font.setWeight(75)
self.loadedFileLabel.setFont(font)
self.loadedFileLabel.setText("")
self.loadedFileLabel.setAlignment(QtCore.Qt.AlignCenter)
@@ -87,10 +86,10 @@ class Ui_Form(object):
self.graphicsSystemCombo.setItemText(2, _translate("Form", "raster"))
self.graphicsSystemCombo.setItemText(3, _translate("Form", "opengl"))
self.qtLibCombo.setItemText(0, _translate("Form", "default"))
- self.qtLibCombo.setItemText(1, _translate("Form", "PyQt4"))
- self.qtLibCombo.setItemText(2, _translate("Form", "PySide"))
- self.qtLibCombo.setItemText(3, _translate("Form", "PyQt5"))
- self.qtLibCombo.setItemText(4, _translate("Form", "PySide2"))
+ self.qtLibCombo.setItemText(1, _translate("Form", "PyQt5"))
+ self.qtLibCombo.setItemText(2, _translate("Form", "PySide2"))
+ self.qtLibCombo.setItemText(3, _translate("Form", "PySide6"))
+ self.qtLibCombo.setItemText(4, _translate("Form", "PyQt6"))
self.label_2.setText(_translate("Form", "Graphics System:"))
self.label.setText(_translate("Form", "Qt Library:"))
self.loadBtn.setText(_translate("Form", "Run Example"))
diff --git a/examples/exampleLoaderTemplate_pyqt6.py b/examples/exampleLoaderTemplate_pyqt6.py
new file mode 100644
index 00000000..f0b38e53
--- /dev/null
+++ b/examples/exampleLoaderTemplate_pyqt6.py
@@ -0,0 +1,93 @@
+# Form implementation generated from reading ui file 'exampleLoaderTemplate.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(846, 552)
+ self.gridLayout_2 = QtWidgets.QGridLayout(Form)
+ self.gridLayout_2.setObjectName("gridLayout_2")
+ self.splitter = QtWidgets.QSplitter(Form)
+ self.splitter.setOrientation(QtCore.Qt.Orientations.Horizontal)
+ self.splitter.setObjectName("splitter")
+ self.widget = QtWidgets.QWidget(self.splitter)
+ self.widget.setObjectName("widget")
+ self.gridLayout = QtWidgets.QGridLayout(self.widget)
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout.setObjectName("gridLayout")
+ self.exampleTree = QtWidgets.QTreeWidget(self.widget)
+ self.exampleTree.setObjectName("exampleTree")
+ self.exampleTree.headerItem().setText(0, "1")
+ self.exampleTree.header().setVisible(False)
+ self.gridLayout.addWidget(self.exampleTree, 0, 0, 1, 2)
+ self.graphicsSystemCombo = QtWidgets.QComboBox(self.widget)
+ self.graphicsSystemCombo.setObjectName("graphicsSystemCombo")
+ self.graphicsSystemCombo.addItem("")
+ self.graphicsSystemCombo.addItem("")
+ self.graphicsSystemCombo.addItem("")
+ self.graphicsSystemCombo.addItem("")
+ self.gridLayout.addWidget(self.graphicsSystemCombo, 2, 1, 1, 1)
+ self.qtLibCombo = QtWidgets.QComboBox(self.widget)
+ self.qtLibCombo.setObjectName("qtLibCombo")
+ self.qtLibCombo.addItem("")
+ self.qtLibCombo.addItem("")
+ self.qtLibCombo.addItem("")
+ self.qtLibCombo.addItem("")
+ self.qtLibCombo.addItem("")
+ self.gridLayout.addWidget(self.qtLibCombo, 1, 1, 1, 1)
+ self.label_2 = QtWidgets.QLabel(self.widget)
+ self.label_2.setObjectName("label_2")
+ self.gridLayout.addWidget(self.label_2, 2, 0, 1, 1)
+ self.label = QtWidgets.QLabel(self.widget)
+ self.label.setObjectName("label")
+ self.gridLayout.addWidget(self.label, 1, 0, 1, 1)
+ self.loadBtn = QtWidgets.QPushButton(self.widget)
+ self.loadBtn.setObjectName("loadBtn")
+ self.gridLayout.addWidget(self.loadBtn, 3, 1, 1, 1)
+ self.widget1 = QtWidgets.QWidget(self.splitter)
+ self.widget1.setObjectName("widget1")
+ self.verticalLayout = QtWidgets.QVBoxLayout(self.widget1)
+ self.verticalLayout.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout.setObjectName("verticalLayout")
+ self.loadedFileLabel = QtWidgets.QLabel(self.widget1)
+ font = QtGui.QFont()
+ font.setBold(True)
+ self.loadedFileLabel.setFont(font)
+ self.loadedFileLabel.setText("")
+ self.loadedFileLabel.setAlignment(QtCore.Qt.Alignment.AlignCenter)
+ self.loadedFileLabel.setObjectName("loadedFileLabel")
+ self.verticalLayout.addWidget(self.loadedFileLabel)
+ self.codeView = QtWidgets.QPlainTextEdit(self.widget1)
+ font = QtGui.QFont()
+ font.setFamily("Courier New")
+ self.codeView.setFont(font)
+ self.codeView.setObjectName("codeView")
+ self.verticalLayout.addWidget(self.codeView)
+ self.gridLayout_2.addWidget(self.splitter, 0, 0, 1, 1)
+
+ self.retranslateUi(Form)
+ QtCore.QMetaObject.connectSlotsByName(Form)
+
+ def retranslateUi(self, Form):
+ _translate = QtCore.QCoreApplication.translate
+ Form.setWindowTitle(_translate("Form", "PyQtGraph"))
+ self.graphicsSystemCombo.setItemText(0, _translate("Form", "default"))
+ self.graphicsSystemCombo.setItemText(1, _translate("Form", "native"))
+ self.graphicsSystemCombo.setItemText(2, _translate("Form", "raster"))
+ self.graphicsSystemCombo.setItemText(3, _translate("Form", "opengl"))
+ self.qtLibCombo.setItemText(0, _translate("Form", "default"))
+ self.qtLibCombo.setItemText(1, _translate("Form", "PyQt5"))
+ self.qtLibCombo.setItemText(2, _translate("Form", "PySide2"))
+ self.qtLibCombo.setItemText(3, _translate("Form", "PySide6"))
+ self.qtLibCombo.setItemText(4, _translate("Form", "PyQt6"))
+ self.label_2.setText(_translate("Form", "Graphics System:"))
+ self.label.setText(_translate("Form", "Qt Library:"))
+ self.loadBtn.setText(_translate("Form", "Run Example"))
diff --git a/examples/exampleLoaderTemplate_pyside.py b/examples/exampleLoaderTemplate_pyside.py
deleted file mode 100644
index a8eb8529..00000000
--- a/examples/exampleLoaderTemplate_pyside.py
+++ /dev/null
@@ -1,94 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file 'exampleLoaderTemplate.ui'
-#
-# Created: Sun Oct 18 21:53:22 2020
-# by: pyside-uic 0.2.15 running on PySide 1.2.4
-#
-# WARNING! All changes made in this file will be lost!
-
-from PySide import QtCore, QtGui
-
-class Ui_Form(object):
- def setupUi(self, Form):
- Form.setObjectName("Form")
- Form.resize(846, 552)
- self.gridLayout_2 = QtGui.QGridLayout(Form)
- self.gridLayout_2.setObjectName("gridLayout_2")
- self.splitter = QtGui.QSplitter(Form)
- self.splitter.setOrientation(QtCore.Qt.Horizontal)
- self.splitter.setObjectName("splitter")
- self.widget = QtGui.QWidget(self.splitter)
- self.widget.setObjectName("widget")
- self.gridLayout = QtGui.QGridLayout(self.widget)
- self.gridLayout.setContentsMargins(0, 0, 0, 0)
- self.gridLayout.setObjectName("gridLayout")
- self.exampleTree = QtGui.QTreeWidget(self.widget)
- self.exampleTree.setObjectName("exampleTree")
- self.exampleTree.headerItem().setText(0, "1")
- self.exampleTree.header().setVisible(False)
- self.gridLayout.addWidget(self.exampleTree, 0, 0, 1, 2)
- self.graphicsSystemCombo = QtGui.QComboBox(self.widget)
- self.graphicsSystemCombo.setObjectName("graphicsSystemCombo")
- self.graphicsSystemCombo.addItem("")
- self.graphicsSystemCombo.addItem("")
- self.graphicsSystemCombo.addItem("")
- self.graphicsSystemCombo.addItem("")
- self.gridLayout.addWidget(self.graphicsSystemCombo, 2, 1, 1, 1)
- self.qtLibCombo = QtGui.QComboBox(self.widget)
- self.qtLibCombo.setObjectName("qtLibCombo")
- self.qtLibCombo.addItem("")
- self.qtLibCombo.addItem("")
- self.qtLibCombo.addItem("")
- self.qtLibCombo.addItem("")
- self.qtLibCombo.addItem("")
- self.gridLayout.addWidget(self.qtLibCombo, 1, 1, 1, 1)
- self.label_2 = QtGui.QLabel(self.widget)
- self.label_2.setObjectName("label_2")
- self.gridLayout.addWidget(self.label_2, 2, 0, 1, 1)
- self.label = QtGui.QLabel(self.widget)
- self.label.setObjectName("label")
- self.gridLayout.addWidget(self.label, 1, 0, 1, 1)
- self.loadBtn = QtGui.QPushButton(self.widget)
- self.loadBtn.setObjectName("loadBtn")
- self.gridLayout.addWidget(self.loadBtn, 3, 1, 1, 1)
- self.widget1 = QtGui.QWidget(self.splitter)
- self.widget1.setObjectName("widget1")
- self.verticalLayout = QtGui.QVBoxLayout(self.widget1)
- self.verticalLayout.setContentsMargins(0, 0, 0, 0)
- self.verticalLayout.setObjectName("verticalLayout")
- self.loadedFileLabel = QtGui.QLabel(self.widget1)
- font = QtGui.QFont()
- font.setWeight(75)
- font.setBold(True)
- self.loadedFileLabel.setFont(font)
- self.loadedFileLabel.setText("")
- self.loadedFileLabel.setAlignment(QtCore.Qt.AlignCenter)
- self.loadedFileLabel.setObjectName("loadedFileLabel")
- self.verticalLayout.addWidget(self.loadedFileLabel)
- self.codeView = QtGui.QPlainTextEdit(self.widget1)
- font = QtGui.QFont()
- font.setFamily("Courier New")
- self.codeView.setFont(font)
- self.codeView.setObjectName("codeView")
- self.verticalLayout.addWidget(self.codeView)
- self.gridLayout_2.addWidget(self.splitter, 0, 0, 1, 1)
-
- self.retranslateUi(Form)
- QtCore.QMetaObject.connectSlotsByName(Form)
-
- def retranslateUi(self, Form):
- Form.setWindowTitle(QtGui.QApplication.translate("Form", "PyQtGraph", None, QtGui.QApplication.UnicodeUTF8))
- self.graphicsSystemCombo.setItemText(0, QtGui.QApplication.translate("Form", "default", None, QtGui.QApplication.UnicodeUTF8))
- self.graphicsSystemCombo.setItemText(1, QtGui.QApplication.translate("Form", "native", None, QtGui.QApplication.UnicodeUTF8))
- self.graphicsSystemCombo.setItemText(2, QtGui.QApplication.translate("Form", "raster", None, QtGui.QApplication.UnicodeUTF8))
- self.graphicsSystemCombo.setItemText(3, QtGui.QApplication.translate("Form", "opengl", None, QtGui.QApplication.UnicodeUTF8))
- self.qtLibCombo.setItemText(0, QtGui.QApplication.translate("Form", "default", None, QtGui.QApplication.UnicodeUTF8))
- self.qtLibCombo.setItemText(1, QtGui.QApplication.translate("Form", "PyQt4", None, QtGui.QApplication.UnicodeUTF8))
- self.qtLibCombo.setItemText(2, QtGui.QApplication.translate("Form", "PySide", None, QtGui.QApplication.UnicodeUTF8))
- self.qtLibCombo.setItemText(3, QtGui.QApplication.translate("Form", "PyQt5", None, QtGui.QApplication.UnicodeUTF8))
- self.qtLibCombo.setItemText(4, QtGui.QApplication.translate("Form", "PySide2", None, QtGui.QApplication.UnicodeUTF8))
- self.label_2.setText(QtGui.QApplication.translate("Form", "Graphics System:", None, QtGui.QApplication.UnicodeUTF8))
- self.label.setText(QtGui.QApplication.translate("Form", "Qt Library:", None, QtGui.QApplication.UnicodeUTF8))
- self.loadBtn.setText(QtGui.QApplication.translate("Form", "Run Example", None, QtGui.QApplication.UnicodeUTF8))
-
diff --git a/examples/exampleLoaderTemplate_pyside2.py b/examples/exampleLoaderTemplate_pyside2.py
index a5a50f01..a3880681 100644
--- a/examples/exampleLoaderTemplate_pyside2.py
+++ b/examples/exampleLoaderTemplate_pyside2.py
@@ -3,16 +3,13 @@
################################################################################
## Form generated from reading UI file 'exampleLoaderTemplate.ui'
##
-## Created by: Qt User Interface Compiler version 5.15.0
+## Created by: Qt User Interface Compiler version 5.15.2
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################
-from PySide2.QtCore import (QCoreApplication, QDate, QDateTime, QMetaObject,
- QObject, QPoint, QRect, QSize, QTime, QUrl, Qt)
-from PySide2.QtGui import (QBrush, QColor, QConicalGradient, QCursor, QFont,
- QFontDatabase, QIcon, QKeySequence, QLinearGradient, QPalette, QPainter,
- QPixmap, QRadialGradient)
+from PySide2.QtCore import *
+from PySide2.QtGui import *
from PySide2.QtWidgets import *
@@ -84,7 +81,6 @@ class Ui_Form(object):
self.loadedFileLabel.setObjectName(u"loadedFileLabel")
font = QFont()
font.setBold(True)
- font.setWeight(75)
self.loadedFileLabel.setFont(font)
self.loadedFileLabel.setAlignment(Qt.AlignCenter)
@@ -116,10 +112,10 @@ class Ui_Form(object):
self.graphicsSystemCombo.setItemText(3, QCoreApplication.translate("Form", u"opengl", None))
self.qtLibCombo.setItemText(0, QCoreApplication.translate("Form", u"default", None))
- self.qtLibCombo.setItemText(1, QCoreApplication.translate("Form", u"PyQt4", None))
- self.qtLibCombo.setItemText(2, QCoreApplication.translate("Form", u"PySide", None))
- self.qtLibCombo.setItemText(3, QCoreApplication.translate("Form", u"PyQt5", None))
- self.qtLibCombo.setItemText(4, QCoreApplication.translate("Form", u"PySide2", None))
+ self.qtLibCombo.setItemText(1, QCoreApplication.translate("Form", u"PyQt5", None))
+ self.qtLibCombo.setItemText(2, QCoreApplication.translate("Form", u"PySide2", None))
+ self.qtLibCombo.setItemText(3, QCoreApplication.translate("Form", u"PySide6", None))
+ self.qtLibCombo.setItemText(4, QCoreApplication.translate("Form", u"PyQt6", None))
self.label_2.setText(QCoreApplication.translate("Form", u"Graphics System:", None))
self.label.setText(QCoreApplication.translate("Form", u"Qt Library:", None))
diff --git a/examples/exampleLoaderTemplate_pyside6.py b/examples/exampleLoaderTemplate_pyside6.py
new file mode 100644
index 00000000..5a24c659
--- /dev/null
+++ b/examples/exampleLoaderTemplate_pyside6.py
@@ -0,0 +1,125 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'exampleLoaderTemplate.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 *
+
+
+class Ui_Form(object):
+ def setupUi(self, Form):
+ if not Form.objectName():
+ Form.setObjectName(u"Form")
+ Form.resize(846, 552)
+ self.gridLayout_2 = QGridLayout(Form)
+ self.gridLayout_2.setObjectName(u"gridLayout_2")
+ self.splitter = QSplitter(Form)
+ self.splitter.setObjectName(u"splitter")
+ self.splitter.setOrientation(Qt.Horizontal)
+ self.widget = QWidget(self.splitter)
+ self.widget.setObjectName(u"widget")
+ self.gridLayout = QGridLayout(self.widget)
+ self.gridLayout.setObjectName(u"gridLayout")
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.exampleTree = QTreeWidget(self.widget)
+ __qtreewidgetitem = QTreeWidgetItem()
+ __qtreewidgetitem.setText(0, u"1");
+ self.exampleTree.setHeaderItem(__qtreewidgetitem)
+ self.exampleTree.setObjectName(u"exampleTree")
+ self.exampleTree.header().setVisible(False)
+
+ self.gridLayout.addWidget(self.exampleTree, 0, 0, 1, 2)
+
+ self.graphicsSystemCombo = QComboBox(self.widget)
+ self.graphicsSystemCombo.addItem("")
+ self.graphicsSystemCombo.addItem("")
+ self.graphicsSystemCombo.addItem("")
+ self.graphicsSystemCombo.addItem("")
+ self.graphicsSystemCombo.setObjectName(u"graphicsSystemCombo")
+
+ self.gridLayout.addWidget(self.graphicsSystemCombo, 2, 1, 1, 1)
+
+ self.qtLibCombo = QComboBox(self.widget)
+ self.qtLibCombo.addItem("")
+ self.qtLibCombo.addItem("")
+ self.qtLibCombo.addItem("")
+ self.qtLibCombo.addItem("")
+ self.qtLibCombo.addItem("")
+ self.qtLibCombo.setObjectName(u"qtLibCombo")
+
+ self.gridLayout.addWidget(self.qtLibCombo, 1, 1, 1, 1)
+
+ self.label_2 = QLabel(self.widget)
+ self.label_2.setObjectName(u"label_2")
+
+ self.gridLayout.addWidget(self.label_2, 2, 0, 1, 1)
+
+ self.label = QLabel(self.widget)
+ self.label.setObjectName(u"label")
+
+ self.gridLayout.addWidget(self.label, 1, 0, 1, 1)
+
+ self.loadBtn = QPushButton(self.widget)
+ self.loadBtn.setObjectName(u"loadBtn")
+
+ self.gridLayout.addWidget(self.loadBtn, 3, 1, 1, 1)
+
+ self.splitter.addWidget(self.widget)
+ self.widget1 = QWidget(self.splitter)
+ self.widget1.setObjectName(u"widget1")
+ self.verticalLayout = QVBoxLayout(self.widget1)
+ self.verticalLayout.setObjectName(u"verticalLayout")
+ self.verticalLayout.setContentsMargins(0, 0, 0, 0)
+ self.loadedFileLabel = QLabel(self.widget1)
+ self.loadedFileLabel.setObjectName(u"loadedFileLabel")
+ font = QFont()
+ font.setBold(True)
+ self.loadedFileLabel.setFont(font)
+ self.loadedFileLabel.setAlignment(Qt.AlignCenter)
+
+ self.verticalLayout.addWidget(self.loadedFileLabel)
+
+ self.codeView = QPlainTextEdit(self.widget1)
+ self.codeView.setObjectName(u"codeView")
+ font1 = QFont()
+ font1.setFamily(u"Courier New")
+ self.codeView.setFont(font1)
+
+ self.verticalLayout.addWidget(self.codeView)
+
+ self.splitter.addWidget(self.widget1)
+
+ self.gridLayout_2.addWidget(self.splitter, 0, 0, 1, 1)
+
+
+ self.retranslateUi(Form)
+
+ QMetaObject.connectSlotsByName(Form)
+ # setupUi
+
+ def retranslateUi(self, Form):
+ Form.setWindowTitle(QCoreApplication.translate("Form", u"PyQtGraph", None))
+ self.graphicsSystemCombo.setItemText(0, QCoreApplication.translate("Form", u"default", None))
+ self.graphicsSystemCombo.setItemText(1, QCoreApplication.translate("Form", u"native", None))
+ self.graphicsSystemCombo.setItemText(2, QCoreApplication.translate("Form", u"raster", None))
+ self.graphicsSystemCombo.setItemText(3, QCoreApplication.translate("Form", u"opengl", None))
+
+ self.qtLibCombo.setItemText(0, QCoreApplication.translate("Form", u"default", None))
+ self.qtLibCombo.setItemText(1, QCoreApplication.translate("Form", u"PyQt5", None))
+ self.qtLibCombo.setItemText(2, QCoreApplication.translate("Form", u"PySide2", None))
+ self.qtLibCombo.setItemText(3, QCoreApplication.translate("Form", u"PySide6", None))
+ self.qtLibCombo.setItemText(4, QCoreApplication.translate("Form", u"PyQt6", None))
+
+ self.label_2.setText(QCoreApplication.translate("Form", u"Graphics System:", None))
+ self.label.setText(QCoreApplication.translate("Form", u"Qt Library:", None))
+ self.loadBtn.setText(QCoreApplication.translate("Form", u"Run Example", None))
+ self.loadedFileLabel.setText("")
+ # retranslateUi
+
diff --git a/examples/fractal.py b/examples/fractal.py
index d91133a5..3f008141 100644
--- a/examples/fractal.py
+++ b/examples/fractal.py
@@ -9,7 +9,7 @@ import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import numpy as np
-app = QtGui.QApplication([])
+app = pg.mkQApp("Fractal Example")
# Set up UI widgets
win = pg.QtGui.QWidget()
diff --git a/examples/infiniteline_performance.py b/examples/infiniteline_performance.py
index 86264142..9682080e 100644
--- a/examples/infiniteline_performance.py
+++ b/examples/infiniteline_performance.py
@@ -5,7 +5,7 @@ from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg
from pyqtgraph.ptime import time
-app = QtGui.QApplication([])
+app = pg.mkQApp("Infinite Line Performance")
p = pg.plot()
p.setWindowTitle('pyqtgraph performance: InfiniteLine')
diff --git a/examples/initExample.py b/examples/initExample.py
index 8bce7441..97f46108 100644
--- a/examples/initExample.py
+++ b/examples/initExample.py
@@ -2,6 +2,7 @@
## we do this to make sure that, when running examples, the correct library
## version is imported (if there are multiple versions present).
import sys, os
+import importlib
if not hasattr(sys, 'frozen'):
if __file__ == '':
@@ -20,14 +21,10 @@ if not hasattr(sys, 'frozen'):
sys.path.insert(0, p)
## should force example to use PySide instead of PyQt
-if 'pyside' in sys.argv:
- from PySide import QtGui
-elif 'pyqt' in sys.argv:
- from PyQt4 import QtGui
-elif 'pyqt5' in sys.argv:
- from PyQt5 import QtGui
-elif 'pyside2' in sys.argv:
- from PySide2 import QtGui
+for module in ['PyQt5', 'PySide2', 'PySide6', 'PyQt6']:
+ if module.lower() in sys.argv:
+ QtGui = importlib.import_module(module + '.QtGui')
+ break
else:
from pyqtgraph.Qt import QtGui
diff --git a/examples/isocurve.py b/examples/isocurve.py
index 63b1699e..1ed30591 100644
--- a/examples/isocurve.py
+++ b/examples/isocurve.py
@@ -11,7 +11,7 @@ from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg
-app = QtGui.QApplication([])
+app = pg.mkQApp("Isocurve Example")
## make pretty looping data
frames = 200
diff --git a/examples/linkedViews.py b/examples/linkedViews.py
index 34f2b698..49d68b6e 100644
--- a/examples/linkedViews.py
+++ b/examples/linkedViews.py
@@ -13,7 +13,7 @@ import numpy as np
import pyqtgraph as pg
#QtGui.QApplication.setGraphicsSystem('raster')
-app = QtGui.QApplication([])
+app = pg.mkQApp("Linked Views Example")
#mw = QtGui.QMainWindow()
#mw.resize(800,800)
diff --git a/examples/logAxis.py b/examples/logAxis.py
index 3b30c50b..9a66f114 100644
--- a/examples/logAxis.py
+++ b/examples/logAxis.py
@@ -9,7 +9,7 @@ from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg
-app = QtGui.QApplication([])
+app = pg.mkQApp("Log Axis Example")
w = pg.GraphicsLayoutWidget(show=True)
w.setWindowTitle('pyqtgraph example: logAxis')
diff --git a/examples/multiprocess.py b/examples/multiprocess.py
index ba550f7f..2e32b041 100644
--- a/examples/multiprocess.py
+++ b/examples/multiprocess.py
@@ -40,7 +40,7 @@ print( "process finished")
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
-app = pg.QtGui.QApplication([])
+app = pg.mkQApp("Multiprocess Example")
print( "\n=================\nStart QtProcess")
import sys
diff --git a/examples/optics_demos.py b/examples/optics_demos.py
index b2ac5c8a..1f173621 100644
--- a/examples/optics_demos.py
+++ b/examples/optics_demos.py
@@ -15,7 +15,7 @@ import pyqtgraph as pg
import numpy as np
from pyqtgraph import Point
-app = pg.QtGui.QApplication([])
+app = pg.mkQApp("Optics Demo")
w = pg.GraphicsLayoutWidget(show=True, border=0.5)
w.resize(1000, 900)
diff --git a/examples/parametertree.py b/examples/parametertree.py
index 6fd8f38d..4660d965 100644
--- a/examples/parametertree.py
+++ b/examples/parametertree.py
@@ -14,7 +14,7 @@ import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
-app = QtGui.QApplication([])
+app = pg.mkQApp("Parameter Tree Example")
import pyqtgraph.parametertree.parameterTypes as pTypes
from pyqtgraph.parametertree import Parameter, ParameterTree, ParameterItem, registerParameterType
diff --git a/examples/template.py b/examples/template.py
index 6b5e1f75..d39c6fb8 100644
--- a/examples/template.py
+++ b/examples/template.py
@@ -8,10 +8,10 @@ Description of example
import initExample ## Add path to library (just for examples; you do not need this)
import pyqtgraph as pg
-from pyqtgraph.Qt import QtCore, QtGui
+from pyqtgraph.Qt import QtCore, QtGui, mkQApp
import numpy as np
-app = QtGui.QApplication([])
+app = mkQApp()
# win.setWindowTitle('pyqtgraph example: ____')
diff --git a/examples/test_examples.py b/examples/test_examples.py
index 685b71d7..18d45e6e 100644
--- a/examples/test_examples.py
+++ b/examples/test_examples.py
@@ -2,42 +2,47 @@
from __future__ import print_function, division, absolute_import
from collections import namedtuple
from pyqtgraph import Qt
-from pyqtgraph.python2_3 import basestring
-from .ExampleApp import examples
import errno
import importlib
import itertools
import pytest
import os, sys
+import platform
import subprocess
import time
+from argparse import Namespace
if __name__ == "__main__" and (__package__ is None or __package__==''):
parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, parent_dir)
import examples
__package__ = "examples"
+from . import utils
def buildFileList(examples, files=None):
if files is None:
- files = [("Example App", "test_ExampleApp.py")]
+ files = []
for key, val in examples.items():
- if isinstance(val, basestring):
- files.append((key,val))
- else:
+ if isinstance(val, dict):
buildFileList(val, files)
+ elif isinstance(val, Namespace):
+ files.append((key, val.filename))
+ else:
+ files.append((key, val))
return files
-
path = os.path.abspath(os.path.dirname(__file__))
-files = sorted(set(buildFileList(examples)))
+files = [("Example App", "test_ExampleApp.py")]
+for ex in [utils.examples, utils.others]:
+ files = buildFileList(ex, files)
+files = sorted(set(files))
frontends = {
- Qt.PYQT4: False,
Qt.PYQT5: False,
- Qt.PYSIDE: False,
- Qt.PYSIDE2: False
+ Qt.PYQT6: False,
+ Qt.PYSIDE2: False,
+ Qt.PYSIDE6: False,
}
# sort out which of the front ends are available
for frontend in frontends.keys():
@@ -53,6 +58,10 @@ installedFrontends = sorted([
exceptionCondition = namedtuple("exceptionCondition", ["condition", "reason"])
conditionalExamples = {
+ "test_ExampleApp.py": exceptionCondition(
+ not(platform.system() == "Linux" and frontends[Qt.PYSIDE2]),
+ reason="Unexplained, intermittent segfault and subsequent timeout on CI"
+ ),
"hdf5.py": exceptionCondition(
False,
reason="Example requires user interaction"
@@ -61,83 +70,108 @@ conditionalExamples = {
False,
reason="Test is being problematic on CI machines"
),
- "optics_demos.py": exceptionCondition(
- not frontends[Qt.PYSIDE],
- reason=(
- "Test fails due to PySide bug: ",
- "https://bugreports.qt.io/browse/PYSIDE-671"
- )
+ "ProgressDialog.py": exceptionCondition(
+ not(platform.system() == "Linux"),
+ reason="QXcbConnection: XCB error"
),
'GLVolumeItem.py': exceptionCondition(
- not(sys.platform == "darwin" and
- sys.version_info[0] == 2 and
- (frontends[Qt.PYQT4] or frontends[Qt.PYSIDE])),
+ not(platform.system() == "Darwin" and
+ tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and
+ (sys.version_info <= (3, 8, 7) or
+ (sys.version_info >= (3, 9) and sys.version_info < (3, 9, 1)))),
reason=(
- "glClear does not work on macOS + Python2.7 + Qt4: ",
- "https://github.com/pyqtgraph/pyqtgraph/issues/939"
+ "pyopenGL cannot find openGL libray on big sur: "
+ "https://github.com/python/cpython/pull/21241"
)
),
'GLIsosurface.py': exceptionCondition(
- not(sys.platform == "darwin" and
- sys.version_info[0] == 2 and
- (frontends[Qt.PYQT4] or frontends[Qt.PYSIDE])),
+ not(platform.system() == "Darwin" and
+ tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and
+ (sys.version_info <= (3, 8, 7) or
+ (sys.version_info >= (3, 9) and sys.version_info < (3, 9, 1)))),
reason=(
- "glClear does not work on macOS + Python2.7 + Qt4: ",
- "https://github.com/pyqtgraph/pyqtgraph/issues/939"
+ "pyopenGL cannot find openGL libray on big sur: "
+ "https://github.com/python/cpython/pull/21241"
)
),
'GLSurfacePlot.py': exceptionCondition(
- not(sys.platform == "darwin" and
- sys.version_info[0] == 2 and
- (frontends[Qt.PYQT4] or frontends[Qt.PYSIDE])),
+ not(platform.system() == "Darwin" and
+ tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and
+ (sys.version_info <= (3, 8, 7) or
+ (sys.version_info >= (3, 9) and sys.version_info < (3, 9, 1)))),
reason=(
- "glClear does not work on macOS + Python2.7 + Qt4: ",
- "https://github.com/pyqtgraph/pyqtgraph/issues/939"
+ "pyopenGL cannot find openGL libray on big sur: "
+ "https://github.com/python/cpython/pull/21241"
)
),
'GLScatterPlotItem.py': exceptionCondition(
- not(sys.platform == "darwin" and
- sys.version_info[0] == 2 and
- (frontends[Qt.PYQT4] or frontends[Qt.PYSIDE])),
+ not(platform.system() == "Darwin" and
+ tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and
+ (sys.version_info <= (3, 8, 7) or
+ (sys.version_info >= (3, 9) and sys.version_info < (3, 9, 1)))),
reason=(
- "glClear does not work on macOS + Python2.7 + Qt4: ",
- "https://github.com/pyqtgraph/pyqtgraph/issues/939"
+ "pyopenGL cannot find openGL libray on big sur: "
+ "https://github.com/python/cpython/pull/21241"
)
),
'GLshaders.py': exceptionCondition(
- not(sys.platform == "darwin" and
- sys.version_info[0] == 2 and
- (frontends[Qt.PYQT4] or frontends[Qt.PYSIDE])),
+ not(platform.system() == "Darwin" and
+ tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and
+ (sys.version_info <= (3, 8, 7) or
+ (sys.version_info >= (3, 9) and sys.version_info < (3, 9, 1)))),
reason=(
- "glClear does not work on macOS + Python2.7 + Qt4: ",
- "https://github.com/pyqtgraph/pyqtgraph/issues/939"
+ "pyopenGL cannot find openGL libray on big sur: "
+ "https://github.com/python/cpython/pull/21241"
)
),
'GLLinePlotItem.py': exceptionCondition(
- not(sys.platform == "darwin" and
- sys.version_info[0] == 2 and
- (frontends[Qt.PYQT4] or frontends[Qt.PYSIDE])),
+ not(platform.system() == "Darwin" and
+ tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and
+ (sys.version_info <= (3, 8, 7) or
+ (sys.version_info >= (3, 9) and sys.version_info < (3, 9, 1)))),
reason=(
- "glClear does not work on macOS + Python2.7 + Qt4: ",
- "https://github.com/pyqtgraph/pyqtgraph/issues/939"
+ "pyopenGL cannot find openGL libray on big sur: "
+ "https://github.com/python/cpython/pull/21241"
)
),
'GLMeshItem.py': exceptionCondition(
- not(sys.platform == "darwin" and
- sys.version_info[0] == 2 and
- (frontends[Qt.PYQT4] or frontends[Qt.PYSIDE])),
+ not(platform.system() == "Darwin" and
+ tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and
+ (sys.version_info <= (3, 8, 7) or
+ (sys.version_info >= (3, 9) and sys.version_info < (3, 9, 1)))),
reason=(
- "glClear does not work on macOS + Python2.7 + Qt4: ",
- "https://github.com/pyqtgraph/pyqtgraph/issues/939"
+ "pyopenGL cannot find openGL libray on big sur: "
+ "https://github.com/python/cpython/pull/21241"
)
),
'GLImageItem.py': exceptionCondition(
- not(sys.platform == "darwin" and
- sys.version_info[0] == 2 and
- (frontends[Qt.PYQT4] or frontends[Qt.PYSIDE])),
+ not(platform.system() == "Darwin" and
+ tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and
+ (sys.version_info <= (3, 8, 7) or
+ (sys.version_info >= (3, 9) and sys.version_info < (3, 9, 1)))),
reason=(
- "glClear does not work on macOS + Python2.7 + Qt4: ",
- "https://github.com/pyqtgraph/pyqtgraph/issues/939"
+ "pyopenGL cannot find openGL libray on big sur: "
+ "https://github.com/python/cpython/pull/21241"
+ )
+ ),
+ 'GLBarGraphItem.py': exceptionCondition(
+ not(platform.system() == "Darwin" and
+ tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and
+ (sys.version_info <= (3, 8, 7) or
+ (sys.version_info >= (3, 9) and sys.version_info < (3, 9, 1)))),
+ reason=(
+ "pyopenGL cannot find openGL libray on big sur: "
+ "https://github.com/python/cpython/pull/21241"
+ )
+ ),
+ 'GLViewWidget.py': exceptionCondition(
+ not(platform.system() == "Darwin" and
+ tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and
+ (sys.version_info <= (3, 8, 7) or
+ (sys.version_info >= (3, 9) and sys.version_info < (3, 9, 1)))),
+ reason=(
+ "pyopenGL cannot find openGL libray on big sur: "
+ "https://github.com/python/cpython/pull/21241"
)
)
}
diff --git a/examples/utils.py b/examples/utils.py
index 8693d4cf..225ce327 100644
--- a/examples/utils.py
+++ b/examples/utils.py
@@ -1,14 +1,10 @@
-from __future__ import division, print_function, absolute_import
-import os
-from pyqtgraph.pgcollections import OrderedDict
-from pyqtgraph.python2_3 import basestring
-
-path = os.path.abspath(os.path.dirname(__file__))
+from collections import OrderedDict
+from argparse import Namespace
examples = OrderedDict([
('Command-line usage', 'CLIexample.py'),
- ('Basic Plotting', 'Plotting.py'),
+ ('Basic Plotting', Namespace(filename='Plotting.py', recommended=True)),
('ImageView', 'ImageView.py'),
('ParameterTree', 'parametertree.py'),
('Crosshair / Mouse interaction', 'crosshair.py'),
@@ -16,7 +12,7 @@ examples = OrderedDict([
('Plot Customization', 'customPlot.py'),
('Timestamps on x axis', 'DateAxisItem.py'),
('Image Analysis', 'imageAnalysis.py'),
- ('ViewBox Features', 'ViewBoxFeatures.py'),
+ ('ViewBox Features', Namespace(filename='ViewBoxFeatures.py', recommended=True)),
('Dock widgets', 'dockarea.py'),
('Console', 'ConsoleWidget.py'),
('Histograms', 'histogram.py'),
@@ -41,6 +37,7 @@ examples = OrderedDict([
('FillBetweenItem', 'FillBetweenItem.py'),
('ImageItem - video', 'ImageItem.py'),
('ImageItem - draw', 'Draw.py'),
+ ('Non-uniform Image', 'NonUniformImage.py'),
('Region-of-Interest', 'ROIExamples.py'),
('Bar Graph', 'BarGraphItem.py'),
('GraphicsLayout', 'GraphicsLayout.py'),
@@ -89,14 +86,35 @@ examples = OrderedDict([
])
-def buildFileList(examples, files=None):
- if files == None:
- files = []
- for key, val in examples.items():
- #item = QtGui.QTreeWidgetItem([key])
- if isinstance(val, basestring):
- #item.file = val
- files.append((key,val))
- else:
- buildFileList(val, files)
- return files
+# don't care about ordering
+# but actually from Python 3.7, dict is ordered
+others = dict([
+ ('logAxis', 'logAxis.py'),
+ ('PanningPlot', 'PanningPlot.py'),
+ ('MultiplePlotAxes', 'MultiplePlotAxes.py'),
+ ('ROItypes', 'ROItypes.py'),
+ ('ScaleBar', 'ScaleBar.py'),
+ ('InfiniteLine', 'InfiniteLine.py'),
+ ('ViewBox', 'ViewBox.py'),
+ ('GradientEditor', 'GradientEditor.py'),
+ ('GLBarGraphItem', 'GLBarGraphItem.py'),
+ ('GLViewWidget', 'GLViewWidget.py'),
+ ('DiffTreeWidget', 'DiffTreeWidget.py'),
+ ('MultiPlotWidget', 'MultiPlotWidget.py'),
+ ('RemoteGraphicsView', 'RemoteGraphicsView.py'),
+ ('colorMaps', 'colorMaps.py'),
+ ('contextMenu', 'contextMenu.py'),
+ ('designerExample', 'designerExample.py'),
+ ('DateAxisItem_QtDesigner', 'DateAxisItem_QtDesigner.py'),
+ ('GraphicsScene', 'GraphicsScene.py'),
+ ('MouseSelection', 'MouseSelection.py'),
+ ('ProgressDialog', 'ProgressDialog.py'),
+])
+
+
+# examples that are subsumed into other examples
+trivial = dict([
+ ('SimplePlot', 'SimplePlot.py'), # Plotting.py
+ ('LogPlotTest', 'LogPlotTest.py'), # Plotting.py
+ ('ViewLimits', 'ViewLimits.py'), # ViewBoxFeatures.py
+])
diff --git a/pyqtgraph/GraphicsScene/GraphicsScene.py b/pyqtgraph/GraphicsScene/GraphicsScene.py
index 1eb5ae9f..1c6e76b3 100644
--- a/pyqtgraph/GraphicsScene/GraphicsScene.py
+++ b/pyqtgraph/GraphicsScene/GraphicsScene.py
@@ -3,7 +3,7 @@ import time
import weakref
import warnings
-from ..Qt import QtCore, QtGui
+from ..Qt import QtCore, QtGui, QT_LIB, isQObjectAlive
from ..Point import Point
from .. import functions as fn
from .. import ptime as ptime
@@ -14,15 +14,9 @@ from .. import getConfigOption
getMillis = lambda: int(round(time.time() * 1000))
-if hasattr(QtCore, 'PYQT_VERSION'):
- try:
- try:
- from PyQt5 import sip
- except ImportError:
- import sip
- HAVE_SIP = True
- except ImportError:
- HAVE_SIP = False
+if QT_LIB.startswith('PyQt'):
+ from ..Qt import sip
+ HAVE_SIP = True
else:
HAVE_SIP = False
@@ -122,7 +116,7 @@ class GraphicsScene(QtGui.QGraphicsScene):
self.lastHoverEvent = None
self.minDragTime = 0.5 # drags shorter than 0.5 sec are interpreted as clicks
- self.contextMenu = [QtGui.QAction("Export...", self)]
+ self.contextMenu = [QtGui.QAction(QtCore.QCoreApplication.translate("GraphicsScene", "Export..."), self)]
self.contextMenu[0].triggered.connect(self.showExportDialog)
self.exportDialog = None
@@ -158,7 +152,7 @@ class GraphicsScene(QtGui.QGraphicsScene):
self._moveDistance = d
def mousePressEvent(self, ev):
- QtGui.QGraphicsScene.mousePressEvent(self, ev)
+ super().mousePressEvent(ev)
if self.mouseGrabberItem() is None: ## nobody claimed press; we are free to generate drag/click events
if self.lastHoverEvent is not None:
# If the mouse has moved since the last hover event, send a new one.
@@ -171,7 +165,7 @@ class GraphicsScene(QtGui.QGraphicsScene):
## set focus on the topmost focusable item under this click
items = self.items(ev.scenePos())
for i in items:
- if i.isEnabled() and i.isVisible() and int(i.flags() & i.ItemIsFocusable) > 0:
+ if i.isEnabled() and i.isVisible() and (i.flags() & i.ItemIsFocusable):
i.setFocus(QtCore.Qt.MouseFocusReason)
break
@@ -197,35 +191,35 @@ class GraphicsScene(QtGui.QGraphicsScene):
self.sigMouseMoved.emit(ev.scenePos())
# First allow QGraphicsScene to eliver hoverEvent/Move/Exit Events
- QtGui.QGraphicsScene.mouseMoveEvent(self, ev)
+ super().mouseMoveEvent(ev)
# Next Deliver our own Hover Events
self.sendHoverEvents(ev)
- if int(ev.buttons()) != 0:
+ if ev.buttons():
# button is pressed' send mouseMoveEvents and mouseDragEvents
- QtGui.QGraphicsScene.mouseMoveEvent(self, ev)
+ super().mouseMoveEvent(ev)
if self.mouseGrabberItem() is None:
now = ptime.time()
init = False
## keep track of which buttons are involved in dragging
- for btn in [QtCore.Qt.LeftButton, QtCore.Qt.MidButton, QtCore.Qt.RightButton]:
- if int(ev.buttons() & btn) == 0:
+ for btn in [QtCore.Qt.LeftButton, QtCore.Qt.MiddleButton, QtCore.Qt.RightButton]:
+ if not (ev.buttons() & btn):
continue
- if int(btn) not in self.dragButtons: ## see if we've dragged far enough yet
- cev = [e for e in self.clickEvents if int(e.button()) == int(btn)]
+ if btn not in self.dragButtons: ## see if we've dragged far enough yet
+ cev = [e for e in self.clickEvents if e.button() == btn]
if cev:
cev = cev[0]
dist = Point(ev.scenePos() - cev.scenePos()).length()
if dist == 0 or (dist < self._moveDistance and now - cev.time() < self.minDragTime):
continue
init = init or (len(self.dragButtons) == 0) ## If this is the first button to be dragged, then init=True
- self.dragButtons.append(int(btn))
+ self.dragButtons.append(btn)
## if we have dragged buttons, deliver a drag event
if len(self.dragButtons) > 0:
if self.sendDragEvent(ev, init=init):
ev.accept()
else:
- QtGui.QGraphicsScene.mouseMoveEvent(self, ev)
+ super().mouseMoveEvent(ev)
# if you do not accept event (which is ignored) then cursor will disappear
ev.accept()
@@ -241,24 +235,24 @@ class GraphicsScene(QtGui.QGraphicsScene):
ev.accept()
self.dragButtons.remove(ev.button())
else:
- cev = [e for e in self.clickEvents if int(e.button()) == int(ev.button())]
+ cev = [e for e in self.clickEvents if e.button() == ev.button()]
if cev:
if self.sendClickEvent(cev[0]):
#print "sent click event"
ev.accept()
self.clickEvents.remove(cev[0])
- if int(ev.buttons()) == 0:
+ if not ev.buttons():
self.dragItem = None
self.dragButtons = []
self.clickEvents = []
self.lastDrag = None
- QtGui.QGraphicsScene.mouseReleaseEvent(self, ev)
+ super().mouseReleaseEvent(ev)
self.sendHoverEvents(ev) ## let items prepare for next click/drag
def mouseDoubleClickEvent(self, ev):
- QtGui.QGraphicsScene.mouseDoubleClickEvent(self, ev)
+ super().mouseDoubleClickEvent(ev)
if self.mouseGrabberItem() is None: ## nobody claimed press; we are free to generate drag/click events
self.clickEvents.append(MouseClickEvent(ev, double=True))
@@ -270,7 +264,7 @@ class GraphicsScene(QtGui.QGraphicsScene):
items = []
event = HoverEvent(None, acceptable)
else:
- acceptable = int(ev.buttons()) == 0 ## if we are in mid-drag, do not allow items to accept the hover event.
+ acceptable = not ev.buttons() ## if we are in mid-drag, do not allow items to accept the hover event.
event = HoverEvent(ev, acceptable)
items = self.itemsNearEvent(event, hoverable=True)
self.sigMouseHover.emit(items)
@@ -298,7 +292,9 @@ class GraphicsScene(QtGui.QGraphicsScene):
for item in prevItems:
event.currentItem = item
try:
- if item.scene() is self:
+ # NOTE: isQObjectAlive(item) was added for PySide6 where
+ # verlet_chain_demo.py triggers a RuntimeError.
+ if isQObjectAlive(item) and item.scene() is self:
item.hoverEvent(event)
except:
debug.printExc("Error sending hover exit event:")
@@ -310,7 +306,7 @@ class GraphicsScene(QtGui.QGraphicsScene):
# item to continue receiving events until the drag is over
# - event is not a mouse event (QEvent.Leave sometimes appears here)
if (ev.type() == ev.GraphicsSceneMousePress or
- (ev.type() == ev.GraphicsSceneMouseMove and int(ev.buttons()) == 0)):
+ (ev.type() == ev.GraphicsSceneMouseMove and not ev.buttons())):
self.lastHoverEvent = event ## save this so we can ask about accepted events later.
def sendDragEvent(self, ev, init=False, final=False):
@@ -348,7 +344,7 @@ class GraphicsScene(QtGui.QGraphicsScene):
if event.isAccepted():
#print " --> accepted"
self.dragItem = item
- if int(item.flags() & item.ItemIsFocusable) > 0:
+ if item.flags() & item.ItemIsFocusable:
item.setFocus(QtCore.Qt.MouseFocusReason)
break
elif self.dragItem is not None:
@@ -393,7 +389,7 @@ class GraphicsScene(QtGui.QGraphicsScene):
debug.printExc("Error sending click event:")
if ev.isAccepted():
- if int(item.flags() & item.ItemIsFocusable) > 0:
+ if item.flags() & item.ItemIsFocusable:
item.setFocus(QtCore.Qt.MouseFocusReason)
break
self.sigMouseClicked.emit(ev)
diff --git a/pyqtgraph/GraphicsScene/exportDialog.py b/pyqtgraph/GraphicsScene/exportDialog.py
index 61f2233d..f4af2651 100644
--- a/pyqtgraph/GraphicsScene/exportDialog.py
+++ b/pyqtgraph/GraphicsScene/exportDialog.py
@@ -1,17 +1,18 @@
-from ..Qt import QtCore, QtGui, QT_LIB
+from ..Qt import QtCore, QtGui, QtWidgets, QT_LIB
from .. import exporters as exporters
from .. import functions as fn
from ..graphicsItems.ViewBox import ViewBox
from ..graphicsItems.PlotItem import PlotItem
-if QT_LIB == 'PySide':
- from . import exportDialogTemplate_pyside as exportDialogTemplate
-elif QT_LIB == 'PySide2':
- from . import exportDialogTemplate_pyside2 as exportDialogTemplate
-elif QT_LIB == 'PyQt5':
- from . import exportDialogTemplate_pyqt5 as exportDialogTemplate
-else:
- from . import exportDialogTemplate_pyqt as exportDialogTemplate
+import importlib
+ui_template = importlib.import_module(
+ f'.exportDialogTemplate_{QT_LIB.lower()}', package=__package__)
+
+
+class FormatExportListWidgetItem(QtWidgets.QListWidgetItem):
+ def __init__(self, expClass, *args, **kwargs):
+ QtWidgets.QListWidgetItem.__init__(self, *args, **kwargs)
+ self.expClass = expClass
class ExportDialog(QtGui.QWidget):
@@ -28,7 +29,7 @@ class ExportDialog(QtGui.QWidget):
self.selectBox.hide()
self.scene.addItem(self.selectBox)
- self.ui = exportDialogTemplate.Ui_Form()
+ self.ui = ui_template.Ui_Form()
self.ui.setupUi(self)
self.ui.closeBtn.clicked.connect(self.close)
@@ -99,16 +100,14 @@ class ExportDialog(QtGui.QWidget):
def updateFormatList(self):
current = self.ui.formatList.currentItem()
- if current is not None:
- current = str(current.text())
+
self.ui.formatList.clear()
- self.exporterClasses = {}
gotCurrent = False
for exp in exporters.listExporters():
- self.ui.formatList.addItem(exp.Name)
- self.exporterClasses[exp.Name] = exp
- if exp.Name == current:
- self.ui.formatList.setCurrentRow(self.ui.formatList.count()-1)
+ item = FormatExportListWidgetItem(exp, QtCore.QCoreApplication.translate('Exporter', exp.Name))
+ self.ui.formatList.addItem(item)
+ if item == current:
+ self.ui.formatList.setCurrentRow(self.ui.formatList.count() - 1)
gotCurrent = True
if not gotCurrent:
@@ -119,7 +118,7 @@ class ExportDialog(QtGui.QWidget):
self.currentExporter = None
self.ui.paramTree.clear()
return
- expClass = self.exporterClasses[str(item.text())]
+ expClass = item.expClass
exp = expClass(item=self.ui.itemTree.currentItem().gitem)
params = exp.parameters()
@@ -145,4 +144,4 @@ class ExportDialog(QtGui.QWidget):
def closeEvent(self, event):
self.close()
- QtGui.QWidget.closeEvent(self, event)
+ super().closeEvent(event)
diff --git a/pyqtgraph/GraphicsScene/exportDialogTemplate_pyqt.py b/pyqtgraph/GraphicsScene/exportDialogTemplate_pyqt.py
deleted file mode 100644
index ad7361ab..00000000
--- a/pyqtgraph/GraphicsScene/exportDialogTemplate_pyqt.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file './pyqtgraph/GraphicsScene/exportDialogTemplate.ui'
-#
-# Created: Mon Dec 23 10:10:52 2013
-# by: PyQt4 UI code generator 4.10
-#
-# WARNING! All changes made in this file will be lost!
-
-from PyQt4 import QtCore, QtGui
-
-try:
- _fromUtf8 = QtCore.QString.fromUtf8
-except AttributeError:
- def _fromUtf8(s):
- return s
-
-try:
- _encoding = QtGui.QApplication.UnicodeUTF8
- def _translate(context, text, disambig):
- return QtGui.QApplication.translate(context, text, disambig, _encoding)
-except AttributeError:
- def _translate(context, text, disambig):
- return QtGui.QApplication.translate(context, text, disambig)
-
-class Ui_Form(object):
- def setupUi(self, Form):
- Form.setObjectName(_fromUtf8("Form"))
- Form.resize(241, 367)
- self.gridLayout = QtGui.QGridLayout(Form)
- self.gridLayout.setSpacing(0)
- self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
- self.label = QtGui.QLabel(Form)
- self.label.setObjectName(_fromUtf8("label"))
- self.gridLayout.addWidget(self.label, 0, 0, 1, 3)
- self.itemTree = QtGui.QTreeWidget(Form)
- self.itemTree.setObjectName(_fromUtf8("itemTree"))
- self.itemTree.headerItem().setText(0, _fromUtf8("1"))
- self.itemTree.header().setVisible(False)
- self.gridLayout.addWidget(self.itemTree, 1, 0, 1, 3)
- self.label_2 = QtGui.QLabel(Form)
- self.label_2.setObjectName(_fromUtf8("label_2"))
- self.gridLayout.addWidget(self.label_2, 2, 0, 1, 3)
- self.formatList = QtGui.QListWidget(Form)
- self.formatList.setObjectName(_fromUtf8("formatList"))
- self.gridLayout.addWidget(self.formatList, 3, 0, 1, 3)
- self.exportBtn = QtGui.QPushButton(Form)
- self.exportBtn.setObjectName(_fromUtf8("exportBtn"))
- self.gridLayout.addWidget(self.exportBtn, 6, 1, 1, 1)
- self.closeBtn = QtGui.QPushButton(Form)
- self.closeBtn.setObjectName(_fromUtf8("closeBtn"))
- self.gridLayout.addWidget(self.closeBtn, 6, 2, 1, 1)
- self.paramTree = ParameterTree(Form)
- self.paramTree.setObjectName(_fromUtf8("paramTree"))
- self.paramTree.headerItem().setText(0, _fromUtf8("1"))
- self.paramTree.header().setVisible(False)
- self.gridLayout.addWidget(self.paramTree, 5, 0, 1, 3)
- self.label_3 = QtGui.QLabel(Form)
- self.label_3.setObjectName(_fromUtf8("label_3"))
- self.gridLayout.addWidget(self.label_3, 4, 0, 1, 3)
- self.copyBtn = QtGui.QPushButton(Form)
- self.copyBtn.setObjectName(_fromUtf8("copyBtn"))
- self.gridLayout.addWidget(self.copyBtn, 6, 0, 1, 1)
-
- self.retranslateUi(Form)
- QtCore.QMetaObject.connectSlotsByName(Form)
-
- def retranslateUi(self, Form):
- Form.setWindowTitle(_translate("Form", "Export", None))
- self.label.setText(_translate("Form", "Item to export:", None))
- self.label_2.setText(_translate("Form", "Export format", None))
- self.exportBtn.setText(_translate("Form", "Export", None))
- self.closeBtn.setText(_translate("Form", "Close", None))
- self.label_3.setText(_translate("Form", "Export options", None))
- self.copyBtn.setText(_translate("Form", "Copy", None))
-
-from ..parametertree import ParameterTree
diff --git a/pyqtgraph/GraphicsScene/exportDialogTemplate_pyside.py b/pyqtgraph/GraphicsScene/exportDialogTemplate_pyqt6.py
similarity index 50%
rename from pyqtgraph/GraphicsScene/exportDialogTemplate_pyside.py
rename to pyqtgraph/GraphicsScene/exportDialogTemplate_pyqt6.py
index f2e8dc70..55cbe3a8 100644
--- a/pyqtgraph/GraphicsScene/exportDialogTemplate_pyside.py
+++ b/pyqtgraph/GraphicsScene/exportDialogTemplate_pyqt6.py
@@ -1,39 +1,39 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file './pyqtgraph/GraphicsScene/exportDialogTemplate.ui'
+# Form implementation generated from reading ui file 'pyqtgraph\GraphicsScene\exportDialogTemplate.ui'
#
-# Created: Mon Dec 23 10:10:53 2013
-# by: pyside-uic 0.2.14 running on PySide 1.1.2
+# Created by: PyQt6 UI code generator 6.0.0
#
-# WARNING! All changes made in this file will be lost!
+# 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
-from PySide import QtCore, QtGui
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(241, 367)
- self.gridLayout = QtGui.QGridLayout(Form)
+ self.gridLayout = QtWidgets.QGridLayout(Form)
self.gridLayout.setSpacing(0)
self.gridLayout.setObjectName("gridLayout")
- self.label = QtGui.QLabel(Form)
+ self.label = QtWidgets.QLabel(Form)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 0, 0, 1, 3)
- self.itemTree = QtGui.QTreeWidget(Form)
+ self.itemTree = QtWidgets.QTreeWidget(Form)
self.itemTree.setObjectName("itemTree")
self.itemTree.headerItem().setText(0, "1")
self.itemTree.header().setVisible(False)
self.gridLayout.addWidget(self.itemTree, 1, 0, 1, 3)
- self.label_2 = QtGui.QLabel(Form)
+ self.label_2 = QtWidgets.QLabel(Form)
self.label_2.setObjectName("label_2")
self.gridLayout.addWidget(self.label_2, 2, 0, 1, 3)
- self.formatList = QtGui.QListWidget(Form)
+ self.formatList = QtWidgets.QListWidget(Form)
self.formatList.setObjectName("formatList")
self.gridLayout.addWidget(self.formatList, 3, 0, 1, 3)
- self.exportBtn = QtGui.QPushButton(Form)
+ self.exportBtn = QtWidgets.QPushButton(Form)
self.exportBtn.setObjectName("exportBtn")
self.gridLayout.addWidget(self.exportBtn, 6, 1, 1, 1)
- self.closeBtn = QtGui.QPushButton(Form)
+ self.closeBtn = QtWidgets.QPushButton(Form)
self.closeBtn.setObjectName("closeBtn")
self.gridLayout.addWidget(self.closeBtn, 6, 2, 1, 1)
self.paramTree = ParameterTree(Form)
@@ -41,10 +41,10 @@ class Ui_Form(object):
self.paramTree.headerItem().setText(0, "1")
self.paramTree.header().setVisible(False)
self.gridLayout.addWidget(self.paramTree, 5, 0, 1, 3)
- self.label_3 = QtGui.QLabel(Form)
+ self.label_3 = QtWidgets.QLabel(Form)
self.label_3.setObjectName("label_3")
self.gridLayout.addWidget(self.label_3, 4, 0, 1, 3)
- self.copyBtn = QtGui.QPushButton(Form)
+ self.copyBtn = QtWidgets.QPushButton(Form)
self.copyBtn.setObjectName("copyBtn")
self.gridLayout.addWidget(self.copyBtn, 6, 0, 1, 1)
@@ -52,12 +52,12 @@ class Ui_Form(object):
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
- Form.setWindowTitle(QtGui.QApplication.translate("Form", "Export", None, QtGui.QApplication.UnicodeUTF8))
- self.label.setText(QtGui.QApplication.translate("Form", "Item to export:", None, QtGui.QApplication.UnicodeUTF8))
- self.label_2.setText(QtGui.QApplication.translate("Form", "Export format", None, QtGui.QApplication.UnicodeUTF8))
- self.exportBtn.setText(QtGui.QApplication.translate("Form", "Export", None, QtGui.QApplication.UnicodeUTF8))
- self.closeBtn.setText(QtGui.QApplication.translate("Form", "Close", None, QtGui.QApplication.UnicodeUTF8))
- self.label_3.setText(QtGui.QApplication.translate("Form", "Export options", None, QtGui.QApplication.UnicodeUTF8))
- self.copyBtn.setText(QtGui.QApplication.translate("Form", "Copy", None, QtGui.QApplication.UnicodeUTF8))
-
+ _translate = QtCore.QCoreApplication.translate
+ Form.setWindowTitle(_translate("Form", "Export"))
+ self.label.setText(_translate("Form", "Item to export:"))
+ self.label_2.setText(_translate("Form", "Export format"))
+ self.exportBtn.setText(_translate("Form", "Export"))
+ self.closeBtn.setText(_translate("Form", "Close"))
+ self.label_3.setText(_translate("Form", "Export options"))
+ self.copyBtn.setText(_translate("Form", "Copy"))
from ..parametertree import ParameterTree
diff --git a/pyqtgraph/GraphicsScene/exportDialogTemplate_pyside6.py b/pyqtgraph/GraphicsScene/exportDialogTemplate_pyside6.py
new file mode 100644
index 00000000..92d813fd
--- /dev/null
+++ b/pyqtgraph/GraphicsScene/exportDialogTemplate_pyside6.py
@@ -0,0 +1,94 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'exportDialogTemplate.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 ..parametertree import ParameterTree
+
+
+class Ui_Form(object):
+ def setupUi(self, Form):
+ if not Form.objectName():
+ Form.setObjectName(u"Form")
+ Form.resize(241, 367)
+ self.gridLayout = QGridLayout(Form)
+ self.gridLayout.setSpacing(0)
+ self.gridLayout.setObjectName(u"gridLayout")
+ self.label = QLabel(Form)
+ self.label.setObjectName(u"label")
+
+ self.gridLayout.addWidget(self.label, 0, 0, 1, 3)
+
+ self.itemTree = QTreeWidget(Form)
+ __qtreewidgetitem = QTreeWidgetItem()
+ __qtreewidgetitem.setText(0, u"1");
+ self.itemTree.setHeaderItem(__qtreewidgetitem)
+ self.itemTree.setObjectName(u"itemTree")
+ self.itemTree.header().setVisible(False)
+
+ self.gridLayout.addWidget(self.itemTree, 1, 0, 1, 3)
+
+ self.label_2 = QLabel(Form)
+ self.label_2.setObjectName(u"label_2")
+
+ self.gridLayout.addWidget(self.label_2, 2, 0, 1, 3)
+
+ self.formatList = QListWidget(Form)
+ self.formatList.setObjectName(u"formatList")
+
+ self.gridLayout.addWidget(self.formatList, 3, 0, 1, 3)
+
+ self.exportBtn = QPushButton(Form)
+ self.exportBtn.setObjectName(u"exportBtn")
+
+ self.gridLayout.addWidget(self.exportBtn, 6, 1, 1, 1)
+
+ self.closeBtn = QPushButton(Form)
+ self.closeBtn.setObjectName(u"closeBtn")
+
+ self.gridLayout.addWidget(self.closeBtn, 6, 2, 1, 1)
+
+ self.paramTree = ParameterTree(Form)
+ __qtreewidgetitem1 = QTreeWidgetItem()
+ __qtreewidgetitem1.setText(0, u"1");
+ self.paramTree.setHeaderItem(__qtreewidgetitem1)
+ self.paramTree.setObjectName(u"paramTree")
+ self.paramTree.header().setVisible(False)
+
+ self.gridLayout.addWidget(self.paramTree, 5, 0, 1, 3)
+
+ self.label_3 = QLabel(Form)
+ self.label_3.setObjectName(u"label_3")
+
+ self.gridLayout.addWidget(self.label_3, 4, 0, 1, 3)
+
+ self.copyBtn = QPushButton(Form)
+ self.copyBtn.setObjectName(u"copyBtn")
+
+ self.gridLayout.addWidget(self.copyBtn, 6, 0, 1, 1)
+
+
+ self.retranslateUi(Form)
+
+ QMetaObject.connectSlotsByName(Form)
+ # setupUi
+
+ def retranslateUi(self, Form):
+ Form.setWindowTitle(QCoreApplication.translate("Form", u"Export", None))
+ self.label.setText(QCoreApplication.translate("Form", u"Item to export:", None))
+ self.label_2.setText(QCoreApplication.translate("Form", u"Export format", None))
+ self.exportBtn.setText(QCoreApplication.translate("Form", u"Export", None))
+ self.closeBtn.setText(QCoreApplication.translate("Form", u"Close", None))
+ self.label_3.setText(QCoreApplication.translate("Form", u"Export options", None))
+ self.copyBtn.setText(QCoreApplication.translate("Form", u"Copy", None))
+ # retranslateUi
+
diff --git a/pyqtgraph/GraphicsScene/mouseEvents.py b/pyqtgraph/GraphicsScene/mouseEvents.py
index fb9d3683..b8c210af 100644
--- a/pyqtgraph/GraphicsScene/mouseEvents.py
+++ b/pyqtgraph/GraphicsScene/mouseEvents.py
@@ -18,9 +18,9 @@ class MouseDragEvent(object):
self.currentItem = None
self._buttonDownScenePos = {}
self._buttonDownScreenPos = {}
- for btn in [QtCore.Qt.LeftButton, QtCore.Qt.MidButton, QtCore.Qt.RightButton]:
- self._buttonDownScenePos[int(btn)] = moveEvent.buttonDownScenePos(btn)
- self._buttonDownScreenPos[int(btn)] = moveEvent.buttonDownScreenPos(btn)
+ for btn in [QtCore.Qt.LeftButton, QtCore.Qt.MiddleButton, QtCore.Qt.RightButton]:
+ self._buttonDownScenePos[btn] = moveEvent.buttonDownScenePos(btn)
+ self._buttonDownScreenPos[btn] = moveEvent.buttonDownScreenPos(btn)
self._scenePos = moveEvent.scenePos()
self._screenPos = moveEvent.screenPos()
if lastEvent is None:
@@ -61,7 +61,7 @@ class MouseDragEvent(object):
"""
if btn is None:
btn = self.button()
- return Point(self._buttonDownScenePos[int(btn)])
+ return Point(self._buttonDownScenePos[btn])
def buttonDownScreenPos(self, btn=None):
"""
@@ -70,7 +70,7 @@ class MouseDragEvent(object):
"""
if btn is None:
btn = self.button()
- return Point(self._buttonDownScreenPos[int(btn)])
+ return Point(self._buttonDownScreenPos[btn])
def lastScenePos(self):
"""
@@ -119,7 +119,7 @@ class MouseDragEvent(object):
"""
if btn is None:
btn = self.button()
- return Point(self.currentItem.mapFromScene(self._buttonDownScenePos[int(btn)]))
+ return Point(self.currentItem.mapFromScene(self._buttonDownScenePos[btn]))
def isStart(self):
"""Returns True if this event is the first since a drag was initiated."""
@@ -137,7 +137,7 @@ class MouseDragEvent(object):
else:
lp = self.lastPos()
p = self.pos()
- return "(%g,%g) buttons=%d start=%s finish=%s>" % (lp.x(), lp.y(), p.x(), p.y(), int(self.buttons()), str(self.isStart()), str(self.isFinish()))
+ return "(%g,%g) buttons=%s start=%s finish=%s>" % (lp.x(), lp.y(), p.x(), p.y(), str(self.buttons()), str(self.isStart()), str(self.isFinish()))
def modifiers(self):
"""Return any keyboard modifiers currently pressed.
@@ -230,9 +230,9 @@ class MouseClickEvent(object):
p = self._scenePos
else:
p = self.pos()
- return "" % (p.x(), p.y(), int(self.button()))
+ return "" % (p.x(), p.y(), str(self.button()))
except:
- return "" % (int(self.button()))
+ return "" % (str(self.button()))
def time(self):
return self._time
@@ -362,7 +362,7 @@ class HoverEvent(object):
else:
lp = self.lastPos()
p = self.pos()
- return "(%g,%g) buttons=%d enter=%s exit=%s>" % (lp.x(), lp.y(), p.x(), p.y(), int(self.buttons()), str(self.isEnter()), str(self.isExit()))
+ return "(%g,%g) buttons=%s enter=%s exit=%s>" % (lp.x(), lp.y(), p.x(), p.y(), str(self.buttons()), str(self.isEnter()), str(self.isExit()))
def modifiers(self):
"""Return any keyboard modifiers currently pressed.
diff --git a/pyqtgraph/Qt.py b/pyqtgraph/Qt.py
index 60fc912a..83654c93 100644
--- a/pyqtgraph/Qt.py
+++ b/pyqtgraph/Qt.py
@@ -11,13 +11,17 @@ This module exists to smooth out some of the differences between PySide and PyQt
"""
import os, sys, re, time, subprocess, warnings
+import importlib
+import enum
from .python2_3 import asUnicode
PYSIDE = 'PySide'
PYSIDE2 = 'PySide2'
+PYSIDE6 = 'PySide6'
PYQT4 = 'PyQt4'
PYQT5 = 'PyQt5'
+PYQT6 = 'PyQt6'
QT_LIB = os.getenv('PYQTGRAPH_QT_LIB')
@@ -26,7 +30,7 @@ QT_LIB = os.getenv('PYQTGRAPH_QT_LIB')
## This is done by first checking to see whether one of the libraries
## is already imported. If not, then attempt to import PyQt4, then PySide.
if QT_LIB is None:
- libOrder = [PYQT4, PYSIDE, PYQT5, PYSIDE2]
+ libOrder = [PYQT4, PYSIDE, PYQT5, PYSIDE2, PYSIDE6, PYQT6]
for lib in libOrder:
if lib in sys.modules:
@@ -43,7 +47,7 @@ if QT_LIB is None:
pass
if QT_LIB is None:
- raise Exception("PyQtGraph requires one of PyQt4, PyQt5, PySide or PySide2; none of these packages could be imported.")
+ raise Exception("PyQtGraph requires one of PyQt4, PyQt5, PyQt6, PySide, PySide2 or PySide6; none of these packages could be imported.")
class FailedImport(object):
@@ -119,10 +123,12 @@ def _loadUiType(uiFile):
# convert ui file to python code
if pysideuic is None:
- pyside2version = tuple(map(int, PySide2.__version__.split(".")))
- if pyside2version >= (5, 14) and pyside2version < (5, 14, 2, 2):
- warnings.warn('For UI compilation, it is recommended to upgrade to PySide >= 5.15')
- uipy = subprocess.check_output(['pyside2-uic', uiFile])
+ if QT_LIB == PYSIDE2:
+ pyside2version = tuple(map(int, PySide2.__version__.split(".")))
+ if pyside2version >= (5, 14) and pyside2version < (5, 14, 2, 2):
+ warnings.warn('For UI compilation, it is recommended to upgrade to PySide >= 5.15')
+ uic_executable = QT_LIB.lower() + '-uic'
+ uipy = subprocess.check_output([uic_executable, uiFile])
else:
o = _StringIO()
with open(uiFile, 'r') as f:
@@ -205,10 +211,6 @@ elif QT_LIB == PYQT5:
from PyQt5 import QtSvg
except ImportError as err:
QtSvg = FailedImport(err)
- try:
- from PyQt5 import QtOpenGL
- except ImportError as err:
- QtOpenGL = FailedImport(err)
try:
from PyQt5 import QtTest
QtTest.QTest.qWaitForWindowShown = QtTest.QTest.qWaitForWindowExposed
@@ -217,6 +219,25 @@ elif QT_LIB == PYQT5:
VERSION_INFO = 'PyQt5 ' + QtCore.PYQT_VERSION_STR + ' Qt ' + QtCore.QT_VERSION_STR
+elif QT_LIB == PYQT6:
+ from PyQt6 import QtGui, QtCore, QtWidgets, uic
+
+ try:
+ from PyQt6 import QtSvg
+ except ImportError as err:
+ QtSvg = FailedImport(err)
+ try:
+ from PyQt6 import QtOpenGLWidgets
+ except ImportError as err:
+ QtOpenGLWidgets = FailedImport(err)
+ try:
+ from PyQt6 import QtTest
+ QtTest.QTest.qWaitForWindowShown = QtTest.QTest.qWaitForWindowExposed
+ except ImportError as err:
+ QtTest = FailedImport(err)
+
+ VERSION_INFO = 'PyQt6 ' + QtCore.PYQT_VERSION_STR + ' Qt ' + QtCore.QT_VERSION_STR
+
elif QT_LIB == PYSIDE2:
from PySide2 import QtGui, QtCore, QtWidgets
@@ -224,10 +245,6 @@ elif QT_LIB == PYSIDE2:
from PySide2 import QtSvg
except ImportError as err:
QtSvg = FailedImport(err)
- try:
- from PySide2 import QtOpenGL
- except ImportError as err:
- QtOpenGL = FailedImport(err)
try:
from PySide2 import QtTest
QtTest.QTest.qWaitForWindowShown = QtTest.QTest.qWaitForWindowExposed
@@ -243,12 +260,38 @@ elif QT_LIB == PYSIDE2:
import PySide2
VERSION_INFO = 'PySide2 ' + PySide2.__version__ + ' Qt ' + QtCore.__version__
+elif QT_LIB == PYSIDE6:
+ from PySide6 import QtGui, QtCore, QtWidgets
+
+ try:
+ from PySide6 import QtSvg
+ except ImportError as err:
+ QtSvg = FailedImport(err)
+ try:
+ from PySide6 import QtOpenGLWidgets
+ except ImportError as err:
+ QtOpenGLWidgets = FailedImport(err)
+ try:
+ from PySide6 import QtTest
+ QtTest.QTest.qWaitForWindowShown = QtTest.QTest.qWaitForWindowExposed
+ except ImportError as err:
+ QtTest = FailedImport(err)
+
+ try:
+ import shiboken6
+ isQObjectAlive = shiboken6.isValid
+ except ImportError:
+ # use approximate version
+ isQObjectAlive = _isQObjectAlive
+ import PySide6
+ VERSION_INFO = 'PySide6 ' + PySide6.__version__ + ' Qt ' + QtCore.__version__
+
else:
raise ValueError("Invalid Qt lib '%s'" % QT_LIB)
-# common to PyQt5 and PySide2
-if QT_LIB in [PYQT5, PYSIDE2]:
+# common to PyQt5, PyQt6, PySide2 and PySide6
+if QT_LIB in [PYQT5, PYQT6, PYSIDE2, PYSIDE6]:
# We're using Qt5 which has a different structure so we're going to use a shim to
# recreate the Qt4 structure
@@ -299,8 +342,16 @@ if QT_LIB in [PYQT5, PYSIDE2]:
setattr(QtGui, o, getattr(QtWidgets,o) )
-# Common to PySide and PySide2
-if QT_LIB in [PYSIDE, PYSIDE2]:
+if QT_LIB in [PYQT6, PYSIDE6]:
+ # We're using Qt6 which has a different structure so we're going to use a shim to
+ # recreate the Qt5 structure
+
+ if not isinstance(QtOpenGLWidgets, FailedImport):
+ QtWidgets.QOpenGLWidget = QtOpenGLWidgets.QOpenGLWidget
+
+
+# Common to PySide, PySide2 and PySide6
+if QT_LIB in [PYSIDE, PYSIDE2, PYSIDE6]:
QtVersion = QtCore.__version__
loadUiType = _loadUiType
@@ -316,13 +367,13 @@ if QT_LIB in [PYSIDE, PYSIDE2]:
QtTest.QTest.qWait = qWait
-# Common to PyQt4 and 5
-if QT_LIB in [PYQT4, PYQT5]:
+# Common to PyQt4, PyQt5 and PyQt6
+if QT_LIB in [PYQT4, PYQT5, PYQT6]:
QtVersion = QtCore.QT_VERSION_STR
try:
- from PyQt5 import sip
- except ImportError:
+ sip = importlib.import_module(QT_LIB + '.sip')
+ except ModuleNotFoundError:
import sip
def isQObjectAlive(obj):
return not sip.isdeleted(obj)
@@ -332,14 +383,75 @@ if QT_LIB in [PYQT4, PYQT5]:
QtCore.Signal = QtCore.pyqtSignal
+if QT_LIB == PYSIDE6:
+ # PySide6 6.0 has a missing binding
+ if not hasattr(QtGui.QGradient, 'setStops'):
+ def __setStops(self, stops):
+ for pos, color in stops:
+ self.setColorAt(pos, color)
+ QtGui.QGradient.setStops = __setStops
+
+
+if QT_LIB == PYQT6:
+ # module.Class.EnumClass.Enum -> module.Class.Enum
+ def promote_enums(module):
+ class_names = [x for x in dir(module) if x[0] == 'Q']
+ for class_name in class_names:
+ klass = getattr(module, class_name)
+ if not isinstance(klass, sip.wrappertype):
+ continue
+ attrib_names = [x for x in dir(klass) if x[0].isupper()]
+ for attrib_name in attrib_names:
+ attrib = getattr(klass, attrib_name)
+ if not isinstance(attrib, enum.EnumMeta):
+ continue
+ for e in attrib:
+ setattr(klass, e.name, e)
+
+ promote_enums(QtCore)
+ promote_enums(QtGui)
+ promote_enums(QtWidgets)
+
+ # QKeyEvent::key() returns an int
+ # so comparison with a Key_* enum will always be False
+ # here we convert the enum to its int value
+ for e in QtCore.Qt.Key:
+ setattr(QtCore.Qt, e.name, e.value)
+
+ # shim the old names for QPointF mouse coords
+ QtGui.QSinglePointEvent.localPos = lambda o : o.position()
+ QtGui.QSinglePointEvent.windowPos = lambda o : o.scenePosition()
+ QtGui.QSinglePointEvent.screenPos = lambda o : o.globalPosition()
+ QtGui.QDropEvent.posF = lambda o : o.position()
+
+ QtWidgets.QApplication.exec_ = QtWidgets.QApplication.exec
+ QtWidgets.QDialog.exec_ = lambda o : o.exec()
+ QtGui.QDrag.exec_ = lambda o : o.exec()
+
+ # PyQt6 6.0.0 has a bug where it can't handle certain Type values returned
+ # by the Qt library.
+ try:
+ # 213 is a known failing value
+ QtCore.QEvent.Type(213)
+ except ValueError:
+ def new_method(self, old_method=QtCore.QEvent.type):
+ try:
+ typ = old_method(self)
+ except ValueError:
+ typ = QtCore.QEvent.Type.None_
+ return typ
+ QtCore.QEvent.type = new_method
+ del new_method
+
+
# USE_XXX variables are deprecated
USE_PYSIDE = QT_LIB == PYSIDE
USE_PYQT4 = QT_LIB == PYQT4
USE_PYQT5 = QT_LIB == PYQT5
-## Make sure we have Qt >= 4.7
-versionReq = [4, 7]
+## Make sure we have Qt >= 5.12
+versionReq = [5, 12]
m = re.match(r'(\d+)\.(\d+).*', QtVersion)
if m is not None and list(map(int, m.groups())) < versionReq:
print(list(map(int, m.groups())))
@@ -349,7 +461,7 @@ class App(QtGui.QApplication):
def __init__(self, *args, **kwargs):
super(App, self).__init__(*args, **kwargs)
- if QT_LIB in ['PyQt5', 'PySide2']:
+ if QT_LIB in ['PyQt5', 'PySide2', 'PySide6']:
# qt4 does not have paletteChanged signal!
self.paletteChanged.connect(self.onPaletteChange)
self.onPaletteChange(self.palette())
@@ -363,7 +475,6 @@ class App(QtGui.QApplication):
color = palette.base().color().name()
self.dark_mode = color.lower() != "#ffffff"
-
QAPP = None
def mkQApp(name=None):
"""
@@ -375,8 +486,20 @@ def mkQApp(name=None):
============== ========================================================
"""
global QAPP
+
QAPP = QtGui.QApplication.instance()
if QAPP is None:
+ # hidpi handling
+ qtVersionCompare = tuple(map(int, QtVersion.split(".")))
+ if qtVersionCompare > (6, 0):
+ # Qt6 seems to support hidpi without needing to do anything so continue
+ pass
+ elif qtVersionCompare > (5, 14):
+ os.environ["QT_ENABLE_HIGHDPI_SCALING"] = "1"
+ QtGui.QApplication.setHighDpiScaleFactorRoundingPolicy(QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
+ else: # qt 5.12 and 5.13
+ QtGui.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
+ QtGui.QApplication.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps)
QAPP = App(sys.argv or ["pyqtgraph"])
if name is not None:
diff --git a/pyqtgraph/SRTTransform.py b/pyqtgraph/SRTTransform.py
index b1aea297..934c6247 100644
--- a/pyqtgraph/SRTTransform.py
+++ b/pyqtgraph/SRTTransform.py
@@ -172,7 +172,7 @@ if __name__ == '__main__':
from . import widgets
import GraphicsView
from .functions import *
- app = QtGui.QApplication([])
+ app = pg.mkQApp()
win = QtGui.QMainWindow()
win.show()
cw = GraphicsView.GraphicsView()
diff --git a/pyqtgraph/SRTTransform3D.py b/pyqtgraph/SRTTransform3D.py
index aedb200b..7d458edd 100644
--- a/pyqtgraph/SRTTransform3D.py
+++ b/pyqtgraph/SRTTransform3D.py
@@ -227,7 +227,7 @@ if __name__ == '__main__':
from . import widgets
import GraphicsView
from .functions import *
- app = QtGui.QApplication([])
+ app = pg.mkQApp()
win = QtGui.QMainWindow()
win.show()
cw = GraphicsView.GraphicsView()
diff --git a/pyqtgraph/WidgetGroup.py b/pyqtgraph/WidgetGroup.py
index 4656cc62..6b99f86c 100644
--- a/pyqtgraph/WidgetGroup.py
+++ b/pyqtgraph/WidgetGroup.py
@@ -218,9 +218,6 @@ class WidgetGroup(QtCore.QObject):
v1 = self.cache[n]
v2 = self.readWidget(w)
if v1 != v2:
- if QT_LIB != 'PyQt5':
- # Old signal kept for backward compatibility.
- self.emit(QtCore.SIGNAL('changed'), self.widgetList[w], v2)
self.sigChanged.emit(self.widgetList[w], v2)
def state(self):
diff --git a/pyqtgraph/__init__.py b/pyqtgraph/__init__.py
index 75abf020..6dac9a0e 100644
--- a/pyqtgraph/__init__.py
+++ b/pyqtgraph/__init__.py
@@ -4,7 +4,7 @@ PyQtGraph - Scientific Graphics and GUI Library for Python
www.pyqtgraph.org
"""
-__version__ = '0.11.0'
+__version__ = '0.11.1.dev0'
### import all the goodies and add some helper functions for easy CLI use
@@ -61,6 +61,7 @@ CONFIG_OPTIONS = {
# For 'col-major', image data is expected in reversed (col, row) order.
# The default is 'col-major' for backward compatibility, but this may
# change in the future.
+ 'useCupy': False, # When True, attempt to use cupy ( currently only with ImageItem and related functions )
}
diff --git a/pyqtgraph/canvas/Canvas.py b/pyqtgraph/canvas/Canvas.py
index 2ec13b19..31a10b37 100644
--- a/pyqtgraph/canvas/Canvas.py
+++ b/pyqtgraph/canvas/Canvas.py
@@ -5,14 +5,9 @@ from ..graphicsItems.ROI import ROI
from ..graphicsItems.ViewBox import ViewBox
from ..graphicsItems.GridItem import GridItem
-if QT_LIB == 'PySide':
- from .CanvasTemplate_pyside import *
-elif QT_LIB == 'PyQt4':
- from .CanvasTemplate_pyqt import *
-elif QT_LIB == 'PySide2':
- from .CanvasTemplate_pyside2 import *
-elif QT_LIB == 'PyQt5':
- from .CanvasTemplate_pyqt5 import *
+import importlib
+ui_template = importlib.import_module(
+ f'.CanvasTemplate_{QT_LIB.lower()}', package=__package__)
import numpy as np
from .. import debug
@@ -21,6 +16,7 @@ import gc
from .CanvasManager import CanvasManager
from .CanvasItem import CanvasItem, GroupCanvasItem
+translate = QtCore.QCoreApplication.translate
class Canvas(QtGui.QWidget):
@@ -30,7 +26,7 @@ class Canvas(QtGui.QWidget):
def __init__(self, parent=None, allowTransforms=True, hideCtrl=False, name=None):
QtGui.QWidget.__init__(self, parent)
- self.ui = Ui_Form()
+ self.ui = ui_template.Ui_Form()
self.ui.setupUi(self)
self.view = ViewBox()
self.ui.view.setCentralItem(self.view)
@@ -83,7 +79,7 @@ class Canvas(QtGui.QWidget):
self.ui.redirectCombo.setHostName(self.registeredName)
self.menu = QtGui.QMenu()
- remAct = QtGui.QAction("Remove item", self.menu)
+ remAct = QtGui.QAction(translate("Context Menu", "Remove item"), self.menu)
remAct.triggered.connect(self.removeClicked)
self.menu.addAction(remAct)
self.menu.remAct = remAct
@@ -112,7 +108,7 @@ class Canvas(QtGui.QWidget):
def resizeEvent(self, ev=None):
if ev is not None:
- QtGui.QWidget.resizeEvent(self, ev)
+ super().resizeEvent(ev)
self.hideBtn.move(self.ui.view.size().width() - self.hideBtn.width(), 0)
if not self.sizeApplied:
diff --git a/pyqtgraph/canvas/CanvasItem.py b/pyqtgraph/canvas/CanvasItem.py
index 57174b5f..88612055 100644
--- a/pyqtgraph/canvas/CanvasItem.py
+++ b/pyqtgraph/canvas/CanvasItem.py
@@ -3,17 +3,14 @@ import numpy as np
from ..Qt import QtGui, QtCore, QtSvg, QT_LIB
from ..graphicsItems.ROI import ROI
from .. import SRTTransform, ItemGroup
-if QT_LIB == 'PySide':
- from . import TransformGuiTemplate_pyside as TransformGuiTemplate
-elif QT_LIB == 'PyQt4':
- from . import TransformGuiTemplate_pyqt as TransformGuiTemplate
-elif QT_LIB == 'PySide2':
- from . import TransformGuiTemplate_pyside2 as TransformGuiTemplate
-elif QT_LIB == 'PyQt5':
- from . import TransformGuiTemplate_pyqt5 as TransformGuiTemplate
+import importlib
+ui_template = importlib.import_module(
+ f'.TransformGuiTemplate_{QT_LIB.lower()}', package=__package__)
from .. import debug
+translate = QtCore.QCoreApplication.translate
+
class SelectBox(ROI):
def __init__(self, scalable=False, rotatable=True):
#QtGui.QGraphicsRectItem.__init__(self, 0, 0, size[0], size[1])
@@ -66,7 +63,7 @@ class CanvasItem(QtCore.QObject):
self.layout.setContentsMargins(0,0,0,0)
self.ctrl.setLayout(self.layout)
- self.alphaLabel = QtGui.QLabel("Alpha")
+ self.alphaLabel = QtGui.QLabel(translate("CanvasItem", "Alpha"))
self.alphaSlider = QtGui.QSlider()
self.alphaSlider.setMaximum(1023)
self.alphaSlider.setOrientation(QtCore.Qt.Horizontal)
@@ -78,7 +75,7 @@ class CanvasItem(QtCore.QObject):
self.pasteBtn = QtGui.QPushButton('Paste')
self.transformWidget = QtGui.QWidget()
- self.transformGui = TransformGuiTemplate.Ui_Form()
+ self.transformGui = ui_template.Ui_Form()
self.transformGui.setupUi(self.transformWidget)
self.layout.addWidget(self.transformWidget, 3, 0, 1, 2)
self.transformGui.mirrorImageBtn.clicked.connect(self.mirrorY)
diff --git a/pyqtgraph/canvas/CanvasTemplate_pyqt.py b/pyqtgraph/canvas/CanvasTemplate_pyqt.py
deleted file mode 100644
index 823265aa..00000000
--- a/pyqtgraph/canvas/CanvasTemplate_pyqt.py
+++ /dev/null
@@ -1,104 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file 'CanvasTemplate.ui'
-#
-# Created by: PyQt4 UI code generator 4.11.4
-#
-# WARNING! All changes made in this file will be lost!
-
-from PyQt4 import QtCore, QtGui
-
-try:
- _fromUtf8 = QtCore.QString.fromUtf8
-except AttributeError:
- def _fromUtf8(s):
- return s
-
-try:
- _encoding = QtGui.QApplication.UnicodeUTF8
- def _translate(context, text, disambig):
- return QtGui.QApplication.translate(context, text, disambig, _encoding)
-except AttributeError:
- def _translate(context, text, disambig):
- return QtGui.QApplication.translate(context, text, disambig)
-
-class Ui_Form(object):
- def setupUi(self, Form):
- Form.setObjectName(_fromUtf8("Form"))
- Form.resize(821, 578)
- self.gridLayout_2 = QtGui.QGridLayout(Form)
- self.gridLayout_2.setMargin(0)
- self.gridLayout_2.setSpacing(0)
- self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2"))
- self.splitter = QtGui.QSplitter(Form)
- self.splitter.setOrientation(QtCore.Qt.Horizontal)
- self.splitter.setObjectName(_fromUtf8("splitter"))
- self.view = GraphicsView(self.splitter)
- self.view.setObjectName(_fromUtf8("view"))
- self.vsplitter = QtGui.QSplitter(self.splitter)
- self.vsplitter.setOrientation(QtCore.Qt.Vertical)
- self.vsplitter.setObjectName(_fromUtf8("vsplitter"))
- self.canvasCtrlWidget = QtGui.QWidget(self.vsplitter)
- self.canvasCtrlWidget.setObjectName(_fromUtf8("canvasCtrlWidget"))
- self.gridLayout = QtGui.QGridLayout(self.canvasCtrlWidget)
- self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
- self.autoRangeBtn = QtGui.QPushButton(self.canvasCtrlWidget)
- sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(1)
- sizePolicy.setHeightForWidth(self.autoRangeBtn.sizePolicy().hasHeightForWidth())
- self.autoRangeBtn.setSizePolicy(sizePolicy)
- self.autoRangeBtn.setObjectName(_fromUtf8("autoRangeBtn"))
- self.gridLayout.addWidget(self.autoRangeBtn, 0, 0, 1, 2)
- self.horizontalLayout = QtGui.QHBoxLayout()
- self.horizontalLayout.setSpacing(0)
- self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
- self.redirectCheck = QtGui.QCheckBox(self.canvasCtrlWidget)
- self.redirectCheck.setObjectName(_fromUtf8("redirectCheck"))
- self.horizontalLayout.addWidget(self.redirectCheck)
- self.redirectCombo = CanvasCombo(self.canvasCtrlWidget)
- self.redirectCombo.setObjectName(_fromUtf8("redirectCombo"))
- self.horizontalLayout.addWidget(self.redirectCombo)
- self.gridLayout.addLayout(self.horizontalLayout, 1, 0, 1, 2)
- self.itemList = TreeWidget(self.canvasCtrlWidget)
- sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(100)
- sizePolicy.setHeightForWidth(self.itemList.sizePolicy().hasHeightForWidth())
- self.itemList.setSizePolicy(sizePolicy)
- self.itemList.setHeaderHidden(True)
- self.itemList.setObjectName(_fromUtf8("itemList"))
- self.itemList.headerItem().setText(0, _fromUtf8("1"))
- self.gridLayout.addWidget(self.itemList, 2, 0, 1, 2)
- self.resetTransformsBtn = QtGui.QPushButton(self.canvasCtrlWidget)
- self.resetTransformsBtn.setObjectName(_fromUtf8("resetTransformsBtn"))
- self.gridLayout.addWidget(self.resetTransformsBtn, 3, 0, 1, 2)
- self.mirrorSelectionBtn = QtGui.QPushButton(self.canvasCtrlWidget)
- self.mirrorSelectionBtn.setObjectName(_fromUtf8("mirrorSelectionBtn"))
- self.gridLayout.addWidget(self.mirrorSelectionBtn, 4, 0, 1, 1)
- self.reflectSelectionBtn = QtGui.QPushButton(self.canvasCtrlWidget)
- self.reflectSelectionBtn.setObjectName(_fromUtf8("reflectSelectionBtn"))
- self.gridLayout.addWidget(self.reflectSelectionBtn, 4, 1, 1, 1)
- self.canvasItemCtrl = QtGui.QWidget(self.vsplitter)
- self.canvasItemCtrl.setObjectName(_fromUtf8("canvasItemCtrl"))
- self.ctrlLayout = QtGui.QGridLayout(self.canvasItemCtrl)
- self.ctrlLayout.setMargin(0)
- self.ctrlLayout.setSpacing(0)
- self.ctrlLayout.setObjectName(_fromUtf8("ctrlLayout"))
- self.gridLayout_2.addWidget(self.splitter, 0, 0, 1, 1)
-
- self.retranslateUi(Form)
- QtCore.QMetaObject.connectSlotsByName(Form)
-
- def retranslateUi(self, Form):
- Form.setWindowTitle(_translate("Form", "PyQtGraph", None))
- self.autoRangeBtn.setText(_translate("Form", "Auto Range", None))
- self.redirectCheck.setToolTip(_translate("Form", "Check to display all local items in a remote canvas.", None))
- self.redirectCheck.setText(_translate("Form", "Redirect", None))
- self.resetTransformsBtn.setText(_translate("Form", "Reset Transforms", None))
- self.mirrorSelectionBtn.setText(_translate("Form", "Mirror Selection", None))
- self.reflectSelectionBtn.setText(_translate("Form", "MirrorXY", None))
-
-from ..widgets.GraphicsView import GraphicsView
-from ..widgets.TreeWidget import TreeWidget
-from .CanvasManager import CanvasCombo
diff --git a/pyqtgraph/canvas/CanvasTemplate_pyside.py b/pyqtgraph/canvas/CanvasTemplate_pyqt6.py
similarity index 54%
rename from pyqtgraph/canvas/CanvasTemplate_pyside.py
rename to pyqtgraph/canvas/CanvasTemplate_pyqt6.py
index c728efac..79557936 100644
--- a/pyqtgraph/canvas/CanvasTemplate_pyside.py
+++ b/pyqtgraph/canvas/CanvasTemplate_pyqt6.py
@@ -1,47 +1,47 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file 'CanvasTemplate.ui'
+# Form implementation generated from reading ui file 'pyqtgraph\canvas\CanvasTemplate.ui'
#
-# Created: Fri Mar 24 16:09:39 2017
-# by: pyside-uic 0.2.15 running on PySide 1.2.2
+# Created by: PyQt6 UI code generator 6.0.0
#
-# WARNING! All changes made in this file will be lost!
+# 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
-from PySide import QtCore, QtGui
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(821, 578)
- self.gridLayout_2 = QtGui.QGridLayout(Form)
+ self.gridLayout_2 = QtWidgets.QGridLayout(Form)
self.gridLayout_2.setContentsMargins(0, 0, 0, 0)
self.gridLayout_2.setSpacing(0)
self.gridLayout_2.setObjectName("gridLayout_2")
- self.splitter = QtGui.QSplitter(Form)
- self.splitter.setOrientation(QtCore.Qt.Horizontal)
+ self.splitter = QtWidgets.QSplitter(Form)
+ self.splitter.setOrientation(QtCore.Qt.Orientations.Horizontal)
self.splitter.setObjectName("splitter")
self.view = GraphicsView(self.splitter)
self.view.setObjectName("view")
- self.vsplitter = QtGui.QSplitter(self.splitter)
- self.vsplitter.setOrientation(QtCore.Qt.Vertical)
+ self.vsplitter = QtWidgets.QSplitter(self.splitter)
+ self.vsplitter.setOrientation(QtCore.Qt.Orientations.Vertical)
self.vsplitter.setObjectName("vsplitter")
- self.canvasCtrlWidget = QtGui.QWidget(self.vsplitter)
+ self.canvasCtrlWidget = QtWidgets.QWidget(self.vsplitter)
self.canvasCtrlWidget.setObjectName("canvasCtrlWidget")
- self.gridLayout = QtGui.QGridLayout(self.canvasCtrlWidget)
+ self.gridLayout = QtWidgets.QGridLayout(self.canvasCtrlWidget)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
- self.autoRangeBtn = QtGui.QPushButton(self.canvasCtrlWidget)
- sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
+ self.autoRangeBtn = QtWidgets.QPushButton(self.canvasCtrlWidget)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(1)
sizePolicy.setHeightForWidth(self.autoRangeBtn.sizePolicy().hasHeightForWidth())
self.autoRangeBtn.setSizePolicy(sizePolicy)
self.autoRangeBtn.setObjectName("autoRangeBtn")
self.gridLayout.addWidget(self.autoRangeBtn, 0, 0, 1, 2)
- self.horizontalLayout = QtGui.QHBoxLayout()
+ self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setSpacing(0)
self.horizontalLayout.setObjectName("horizontalLayout")
- self.redirectCheck = QtGui.QCheckBox(self.canvasCtrlWidget)
+ self.redirectCheck = QtWidgets.QCheckBox(self.canvasCtrlWidget)
self.redirectCheck.setObjectName("redirectCheck")
self.horizontalLayout.addWidget(self.redirectCheck)
self.redirectCombo = CanvasCombo(self.canvasCtrlWidget)
@@ -49,7 +49,7 @@ class Ui_Form(object):
self.horizontalLayout.addWidget(self.redirectCombo)
self.gridLayout.addLayout(self.horizontalLayout, 1, 0, 1, 2)
self.itemList = TreeWidget(self.canvasCtrlWidget)
- sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(100)
sizePolicy.setHeightForWidth(self.itemList.sizePolicy().hasHeightForWidth())
@@ -58,21 +58,20 @@ class Ui_Form(object):
self.itemList.setObjectName("itemList")
self.itemList.headerItem().setText(0, "1")
self.gridLayout.addWidget(self.itemList, 2, 0, 1, 2)
- self.resetTransformsBtn = QtGui.QPushButton(self.canvasCtrlWidget)
+ self.resetTransformsBtn = QtWidgets.QPushButton(self.canvasCtrlWidget)
self.resetTransformsBtn.setObjectName("resetTransformsBtn")
self.gridLayout.addWidget(self.resetTransformsBtn, 3, 0, 1, 2)
- self.mirrorSelectionBtn = QtGui.QPushButton(self.canvasCtrlWidget)
+ self.mirrorSelectionBtn = QtWidgets.QPushButton(self.canvasCtrlWidget)
self.mirrorSelectionBtn.setObjectName("mirrorSelectionBtn")
self.gridLayout.addWidget(self.mirrorSelectionBtn, 4, 0, 1, 1)
- self.reflectSelectionBtn = QtGui.QPushButton(self.canvasCtrlWidget)
+ self.reflectSelectionBtn = QtWidgets.QPushButton(self.canvasCtrlWidget)
self.reflectSelectionBtn.setObjectName("reflectSelectionBtn")
self.gridLayout.addWidget(self.reflectSelectionBtn, 4, 1, 1, 1)
- self.canvasItemCtrl = QtGui.QWidget(self.vsplitter)
+ self.canvasItemCtrl = QtWidgets.QWidget(self.vsplitter)
self.canvasItemCtrl.setObjectName("canvasItemCtrl")
- self.ctrlLayout = QtGui.QGridLayout(self.canvasItemCtrl)
+ self.ctrlLayout = QtWidgets.QGridLayout(self.canvasItemCtrl)
self.ctrlLayout.setContentsMargins(0, 0, 0, 0)
self.ctrlLayout.setSpacing(0)
- self.ctrlLayout.setContentsMargins(0, 0, 0, 0)
self.ctrlLayout.setObjectName("ctrlLayout")
self.gridLayout_2.addWidget(self.splitter, 0, 0, 1, 1)
@@ -80,14 +79,14 @@ class Ui_Form(object):
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
- Form.setWindowTitle(QtGui.QApplication.translate("Form", "PyQtGraph", None, QtGui.QApplication.UnicodeUTF8))
- self.autoRangeBtn.setText(QtGui.QApplication.translate("Form", "Auto Range", None, QtGui.QApplication.UnicodeUTF8))
- self.redirectCheck.setToolTip(QtGui.QApplication.translate("Form", "Check to display all local items in a remote canvas.", None, QtGui.QApplication.UnicodeUTF8))
- self.redirectCheck.setText(QtGui.QApplication.translate("Form", "Redirect", None, QtGui.QApplication.UnicodeUTF8))
- self.resetTransformsBtn.setText(QtGui.QApplication.translate("Form", "Reset Transforms", None, QtGui.QApplication.UnicodeUTF8))
- self.mirrorSelectionBtn.setText(QtGui.QApplication.translate("Form", "Mirror Selection", None, QtGui.QApplication.UnicodeUTF8))
- self.reflectSelectionBtn.setText(QtGui.QApplication.translate("Form", "MirrorXY", None, QtGui.QApplication.UnicodeUTF8))
-
-from .CanvasManager import CanvasCombo
-from ..widgets.TreeWidget import TreeWidget
+ _translate = QtCore.QCoreApplication.translate
+ Form.setWindowTitle(_translate("Form", "PyQtGraph"))
+ self.autoRangeBtn.setText(_translate("Form", "Auto Range"))
+ self.redirectCheck.setToolTip(_translate("Form", "Check to display all local items in a remote canvas."))
+ self.redirectCheck.setText(_translate("Form", "Redirect"))
+ self.resetTransformsBtn.setText(_translate("Form", "Reset Transforms"))
+ self.mirrorSelectionBtn.setText(_translate("Form", "Mirror Selection"))
+ self.reflectSelectionBtn.setText(_translate("Form", "MirrorXY"))
from ..widgets.GraphicsView import GraphicsView
+from ..widgets.TreeWidget import TreeWidget
+from .CanvasManager import CanvasCombo
diff --git a/pyqtgraph/canvas/CanvasTemplate_pyside6.py b/pyqtgraph/canvas/CanvasTemplate_pyside6.py
new file mode 100644
index 00000000..a872510e
--- /dev/null
+++ b/pyqtgraph/canvas/CanvasTemplate_pyside6.py
@@ -0,0 +1,126 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'CanvasTemplate.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 ..widgets.TreeWidget import TreeWidget
+from ..widgets.GraphicsView import GraphicsView
+from .CanvasManager import CanvasCombo
+
+
+class Ui_Form(object):
+ def setupUi(self, Form):
+ if not Form.objectName():
+ Form.setObjectName(u"Form")
+ Form.resize(821, 578)
+ self.gridLayout_2 = QGridLayout(Form)
+ self.gridLayout_2.setSpacing(0)
+ self.gridLayout_2.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_2.setObjectName(u"gridLayout_2")
+ self.splitter = QSplitter(Form)
+ self.splitter.setObjectName(u"splitter")
+ self.splitter.setOrientation(Qt.Horizontal)
+ self.view = GraphicsView(self.splitter)
+ self.view.setObjectName(u"view")
+ self.splitter.addWidget(self.view)
+ self.vsplitter = QSplitter(self.splitter)
+ self.vsplitter.setObjectName(u"vsplitter")
+ self.vsplitter.setOrientation(Qt.Vertical)
+ self.canvasCtrlWidget = QWidget(self.vsplitter)
+ self.canvasCtrlWidget.setObjectName(u"canvasCtrlWidget")
+ self.gridLayout = QGridLayout(self.canvasCtrlWidget)
+ self.gridLayout.setObjectName(u"gridLayout")
+ self.autoRangeBtn = QPushButton(self.canvasCtrlWidget)
+ self.autoRangeBtn.setObjectName(u"autoRangeBtn")
+ sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(1)
+ sizePolicy.setHeightForWidth(self.autoRangeBtn.sizePolicy().hasHeightForWidth())
+ self.autoRangeBtn.setSizePolicy(sizePolicy)
+
+ self.gridLayout.addWidget(self.autoRangeBtn, 0, 0, 1, 2)
+
+ self.horizontalLayout = QHBoxLayout()
+ self.horizontalLayout.setSpacing(0)
+ self.horizontalLayout.setObjectName(u"horizontalLayout")
+ self.redirectCheck = QCheckBox(self.canvasCtrlWidget)
+ self.redirectCheck.setObjectName(u"redirectCheck")
+
+ self.horizontalLayout.addWidget(self.redirectCheck)
+
+ self.redirectCombo = CanvasCombo(self.canvasCtrlWidget)
+ self.redirectCombo.setObjectName(u"redirectCombo")
+
+ self.horizontalLayout.addWidget(self.redirectCombo)
+
+
+ self.gridLayout.addLayout(self.horizontalLayout, 1, 0, 1, 2)
+
+ self.itemList = TreeWidget(self.canvasCtrlWidget)
+ __qtreewidgetitem = QTreeWidgetItem()
+ __qtreewidgetitem.setText(0, u"1");
+ self.itemList.setHeaderItem(__qtreewidgetitem)
+ self.itemList.setObjectName(u"itemList")
+ sizePolicy1 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
+ sizePolicy1.setHorizontalStretch(0)
+ sizePolicy1.setVerticalStretch(100)
+ sizePolicy1.setHeightForWidth(self.itemList.sizePolicy().hasHeightForWidth())
+ self.itemList.setSizePolicy(sizePolicy1)
+ self.itemList.setHeaderHidden(True)
+
+ self.gridLayout.addWidget(self.itemList, 2, 0, 1, 2)
+
+ self.resetTransformsBtn = QPushButton(self.canvasCtrlWidget)
+ self.resetTransformsBtn.setObjectName(u"resetTransformsBtn")
+
+ self.gridLayout.addWidget(self.resetTransformsBtn, 3, 0, 1, 2)
+
+ self.mirrorSelectionBtn = QPushButton(self.canvasCtrlWidget)
+ self.mirrorSelectionBtn.setObjectName(u"mirrorSelectionBtn")
+
+ self.gridLayout.addWidget(self.mirrorSelectionBtn, 4, 0, 1, 1)
+
+ self.reflectSelectionBtn = QPushButton(self.canvasCtrlWidget)
+ self.reflectSelectionBtn.setObjectName(u"reflectSelectionBtn")
+
+ self.gridLayout.addWidget(self.reflectSelectionBtn, 4, 1, 1, 1)
+
+ self.vsplitter.addWidget(self.canvasCtrlWidget)
+ self.canvasItemCtrl = QWidget(self.vsplitter)
+ self.canvasItemCtrl.setObjectName(u"canvasItemCtrl")
+ self.ctrlLayout = QGridLayout(self.canvasItemCtrl)
+ self.ctrlLayout.setSpacing(0)
+ self.ctrlLayout.setContentsMargins(0, 0, 0, 0)
+ self.ctrlLayout.setObjectName(u"ctrlLayout")
+ self.vsplitter.addWidget(self.canvasItemCtrl)
+ self.splitter.addWidget(self.vsplitter)
+
+ self.gridLayout_2.addWidget(self.splitter, 0, 0, 1, 1)
+
+
+ self.retranslateUi(Form)
+
+ QMetaObject.connectSlotsByName(Form)
+ # setupUi
+
+ def retranslateUi(self, Form):
+ Form.setWindowTitle(QCoreApplication.translate("Form", u"PyQtGraph", None))
+ self.autoRangeBtn.setText(QCoreApplication.translate("Form", u"Auto Range", None))
+#if QT_CONFIG(tooltip)
+ self.redirectCheck.setToolTip(QCoreApplication.translate("Form", u"Check to display all local items in a remote canvas.", None))
+#endif // QT_CONFIG(tooltip)
+ self.redirectCheck.setText(QCoreApplication.translate("Form", u"Redirect", None))
+ self.resetTransformsBtn.setText(QCoreApplication.translate("Form", u"Reset Transforms", None))
+ self.mirrorSelectionBtn.setText(QCoreApplication.translate("Form", u"Mirror Selection", None))
+ self.reflectSelectionBtn.setText(QCoreApplication.translate("Form", u"MirrorXY", None))
+ # retranslateUi
+
diff --git a/pyqtgraph/canvas/TransformGuiTemplate_pyqt.py b/pyqtgraph/canvas/TransformGuiTemplate_pyqt.py
deleted file mode 100644
index 7cbb3652..00000000
--- a/pyqtgraph/canvas/TransformGuiTemplate_pyqt.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file 'pyqtgraph/canvas/TransformGuiTemplate.ui'
-#
-# Created by: PyQt4 UI code generator 4.11.4
-#
-# WARNING! All changes made in this file will be lost!
-
-from PyQt4 import QtCore, QtGui
-
-try:
- _fromUtf8 = QtCore.QString.fromUtf8
-except AttributeError:
- def _fromUtf8(s):
- return s
-
-try:
- _encoding = QtGui.QApplication.UnicodeUTF8
- def _translate(context, text, disambig):
- return QtGui.QApplication.translate(context, text, disambig, _encoding)
-except AttributeError:
- def _translate(context, text, disambig):
- return QtGui.QApplication.translate(context, text, disambig)
-
-class Ui_Form(object):
- def setupUi(self, Form):
- Form.setObjectName(_fromUtf8("Form"))
- Form.resize(224, 117)
- sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(Form.sizePolicy().hasHeightForWidth())
- Form.setSizePolicy(sizePolicy)
- self.verticalLayout = QtGui.QVBoxLayout(Form)
- self.verticalLayout.setMargin(0)
- self.verticalLayout.setSpacing(1)
- self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
- self.translateLabel = QtGui.QLabel(Form)
- self.translateLabel.setObjectName(_fromUtf8("translateLabel"))
- self.verticalLayout.addWidget(self.translateLabel)
- self.rotateLabel = QtGui.QLabel(Form)
- self.rotateLabel.setObjectName(_fromUtf8("rotateLabel"))
- self.verticalLayout.addWidget(self.rotateLabel)
- self.scaleLabel = QtGui.QLabel(Form)
- self.scaleLabel.setObjectName(_fromUtf8("scaleLabel"))
- self.verticalLayout.addWidget(self.scaleLabel)
- self.horizontalLayout = QtGui.QHBoxLayout()
- self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
- self.mirrorImageBtn = QtGui.QPushButton(Form)
- self.mirrorImageBtn.setToolTip(_fromUtf8(""))
- self.mirrorImageBtn.setObjectName(_fromUtf8("mirrorImageBtn"))
- self.horizontalLayout.addWidget(self.mirrorImageBtn)
- self.reflectImageBtn = QtGui.QPushButton(Form)
- self.reflectImageBtn.setObjectName(_fromUtf8("reflectImageBtn"))
- self.horizontalLayout.addWidget(self.reflectImageBtn)
- self.verticalLayout.addLayout(self.horizontalLayout)
-
- self.retranslateUi(Form)
- QtCore.QMetaObject.connectSlotsByName(Form)
-
- def retranslateUi(self, Form):
- Form.setWindowTitle(_translate("Form", "PyQtGraph", None))
- self.translateLabel.setText(_translate("Form", "Translate:", None))
- self.rotateLabel.setText(_translate("Form", "Rotate:", None))
- self.scaleLabel.setText(_translate("Form", "Scale:", None))
- self.mirrorImageBtn.setText(_translate("Form", "Mirror", None))
- self.reflectImageBtn.setText(_translate("Form", "Reflect", None))
-
diff --git a/pyqtgraph/canvas/TransformGuiTemplate_pyqt6.py b/pyqtgraph/canvas/TransformGuiTemplate_pyqt6.py
new file mode 100644
index 00000000..4b0d9880
--- /dev/null
+++ b/pyqtgraph/canvas/TransformGuiTemplate_pyqt6.py
@@ -0,0 +1,55 @@
+# Form implementation generated from reading ui file 'pyqtgraph\canvas\TransformGuiTemplate.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(224, 117)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(Form.sizePolicy().hasHeightForWidth())
+ Form.setSizePolicy(sizePolicy)
+ self.verticalLayout = QtWidgets.QVBoxLayout(Form)
+ self.verticalLayout.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout.setSpacing(1)
+ self.verticalLayout.setObjectName("verticalLayout")
+ self.translateLabel = QtWidgets.QLabel(Form)
+ self.translateLabel.setObjectName("translateLabel")
+ self.verticalLayout.addWidget(self.translateLabel)
+ self.rotateLabel = QtWidgets.QLabel(Form)
+ self.rotateLabel.setObjectName("rotateLabel")
+ self.verticalLayout.addWidget(self.rotateLabel)
+ self.scaleLabel = QtWidgets.QLabel(Form)
+ self.scaleLabel.setObjectName("scaleLabel")
+ self.verticalLayout.addWidget(self.scaleLabel)
+ self.horizontalLayout = QtWidgets.QHBoxLayout()
+ self.horizontalLayout.setObjectName("horizontalLayout")
+ self.mirrorImageBtn = QtWidgets.QPushButton(Form)
+ self.mirrorImageBtn.setToolTip("")
+ self.mirrorImageBtn.setObjectName("mirrorImageBtn")
+ self.horizontalLayout.addWidget(self.mirrorImageBtn)
+ self.reflectImageBtn = QtWidgets.QPushButton(Form)
+ self.reflectImageBtn.setObjectName("reflectImageBtn")
+ self.horizontalLayout.addWidget(self.reflectImageBtn)
+ self.verticalLayout.addLayout(self.horizontalLayout)
+
+ self.retranslateUi(Form)
+ QtCore.QMetaObject.connectSlotsByName(Form)
+
+ def retranslateUi(self, Form):
+ _translate = QtCore.QCoreApplication.translate
+ Form.setWindowTitle(_translate("Form", "PyQtGraph"))
+ self.translateLabel.setText(_translate("Form", "Translate:"))
+ self.rotateLabel.setText(_translate("Form", "Rotate:"))
+ self.scaleLabel.setText(_translate("Form", "Scale:"))
+ self.mirrorImageBtn.setText(_translate("Form", "Mirror"))
+ self.reflectImageBtn.setText(_translate("Form", "Reflect"))
diff --git a/pyqtgraph/canvas/TransformGuiTemplate_pyside.py b/pyqtgraph/canvas/TransformGuiTemplate_pyside.py
deleted file mode 100644
index 76620342..00000000
--- a/pyqtgraph/canvas/TransformGuiTemplate_pyside.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file 'pyqtgraph/canvas/TransformGuiTemplate.ui'
-#
-# Created: Wed Nov 9 17:57:16 2016
-# by: pyside-uic 0.2.15 running on PySide 1.2.2
-#
-# WARNING! All changes made in this file will be lost!
-
-from PySide import QtCore, QtGui
-
-class Ui_Form(object):
- def setupUi(self, Form):
- Form.setObjectName("Form")
- Form.resize(224, 117)
- sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(Form.sizePolicy().hasHeightForWidth())
- Form.setSizePolicy(sizePolicy)
- self.verticalLayout = QtGui.QVBoxLayout(Form)
- self.verticalLayout.setSpacing(1)
- self.verticalLayout.setContentsMargins(0, 0, 0, 0)
- self.verticalLayout.setObjectName("verticalLayout")
- self.translateLabel = QtGui.QLabel(Form)
- self.translateLabel.setObjectName("translateLabel")
- self.verticalLayout.addWidget(self.translateLabel)
- self.rotateLabel = QtGui.QLabel(Form)
- self.rotateLabel.setObjectName("rotateLabel")
- self.verticalLayout.addWidget(self.rotateLabel)
- self.scaleLabel = QtGui.QLabel(Form)
- self.scaleLabel.setObjectName("scaleLabel")
- self.verticalLayout.addWidget(self.scaleLabel)
- self.horizontalLayout = QtGui.QHBoxLayout()
- self.horizontalLayout.setObjectName("horizontalLayout")
- self.mirrorImageBtn = QtGui.QPushButton(Form)
- self.mirrorImageBtn.setToolTip("")
- self.mirrorImageBtn.setObjectName("mirrorImageBtn")
- self.horizontalLayout.addWidget(self.mirrorImageBtn)
- self.reflectImageBtn = QtGui.QPushButton(Form)
- self.reflectImageBtn.setObjectName("reflectImageBtn")
- self.horizontalLayout.addWidget(self.reflectImageBtn)
- self.verticalLayout.addLayout(self.horizontalLayout)
-
- self.retranslateUi(Form)
- QtCore.QMetaObject.connectSlotsByName(Form)
-
- def retranslateUi(self, Form):
- Form.setWindowTitle(QtGui.QApplication.translate("Form", "PyQtGraph", None, QtGui.QApplication.UnicodeUTF8))
- self.translateLabel.setText(QtGui.QApplication.translate("Form", "Translate:", None, QtGui.QApplication.UnicodeUTF8))
- self.rotateLabel.setText(QtGui.QApplication.translate("Form", "Rotate:", None, QtGui.QApplication.UnicodeUTF8))
- self.scaleLabel.setText(QtGui.QApplication.translate("Form", "Scale:", None, QtGui.QApplication.UnicodeUTF8))
- self.mirrorImageBtn.setText(QtGui.QApplication.translate("Form", "Mirror", None, QtGui.QApplication.UnicodeUTF8))
- self.reflectImageBtn.setText(QtGui.QApplication.translate("Form", "Reflect", None, QtGui.QApplication.UnicodeUTF8))
-
diff --git a/pyqtgraph/canvas/TransformGuiTemplate_pyside6.py b/pyqtgraph/canvas/TransformGuiTemplate_pyside6.py
new file mode 100644
index 00000000..5ec15bd1
--- /dev/null
+++ b/pyqtgraph/canvas/TransformGuiTemplate_pyside6.py
@@ -0,0 +1,77 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'TransformGuiTemplate.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 *
+
+
+class Ui_Form(object):
+ def setupUi(self, Form):
+ if not Form.objectName():
+ Form.setObjectName(u"Form")
+ Form.resize(224, 117)
+ sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(0)
+ sizePolicy.setHeightForWidth(Form.sizePolicy().hasHeightForWidth())
+ Form.setSizePolicy(sizePolicy)
+ self.verticalLayout = QVBoxLayout(Form)
+ self.verticalLayout.setSpacing(1)
+ self.verticalLayout.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout.setObjectName(u"verticalLayout")
+ self.translateLabel = QLabel(Form)
+ self.translateLabel.setObjectName(u"translateLabel")
+
+ self.verticalLayout.addWidget(self.translateLabel)
+
+ self.rotateLabel = QLabel(Form)
+ self.rotateLabel.setObjectName(u"rotateLabel")
+
+ self.verticalLayout.addWidget(self.rotateLabel)
+
+ self.scaleLabel = QLabel(Form)
+ self.scaleLabel.setObjectName(u"scaleLabel")
+
+ self.verticalLayout.addWidget(self.scaleLabel)
+
+ self.horizontalLayout = QHBoxLayout()
+ self.horizontalLayout.setObjectName(u"horizontalLayout")
+ self.mirrorImageBtn = QPushButton(Form)
+ self.mirrorImageBtn.setObjectName(u"mirrorImageBtn")
+
+ self.horizontalLayout.addWidget(self.mirrorImageBtn)
+
+ self.reflectImageBtn = QPushButton(Form)
+ self.reflectImageBtn.setObjectName(u"reflectImageBtn")
+
+ self.horizontalLayout.addWidget(self.reflectImageBtn)
+
+
+ self.verticalLayout.addLayout(self.horizontalLayout)
+
+
+ self.retranslateUi(Form)
+
+ QMetaObject.connectSlotsByName(Form)
+ # setupUi
+
+ def retranslateUi(self, Form):
+ Form.setWindowTitle(QCoreApplication.translate("Form", u"PyQtGraph", None))
+ self.translateLabel.setText(QCoreApplication.translate("Form", u"Translate:", None))
+ self.rotateLabel.setText(QCoreApplication.translate("Form", u"Rotate:", None))
+ self.scaleLabel.setText(QCoreApplication.translate("Form", u"Scale:", None))
+#if QT_CONFIG(tooltip)
+ self.mirrorImageBtn.setToolTip("")
+#endif // QT_CONFIG(tooltip)
+ self.mirrorImageBtn.setText(QCoreApplication.translate("Form", u"Mirror", None))
+ self.reflectImageBtn.setText(QCoreApplication.translate("Form", u"Reflect", None))
+ # retranslateUi
+
diff --git a/pyqtgraph/colormap.py b/pyqtgraph/colormap.py
index b34264d4..2ca414a8 100644
--- a/pyqtgraph/colormap.py
+++ b/pyqtgraph/colormap.py
@@ -2,6 +2,180 @@ import numpy as np
from .Qt import QtGui, QtCore
from .python2_3 import basestring
from .functions import mkColor, eq
+from os import path, listdir
+import collections
+
+_mapCache = {}
+
+def listMaps(source=None):
+ """
+ Warning, highly experimental, subject to change.
+
+ List available color maps
+ =============== =================================================================
+ **Arguments:**
+ source 'matplotlib' lists maps that can be imported from MatPlotLib
+ 'colorcet' lists maps that can be imported from ColorCET
+ otherwise local maps are listed
+ =============== =================================================================
+ """
+ if source is None:
+ pathname = path.join(path.dirname(__file__), 'colors','maps')
+ files = listdir( pathname )
+ list_of_maps = []
+ for filename in files:
+ if filename[-4:] == '.csv':
+ list_of_maps.append(filename[:-4])
+ return list_of_maps
+ elif source.lower() == 'matplotlib':
+ try:
+ import matplotlib.pyplot as mpl_plt
+ list_of_maps = mpl_plt.colormaps()
+ return list_of_maps
+ except ModuleNotFoundError:
+ return []
+ elif source.lower() == 'colorcet':
+ try:
+ import colorcet
+ list_of_maps = list( colorcet.palette.keys() )
+ list_of_maps.sort()
+ return list_of_maps
+ except ModuleNotFoundError:
+ return []
+ return []
+
+
+def get(name, source=None, skipCache=False):
+ """
+ Warning, highly experimental, subject to change.
+
+ Returns a ColorMap object from a local definition or imported from another library
+ =============== =================================================================
+ **Arguments:**
+ name Name of color map. Can be a path to a defining file.
+ source 'matplotlib' imports a map defined by Matplotlib
+ 'colorcet' imports a maps defined by ColorCET
+ otherwise local data is used
+ =============== =================================================================
+ """
+ if not skipCache and name in _mapCache:
+ return _mapCache[name]
+ if source is None:
+ return _get_from_file(name)
+ elif source == 'matplotlib':
+ return _get_from_matplotlib(name)
+ elif source == 'colorcet':
+ return _get_from_colorcet(name)
+ return None
+
+def _get_from_file(name):
+ filename = name
+ if filename[0] !='.': # load from built-in directory
+ dirname = path.dirname(__file__)
+ filename = path.join(dirname, 'colors/maps/'+filename)
+ if not path.isfile( filename ): # try suffixes if file is not found:
+ if path.isfile( filename+'.csv' ): filename += '.csv'
+ elif path.isfile( filename+'.txt' ): filename += '.txt'
+ with open(filename,'r') as fh:
+ idx = 0
+ color_list = []
+ if filename[-4:].lower() != '.txt':
+ csv_mode = True
+ else:
+ csv_mode = False
+ for line in fh:
+ name = None
+ line = line.strip()
+ if len(line) == 0: continue # empty line
+ if line[0] == ';': continue # comment
+ parts = line.split(sep=';', maxsplit=1) # split into color and names/comments
+ if csv_mode:
+ comp = parts[0].split(',')
+ if len( comp ) < 3: continue # not enough components given
+ color_tuple = tuple( [ int(255*float(c)+0.5) for c in comp ] )
+ else:
+ hex_str = parts[0]
+ if hex_str[0] == '#':
+ hex_str = hex_str[1:] # strip leading #
+ if len(hex_str) < 3: continue # not enough information
+ if len(hex_str) == 3: # parse as abbreviated RGB
+ hex_str = 2*hex_str[0] + 2*hex_str[1] + 2*hex_str[2]
+ elif len(hex_str) == 4: # parse as abbreviated RGBA
+ hex_str = 2*hex_str[0] + 2*hex_str[1] + 2*hex_str[2] + 2*hex_str[3]
+ if len(hex_str) < 6: continue # not enough information
+ color_tuple = tuple( bytes.fromhex( hex_str ) )
+ color_list.append( color_tuple )
+ idx += 1
+ # end of line reading loop
+ # end of open
+ cm = ColorMap(
+ pos=np.linspace(0.0, 1.0, len(color_list)),
+ color=color_list) #, names=color_names)
+ _mapCache[name] = cm
+ return cm
+
+def _get_from_matplotlib(name):
+ """ import colormap from matplotlib definition """
+ # inspired and informed by "mpl_cmaps_in_ImageItem.py", published by Sebastian Hoefer at
+ # https://github.com/honkomonk/pyqtgraph_sandbox/blob/master/mpl_cmaps_in_ImageItem.py
+ try:
+ import matplotlib.pyplot as mpl_plt
+ except ModuleNotFoundError:
+ return None
+ cm = None
+ col_map = mpl_plt.get_cmap(name)
+ if hasattr(col_map, '_segmentdata'): # handle LinearSegmentedColormap
+ data = col_map._segmentdata
+ if ('red' in data) and isinstance(data['red'], collections.Sequence):
+ positions = set() # super-set of handle positions in individual channels
+ for key in ['red','green','blue']:
+ for tup in data[key]:
+ positions.add(tup[0])
+ col_data = np.zeros((len(positions),4 ))
+ col_data[:,-1] = sorted(positions)
+ for idx, key in enumerate(['red','green','blue']):
+ positions = np.zeros( len(data[key] ) )
+ comp_vals = np.zeros( len(data[key] ) )
+ for idx2, tup in enumerate( data[key] ):
+ positions[idx2] = tup[0]
+ comp_vals[idx2] = tup[1] # these are sorted in the raw data
+ col_data[:,idx] = np.interp(col_data[:,3], positions, comp_vals)
+ cm = ColorMap(pos=col_data[:,-1], color=255*col_data[:,:3]+0.5)
+ # some color maps (gnuplot in particular) are defined by RGB component functions:
+ elif ('red' in data) and isinstance(data['red'], collections.Callable):
+ col_data = np.zeros((64, 4))
+ col_data[:,-1] = np.linspace(0., 1., 64)
+ for idx, key in enumerate(['red','green','blue']):
+ col_data[:,idx] = np.clip( data[key](col_data[:,-1]), 0, 1)
+ cm = ColorMap(pos=col_data[:,-1], color=255*col_data[:,:3]+0.5)
+ elif hasattr(col_map, 'colors'): # handle ListedColormap
+ col_data = np.array(col_map.colors)
+ cm = ColorMap(pos=np.linspace(0.0, 1.0, col_data.shape[0]), color=255*col_data[:,:3]+0.5 )
+ if cm is not None:
+ _mapCache[name] = cm
+ return cm
+
+def _get_from_colorcet(name):
+ """ import colormap from colorcet definition """
+ try:
+ import colorcet
+ except ModuleNotFoundError:
+ return None
+ color_strings = colorcet.palette[name]
+ color_list = []
+ for hex_str in color_strings:
+ if hex_str[0] != '#': continue
+ if len(hex_str) != 7:
+ raise ValueError('Invalid color string '+str(hex_str)+' in colorcet import.')
+ color_tuple = tuple( bytes.fromhex( hex_str[1:] ) )
+ color_list.append( color_tuple )
+ if len(color_list) == 0:
+ return None
+ cm = ColorMap(
+ pos=np.linspace(0.0, 1.0, len(color_list)),
+ color=color_list) #, names=color_names)
+ _mapCache[name] = cm
+ return cm
class ColorMap(object):
@@ -9,52 +183,51 @@ class ColorMap(object):
A ColorMap defines a relationship between a scalar value and a range of colors.
ColorMaps are commonly used for false-coloring monochromatic images, coloring
scatter-plot points, and coloring surface plots by height.
-
+
Each color map is defined by a set of colors, each corresponding to a
particular scalar value. For example:
-
+
| 0.0 -> black
| 0.2 -> red
| 0.6 -> yellow
| 1.0 -> white
-
+
The colors for intermediate values are determined by interpolating between
the two nearest colors in either RGB or HSV color space.
-
+
To provide user-defined color mappings, see :class:`GradientWidget `.
"""
-
-
+
## color interpolation modes
RGB = 1
HSV_POS = 2
HSV_NEG = 3
-
- ## boundary modes
- CLIP = 1
+
+ ## mapping modes
+ CLIP = 1
REPEAT = 2
MIRROR = 3
-
+ DIVERGING = 4
+
## return types
BYTE = 1
FLOAT = 2
QCOLOR = 3
-
+
enumMap = {
'rgb': RGB,
- 'hsv+': HSV_POS,
- 'hsv-': HSV_NEG,
- 'clip': CLIP,
- 'repeat': REPEAT,
- 'mirror': MIRROR,
+ # 'hsv+': HSV_POS,
+ # 'hsv-': HSV_NEG,
+ # 'clip': CLIP,
+ # 'repeat': REPEAT,
'byte': BYTE,
'float': FLOAT,
'qcolor': QCOLOR,
}
-
- def __init__(self, pos, color, mode=None):
+
+ def __init__(self, pos, color, mode=None, mapping=None): #, names=None):
"""
- =============== ==============================================================
+ =============== =================================================================
**Arguments:**
pos Array of positions where each color is defined
color Array of colors.
@@ -64,7 +237,13 @@ class ColorMap(object):
indicating the color space that should be used when
interpolating between stops. Note that the last mode value is
ignored. By default, the mode is entirely RGB.
- =============== ==============================================================
+ mapping Mapping mode (ColorMap.CLIP, REPEAT, MIRROR, or DIVERGING)
+ controlling mapping of relative index to color.
+ CLIP maps colors to [0.0;1.0]
+ REPEAT maps colors to repeating intervals [0.0;1.0];[1.0-2.0],...
+ MIRROR maps colors to [0.0;-1.0] and [0.0;+1.0] identically
+ DIVERGING maps colors to [-1.0;+1.0]
+ =============== =================================================================
"""
self.pos = np.array(pos)
order = np.argsort(self.pos)
@@ -77,15 +256,38 @@ class ColorMap(object):
if mode is None:
mode = np.ones(len(pos))
self.mode = mode
- self.stopsCache = {}
+
+ if mapping is None:
+ self.mapping_mode = self.CLIP
+ elif mapping == self.REPEAT:
+ self.mapping_mode = self.REPEAT
+ elif mapping == self.DIVERGING:
+ self.mapping_mode = self.DIVERGING
+ elif mapping == self.MIRROR:
+ self.mapping_mode = self.MIRROR
+ else:
+ self.mapping_mode = self.CLIP
+ self.stopsCache = {}
+
+ def __getitem__(self, key):
+ """ Convenient shorthand access to palette colors """
+ if isinstance(key, int): # access by color index
+ return self.getByIndex(key)
+ # otherwise access by map
+ try: # accept any numerical format that converts to float
+ float_idx = float(key)
+ return self.mapToQColor(float_idx)
+ except ValueError: pass
+ return None
+
def map(self, data, mode='byte'):
"""
Return an array of colors corresponding to the values in *data*.
Data must be either a scalar position or an array (any shape) of positions.
The *mode* argument determines the type of data returned:
-
+
=========== ===============================================================
byte (default) Values are returned as 0-255 unsigned bytes.
float Values are returned as 0.0-1.0 floats.
@@ -99,10 +301,7 @@ class ColorMap(object):
pos, color = self.getStops(self.BYTE)
else:
pos, color = self.getStops(mode)
-
- # don't need this--np.interp takes care of it.
- #data = np.clip(data, pos.min(), pos.max())
-
+
# Interpolate
# TODO: is griddata faster?
# interp = scipy.interpolate.griddata(pos, color, data)
@@ -112,6 +311,15 @@ class ColorMap(object):
if not isinstance(data, np.ndarray):
data = np.array(data)
interp = np.empty(data.shape + (color.shape[1],), dtype=color.dtype)
+
+ if self.mapping_mode != self.CLIP:
+ if self.mapping_mode == self.REPEAT:
+ data = data % 1.0
+ elif self.mapping_mode == self.DIVERGING:
+ data = (data/2)+0.5
+ elif self.mapping_mode == self.MIRROR:
+ data = abs(data)
+
for i in range(color.shape[1]):
interp[...,i] = np.interp(data, pos, color[:,i])
@@ -135,7 +343,11 @@ class ColorMap(object):
def mapToFloat(self, data):
"""Convenience function; see :func:`map() `."""
return self.map(data, mode=self.FLOAT)
-
+
+ def getByIndex(self, idx):
+ """Retrieve palette QColor by index"""
+ return QtGui.QColor( *self.color[idx] )
+
def getGradient(self, p1=None, p2=None):
"""Return a QLinearGradient object spanning from QPoints p1 to p2."""
if p1 == None:
@@ -147,25 +359,8 @@ class ColorMap(object):
pos, color = self.getStops(mode=self.BYTE)
color = [QtGui.QColor(*x) for x in color]
g.setStops(list(zip(pos, color)))
-
- #if self.colorMode == 'rgb':
- #ticks = self.listTicks()
- #g.setStops([(x, QtGui.QColor(t.color)) for t,x in ticks])
- #elif self.colorMode == 'hsv': ## HSV mode is approximated for display by interpolating 10 points between each stop
- #ticks = self.listTicks()
- #stops = []
- #stops.append((ticks[0][1], ticks[0][0].color))
- #for i in range(1,len(ticks)):
- #x1 = ticks[i-1][1]
- #x2 = ticks[i][1]
- #dx = (x2-x1) / 10.
- #for j in range(1,10):
- #x = x1 + dx*j
- #stops.append((x, self.getColor(x)))
- #stops.append((x2, self.getColor(x2)))
- #g.setStops(stops)
return g
-
+
def getColors(self, mode=None):
"""Return list of all color stops converted to the specified mode.
If mode is None, then no conversion is done."""
@@ -182,7 +377,7 @@ class ColorMap(object):
color = [QtGui.QColor(*x) for x in color]
return color
-
+
def getStops(self, mode):
## Get fully-expanded set of RGBA stops in either float or byte mode.
if mode not in self.stopsCache:
@@ -193,19 +388,9 @@ class ColorMap(object):
color = color.astype(float) / 255.
## to support HSV mode, we need to do a little more work..
- #stops = []
- #for i in range(len(self.pos)):
- #pos = self.pos[i]
- #color = color[i]
-
- #imode = self.mode[i]
- #if imode == self.RGB:
- #stops.append((x,color))
- #else:
- #ns =
self.stopsCache[mode] = (self.pos, color)
return self.stopsCache[mode]
-
+
def getLookupTable(self, start=0.0, stop=1.0, nPts=512, alpha=None, mode='byte'):
"""
Return an RGB(A) lookup table (ndarray).
@@ -223,23 +408,23 @@ class ColorMap(object):
"""
if isinstance(mode, basestring):
mode = self.enumMap[mode.lower()]
-
+
if alpha is None:
alpha = self.usesAlpha()
-
+
x = np.linspace(start, stop, nPts)
table = self.map(x, mode)
-
+
if not alpha and mode != self.QCOLOR:
return table[:,:3]
else:
return table
-
+
def usesAlpha(self):
"""Return True if any stops have an alpha < 255"""
max = 1.0 if self.color.dtype.kind == 'f' else 255
return np.any(self.color[:,3] != max)
-
+
def isMapTrivial(self):
"""
Return True if the gradient has exactly two stops in it: black at 0.0 and white at 1.0.
diff --git a/pyqtgraph/colors/maps/CC-BY license - applies to CET color map data.txt b/pyqtgraph/colors/maps/CC-BY license - applies to CET color map data.txt
new file mode 100644
index 00000000..36790535
--- /dev/null
+++ b/pyqtgraph/colors/maps/CC-BY license - applies to CET color map data.txt
@@ -0,0 +1,250 @@
+Creative Commons Attribution 4.0 International Public License (CC-BY)
+
+ By exercising the Licensed Rights (defined below), You accept and agree
+ to be bound by the terms and conditions of this Creative Commons
+ Attribution 4.0 International Public License ("Public License"). To the
+ extent this Public License may be interpreted as a contract, You are
+ granted the Licensed Rights in consideration of Your acceptance of
+ these terms and conditions, and the Licensor grants You such rights in
+ consideration of benefits the Licensor receives from making the
+ Licensed Material available under these terms and conditions.
+
+ Section 1 - Definitions.
+ a. Adapted Material means material subject to Copyright and Similar
+ Rights that is derived from or based upon the Licensed Material and
+ in which the Licensed Material is translated, altered, arranged,
+ transformed, or otherwise modified in a manner requiring permission
+ under the Copyright and Similar Rights held by the Licensor. For
+ purposes of this Public License, where the Licensed Material is a
+ musical work, performance, or sound recording, Adapted Material is
+ always produced where the Licensed Material is synched in timed
+ relation with a moving image.
+ b. Adapter's License means the license You apply to Your Copyright and
+ Similar Rights in Your contributions to Adapted Material in
+ accordance with the terms and conditions of this Public License.
+ c. Copyright and Similar Rights means copyright and/or similar rights
+ closely related to copyright including, without limitation,
+ performance, broadcast, sound recording, and Sui Generis Database
+ Rights, without regard to how the rights are labeled or
+ categorized. For purposes of this Public License, the rights
+ specified in Section [5]2(b)(1)-(2) are not Copyright and Similar
+ Rights.
+ d. Effective Technological Measures means those measures that, in the
+ absence of proper authority, may not be circumvented under laws
+ fulfilling obligations under Article 11 of the WIPO Copyright
+ Treaty adopted on December 20, 1996, and/or similar international
+ agreements.
+ e. Exceptions and Limitations means fair use, fair dealing, and/or any
+ other exception or limitation to Copyright and Similar Rights that
+ applies to Your use of the Licensed Material.
+ f. Licensed Material means the artistic or literary work, database, or
+ other material to which the Licensor applied this Public License.
+ g. Licensed Rights means the rights granted to You subject to the
+ terms and conditions of this Public License, which are limited to
+ all Copyright and Similar Rights that apply to Your use of the
+ Licensed Material and that the Licensor has authority to license.
+ h. Licensor means the individual(s) or entity(ies) granting rights
+ under this Public License.
+ i. Share means to provide material to the public by any means or
+ process that requires permission under the Licensed Rights, such as
+ reproduction, public display, public performance, distribution,
+ dissemination, communication, or importation, and to make material
+ available to the public including in ways that members of the
+ public may access the material from a place and at a time
+ individually chosen by them.
+ j. Sui Generis Database Rights means rights other than copyright
+ resulting from Directive 96/9/EC of the European Parliament and of
+ the Council of 11 March 1996 on the legal protection of databases,
+ as amended and/or succeeded, as well as other essentially
+ equivalent rights anywhere in the world.
+ k. You means the individual or entity exercising the Licensed Rights
+ under this Public License. Your has a corresponding meaning.
+
+ Section 2 - Scope.
+ a. License grant.
+ 1. Subject to the terms and conditions of this Public License,
+ the Licensor hereby grants You a worldwide, royalty-free,
+ non-sublicensable, non-exclusive, irrevocable license to
+ exercise the Licensed Rights in the Licensed Material to:
+ A. reproduce and Share the Licensed Material, in whole or in
+ part; and
+ B. produce, reproduce, and Share Adapted Material.
+ 2. Exceptions and Limitations. For the avoidance of doubt, where
+ Exceptions and Limitations apply to Your use, this Public
+ License does not apply, and You do not need to comply with its
+ terms and conditions.
+ 3. Term. The term of this Public License is specified in Section
+ [6]6(a).
+ 4. Media and formats; technical modifications allowed. The
+ Licensor authorizes You to exercise the Licensed Rights in all
+ media and formats whether now known or hereafter created, and
+ to make technical modifications necessary to do so. The
+ Licensor waives and/or agrees not to assert any right or
+ authority to forbid You from making technical modifications
+ necessary to exercise the Licensed Rights, including technical
+ modifications necessary to circumvent Effective Technological
+ Measures. For purposes of this Public License, simply making
+ modifications authorized by this Section [7]2(a)(4) never
+ produces Adapted Material.
+ 5. Downstream recipients.
+ A. Offer from the Licensor - Licensed Material. Every
+ recipient of the Licensed Material automatically receives
+ an offer from the Licensor to exercise the Licensed
+ Rights under the terms and conditions of this Public
+ License.
+ B. No downstream restrictions. You may not offer or impose
+ any additional or different terms or conditions on, or
+ apply any Effective Technological Measures to, the
+ Licensed Material if doing so restricts exercise of the
+ Licensed Rights by any recipient of the Licensed
+ Material.
+ 6. No endorsement. Nothing in this Public License constitutes or
+ may be construed as permission to assert or imply that You
+ are, or that Your use of the Licensed Material is, connected
+ with, or sponsored, endorsed, or granted official status by,
+ the Licensor or others designated to receive attribution as
+ provided in Section [8]3(a)(1)(A)(i).
+ b. Other rights.
+ 1. Moral rights, such as the right of integrity, are not licensed
+ under this Public License, nor are publicity, privacy, and/or
+ other similar personality rights; however, to the extent
+ possible, the Licensor waives and/or agrees not to assert any
+ such rights held by the Licensor to the limited extent
+ necessary to allow You to exercise the Licensed Rights, but
+ not otherwise.
+ 2. Patent and trademark rights are not licensed under this Public
+ License.
+ 3. To the extent possible, the Licensor waives any right to
+ collect royalties from You for the exercise of the Licensed
+ Rights, whether directly or through a collecting society under
+ any voluntary or waivable statutory or compulsory licensing
+ scheme. In all other cases the Licensor expressly reserves any
+ right to collect such royalties.
+
+ Section 3 - License Conditions.
+
+ Your exercise of the Licensed Rights is expressly made subject to the
+ following conditions.
+ a. Attribution.
+ 1. If You Share the Licensed Material (including in modified
+ form), You must:
+ A. retain the following if it is supplied by the Licensor
+ with the Licensed Material:
+ i. identification of the creator(s) of the Licensed
+ Material and any others designated to receive
+ attribution, in any reasonable manner requested by
+ the Licensor (including by pseudonym if designated);
+ ii. a copyright notice;
+ iii. a notice that refers to this Public License;
+ iv. a notice that refers to the disclaimer of
+ warranties;
+ v. a URI or hyperlink to the Licensed Material to the
+ extent reasonably practicable;
+ B. indicate if You modified the Licensed Material and retain
+ an indication of any previous modifications; and
+ C. indicate the Licensed Material is licensed under this
+ Public License, and include the text of, or the URI or
+ hyperlink to, this Public License.
+ 2. You may satisfy the conditions in Section [9]3(a)(1) in any
+ reasonable manner based on the medium, means, and context in
+ which You Share the Licensed Material. For example, it may be
+ reasonable to satisfy the conditions by providing a URI or
+ hyperlink to a resource that includes the required
+ information.
+ 3. If requested by the Licensor, You must remove any of the
+ information required by Section [10]3(a)(1)(A) to the extent
+ reasonably practicable.
+ 4. If You Share Adapted Material You produce, the Adapter's
+ License You apply must not prevent recipients of the Adapted
+ Material from complying with this Public License.
+
+ Section 4 - Sui Generis Database Rights.
+
+ Where the Licensed Rights include Sui Generis Database Rights that
+ apply to Your use of the Licensed Material:
+ a. for the avoidance of doubt, Section [11]2(a)(1) grants You the
+ right to extract, reuse, reproduce, and Share all or a substantial
+ portion of the contents of the database;
+ b. if You include all or a substantial portion of the database
+ contents in a database in which You have Sui Generis Database
+ Rights, then the database in which You have Sui Generis Database
+ Rights (but not its individual contents) is Adapted Material; and
+ c. You must comply with the conditions in Section [12]3(a) if You
+ Share all or a substantial portion of the contents of the database.
+
+ For the avoidance of doubt, this Section [13]4 supplements and does not
+ replace Your obligations under this Public License where the Licensed
+ Rights include other Copyright and Similar Rights.
+
+ Section 5 - Disclaimer of Warranties and Limitation of Liability.
+ a. Unless otherwise separately undertaken by the Licensor, to the
+ extent possible, the Licensor offers the Licensed Material as-is
+ and as-available, and makes no representations or warranties of any
+ kind concerning the Licensed Material, whether express, implied,
+ statutory, or other. This includes, without limitation, warranties
+ of title, merchantability, fitness for a particular purpose,
+ non-infringement, absence of latent or other defects, accuracy, or
+ the presence or absence of errors, whether or not known or
+ discoverable. Where disclaimers of warranties are not allowed in
+ full or in part, this disclaimer may not apply to You.
+ b. To the extent possible, in no event will the Licensor be liable to
+ You on any legal theory (including, without limitation, negligence)
+ or otherwise for any direct, special, indirect, incidental,
+ consequential, punitive, exemplary, or other losses, costs,
+ expenses, or damages arising out of this Public License or use of
+ the Licensed Material, even if the Licensor has been advised of the
+ possibility of such losses, costs, expenses, or damages. Where a
+ limitation of liability is not allowed in full or in part, this
+ limitation may not apply to You.
+
+ c. The disclaimer of warranties and limitation of liability provided
+ above shall be interpreted in a manner that, to the extent
+ possible, most closely approximates an absolute disclaimer and
+ waiver of all liability.
+
+ Section 6 - Term and Termination.
+ a. This Public License applies for the term of the Copyright and
+ Similar Rights licensed here. However, if You fail to comply with
+ this Public License, then Your rights under this Public License
+ terminate automatically.
+ b. Where Your right to use the Licensed Material has terminated under
+ Section [14]6(a), it reinstates:
+ 1. automatically as of the date the violation is cured, provided
+ it is cured within 30 days of Your discovery of the violation;
+ or
+ 2. upon express reinstatement by the Licensor.
+ For the avoidance of doubt, this Section [15]6(b) does not affect
+ any right the Licensor may have to seek remedies for Your
+ violations of this Public License.
+ c. For the avoidance of doubt, the Licensor may also offer the
+ Licensed Material under separate terms or conditions or stop
+ distributing the Licensed Material at any time; however, doing so
+ will not terminate this Public License.
+ d. Sections [16]1, [17]5, [18]6, [19]7, and [20]8 survive termination
+ of this Public License.
+
+ Section 7 - Other Terms and Conditions.
+ a. The Licensor shall not be bound by any additional or different
+ terms or conditions communicated by You unless expressly agreed.
+ b. Any arrangements, understandings, or agreements regarding the
+ Licensed Material not stated herein are separate from and
+ independent of the terms and conditions of this Public License.
+
+ Section 8 - Interpretation.
+ a. For the avoidance of doubt, this Public License does not, and shall
+ not be interpreted to, reduce, limit, restrict, or impose
+ conditions on any use of the Licensed Material that could lawfully
+ be made without permission under this Public License.
+ b. To the extent possible, if any provision of this Public License is
+ deemed unenforceable, it shall be automatically reformed to the
+ minimum extent necessary to make it enforceable. If the provision
+ cannot be reformed, it shall be severed from this Public License
+ without affecting the enforceability of the remaining terms and
+ conditions.
+ c. No term or condition of this Public License will be waived and no
+ failure to comply consented to unless expressly agreed to by the
+ Licensor.
+ d. Nothing in this Public License constitutes or may be interpreted as
+ a limitation upon, or waiver of, any privileges and immunities that
+ apply to the Licensor or You, including from the legal processes of
+ any jurisdiction or authority.
diff --git a/pyqtgraph/colors/maps/CET-C1.csv b/pyqtgraph/colors/maps/CET-C1.csv
new file mode 100644
index 00000000..89333d21
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-C1.csv
@@ -0,0 +1,256 @@
+0.976,0.520,0.971
+0.980,0.517,0.963
+0.984,0.514,0.954
+0.987,0.509,0.945
+0.990,0.504,0.934
+0.991,0.499,0.923
+0.992,0.492,0.911
+0.992,0.486,0.899
+0.992,0.478,0.886
+0.992,0.471,0.872
+0.991,0.463,0.858
+0.989,0.455,0.844
+0.988,0.446,0.830
+0.986,0.438,0.815
+0.984,0.429,0.800
+0.981,0.420,0.786
+0.979,0.411,0.771
+0.976,0.402,0.756
+0.973,0.393,0.741
+0.971,0.384,0.726
+0.968,0.375,0.711
+0.964,0.365,0.696
+0.961,0.356,0.682
+0.958,0.347,0.667
+0.954,0.337,0.652
+0.951,0.328,0.637
+0.947,0.318,0.623
+0.943,0.309,0.608
+0.938,0.300,0.593
+0.934,0.291,0.578
+0.929,0.282,0.564
+0.924,0.273,0.549
+0.919,0.264,0.534
+0.914,0.256,0.519
+0.908,0.247,0.504
+0.903,0.239,0.489
+0.897,0.231,0.474
+0.890,0.223,0.459
+0.884,0.215,0.444
+0.877,0.207,0.429
+0.871,0.200,0.414
+0.864,0.193,0.399
+0.857,0.185,0.384
+0.850,0.178,0.369
+0.842,0.171,0.354
+0.835,0.164,0.339
+0.828,0.157,0.324
+0.820,0.150,0.309
+0.812,0.143,0.295
+0.805,0.136,0.280
+0.797,0.129,0.265
+0.790,0.122,0.251
+0.782,0.116,0.236
+0.775,0.110,0.222
+0.767,0.104,0.208
+0.760,0.099,0.194
+0.753,0.095,0.180
+0.747,0.091,0.167
+0.740,0.089,0.154
+0.734,0.088,0.142
+0.729,0.089,0.130
+0.724,0.091,0.118
+0.720,0.095,0.107
+0.716,0.100,0.096
+0.713,0.106,0.086
+0.711,0.113,0.077
+0.710,0.121,0.068
+0.709,0.130,0.060
+0.709,0.139,0.052
+0.710,0.149,0.045
+0.711,0.159,0.039
+0.713,0.169,0.033
+0.715,0.180,0.029
+0.717,0.191,0.025
+0.720,0.201,0.023
+0.723,0.212,0.021
+0.727,0.222,0.019
+0.730,0.233,0.018
+0.734,0.243,0.017
+0.738,0.253,0.017
+0.742,0.263,0.016
+0.746,0.273,0.016
+0.750,0.283,0.016
+0.754,0.293,0.016
+0.758,0.303,0.016
+0.762,0.312,0.017
+0.765,0.322,0.017
+0.769,0.331,0.017
+0.773,0.341,0.018
+0.777,0.350,0.018
+0.780,0.359,0.018
+0.784,0.369,0.018
+0.787,0.378,0.019
+0.791,0.387,0.019
+0.794,0.396,0.019
+0.797,0.406,0.019
+0.800,0.415,0.019
+0.803,0.424,0.019
+0.806,0.433,0.019
+0.809,0.443,0.019
+0.811,0.452,0.019
+0.814,0.461,0.019
+0.816,0.471,0.018
+0.819,0.480,0.018
+0.821,0.489,0.018
+0.823,0.498,0.017
+0.825,0.508,0.017
+0.827,0.517,0.017
+0.829,0.526,0.016
+0.831,0.535,0.016
+0.833,0.544,0.016
+0.834,0.554,0.016
+0.836,0.563,0.016
+0.837,0.572,0.017
+0.839,0.580,0.018
+0.840,0.589,0.020
+0.841,0.598,0.023
+0.841,0.606,0.027
+0.842,0.614,0.032
+0.842,0.622,0.040
+0.841,0.629,0.049
+0.840,0.636,0.059
+0.839,0.643,0.070
+0.836,0.649,0.083
+0.834,0.654,0.096
+0.830,0.658,0.109
+0.825,0.662,0.123
+0.820,0.665,0.138
+0.814,0.667,0.153
+0.807,0.669,0.169
+0.799,0.669,0.184
+0.791,0.669,0.200
+0.782,0.668,0.215
+0.772,0.666,0.231
+0.761,0.664,0.246
+0.750,0.661,0.261
+0.739,0.658,0.276
+0.727,0.655,0.291
+0.714,0.651,0.306
+0.701,0.647,0.320
+0.688,0.642,0.334
+0.675,0.638,0.348
+0.661,0.633,0.361
+0.647,0.628,0.375
+0.632,0.624,0.388
+0.618,0.619,0.401
+0.602,0.614,0.413
+0.587,0.609,0.426
+0.571,0.604,0.438
+0.555,0.599,0.450
+0.539,0.594,0.463
+0.522,0.590,0.475
+0.504,0.585,0.486
+0.486,0.580,0.498
+0.468,0.575,0.510
+0.449,0.570,0.522
+0.430,0.565,0.533
+0.410,0.560,0.545
+0.390,0.555,0.556
+0.369,0.549,0.568
+0.348,0.544,0.579
+0.327,0.538,0.591
+0.306,0.532,0.603
+0.284,0.526,0.614
+0.263,0.519,0.626
+0.242,0.513,0.638
+0.223,0.506,0.649
+0.204,0.498,0.661
+0.186,0.490,0.673
+0.171,0.482,0.685
+0.157,0.473,0.697
+0.146,0.464,0.709
+0.139,0.454,0.722
+0.134,0.445,0.734
+0.132,0.434,0.746
+0.133,0.424,0.759
+0.135,0.413,0.771
+0.139,0.401,0.783
+0.144,0.390,0.796
+0.150,0.378,0.808
+0.156,0.366,0.820
+0.162,0.354,0.833
+0.169,0.342,0.845
+0.175,0.330,0.856
+0.181,0.318,0.868
+0.187,0.306,0.879
+0.194,0.295,0.889
+0.201,0.285,0.900
+0.208,0.275,0.909
+0.216,0.266,0.918
+0.225,0.258,0.927
+0.234,0.251,0.934
+0.244,0.245,0.941
+0.254,0.241,0.948
+0.265,0.239,0.953
+0.277,0.237,0.958
+0.288,0.238,0.962
+0.300,0.239,0.965
+0.311,0.242,0.968
+0.323,0.246,0.970
+0.335,0.251,0.972
+0.346,0.257,0.974
+0.357,0.263,0.975
+0.368,0.270,0.976
+0.379,0.277,0.977
+0.390,0.285,0.977
+0.400,0.293,0.977
+0.410,0.300,0.978
+0.420,0.308,0.978
+0.430,0.316,0.978
+0.440,0.324,0.978
+0.449,0.332,0.978
+0.459,0.340,0.978
+0.469,0.348,0.978
+0.478,0.355,0.978
+0.488,0.363,0.979
+0.498,0.370,0.979
+0.508,0.377,0.979
+0.518,0.384,0.979
+0.529,0.391,0.980
+0.540,0.398,0.980
+0.551,0.404,0.981
+0.563,0.410,0.981
+0.575,0.416,0.982
+0.588,0.421,0.982
+0.600,0.427,0.983
+0.613,0.432,0.984
+0.627,0.437,0.985
+0.640,0.442,0.986
+0.654,0.446,0.987
+0.668,0.451,0.988
+0.682,0.455,0.989
+0.696,0.460,0.990
+0.710,0.464,0.991
+0.724,0.468,0.992
+0.738,0.472,0.994
+0.752,0.476,0.995
+0.766,0.480,0.996
+0.780,0.484,0.997
+0.794,0.488,0.998
+0.807,0.492,0.999
+0.821,0.496,1.000
+0.834,0.500,1.000
+0.847,0.503,1.000
+0.860,0.507,1.000
+0.873,0.510,1.000
+0.885,0.513,1.000
+0.897,0.516,1.000
+0.909,0.519,1.000
+0.919,0.521,1.000
+0.930,0.523,0.999
+0.939,0.524,0.996
+0.948,0.525,0.993
+0.956,0.524,0.989
+0.964,0.524,0.984
+0.970,0.522,0.978
diff --git a/pyqtgraph/colors/maps/CET-C1s.csv b/pyqtgraph/colors/maps/CET-C1s.csv
new file mode 100644
index 00000000..cdf337b2
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-C1s.csv
@@ -0,0 +1,256 @@
+0.244,0.245,0.941
+0.254,0.241,0.948
+0.265,0.239,0.953
+0.277,0.237,0.958
+0.288,0.238,0.962
+0.300,0.239,0.965
+0.311,0.242,0.968
+0.323,0.246,0.970
+0.335,0.251,0.972
+0.346,0.257,0.974
+0.357,0.263,0.975
+0.368,0.270,0.976
+0.379,0.277,0.977
+0.390,0.285,0.977
+0.400,0.293,0.977
+0.410,0.300,0.978
+0.420,0.308,0.978
+0.430,0.316,0.978
+0.440,0.324,0.978
+0.449,0.332,0.978
+0.459,0.340,0.978
+0.469,0.348,0.978
+0.478,0.355,0.978
+0.488,0.363,0.979
+0.498,0.370,0.979
+0.508,0.377,0.979
+0.518,0.384,0.979
+0.529,0.391,0.980
+0.540,0.398,0.980
+0.551,0.404,0.981
+0.563,0.410,0.981
+0.575,0.416,0.982
+0.588,0.421,0.982
+0.600,0.427,0.983
+0.613,0.432,0.984
+0.627,0.437,0.985
+0.640,0.442,0.986
+0.654,0.446,0.987
+0.668,0.451,0.988
+0.682,0.455,0.989
+0.696,0.460,0.990
+0.710,0.464,0.991
+0.724,0.468,0.992
+0.738,0.472,0.994
+0.752,0.476,0.995
+0.766,0.480,0.996
+0.780,0.484,0.997
+0.794,0.488,0.998
+0.807,0.492,0.999
+0.821,0.496,1.000
+0.834,0.500,1.000
+0.847,0.503,1.000
+0.860,0.507,1.000
+0.873,0.510,1.000
+0.885,0.513,1.000
+0.897,0.516,1.000
+0.909,0.519,1.000
+0.919,0.521,1.000
+0.930,0.523,0.999
+0.939,0.524,0.996
+0.948,0.525,0.993
+0.956,0.524,0.989
+0.964,0.524,0.984
+0.970,0.522,0.978
+0.976,0.520,0.971
+0.980,0.517,0.963
+0.984,0.514,0.954
+0.987,0.509,0.945
+0.990,0.504,0.934
+0.991,0.499,0.923
+0.992,0.492,0.911
+0.992,0.486,0.899
+0.992,0.478,0.886
+0.992,0.471,0.872
+0.991,0.463,0.858
+0.989,0.455,0.844
+0.988,0.446,0.830
+0.986,0.438,0.815
+0.984,0.429,0.800
+0.981,0.420,0.786
+0.979,0.411,0.771
+0.976,0.402,0.756
+0.973,0.393,0.741
+0.971,0.384,0.726
+0.968,0.375,0.711
+0.964,0.365,0.696
+0.961,0.356,0.682
+0.958,0.347,0.667
+0.954,0.337,0.652
+0.951,0.328,0.637
+0.947,0.318,0.623
+0.943,0.309,0.608
+0.938,0.300,0.593
+0.934,0.291,0.578
+0.929,0.282,0.564
+0.924,0.273,0.549
+0.919,0.264,0.534
+0.914,0.256,0.519
+0.908,0.247,0.504
+0.903,0.239,0.489
+0.897,0.231,0.474
+0.890,0.223,0.459
+0.884,0.215,0.444
+0.877,0.207,0.429
+0.871,0.200,0.414
+0.864,0.193,0.399
+0.857,0.185,0.384
+0.850,0.178,0.369
+0.842,0.171,0.354
+0.835,0.164,0.339
+0.828,0.157,0.324
+0.820,0.150,0.309
+0.812,0.143,0.295
+0.805,0.136,0.280
+0.797,0.129,0.265
+0.790,0.122,0.251
+0.782,0.116,0.236
+0.775,0.110,0.222
+0.767,0.104,0.208
+0.760,0.099,0.194
+0.753,0.095,0.180
+0.747,0.091,0.167
+0.740,0.089,0.154
+0.734,0.088,0.142
+0.729,0.089,0.130
+0.724,0.091,0.118
+0.720,0.095,0.107
+0.716,0.100,0.096
+0.713,0.106,0.086
+0.711,0.113,0.077
+0.710,0.121,0.068
+0.709,0.130,0.060
+0.709,0.139,0.052
+0.710,0.149,0.045
+0.711,0.159,0.039
+0.713,0.169,0.033
+0.715,0.180,0.029
+0.717,0.191,0.025
+0.720,0.201,0.023
+0.723,0.212,0.021
+0.727,0.222,0.019
+0.730,0.233,0.018
+0.734,0.243,0.017
+0.738,0.253,0.017
+0.742,0.263,0.016
+0.746,0.273,0.016
+0.750,0.283,0.016
+0.754,0.293,0.016
+0.758,0.303,0.016
+0.762,0.312,0.017
+0.765,0.322,0.017
+0.769,0.331,0.017
+0.773,0.341,0.018
+0.777,0.350,0.018
+0.780,0.359,0.018
+0.784,0.369,0.018
+0.787,0.378,0.019
+0.791,0.387,0.019
+0.794,0.396,0.019
+0.797,0.406,0.019
+0.800,0.415,0.019
+0.803,0.424,0.019
+0.806,0.433,0.019
+0.809,0.443,0.019
+0.811,0.452,0.019
+0.814,0.461,0.019
+0.816,0.471,0.018
+0.819,0.480,0.018
+0.821,0.489,0.018
+0.823,0.498,0.017
+0.825,0.508,0.017
+0.827,0.517,0.017
+0.829,0.526,0.016
+0.831,0.535,0.016
+0.833,0.544,0.016
+0.834,0.554,0.016
+0.836,0.563,0.016
+0.837,0.572,0.017
+0.839,0.580,0.018
+0.840,0.589,0.020
+0.841,0.598,0.023
+0.841,0.606,0.027
+0.842,0.614,0.032
+0.842,0.622,0.040
+0.841,0.629,0.049
+0.840,0.636,0.059
+0.839,0.643,0.070
+0.836,0.649,0.083
+0.834,0.654,0.096
+0.830,0.658,0.109
+0.825,0.662,0.123
+0.820,0.665,0.138
+0.814,0.667,0.153
+0.807,0.669,0.169
+0.799,0.669,0.184
+0.791,0.669,0.200
+0.782,0.668,0.215
+0.772,0.666,0.231
+0.761,0.664,0.246
+0.750,0.661,0.261
+0.739,0.658,0.276
+0.727,0.655,0.291
+0.714,0.651,0.306
+0.701,0.647,0.320
+0.688,0.642,0.334
+0.675,0.638,0.348
+0.661,0.633,0.361
+0.647,0.628,0.375
+0.632,0.624,0.388
+0.618,0.619,0.401
+0.602,0.614,0.413
+0.587,0.609,0.426
+0.571,0.604,0.438
+0.555,0.599,0.450
+0.539,0.594,0.463
+0.522,0.590,0.475
+0.504,0.585,0.486
+0.486,0.580,0.498
+0.468,0.575,0.510
+0.449,0.570,0.522
+0.430,0.565,0.533
+0.410,0.560,0.545
+0.390,0.555,0.556
+0.369,0.549,0.568
+0.348,0.544,0.579
+0.327,0.538,0.591
+0.306,0.532,0.603
+0.284,0.526,0.614
+0.263,0.519,0.626
+0.242,0.513,0.638
+0.223,0.506,0.649
+0.204,0.498,0.661
+0.186,0.490,0.673
+0.171,0.482,0.685
+0.157,0.473,0.697
+0.146,0.464,0.709
+0.139,0.454,0.722
+0.134,0.445,0.734
+0.132,0.434,0.746
+0.133,0.424,0.759
+0.135,0.413,0.771
+0.139,0.401,0.783
+0.144,0.390,0.796
+0.150,0.378,0.808
+0.156,0.366,0.820
+0.162,0.354,0.833
+0.169,0.342,0.845
+0.175,0.330,0.856
+0.181,0.318,0.868
+0.187,0.306,0.879
+0.194,0.295,0.889
+0.201,0.285,0.900
+0.208,0.275,0.909
+0.216,0.266,0.918
+0.225,0.258,0.927
+0.234,0.251,0.934
diff --git a/pyqtgraph/colors/maps/CET-C2.csv b/pyqtgraph/colors/maps/CET-C2.csv
new file mode 100644
index 00000000..74424d90
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-C2.csv
@@ -0,0 +1,256 @@
+0.938,0.334,0.948
+0.944,0.343,0.942
+0.949,0.353,0.936
+0.954,0.363,0.929
+0.959,0.374,0.922
+0.963,0.386,0.914
+0.966,0.397,0.906
+0.969,0.409,0.897
+0.972,0.421,0.888
+0.975,0.433,0.879
+0.977,0.446,0.869
+0.978,0.458,0.859
+0.980,0.470,0.849
+0.981,0.482,0.839
+0.983,0.494,0.829
+0.984,0.506,0.819
+0.985,0.518,0.808
+0.985,0.530,0.798
+0.986,0.541,0.787
+0.986,0.553,0.776
+0.987,0.564,0.766
+0.987,0.575,0.755
+0.987,0.586,0.744
+0.987,0.597,0.733
+0.987,0.608,0.722
+0.987,0.618,0.712
+0.987,0.629,0.701
+0.987,0.639,0.690
+0.987,0.649,0.679
+0.987,0.659,0.668
+0.987,0.670,0.657
+0.986,0.679,0.645
+0.986,0.689,0.634
+0.986,0.699,0.623
+0.986,0.708,0.612
+0.986,0.718,0.601
+0.986,0.727,0.589
+0.986,0.736,0.578
+0.987,0.745,0.566
+0.987,0.754,0.555
+0.987,0.763,0.543
+0.987,0.772,0.531
+0.988,0.781,0.519
+0.988,0.789,0.507
+0.988,0.798,0.495
+0.988,0.807,0.483
+0.989,0.815,0.470
+0.989,0.824,0.458
+0.989,0.832,0.445
+0.989,0.840,0.432
+0.988,0.849,0.418
+0.988,0.857,0.404
+0.987,0.865,0.390
+0.986,0.873,0.376
+0.985,0.880,0.362
+0.983,0.888,0.347
+0.981,0.895,0.332
+0.978,0.901,0.316
+0.975,0.907,0.301
+0.972,0.913,0.285
+0.967,0.918,0.270
+0.962,0.923,0.254
+0.957,0.927,0.239
+0.951,0.930,0.224
+0.944,0.932,0.209
+0.936,0.934,0.195
+0.928,0.935,0.182
+0.920,0.935,0.169
+0.910,0.935,0.157
+0.901,0.934,0.146
+0.891,0.933,0.136
+0.881,0.931,0.127
+0.870,0.928,0.120
+0.859,0.925,0.113
+0.848,0.922,0.107
+0.837,0.919,0.103
+0.826,0.915,0.099
+0.815,0.911,0.095
+0.803,0.907,0.092
+0.792,0.903,0.090
+0.780,0.899,0.088
+0.769,0.895,0.086
+0.757,0.891,0.084
+0.746,0.887,0.082
+0.734,0.882,0.081
+0.722,0.878,0.079
+0.711,0.874,0.078
+0.699,0.869,0.076
+0.687,0.865,0.075
+0.675,0.861,0.074
+0.663,0.856,0.072
+0.652,0.852,0.071
+0.640,0.848,0.070
+0.628,0.843,0.068
+0.616,0.839,0.067
+0.604,0.835,0.066
+0.591,0.830,0.064
+0.579,0.826,0.063
+0.567,0.822,0.062
+0.554,0.817,0.060
+0.542,0.813,0.059
+0.529,0.808,0.058
+0.517,0.804,0.057
+0.504,0.800,0.055
+0.491,0.795,0.054
+0.478,0.791,0.053
+0.465,0.786,0.051
+0.452,0.782,0.050
+0.438,0.777,0.049
+0.424,0.773,0.048
+0.411,0.768,0.047
+0.397,0.764,0.047
+0.382,0.759,0.046
+0.368,0.755,0.047
+0.354,0.750,0.047
+0.339,0.745,0.049
+0.324,0.741,0.051
+0.310,0.736,0.054
+0.295,0.731,0.058
+0.281,0.726,0.064
+0.267,0.721,0.070
+0.254,0.716,0.078
+0.241,0.711,0.087
+0.230,0.706,0.097
+0.220,0.700,0.107
+0.211,0.695,0.119
+0.204,0.689,0.131
+0.199,0.683,0.144
+0.196,0.677,0.158
+0.195,0.671,0.172
+0.196,0.664,0.186
+0.198,0.658,0.200
+0.202,0.651,0.215
+0.206,0.644,0.230
+0.212,0.638,0.245
+0.218,0.631,0.261
+0.224,0.623,0.276
+0.230,0.616,0.291
+0.236,0.609,0.306
+0.242,0.602,0.321
+0.247,0.595,0.335
+0.252,0.587,0.350
+0.256,0.580,0.365
+0.260,0.572,0.379
+0.263,0.565,0.393
+0.266,0.558,0.407
+0.268,0.550,0.421
+0.270,0.543,0.435
+0.271,0.535,0.449
+0.272,0.528,0.462
+0.272,0.521,0.476
+0.271,0.513,0.489
+0.270,0.506,0.503
+0.268,0.498,0.516
+0.266,0.491,0.529
+0.263,0.484,0.542
+0.260,0.476,0.555
+0.256,0.469,0.568
+0.252,0.461,0.581
+0.247,0.454,0.594
+0.242,0.446,0.606
+0.236,0.438,0.619
+0.230,0.431,0.631
+0.224,0.423,0.644
+0.218,0.415,0.656
+0.212,0.407,0.667
+0.206,0.399,0.679
+0.199,0.391,0.691
+0.194,0.382,0.702
+0.188,0.374,0.713
+0.183,0.365,0.724
+0.178,0.356,0.735
+0.174,0.347,0.745
+0.170,0.337,0.756
+0.166,0.327,0.766
+0.163,0.317,0.776
+0.160,0.307,0.786
+0.157,0.297,0.796
+0.155,0.286,0.805
+0.152,0.275,0.815
+0.150,0.264,0.824
+0.147,0.253,0.833
+0.146,0.241,0.843
+0.144,0.230,0.851
+0.143,0.218,0.860
+0.143,0.206,0.869
+0.144,0.195,0.877
+0.146,0.183,0.885
+0.150,0.172,0.892
+0.155,0.161,0.900
+0.162,0.151,0.906
+0.171,0.141,0.913
+0.181,0.132,0.919
+0.192,0.124,0.924
+0.204,0.118,0.929
+0.217,0.112,0.933
+0.230,0.108,0.937
+0.244,0.105,0.941
+0.258,0.104,0.944
+0.272,0.104,0.947
+0.287,0.106,0.950
+0.301,0.108,0.952
+0.314,0.112,0.954
+0.328,0.116,0.956
+0.341,0.120,0.958
+0.354,0.125,0.960
+0.367,0.131,0.961
+0.379,0.136,0.963
+0.392,0.142,0.964
+0.404,0.148,0.966
+0.415,0.154,0.967
+0.427,0.159,0.969
+0.438,0.165,0.970
+0.449,0.171,0.971
+0.460,0.176,0.973
+0.471,0.182,0.974
+0.482,0.188,0.975
+0.493,0.193,0.976
+0.504,0.198,0.978
+0.514,0.203,0.979
+0.525,0.208,0.980
+0.536,0.213,0.981
+0.548,0.217,0.982
+0.559,0.221,0.982
+0.571,0.225,0.983
+0.582,0.229,0.984
+0.594,0.233,0.984
+0.606,0.236,0.985
+0.619,0.239,0.985
+0.631,0.242,0.985
+0.644,0.245,0.985
+0.657,0.247,0.985
+0.669,0.250,0.985
+0.682,0.252,0.985
+0.695,0.254,0.985
+0.708,0.256,0.985
+0.721,0.258,0.984
+0.734,0.260,0.984
+0.747,0.261,0.984
+0.760,0.263,0.983
+0.773,0.265,0.983
+0.785,0.267,0.982
+0.798,0.269,0.982
+0.810,0.271,0.981
+0.822,0.273,0.980
+0.834,0.275,0.979
+0.846,0.278,0.978
+0.857,0.281,0.977
+0.868,0.284,0.975
+0.878,0.288,0.973
+0.889,0.293,0.971
+0.898,0.298,0.968
+0.907,0.303,0.965
+0.916,0.310,0.962
+0.924,0.317,0.958
+0.931,0.325,0.953
diff --git a/pyqtgraph/colors/maps/CET-C2s.csv b/pyqtgraph/colors/maps/CET-C2s.csv
new file mode 100644
index 00000000..fada4a2d
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-C2s.csv
@@ -0,0 +1,256 @@
+0.181,0.132,0.919
+0.192,0.124,0.924
+0.204,0.118,0.929
+0.217,0.112,0.933
+0.230,0.108,0.937
+0.244,0.105,0.941
+0.258,0.104,0.944
+0.272,0.104,0.947
+0.287,0.106,0.950
+0.301,0.108,0.952
+0.314,0.112,0.954
+0.328,0.116,0.956
+0.341,0.120,0.958
+0.354,0.125,0.960
+0.367,0.131,0.961
+0.379,0.136,0.963
+0.392,0.142,0.964
+0.404,0.148,0.966
+0.415,0.154,0.967
+0.427,0.159,0.969
+0.438,0.165,0.970
+0.449,0.171,0.971
+0.460,0.176,0.973
+0.471,0.182,0.974
+0.482,0.188,0.975
+0.493,0.193,0.976
+0.504,0.198,0.978
+0.514,0.203,0.979
+0.525,0.208,0.980
+0.536,0.213,0.981
+0.548,0.217,0.982
+0.559,0.221,0.982
+0.571,0.225,0.983
+0.582,0.229,0.984
+0.594,0.233,0.984
+0.606,0.236,0.985
+0.619,0.239,0.985
+0.631,0.242,0.985
+0.644,0.245,0.985
+0.657,0.247,0.985
+0.669,0.250,0.985
+0.682,0.252,0.985
+0.695,0.254,0.985
+0.708,0.256,0.985
+0.721,0.258,0.984
+0.734,0.260,0.984
+0.747,0.261,0.984
+0.760,0.263,0.983
+0.773,0.265,0.983
+0.785,0.267,0.982
+0.798,0.269,0.982
+0.810,0.271,0.981
+0.822,0.273,0.980
+0.834,0.275,0.979
+0.846,0.278,0.978
+0.857,0.281,0.977
+0.868,0.284,0.975
+0.878,0.288,0.973
+0.889,0.293,0.971
+0.898,0.298,0.968
+0.907,0.303,0.965
+0.916,0.310,0.962
+0.924,0.317,0.958
+0.931,0.325,0.953
+0.938,0.334,0.948
+0.944,0.343,0.942
+0.949,0.353,0.936
+0.954,0.363,0.929
+0.959,0.374,0.922
+0.963,0.386,0.914
+0.966,0.397,0.906
+0.969,0.409,0.897
+0.972,0.421,0.888
+0.975,0.433,0.879
+0.977,0.446,0.869
+0.978,0.458,0.859
+0.980,0.470,0.849
+0.981,0.482,0.839
+0.983,0.494,0.829
+0.984,0.506,0.819
+0.985,0.518,0.808
+0.985,0.530,0.798
+0.986,0.541,0.787
+0.986,0.553,0.776
+0.987,0.564,0.766
+0.987,0.575,0.755
+0.987,0.586,0.744
+0.987,0.597,0.733
+0.987,0.608,0.722
+0.987,0.618,0.712
+0.987,0.629,0.701
+0.987,0.639,0.690
+0.987,0.649,0.679
+0.987,0.659,0.668
+0.987,0.670,0.657
+0.986,0.679,0.645
+0.986,0.689,0.634
+0.986,0.699,0.623
+0.986,0.708,0.612
+0.986,0.718,0.601
+0.986,0.727,0.589
+0.986,0.736,0.578
+0.987,0.745,0.566
+0.987,0.754,0.555
+0.987,0.763,0.543
+0.987,0.772,0.531
+0.988,0.781,0.519
+0.988,0.789,0.507
+0.988,0.798,0.495
+0.988,0.807,0.483
+0.989,0.815,0.470
+0.989,0.824,0.458
+0.989,0.832,0.445
+0.989,0.840,0.432
+0.988,0.849,0.418
+0.988,0.857,0.404
+0.987,0.865,0.390
+0.986,0.873,0.376
+0.985,0.880,0.362
+0.983,0.888,0.347
+0.981,0.895,0.332
+0.978,0.901,0.316
+0.975,0.907,0.301
+0.972,0.913,0.285
+0.967,0.918,0.270
+0.962,0.923,0.254
+0.957,0.927,0.239
+0.951,0.930,0.224
+0.944,0.932,0.209
+0.936,0.934,0.195
+0.928,0.935,0.182
+0.920,0.935,0.169
+0.910,0.935,0.157
+0.901,0.934,0.146
+0.891,0.933,0.136
+0.881,0.931,0.127
+0.870,0.928,0.120
+0.859,0.925,0.113
+0.848,0.922,0.107
+0.837,0.919,0.103
+0.826,0.915,0.099
+0.815,0.911,0.095
+0.803,0.907,0.092
+0.792,0.903,0.090
+0.780,0.899,0.088
+0.769,0.895,0.086
+0.757,0.891,0.084
+0.746,0.887,0.082
+0.734,0.882,0.081
+0.722,0.878,0.079
+0.711,0.874,0.078
+0.699,0.869,0.076
+0.687,0.865,0.075
+0.675,0.861,0.074
+0.663,0.856,0.072
+0.652,0.852,0.071
+0.640,0.848,0.070
+0.628,0.843,0.068
+0.616,0.839,0.067
+0.604,0.835,0.066
+0.591,0.830,0.064
+0.579,0.826,0.063
+0.567,0.822,0.062
+0.554,0.817,0.060
+0.542,0.813,0.059
+0.529,0.808,0.058
+0.517,0.804,0.057
+0.504,0.800,0.055
+0.491,0.795,0.054
+0.478,0.791,0.053
+0.465,0.786,0.051
+0.452,0.782,0.050
+0.438,0.777,0.049
+0.424,0.773,0.048
+0.411,0.768,0.047
+0.397,0.764,0.047
+0.382,0.759,0.046
+0.368,0.755,0.047
+0.354,0.750,0.047
+0.339,0.745,0.049
+0.324,0.741,0.051
+0.310,0.736,0.054
+0.295,0.731,0.058
+0.281,0.726,0.064
+0.267,0.721,0.070
+0.254,0.716,0.078
+0.241,0.711,0.087
+0.230,0.706,0.097
+0.220,0.700,0.107
+0.211,0.695,0.119
+0.204,0.689,0.131
+0.199,0.683,0.144
+0.196,0.677,0.158
+0.195,0.671,0.172
+0.196,0.664,0.186
+0.198,0.658,0.200
+0.202,0.651,0.215
+0.206,0.644,0.230
+0.212,0.638,0.245
+0.218,0.631,0.261
+0.224,0.623,0.276
+0.230,0.616,0.291
+0.236,0.609,0.306
+0.242,0.602,0.321
+0.247,0.595,0.335
+0.252,0.587,0.350
+0.256,0.580,0.365
+0.260,0.572,0.379
+0.263,0.565,0.393
+0.266,0.558,0.407
+0.268,0.550,0.421
+0.270,0.543,0.435
+0.271,0.535,0.449
+0.272,0.528,0.462
+0.272,0.521,0.476
+0.271,0.513,0.489
+0.270,0.506,0.503
+0.268,0.498,0.516
+0.266,0.491,0.529
+0.263,0.484,0.542
+0.260,0.476,0.555
+0.256,0.469,0.568
+0.252,0.461,0.581
+0.247,0.454,0.594
+0.242,0.446,0.606
+0.236,0.438,0.619
+0.230,0.431,0.631
+0.224,0.423,0.644
+0.218,0.415,0.656
+0.212,0.407,0.667
+0.206,0.399,0.679
+0.199,0.391,0.691
+0.194,0.382,0.702
+0.188,0.374,0.713
+0.183,0.365,0.724
+0.178,0.356,0.735
+0.174,0.347,0.745
+0.170,0.337,0.756
+0.166,0.327,0.766
+0.163,0.317,0.776
+0.160,0.307,0.786
+0.157,0.297,0.796
+0.155,0.286,0.805
+0.152,0.275,0.815
+0.150,0.264,0.824
+0.147,0.253,0.833
+0.146,0.241,0.843
+0.144,0.230,0.851
+0.143,0.218,0.860
+0.143,0.206,0.869
+0.144,0.195,0.877
+0.146,0.183,0.885
+0.150,0.172,0.892
+0.155,0.161,0.900
+0.162,0.151,0.906
+0.171,0.141,0.913
diff --git a/pyqtgraph/colors/maps/CET-C3.csv b/pyqtgraph/colors/maps/CET-C3.csv
new file mode 100644
index 00000000..39f6da23
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-C3.csv
@@ -0,0 +1,256 @@
+0.881,0.843,0.856
+0.886,0.842,0.849
+0.891,0.839,0.840
+0.896,0.835,0.831
+0.900,0.830,0.821
+0.904,0.825,0.811
+0.907,0.819,0.800
+0.911,0.812,0.789
+0.914,0.804,0.778
+0.917,0.797,0.766
+0.919,0.788,0.754
+0.922,0.780,0.742
+0.924,0.771,0.730
+0.926,0.762,0.717
+0.928,0.752,0.705
+0.930,0.743,0.692
+0.932,0.734,0.679
+0.933,0.724,0.667
+0.935,0.714,0.654
+0.936,0.705,0.641
+0.937,0.695,0.629
+0.938,0.685,0.616
+0.939,0.676,0.604
+0.940,0.666,0.591
+0.940,0.656,0.579
+0.941,0.646,0.566
+0.941,0.636,0.554
+0.941,0.627,0.541
+0.941,0.617,0.529
+0.941,0.607,0.517
+0.941,0.597,0.504
+0.941,0.587,0.492
+0.941,0.577,0.480
+0.940,0.567,0.468
+0.940,0.557,0.456
+0.939,0.547,0.444
+0.939,0.537,0.431
+0.938,0.527,0.419
+0.937,0.516,0.407
+0.936,0.506,0.395
+0.935,0.496,0.383
+0.934,0.485,0.371
+0.932,0.475,0.359
+0.931,0.464,0.348
+0.930,0.454,0.336
+0.928,0.443,0.324
+0.926,0.432,0.312
+0.925,0.421,0.300
+0.923,0.410,0.288
+0.921,0.399,0.277
+0.919,0.388,0.265
+0.916,0.377,0.254
+0.914,0.365,0.242
+0.911,0.354,0.231
+0.908,0.343,0.220
+0.905,0.332,0.209
+0.901,0.320,0.198
+0.898,0.309,0.188
+0.893,0.299,0.178
+0.889,0.288,0.168
+0.883,0.278,0.159
+0.877,0.268,0.151
+0.871,0.259,0.143
+0.864,0.250,0.136
+0.857,0.242,0.130
+0.849,0.235,0.124
+0.840,0.229,0.119
+0.831,0.223,0.115
+0.821,0.218,0.111
+0.811,0.214,0.109
+0.800,0.211,0.107
+0.789,0.208,0.105
+0.778,0.206,0.104
+0.766,0.204,0.103
+0.755,0.202,0.103
+0.743,0.201,0.103
+0.730,0.200,0.103
+0.718,0.199,0.103
+0.706,0.198,0.104
+0.694,0.198,0.104
+0.681,0.197,0.105
+0.669,0.196,0.105
+0.656,0.195,0.106
+0.644,0.195,0.106
+0.631,0.194,0.107
+0.619,0.193,0.107
+0.607,0.192,0.108
+0.594,0.191,0.108
+0.582,0.190,0.109
+0.570,0.189,0.109
+0.558,0.188,0.110
+0.546,0.187,0.110
+0.534,0.186,0.110
+0.521,0.184,0.111
+0.509,0.183,0.111
+0.497,0.182,0.111
+0.485,0.180,0.112
+0.474,0.179,0.112
+0.462,0.177,0.112
+0.450,0.176,0.112
+0.438,0.174,0.112
+0.426,0.172,0.112
+0.414,0.171,0.112
+0.403,0.169,0.113
+0.391,0.167,0.113
+0.379,0.165,0.113
+0.368,0.163,0.113
+0.356,0.161,0.113
+0.345,0.159,0.113
+0.333,0.157,0.113
+0.322,0.155,0.113
+0.310,0.153,0.113
+0.299,0.151,0.113
+0.288,0.149,0.113
+0.277,0.146,0.113
+0.266,0.144,0.113
+0.255,0.142,0.114
+0.244,0.140,0.114
+0.234,0.138,0.115
+0.224,0.136,0.116
+0.215,0.135,0.118
+0.206,0.133,0.120
+0.197,0.132,0.122
+0.189,0.131,0.125
+0.182,0.130,0.129
+0.176,0.130,0.133
+0.170,0.130,0.138
+0.165,0.131,0.144
+0.161,0.131,0.150
+0.157,0.133,0.157
+0.155,0.134,0.164
+0.153,0.136,0.173
+0.152,0.139,0.182
+0.151,0.142,0.191
+0.151,0.145,0.201
+0.152,0.148,0.212
+0.152,0.152,0.223
+0.154,0.156,0.235
+0.155,0.160,0.246
+0.157,0.164,0.258
+0.159,0.169,0.271
+0.162,0.173,0.283
+0.164,0.178,0.296
+0.166,0.182,0.309
+0.168,0.187,0.322
+0.170,0.192,0.335
+0.172,0.196,0.348
+0.174,0.201,0.361
+0.176,0.206,0.375
+0.178,0.211,0.388
+0.180,0.216,0.402
+0.181,0.221,0.415
+0.183,0.226,0.429
+0.184,0.230,0.443
+0.185,0.235,0.457
+0.186,0.240,0.470
+0.187,0.245,0.484
+0.188,0.250,0.499
+0.188,0.255,0.513
+0.188,0.261,0.527
+0.189,0.266,0.541
+0.189,0.271,0.555
+0.188,0.276,0.570
+0.188,0.281,0.584
+0.187,0.286,0.599
+0.187,0.291,0.614
+0.186,0.297,0.628
+0.184,0.302,0.643
+0.183,0.307,0.658
+0.181,0.312,0.673
+0.179,0.317,0.687
+0.177,0.323,0.702
+0.174,0.328,0.717
+0.171,0.333,0.732
+0.168,0.339,0.747
+0.165,0.344,0.762
+0.161,0.349,0.777
+0.158,0.355,0.792
+0.154,0.360,0.807
+0.150,0.366,0.822
+0.146,0.371,0.837
+0.143,0.377,0.851
+0.140,0.382,0.865
+0.138,0.388,0.878
+0.137,0.393,0.892
+0.138,0.399,0.904
+0.141,0.405,0.916
+0.146,0.410,0.927
+0.153,0.416,0.937
+0.162,0.422,0.947
+0.173,0.428,0.955
+0.186,0.434,0.963
+0.200,0.440,0.969
+0.216,0.446,0.975
+0.232,0.452,0.979
+0.248,0.458,0.983
+0.265,0.465,0.986
+0.282,0.471,0.988
+0.299,0.477,0.989
+0.316,0.484,0.990
+0.332,0.490,0.990
+0.348,0.497,0.990
+0.364,0.503,0.989
+0.380,0.510,0.989
+0.394,0.517,0.988
+0.409,0.523,0.986
+0.423,0.530,0.985
+0.437,0.537,0.983
+0.450,0.544,0.982
+0.463,0.551,0.980
+0.476,0.557,0.979
+0.488,0.564,0.977
+0.500,0.571,0.975
+0.512,0.578,0.973
+0.524,0.585,0.972
+0.535,0.592,0.970
+0.546,0.599,0.968
+0.557,0.606,0.966
+0.568,0.613,0.964
+0.578,0.620,0.963
+0.589,0.627,0.961
+0.599,0.635,0.959
+0.609,0.642,0.957
+0.619,0.649,0.955
+0.629,0.656,0.953
+0.638,0.663,0.951
+0.648,0.671,0.950
+0.657,0.678,0.948
+0.666,0.685,0.946
+0.675,0.692,0.944
+0.685,0.700,0.942
+0.693,0.707,0.940
+0.702,0.714,0.938
+0.711,0.722,0.936
+0.720,0.729,0.934
+0.728,0.736,0.932
+0.737,0.744,0.930
+0.745,0.751,0.928
+0.754,0.759,0.925
+0.762,0.766,0.923
+0.770,0.773,0.921
+0.778,0.780,0.919
+0.786,0.788,0.917
+0.794,0.795,0.914
+0.802,0.801,0.912
+0.810,0.808,0.909
+0.817,0.814,0.906
+0.825,0.820,0.903
+0.832,0.826,0.900
+0.839,0.831,0.896
+0.846,0.835,0.892
+0.852,0.838,0.887
+0.859,0.841,0.882
+0.865,0.843,0.877
+0.871,0.844,0.870
+0.876,0.844,0.864
diff --git a/pyqtgraph/colors/maps/CET-C3s.csv b/pyqtgraph/colors/maps/CET-C3s.csv
new file mode 100644
index 00000000..7b9bfab5
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-C3s.csv
@@ -0,0 +1,256 @@
+0.200,0.440,0.969
+0.216,0.446,0.975
+0.232,0.452,0.979
+0.248,0.458,0.983
+0.265,0.465,0.986
+0.282,0.471,0.988
+0.299,0.477,0.989
+0.316,0.484,0.990
+0.332,0.490,0.990
+0.348,0.497,0.990
+0.364,0.503,0.989
+0.380,0.510,0.989
+0.394,0.517,0.988
+0.409,0.523,0.986
+0.423,0.530,0.985
+0.437,0.537,0.983
+0.450,0.544,0.982
+0.463,0.551,0.980
+0.476,0.557,0.979
+0.488,0.564,0.977
+0.500,0.571,0.975
+0.512,0.578,0.973
+0.524,0.585,0.972
+0.535,0.592,0.970
+0.546,0.599,0.968
+0.557,0.606,0.966
+0.568,0.613,0.964
+0.578,0.620,0.963
+0.589,0.627,0.961
+0.599,0.635,0.959
+0.609,0.642,0.957
+0.619,0.649,0.955
+0.629,0.656,0.953
+0.638,0.663,0.951
+0.648,0.671,0.950
+0.657,0.678,0.948
+0.666,0.685,0.946
+0.675,0.692,0.944
+0.685,0.700,0.942
+0.693,0.707,0.940
+0.702,0.714,0.938
+0.711,0.722,0.936
+0.720,0.729,0.934
+0.728,0.736,0.932
+0.737,0.744,0.930
+0.745,0.751,0.928
+0.754,0.759,0.925
+0.762,0.766,0.923
+0.770,0.773,0.921
+0.778,0.780,0.919
+0.786,0.788,0.917
+0.794,0.795,0.914
+0.802,0.801,0.912
+0.810,0.808,0.909
+0.817,0.814,0.906
+0.825,0.820,0.903
+0.832,0.826,0.900
+0.839,0.831,0.896
+0.846,0.835,0.892
+0.852,0.838,0.887
+0.859,0.841,0.882
+0.865,0.843,0.877
+0.871,0.844,0.870
+0.876,0.844,0.864
+0.881,0.843,0.856
+0.886,0.842,0.849
+0.891,0.839,0.840
+0.896,0.835,0.831
+0.900,0.830,0.821
+0.904,0.825,0.811
+0.907,0.819,0.800
+0.911,0.812,0.789
+0.914,0.804,0.778
+0.917,0.797,0.766
+0.919,0.788,0.754
+0.922,0.780,0.742
+0.924,0.771,0.730
+0.926,0.762,0.717
+0.928,0.752,0.705
+0.930,0.743,0.692
+0.932,0.734,0.679
+0.933,0.724,0.667
+0.935,0.714,0.654
+0.936,0.705,0.641
+0.937,0.695,0.629
+0.938,0.685,0.616
+0.939,0.676,0.604
+0.940,0.666,0.591
+0.940,0.656,0.579
+0.941,0.646,0.566
+0.941,0.636,0.554
+0.941,0.627,0.541
+0.941,0.617,0.529
+0.941,0.607,0.517
+0.941,0.597,0.504
+0.941,0.587,0.492
+0.941,0.577,0.480
+0.940,0.567,0.468
+0.940,0.557,0.456
+0.939,0.547,0.444
+0.939,0.537,0.431
+0.938,0.527,0.419
+0.937,0.516,0.407
+0.936,0.506,0.395
+0.935,0.496,0.383
+0.934,0.485,0.371
+0.932,0.475,0.359
+0.931,0.464,0.348
+0.930,0.454,0.336
+0.928,0.443,0.324
+0.926,0.432,0.312
+0.925,0.421,0.300
+0.923,0.410,0.288
+0.921,0.399,0.277
+0.919,0.388,0.265
+0.916,0.377,0.254
+0.914,0.365,0.242
+0.911,0.354,0.231
+0.908,0.343,0.220
+0.905,0.332,0.209
+0.901,0.320,0.198
+0.898,0.309,0.188
+0.893,0.299,0.178
+0.889,0.288,0.168
+0.883,0.278,0.159
+0.877,0.268,0.151
+0.871,0.259,0.143
+0.864,0.250,0.136
+0.857,0.242,0.130
+0.849,0.235,0.124
+0.840,0.229,0.119
+0.831,0.223,0.115
+0.821,0.218,0.111
+0.811,0.214,0.109
+0.800,0.211,0.107
+0.789,0.208,0.105
+0.778,0.206,0.104
+0.766,0.204,0.103
+0.755,0.202,0.103
+0.743,0.201,0.103
+0.730,0.200,0.103
+0.718,0.199,0.103
+0.706,0.198,0.104
+0.694,0.198,0.104
+0.681,0.197,0.105
+0.669,0.196,0.105
+0.656,0.195,0.106
+0.644,0.195,0.106
+0.631,0.194,0.107
+0.619,0.193,0.107
+0.607,0.192,0.108
+0.594,0.191,0.108
+0.582,0.190,0.109
+0.570,0.189,0.109
+0.558,0.188,0.110
+0.546,0.187,0.110
+0.534,0.186,0.110
+0.521,0.184,0.111
+0.509,0.183,0.111
+0.497,0.182,0.111
+0.485,0.180,0.112
+0.474,0.179,0.112
+0.462,0.177,0.112
+0.450,0.176,0.112
+0.438,0.174,0.112
+0.426,0.172,0.112
+0.414,0.171,0.112
+0.403,0.169,0.113
+0.391,0.167,0.113
+0.379,0.165,0.113
+0.368,0.163,0.113
+0.356,0.161,0.113
+0.345,0.159,0.113
+0.333,0.157,0.113
+0.322,0.155,0.113
+0.310,0.153,0.113
+0.299,0.151,0.113
+0.288,0.149,0.113
+0.277,0.146,0.113
+0.266,0.144,0.113
+0.255,0.142,0.114
+0.244,0.140,0.114
+0.234,0.138,0.115
+0.224,0.136,0.116
+0.215,0.135,0.118
+0.206,0.133,0.120
+0.197,0.132,0.122
+0.189,0.131,0.125
+0.182,0.130,0.129
+0.176,0.130,0.133
+0.170,0.130,0.138
+0.165,0.131,0.144
+0.161,0.131,0.150
+0.157,0.133,0.157
+0.155,0.134,0.164
+0.153,0.136,0.173
+0.152,0.139,0.182
+0.151,0.142,0.191
+0.151,0.145,0.201
+0.152,0.148,0.212
+0.152,0.152,0.223
+0.154,0.156,0.235
+0.155,0.160,0.246
+0.157,0.164,0.258
+0.159,0.169,0.271
+0.162,0.173,0.283
+0.164,0.178,0.296
+0.166,0.182,0.309
+0.168,0.187,0.322
+0.170,0.192,0.335
+0.172,0.196,0.348
+0.174,0.201,0.361
+0.176,0.206,0.375
+0.178,0.211,0.388
+0.180,0.216,0.402
+0.181,0.221,0.415
+0.183,0.226,0.429
+0.184,0.230,0.443
+0.185,0.235,0.457
+0.186,0.240,0.470
+0.187,0.245,0.484
+0.188,0.250,0.499
+0.188,0.255,0.513
+0.188,0.261,0.527
+0.189,0.266,0.541
+0.189,0.271,0.555
+0.188,0.276,0.570
+0.188,0.281,0.584
+0.187,0.286,0.599
+0.187,0.291,0.614
+0.186,0.297,0.628
+0.184,0.302,0.643
+0.183,0.307,0.658
+0.181,0.312,0.673
+0.179,0.317,0.687
+0.177,0.323,0.702
+0.174,0.328,0.717
+0.171,0.333,0.732
+0.168,0.339,0.747
+0.165,0.344,0.762
+0.161,0.349,0.777
+0.158,0.355,0.792
+0.154,0.360,0.807
+0.150,0.366,0.822
+0.146,0.371,0.837
+0.143,0.377,0.851
+0.140,0.382,0.865
+0.138,0.388,0.878
+0.137,0.393,0.892
+0.138,0.399,0.904
+0.141,0.405,0.916
+0.146,0.410,0.927
+0.153,0.416,0.937
+0.162,0.422,0.947
+0.173,0.428,0.955
+0.186,0.434,0.963
diff --git a/pyqtgraph/colors/maps/CET-C4.csv b/pyqtgraph/colors/maps/CET-C4.csv
new file mode 100644
index 00000000..f2f82bb3
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-C4.csv
@@ -0,0 +1,256 @@
+0.873,0.836,0.849
+0.878,0.834,0.841
+0.882,0.831,0.832
+0.886,0.827,0.823
+0.889,0.821,0.812
+0.892,0.815,0.802
+0.895,0.808,0.790
+0.897,0.800,0.778
+0.898,0.792,0.766
+0.900,0.783,0.753
+0.901,0.773,0.740
+0.902,0.763,0.727
+0.903,0.753,0.713
+0.903,0.743,0.700
+0.904,0.732,0.686
+0.904,0.722,0.672
+0.904,0.711,0.658
+0.903,0.700,0.644
+0.903,0.689,0.630
+0.902,0.678,0.617
+0.902,0.667,0.603
+0.901,0.656,0.589
+0.900,0.645,0.575
+0.899,0.634,0.562
+0.898,0.623,0.548
+0.896,0.612,0.534
+0.895,0.601,0.521
+0.893,0.589,0.507
+0.892,0.578,0.494
+0.890,0.567,0.480
+0.888,0.556,0.467
+0.886,0.545,0.454
+0.884,0.533,0.440
+0.881,0.522,0.427
+0.879,0.511,0.414
+0.876,0.500,0.401
+0.874,0.488,0.388
+0.871,0.477,0.375
+0.868,0.465,0.362
+0.866,0.454,0.349
+0.863,0.442,0.336
+0.859,0.430,0.323
+0.856,0.419,0.310
+0.853,0.407,0.297
+0.850,0.395,0.284
+0.846,0.383,0.271
+0.843,0.371,0.259
+0.839,0.358,0.246
+0.835,0.346,0.233
+0.832,0.334,0.221
+0.828,0.321,0.208
+0.824,0.309,0.196
+0.820,0.296,0.184
+0.816,0.284,0.172
+0.813,0.271,0.161
+0.809,0.260,0.150
+0.805,0.248,0.139
+0.802,0.237,0.130
+0.799,0.226,0.120
+0.796,0.217,0.112
+0.794,0.209,0.105
+0.792,0.202,0.099
+0.791,0.196,0.095
+0.790,0.193,0.092
+0.789,0.191,0.090
+0.789,0.191,0.090
+0.790,0.193,0.092
+0.791,0.198,0.096
+0.793,0.203,0.101
+0.795,0.211,0.107
+0.797,0.219,0.114
+0.800,0.229,0.123
+0.803,0.240,0.132
+0.806,0.251,0.142
+0.810,0.263,0.153
+0.814,0.275,0.164
+0.817,0.287,0.176
+0.821,0.300,0.187
+0.825,0.312,0.199
+0.829,0.324,0.212
+0.833,0.337,0.224
+0.836,0.349,0.237
+0.840,0.362,0.249
+0.844,0.374,0.262
+0.847,0.386,0.275
+0.851,0.398,0.288
+0.854,0.410,0.300
+0.857,0.422,0.313
+0.860,0.433,0.326
+0.863,0.445,0.339
+0.866,0.457,0.352
+0.869,0.468,0.365
+0.872,0.480,0.378
+0.875,0.491,0.391
+0.877,0.503,0.404
+0.880,0.514,0.418
+0.882,0.525,0.431
+0.884,0.537,0.444
+0.886,0.548,0.457
+0.888,0.559,0.471
+0.890,0.570,0.484
+0.892,0.581,0.497
+0.894,0.592,0.511
+0.895,0.604,0.524
+0.897,0.615,0.538
+0.898,0.626,0.552
+0.899,0.637,0.565
+0.900,0.648,0.579
+0.901,0.659,0.593
+0.902,0.670,0.607
+0.902,0.681,0.620
+0.903,0.692,0.634
+0.903,0.703,0.648
+0.903,0.713,0.662
+0.903,0.724,0.676
+0.903,0.735,0.690
+0.902,0.745,0.703
+0.901,0.755,0.717
+0.900,0.764,0.731
+0.899,0.774,0.744
+0.897,0.782,0.757
+0.894,0.790,0.770
+0.891,0.798,0.782
+0.888,0.804,0.794
+0.884,0.810,0.806
+0.880,0.815,0.816
+0.875,0.818,0.827
+0.870,0.821,0.836
+0.864,0.822,0.844
+0.857,0.822,0.852
+0.851,0.821,0.859
+0.843,0.819,0.865
+0.836,0.816,0.871
+0.828,0.812,0.875
+0.819,0.807,0.879
+0.811,0.802,0.883
+0.802,0.795,0.886
+0.793,0.788,0.888
+0.784,0.781,0.890
+0.775,0.773,0.891
+0.765,0.765,0.892
+0.756,0.757,0.893
+0.746,0.749,0.894
+0.737,0.740,0.895
+0.727,0.731,0.895
+0.717,0.723,0.896
+0.707,0.714,0.896
+0.697,0.705,0.897
+0.687,0.697,0.897
+0.677,0.688,0.897
+0.667,0.679,0.897
+0.657,0.670,0.898
+0.646,0.662,0.898
+0.636,0.653,0.898
+0.625,0.644,0.898
+0.615,0.636,0.898
+0.604,0.627,0.899
+0.593,0.619,0.899
+0.582,0.610,0.899
+0.571,0.602,0.899
+0.559,0.593,0.899
+0.548,0.585,0.899
+0.536,0.576,0.899
+0.524,0.568,0.899
+0.512,0.560,0.899
+0.500,0.551,0.899
+0.487,0.543,0.899
+0.475,0.535,0.899
+0.462,0.526,0.899
+0.448,0.518,0.899
+0.435,0.510,0.899
+0.421,0.502,0.899
+0.406,0.494,0.899
+0.392,0.486,0.899
+0.376,0.478,0.899
+0.361,0.470,0.899
+0.344,0.462,0.899
+0.328,0.455,0.898
+0.311,0.447,0.898
+0.293,0.440,0.898
+0.274,0.433,0.898
+0.255,0.426,0.898
+0.236,0.420,0.898
+0.216,0.414,0.898
+0.196,0.409,0.897
+0.177,0.404,0.897
+0.157,0.400,0.897
+0.139,0.396,0.897
+0.123,0.393,0.897
+0.110,0.391,0.897
+0.101,0.390,0.897
+0.099,0.390,0.897
+0.102,0.390,0.897
+0.112,0.392,0.897
+0.126,0.394,0.897
+0.143,0.397,0.897
+0.161,0.400,0.897
+0.181,0.405,0.897
+0.201,0.410,0.897
+0.221,0.415,0.898
+0.240,0.421,0.898
+0.260,0.428,0.898
+0.278,0.435,0.898
+0.297,0.442,0.898
+0.314,0.449,0.898
+0.331,0.456,0.898
+0.348,0.464,0.899
+0.364,0.472,0.899
+0.380,0.480,0.899
+0.395,0.488,0.899
+0.409,0.496,0.899
+0.424,0.504,0.899
+0.438,0.512,0.899
+0.451,0.520,0.899
+0.465,0.528,0.899
+0.477,0.536,0.899
+0.490,0.545,0.899
+0.503,0.553,0.899
+0.515,0.561,0.899
+0.527,0.570,0.899
+0.539,0.578,0.899
+0.550,0.586,0.899
+0.562,0.595,0.899
+0.573,0.603,0.899
+0.584,0.612,0.899
+0.595,0.620,0.899
+0.606,0.629,0.899
+0.617,0.638,0.898
+0.628,0.646,0.898
+0.638,0.655,0.898
+0.648,0.664,0.898
+0.659,0.672,0.898
+0.669,0.681,0.897
+0.679,0.690,0.897
+0.689,0.698,0.897
+0.699,0.707,0.897
+0.709,0.716,0.896
+0.719,0.725,0.896
+0.729,0.734,0.896
+0.739,0.742,0.895
+0.748,0.751,0.895
+0.758,0.760,0.894
+0.767,0.768,0.894
+0.776,0.777,0.893
+0.785,0.785,0.892
+0.794,0.793,0.891
+0.803,0.800,0.889
+0.811,0.807,0.888
+0.820,0.814,0.886
+0.828,0.820,0.883
+0.835,0.825,0.880
+0.843,0.829,0.877
+0.850,0.833,0.873
+0.856,0.835,0.868
+0.862,0.837,0.862
+0.868,0.837,0.856
diff --git a/pyqtgraph/colors/maps/CET-C4s.csv b/pyqtgraph/colors/maps/CET-C4s.csv
new file mode 100644
index 00000000..67dd578a
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-C4s.csv
@@ -0,0 +1,256 @@
+0.102,0.390,0.897
+0.112,0.392,0.897
+0.126,0.394,0.897
+0.143,0.397,0.897
+0.161,0.400,0.897
+0.181,0.405,0.897
+0.201,0.410,0.897
+0.221,0.415,0.898
+0.240,0.421,0.898
+0.260,0.428,0.898
+0.278,0.435,0.898
+0.297,0.442,0.898
+0.314,0.449,0.898
+0.331,0.456,0.898
+0.348,0.464,0.899
+0.364,0.472,0.899
+0.380,0.480,0.899
+0.395,0.488,0.899
+0.409,0.496,0.899
+0.424,0.504,0.899
+0.438,0.512,0.899
+0.451,0.520,0.899
+0.465,0.528,0.899
+0.477,0.536,0.899
+0.490,0.545,0.899
+0.503,0.553,0.899
+0.515,0.561,0.899
+0.527,0.570,0.899
+0.539,0.578,0.899
+0.550,0.586,0.899
+0.562,0.595,0.899
+0.573,0.603,0.899
+0.584,0.612,0.899
+0.595,0.620,0.899
+0.606,0.629,0.899
+0.617,0.638,0.898
+0.628,0.646,0.898
+0.638,0.655,0.898
+0.648,0.664,0.898
+0.659,0.672,0.898
+0.669,0.681,0.897
+0.679,0.690,0.897
+0.689,0.698,0.897
+0.699,0.707,0.897
+0.709,0.716,0.896
+0.719,0.725,0.896
+0.729,0.734,0.896
+0.739,0.742,0.895
+0.748,0.751,0.895
+0.758,0.760,0.894
+0.767,0.768,0.894
+0.776,0.777,0.893
+0.785,0.785,0.892
+0.794,0.793,0.891
+0.803,0.800,0.889
+0.811,0.807,0.888
+0.820,0.814,0.886
+0.828,0.820,0.883
+0.835,0.825,0.880
+0.843,0.829,0.877
+0.850,0.833,0.873
+0.856,0.835,0.868
+0.862,0.837,0.862
+0.868,0.837,0.856
+0.873,0.836,0.849
+0.878,0.834,0.841
+0.882,0.831,0.832
+0.886,0.827,0.823
+0.889,0.821,0.812
+0.892,0.815,0.802
+0.895,0.808,0.790
+0.897,0.800,0.778
+0.898,0.792,0.766
+0.900,0.783,0.753
+0.901,0.773,0.740
+0.902,0.763,0.727
+0.903,0.753,0.713
+0.903,0.743,0.700
+0.904,0.732,0.686
+0.904,0.722,0.672
+0.904,0.711,0.658
+0.903,0.700,0.644
+0.903,0.689,0.630
+0.902,0.678,0.617
+0.902,0.667,0.603
+0.901,0.656,0.589
+0.900,0.645,0.575
+0.899,0.634,0.562
+0.898,0.623,0.548
+0.896,0.612,0.534
+0.895,0.601,0.521
+0.893,0.589,0.507
+0.892,0.578,0.494
+0.890,0.567,0.480
+0.888,0.556,0.467
+0.886,0.545,0.454
+0.884,0.533,0.440
+0.881,0.522,0.427
+0.879,0.511,0.414
+0.876,0.500,0.401
+0.874,0.488,0.388
+0.871,0.477,0.375
+0.868,0.465,0.362
+0.866,0.454,0.349
+0.863,0.442,0.336
+0.859,0.430,0.323
+0.856,0.419,0.310
+0.853,0.407,0.297
+0.850,0.395,0.284
+0.846,0.383,0.271
+0.843,0.371,0.259
+0.839,0.358,0.246
+0.835,0.346,0.233
+0.832,0.334,0.221
+0.828,0.321,0.208
+0.824,0.309,0.196
+0.820,0.296,0.184
+0.816,0.284,0.172
+0.813,0.271,0.161
+0.809,0.260,0.150
+0.805,0.248,0.139
+0.802,0.237,0.130
+0.799,0.226,0.120
+0.796,0.217,0.112
+0.794,0.209,0.105
+0.792,0.202,0.099
+0.791,0.196,0.095
+0.790,0.193,0.092
+0.789,0.191,0.090
+0.789,0.191,0.090
+0.790,0.193,0.092
+0.791,0.198,0.096
+0.793,0.203,0.101
+0.795,0.211,0.107
+0.797,0.219,0.114
+0.800,0.229,0.123
+0.803,0.240,0.132
+0.806,0.251,0.142
+0.810,0.263,0.153
+0.814,0.275,0.164
+0.817,0.287,0.176
+0.821,0.300,0.187
+0.825,0.312,0.199
+0.829,0.324,0.212
+0.833,0.337,0.224
+0.836,0.349,0.237
+0.840,0.362,0.249
+0.844,0.374,0.262
+0.847,0.386,0.275
+0.851,0.398,0.288
+0.854,0.410,0.300
+0.857,0.422,0.313
+0.860,0.433,0.326
+0.863,0.445,0.339
+0.866,0.457,0.352
+0.869,0.468,0.365
+0.872,0.480,0.378
+0.875,0.491,0.391
+0.877,0.503,0.404
+0.880,0.514,0.418
+0.882,0.525,0.431
+0.884,0.537,0.444
+0.886,0.548,0.457
+0.888,0.559,0.471
+0.890,0.570,0.484
+0.892,0.581,0.497
+0.894,0.592,0.511
+0.895,0.604,0.524
+0.897,0.615,0.538
+0.898,0.626,0.552
+0.899,0.637,0.565
+0.900,0.648,0.579
+0.901,0.659,0.593
+0.902,0.670,0.607
+0.902,0.681,0.620
+0.903,0.692,0.634
+0.903,0.703,0.648
+0.903,0.713,0.662
+0.903,0.724,0.676
+0.903,0.735,0.690
+0.902,0.745,0.703
+0.901,0.755,0.717
+0.900,0.764,0.731
+0.899,0.774,0.744
+0.897,0.782,0.757
+0.894,0.790,0.770
+0.891,0.798,0.782
+0.888,0.804,0.794
+0.884,0.810,0.806
+0.880,0.815,0.816
+0.875,0.818,0.827
+0.870,0.821,0.836
+0.864,0.822,0.844
+0.857,0.822,0.852
+0.851,0.821,0.859
+0.843,0.819,0.865
+0.836,0.816,0.871
+0.828,0.812,0.875
+0.819,0.807,0.879
+0.811,0.802,0.883
+0.802,0.795,0.886
+0.793,0.788,0.888
+0.784,0.781,0.890
+0.775,0.773,0.891
+0.765,0.765,0.892
+0.756,0.757,0.893
+0.746,0.749,0.894
+0.737,0.740,0.895
+0.727,0.731,0.895
+0.717,0.723,0.896
+0.707,0.714,0.896
+0.697,0.705,0.897
+0.687,0.697,0.897
+0.677,0.688,0.897
+0.667,0.679,0.897
+0.657,0.670,0.898
+0.646,0.662,0.898
+0.636,0.653,0.898
+0.625,0.644,0.898
+0.615,0.636,0.898
+0.604,0.627,0.899
+0.593,0.619,0.899
+0.582,0.610,0.899
+0.571,0.602,0.899
+0.559,0.593,0.899
+0.548,0.585,0.899
+0.536,0.576,0.899
+0.524,0.568,0.899
+0.512,0.560,0.899
+0.500,0.551,0.899
+0.487,0.543,0.899
+0.475,0.535,0.899
+0.462,0.526,0.899
+0.448,0.518,0.899
+0.435,0.510,0.899
+0.421,0.502,0.899
+0.406,0.494,0.899
+0.392,0.486,0.899
+0.376,0.478,0.899
+0.361,0.470,0.899
+0.344,0.462,0.899
+0.328,0.455,0.898
+0.311,0.447,0.898
+0.293,0.440,0.898
+0.274,0.433,0.898
+0.255,0.426,0.898
+0.236,0.420,0.898
+0.216,0.414,0.898
+0.196,0.409,0.897
+0.177,0.404,0.897
+0.157,0.400,0.897
+0.139,0.396,0.897
+0.123,0.393,0.897
+0.110,0.391,0.897
+0.101,0.390,0.897
+0.099,0.390,0.897
diff --git a/pyqtgraph/colors/maps/CET-C5.csv b/pyqtgraph/colors/maps/CET-C5.csv
new file mode 100644
index 00000000..c9256c44
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-C5.csv
@@ -0,0 +1,256 @@
+0.469,0.469,0.469
+0.474,0.474,0.474
+0.479,0.479,0.479
+0.484,0.484,0.484
+0.489,0.489,0.489
+0.494,0.494,0.494
+0.499,0.499,0.499
+0.505,0.505,0.505
+0.510,0.510,0.510
+0.515,0.515,0.515
+0.520,0.521,0.521
+0.526,0.526,0.526
+0.531,0.531,0.531
+0.537,0.537,0.537
+0.542,0.542,0.542
+0.548,0.548,0.548
+0.553,0.553,0.553
+0.558,0.559,0.559
+0.564,0.564,0.564
+0.569,0.570,0.570
+0.575,0.575,0.575
+0.581,0.581,0.581
+0.586,0.586,0.586
+0.592,0.592,0.592
+0.597,0.597,0.597
+0.603,0.603,0.603
+0.608,0.609,0.609
+0.614,0.614,0.614
+0.620,0.620,0.620
+0.625,0.625,0.625
+0.631,0.631,0.631
+0.637,0.637,0.637
+0.642,0.642,0.642
+0.648,0.648,0.648
+0.653,0.654,0.654
+0.659,0.659,0.659
+0.665,0.665,0.665
+0.671,0.671,0.671
+0.676,0.676,0.676
+0.682,0.682,0.682
+0.688,0.688,0.688
+0.693,0.694,0.693
+0.699,0.699,0.699
+0.705,0.705,0.705
+0.711,0.711,0.711
+0.716,0.717,0.716
+0.722,0.722,0.722
+0.728,0.728,0.728
+0.733,0.734,0.734
+0.739,0.739,0.739
+0.745,0.745,0.745
+0.750,0.750,0.750
+0.755,0.756,0.756
+0.761,0.761,0.761
+0.766,0.766,0.766
+0.770,0.771,0.771
+0.775,0.775,0.775
+0.779,0.779,0.779
+0.783,0.783,0.783
+0.786,0.786,0.786
+0.788,0.788,0.788
+0.790,0.790,0.790
+0.792,0.792,0.792
+0.792,0.793,0.793
+0.793,0.793,0.793
+0.792,0.792,0.792
+0.791,0.791,0.791
+0.789,0.789,0.789
+0.786,0.786,0.786
+0.783,0.783,0.783
+0.780,0.780,0.780
+0.776,0.776,0.776
+0.771,0.772,0.772
+0.767,0.767,0.767
+0.762,0.762,0.762
+0.757,0.757,0.757
+0.751,0.752,0.752
+0.746,0.746,0.746
+0.740,0.741,0.741
+0.735,0.735,0.735
+0.729,0.729,0.729
+0.723,0.724,0.724
+0.718,0.718,0.718
+0.712,0.712,0.712
+0.706,0.706,0.706
+0.701,0.701,0.701
+0.695,0.695,0.695
+0.689,0.689,0.689
+0.683,0.683,0.683
+0.678,0.678,0.678
+0.672,0.672,0.672
+0.666,0.666,0.666
+0.661,0.661,0.661
+0.655,0.655,0.655
+0.649,0.649,0.649
+0.644,0.644,0.644
+0.638,0.638,0.638
+0.632,0.632,0.632
+0.627,0.627,0.627
+0.621,0.621,0.621
+0.615,0.615,0.615
+0.610,0.610,0.610
+0.604,0.604,0.604
+0.599,0.599,0.599
+0.593,0.593,0.593
+0.587,0.588,0.588
+0.582,0.582,0.582
+0.576,0.576,0.576
+0.571,0.571,0.571
+0.565,0.565,0.565
+0.560,0.560,0.560
+0.554,0.554,0.554
+0.549,0.549,0.549
+0.543,0.543,0.543
+0.538,0.538,0.538
+0.532,0.532,0.532
+0.527,0.527,0.527
+0.521,0.522,0.522
+0.516,0.516,0.516
+0.511,0.511,0.511
+0.505,0.505,0.505
+0.500,0.500,0.500
+0.494,0.494,0.494
+0.489,0.489,0.489
+0.484,0.484,0.484
+0.478,0.478,0.478
+0.473,0.473,0.473
+0.468,0.468,0.468
+0.462,0.462,0.462
+0.457,0.457,0.457
+0.452,0.452,0.452
+0.446,0.446,0.446
+0.441,0.441,0.441
+0.436,0.436,0.436
+0.430,0.431,0.431
+0.425,0.425,0.425
+0.420,0.420,0.420
+0.415,0.415,0.415
+0.410,0.410,0.410
+0.404,0.404,0.404
+0.399,0.399,0.399
+0.394,0.394,0.394
+0.389,0.389,0.389
+0.384,0.384,0.384
+0.378,0.379,0.379
+0.373,0.373,0.373
+0.368,0.368,0.368
+0.363,0.363,0.363
+0.358,0.358,0.358
+0.353,0.353,0.353
+0.348,0.348,0.348
+0.343,0.343,0.343
+0.338,0.338,0.338
+0.333,0.333,0.333
+0.328,0.328,0.328
+0.323,0.323,0.323
+0.318,0.318,0.318
+0.313,0.313,0.313
+0.308,0.308,0.308
+0.303,0.303,0.303
+0.298,0.298,0.298
+0.293,0.293,0.293
+0.288,0.288,0.288
+0.283,0.283,0.283
+0.278,0.278,0.278
+0.273,0.273,0.273
+0.269,0.269,0.269
+0.264,0.264,0.264
+0.259,0.259,0.259
+0.254,0.254,0.254
+0.249,0.249,0.249
+0.244,0.245,0.245
+0.240,0.240,0.240
+0.235,0.235,0.235
+0.230,0.230,0.230
+0.226,0.226,0.226
+0.221,0.221,0.221
+0.217,0.217,0.217
+0.212,0.212,0.212
+0.208,0.208,0.208
+0.204,0.204,0.204
+0.200,0.200,0.200
+0.196,0.196,0.196
+0.192,0.192,0.192
+0.189,0.189,0.189
+0.186,0.186,0.186
+0.183,0.183,0.183
+0.181,0.181,0.181
+0.179,0.179,0.179
+0.178,0.178,0.178
+0.177,0.177,0.177
+0.177,0.177,0.177
+0.177,0.177,0.177
+0.178,0.178,0.178
+0.179,0.179,0.179
+0.180,0.180,0.180
+0.183,0.183,0.183
+0.185,0.185,0.185
+0.188,0.188,0.188
+0.191,0.191,0.191
+0.195,0.195,0.195
+0.199,0.199,0.199
+0.203,0.203,0.203
+0.207,0.207,0.207
+0.211,0.211,0.211
+0.215,0.216,0.216
+0.220,0.220,0.220
+0.225,0.225,0.225
+0.229,0.229,0.229
+0.234,0.234,0.234
+0.239,0.239,0.239
+0.243,0.243,0.243
+0.248,0.248,0.248
+0.253,0.253,0.253
+0.258,0.258,0.258
+0.263,0.263,0.263
+0.267,0.267,0.267
+0.272,0.272,0.272
+0.277,0.277,0.277
+0.282,0.282,0.282
+0.287,0.287,0.287
+0.292,0.292,0.292
+0.297,0.297,0.297
+0.302,0.302,0.302
+0.307,0.307,0.307
+0.312,0.312,0.312
+0.317,0.317,0.317
+0.321,0.322,0.322
+0.326,0.327,0.327
+0.332,0.332,0.332
+0.337,0.337,0.337
+0.342,0.342,0.342
+0.347,0.347,0.347
+0.352,0.352,0.352
+0.357,0.357,0.357
+0.362,0.362,0.362
+0.367,0.367,0.367
+0.372,0.372,0.372
+0.377,0.377,0.377
+0.382,0.382,0.382
+0.387,0.388,0.388
+0.393,0.393,0.393
+0.398,0.398,0.398
+0.403,0.403,0.403
+0.408,0.408,0.408
+0.413,0.413,0.413
+0.418,0.418,0.418
+0.423,0.423,0.423
+0.428,0.429,0.429
+0.434,0.434,0.434
+0.439,0.439,0.439
+0.444,0.444,0.444
+0.449,0.449,0.449
+0.454,0.454,0.454
+0.459,0.459,0.459
+0.464,0.464,0.464
diff --git a/pyqtgraph/colors/maps/CET-C5s.csv b/pyqtgraph/colors/maps/CET-C5s.csv
new file mode 100644
index 00000000..64e44ca7
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-C5s.csv
@@ -0,0 +1,256 @@
+0.177,0.177,0.177
+0.178,0.178,0.178
+0.179,0.179,0.179
+0.180,0.180,0.180
+0.183,0.183,0.183
+0.185,0.185,0.185
+0.188,0.188,0.188
+0.191,0.191,0.191
+0.195,0.195,0.195
+0.199,0.199,0.199
+0.203,0.203,0.203
+0.207,0.207,0.207
+0.211,0.211,0.211
+0.215,0.216,0.216
+0.220,0.220,0.220
+0.225,0.225,0.225
+0.229,0.229,0.229
+0.234,0.234,0.234
+0.239,0.239,0.239
+0.243,0.243,0.243
+0.248,0.248,0.248
+0.253,0.253,0.253
+0.258,0.258,0.258
+0.263,0.263,0.263
+0.267,0.267,0.267
+0.272,0.272,0.272
+0.277,0.277,0.277
+0.282,0.282,0.282
+0.287,0.287,0.287
+0.292,0.292,0.292
+0.297,0.297,0.297
+0.302,0.302,0.302
+0.307,0.307,0.307
+0.312,0.312,0.312
+0.317,0.317,0.317
+0.321,0.322,0.322
+0.326,0.327,0.327
+0.332,0.332,0.332
+0.337,0.337,0.337
+0.342,0.342,0.342
+0.347,0.347,0.347
+0.352,0.352,0.352
+0.357,0.357,0.357
+0.362,0.362,0.362
+0.367,0.367,0.367
+0.372,0.372,0.372
+0.377,0.377,0.377
+0.382,0.382,0.382
+0.387,0.388,0.388
+0.393,0.393,0.393
+0.398,0.398,0.398
+0.403,0.403,0.403
+0.408,0.408,0.408
+0.413,0.413,0.413
+0.418,0.418,0.418
+0.423,0.423,0.423
+0.428,0.429,0.429
+0.434,0.434,0.434
+0.439,0.439,0.439
+0.444,0.444,0.444
+0.449,0.449,0.449
+0.454,0.454,0.454
+0.459,0.459,0.459
+0.464,0.464,0.464
+0.469,0.469,0.469
+0.474,0.474,0.474
+0.479,0.479,0.479
+0.484,0.484,0.484
+0.489,0.489,0.489
+0.494,0.494,0.494
+0.499,0.499,0.499
+0.505,0.505,0.505
+0.510,0.510,0.510
+0.515,0.515,0.515
+0.520,0.521,0.521
+0.526,0.526,0.526
+0.531,0.531,0.531
+0.537,0.537,0.537
+0.542,0.542,0.542
+0.548,0.548,0.548
+0.553,0.553,0.553
+0.558,0.559,0.559
+0.564,0.564,0.564
+0.569,0.570,0.570
+0.575,0.575,0.575
+0.581,0.581,0.581
+0.586,0.586,0.586
+0.592,0.592,0.592
+0.597,0.597,0.597
+0.603,0.603,0.603
+0.608,0.609,0.609
+0.614,0.614,0.614
+0.620,0.620,0.620
+0.625,0.625,0.625
+0.631,0.631,0.631
+0.637,0.637,0.637
+0.642,0.642,0.642
+0.648,0.648,0.648
+0.653,0.654,0.654
+0.659,0.659,0.659
+0.665,0.665,0.665
+0.671,0.671,0.671
+0.676,0.676,0.676
+0.682,0.682,0.682
+0.688,0.688,0.688
+0.693,0.694,0.693
+0.699,0.699,0.699
+0.705,0.705,0.705
+0.711,0.711,0.711
+0.716,0.717,0.716
+0.722,0.722,0.722
+0.728,0.728,0.728
+0.733,0.734,0.734
+0.739,0.739,0.739
+0.745,0.745,0.745
+0.750,0.750,0.750
+0.755,0.756,0.756
+0.761,0.761,0.761
+0.766,0.766,0.766
+0.770,0.771,0.771
+0.775,0.775,0.775
+0.779,0.779,0.779
+0.783,0.783,0.783
+0.786,0.786,0.786
+0.788,0.788,0.788
+0.790,0.790,0.790
+0.792,0.792,0.792
+0.792,0.793,0.793
+0.793,0.793,0.793
+0.792,0.792,0.792
+0.791,0.791,0.791
+0.789,0.789,0.789
+0.786,0.786,0.786
+0.783,0.783,0.783
+0.780,0.780,0.780
+0.776,0.776,0.776
+0.771,0.772,0.772
+0.767,0.767,0.767
+0.762,0.762,0.762
+0.757,0.757,0.757
+0.751,0.752,0.752
+0.746,0.746,0.746
+0.740,0.741,0.741
+0.735,0.735,0.735
+0.729,0.729,0.729
+0.723,0.724,0.724
+0.718,0.718,0.718
+0.712,0.712,0.712
+0.706,0.706,0.706
+0.701,0.701,0.701
+0.695,0.695,0.695
+0.689,0.689,0.689
+0.683,0.683,0.683
+0.678,0.678,0.678
+0.672,0.672,0.672
+0.666,0.666,0.666
+0.661,0.661,0.661
+0.655,0.655,0.655
+0.649,0.649,0.649
+0.644,0.644,0.644
+0.638,0.638,0.638
+0.632,0.632,0.632
+0.627,0.627,0.627
+0.621,0.621,0.621
+0.615,0.615,0.615
+0.610,0.610,0.610
+0.604,0.604,0.604
+0.599,0.599,0.599
+0.593,0.593,0.593
+0.587,0.588,0.588
+0.582,0.582,0.582
+0.576,0.576,0.576
+0.571,0.571,0.571
+0.565,0.565,0.565
+0.560,0.560,0.560
+0.554,0.554,0.554
+0.549,0.549,0.549
+0.543,0.543,0.543
+0.538,0.538,0.538
+0.532,0.532,0.532
+0.527,0.527,0.527
+0.521,0.522,0.522
+0.516,0.516,0.516
+0.511,0.511,0.511
+0.505,0.505,0.505
+0.500,0.500,0.500
+0.494,0.494,0.494
+0.489,0.489,0.489
+0.484,0.484,0.484
+0.478,0.478,0.478
+0.473,0.473,0.473
+0.468,0.468,0.468
+0.462,0.462,0.462
+0.457,0.457,0.457
+0.452,0.452,0.452
+0.446,0.446,0.446
+0.441,0.441,0.441
+0.436,0.436,0.436
+0.430,0.431,0.431
+0.425,0.425,0.425
+0.420,0.420,0.420
+0.415,0.415,0.415
+0.410,0.410,0.410
+0.404,0.404,0.404
+0.399,0.399,0.399
+0.394,0.394,0.394
+0.389,0.389,0.389
+0.384,0.384,0.384
+0.378,0.379,0.379
+0.373,0.373,0.373
+0.368,0.368,0.368
+0.363,0.363,0.363
+0.358,0.358,0.358
+0.353,0.353,0.353
+0.348,0.348,0.348
+0.343,0.343,0.343
+0.338,0.338,0.338
+0.333,0.333,0.333
+0.328,0.328,0.328
+0.323,0.323,0.323
+0.318,0.318,0.318
+0.313,0.313,0.313
+0.308,0.308,0.308
+0.303,0.303,0.303
+0.298,0.298,0.298
+0.293,0.293,0.293
+0.288,0.288,0.288
+0.283,0.283,0.283
+0.278,0.278,0.278
+0.273,0.273,0.273
+0.269,0.269,0.269
+0.264,0.264,0.264
+0.259,0.259,0.259
+0.254,0.254,0.254
+0.249,0.249,0.249
+0.244,0.245,0.245
+0.240,0.240,0.240
+0.235,0.235,0.235
+0.230,0.230,0.230
+0.226,0.226,0.226
+0.221,0.221,0.221
+0.217,0.217,0.217
+0.212,0.212,0.212
+0.208,0.208,0.208
+0.204,0.204,0.204
+0.200,0.200,0.200
+0.196,0.196,0.196
+0.192,0.192,0.192
+0.189,0.189,0.189
+0.186,0.186,0.186
+0.183,0.183,0.183
+0.181,0.181,0.181
+0.179,0.179,0.179
+0.178,0.178,0.178
+0.177,0.177,0.177
+0.177,0.177,0.177
diff --git a/pyqtgraph/colors/maps/CET-C6.csv b/pyqtgraph/colors/maps/CET-C6.csv
new file mode 100644
index 00000000..aa39a478
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-C6.csv
@@ -0,0 +1,256 @@
+0.967,0.214,0.103
+0.967,0.220,0.092
+0.966,0.228,0.082
+0.967,0.239,0.072
+0.967,0.252,0.063
+0.968,0.266,0.055
+0.969,0.282,0.047
+0.971,0.298,0.040
+0.972,0.315,0.033
+0.974,0.333,0.027
+0.976,0.350,0.023
+0.978,0.368,0.019
+0.980,0.386,0.015
+0.983,0.403,0.012
+0.985,0.421,0.010
+0.987,0.438,0.007
+0.989,0.455,0.005
+0.991,0.472,0.003
+0.992,0.489,0.001
+0.994,0.505,0.000
+0.996,0.522,0.000
+0.998,0.538,0.000
+0.999,0.554,0.000
+1.000,0.569,0.000
+1.000,0.585,0.000
+1.000,0.600,0.000
+1.000,0.616,0.000
+1.000,0.631,0.000
+1.000,0.646,0.000
+1.000,0.660,0.000
+1.000,0.675,0.000
+1.000,0.689,0.000
+1.000,0.703,0.000
+1.000,0.717,0.000
+1.000,0.730,0.000
+1.000,0.743,0.000
+0.997,0.755,0.000
+0.993,0.766,0.000
+0.988,0.777,0.000
+0.983,0.787,0.000
+0.976,0.795,0.000
+0.968,0.803,0.000
+0.959,0.809,0.000
+0.949,0.814,0.000
+0.938,0.817,0.000
+0.925,0.820,0.000
+0.912,0.821,0.000
+0.898,0.821,0.000
+0.883,0.820,0.000
+0.868,0.817,0.000
+0.852,0.814,0.000
+0.835,0.810,0.000
+0.818,0.805,0.000
+0.801,0.800,0.000
+0.783,0.794,0.000
+0.765,0.788,0.000
+0.747,0.781,0.000
+0.729,0.774,0.000
+0.711,0.767,0.000
+0.692,0.760,0.000
+0.674,0.752,0.000
+0.655,0.745,0.000
+0.637,0.737,0.000
+0.618,0.730,0.000
+0.600,0.722,0.000
+0.581,0.714,0.000
+0.562,0.707,0.001
+0.543,0.699,0.003
+0.524,0.691,0.004
+0.505,0.684,0.006
+0.486,0.676,0.008
+0.467,0.668,0.010
+0.448,0.661,0.014
+0.429,0.654,0.017
+0.409,0.647,0.022
+0.390,0.640,0.027
+0.371,0.633,0.034
+0.352,0.627,0.042
+0.334,0.621,0.051
+0.316,0.616,0.061
+0.298,0.611,0.071
+0.281,0.607,0.082
+0.265,0.604,0.094
+0.249,0.602,0.106
+0.235,0.601,0.119
+0.222,0.601,0.133
+0.210,0.601,0.147
+0.199,0.603,0.162
+0.190,0.606,0.177
+0.183,0.610,0.193
+0.177,0.614,0.210
+0.173,0.620,0.227
+0.170,0.626,0.244
+0.169,0.632,0.262
+0.169,0.640,0.281
+0.169,0.648,0.299
+0.171,0.656,0.318
+0.173,0.665,0.337
+0.176,0.674,0.356
+0.179,0.683,0.375
+0.181,0.692,0.395
+0.184,0.702,0.414
+0.187,0.711,0.434
+0.190,0.721,0.454
+0.192,0.731,0.473
+0.194,0.741,0.493
+0.195,0.751,0.513
+0.196,0.760,0.533
+0.197,0.770,0.552
+0.198,0.780,0.572
+0.197,0.790,0.592
+0.197,0.800,0.612
+0.196,0.810,0.632
+0.194,0.820,0.652
+0.192,0.830,0.672
+0.190,0.839,0.692
+0.187,0.848,0.712
+0.183,0.858,0.732
+0.180,0.866,0.752
+0.176,0.874,0.771
+0.172,0.882,0.790
+0.167,0.889,0.809
+0.163,0.895,0.827
+0.159,0.901,0.845
+0.155,0.905,0.862
+0.151,0.908,0.878
+0.149,0.910,0.893
+0.147,0.911,0.907
+0.146,0.911,0.920
+0.146,0.909,0.932
+0.147,0.906,0.943
+0.149,0.901,0.953
+0.152,0.896,0.961
+0.156,0.889,0.969
+0.160,0.881,0.975
+0.164,0.873,0.980
+0.168,0.863,0.985
+0.172,0.853,0.989
+0.176,0.843,0.992
+0.180,0.832,0.995
+0.183,0.820,0.997
+0.186,0.809,0.999
+0.188,0.797,1.000
+0.190,0.785,1.000
+0.192,0.773,1.000
+0.193,0.760,1.000
+0.193,0.748,1.000
+0.193,0.736,1.000
+0.192,0.723,1.000
+0.191,0.711,1.000
+0.189,0.699,1.000
+0.187,0.687,1.000
+0.184,0.674,1.000
+0.181,0.662,1.000
+0.177,0.650,1.000
+0.173,0.638,1.000
+0.169,0.626,1.000
+0.165,0.614,1.000
+0.161,0.603,1.000
+0.158,0.591,1.000
+0.156,0.580,1.000
+0.155,0.570,1.000
+0.155,0.559,1.000
+0.158,0.550,1.000
+0.163,0.541,1.000
+0.170,0.533,1.000
+0.180,0.525,1.000
+0.193,0.519,1.000
+0.207,0.513,1.000
+0.224,0.509,1.000
+0.242,0.506,1.000
+0.262,0.504,1.000
+0.283,0.503,1.000
+0.304,0.503,1.000
+0.326,0.504,1.000
+0.348,0.507,1.000
+0.370,0.510,1.000
+0.392,0.514,1.000
+0.414,0.519,1.000
+0.435,0.525,1.000
+0.457,0.531,1.000
+0.478,0.538,1.000
+0.498,0.546,1.000
+0.518,0.553,1.000
+0.538,0.561,1.000
+0.558,0.570,1.000
+0.577,0.578,1.000
+0.595,0.586,1.000
+0.614,0.595,1.000
+0.632,0.604,1.000
+0.649,0.613,1.000
+0.667,0.622,1.000
+0.684,0.631,1.000
+0.701,0.640,1.000
+0.718,0.648,1.000
+0.734,0.657,1.000
+0.751,0.666,1.000
+0.767,0.675,1.000
+0.783,0.684,1.000
+0.799,0.692,1.000
+0.814,0.701,1.000
+0.830,0.709,1.000
+0.845,0.716,1.000
+0.861,0.723,1.000
+0.876,0.730,1.000
+0.890,0.736,1.000
+0.905,0.740,0.994
+0.919,0.744,0.987
+0.932,0.747,0.979
+0.945,0.749,0.970
+0.957,0.750,0.959
+0.969,0.749,0.947
+0.980,0.747,0.934
+0.990,0.743,0.920
+0.999,0.738,0.904
+1.000,0.732,0.887
+1.000,0.725,0.870
+1.000,0.716,0.851
+1.000,0.707,0.832
+1.000,0.696,0.812
+1.000,0.685,0.792
+1.000,0.673,0.771
+1.000,0.661,0.750
+1.000,0.648,0.729
+1.000,0.635,0.707
+1.000,0.621,0.686
+1.000,0.607,0.664
+1.000,0.593,0.643
+1.000,0.579,0.621
+1.000,0.564,0.600
+1.000,0.549,0.578
+1.000,0.535,0.557
+1.000,0.520,0.536
+1.000,0.505,0.515
+1.000,0.489,0.494
+1.000,0.474,0.473
+1.000,0.458,0.452
+1.000,0.443,0.431
+1.000,0.427,0.411
+1.000,0.411,0.390
+1.000,0.395,0.370
+1.000,0.378,0.350
+1.000,0.362,0.330
+1.000,0.346,0.310
+1.000,0.329,0.291
+0.999,0.313,0.272
+0.995,0.297,0.254
+0.991,0.282,0.235
+0.987,0.267,0.218
+0.984,0.253,0.201
+0.980,0.240,0.185
+0.977,0.230,0.169
+0.974,0.221,0.154
+0.972,0.215,0.140
+0.970,0.212,0.127
+0.968,0.211,0.115
diff --git a/pyqtgraph/colors/maps/CET-C6s.csv b/pyqtgraph/colors/maps/CET-C6s.csv
new file mode 100644
index 00000000..b34d26c9
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-C6s.csv
@@ -0,0 +1,256 @@
+0.684,0.631,1.000
+0.701,0.640,1.000
+0.718,0.648,1.000
+0.734,0.657,1.000
+0.751,0.666,1.000
+0.767,0.675,1.000
+0.783,0.684,1.000
+0.799,0.692,1.000
+0.814,0.701,1.000
+0.830,0.709,1.000
+0.845,0.716,1.000
+0.861,0.723,1.000
+0.876,0.730,1.000
+0.890,0.736,1.000
+0.905,0.740,0.994
+0.919,0.744,0.987
+0.932,0.747,0.979
+0.945,0.749,0.970
+0.957,0.750,0.959
+0.969,0.749,0.947
+0.980,0.747,0.934
+0.990,0.743,0.920
+0.999,0.738,0.904
+1.000,0.732,0.887
+1.000,0.725,0.870
+1.000,0.716,0.851
+1.000,0.707,0.832
+1.000,0.696,0.812
+1.000,0.685,0.792
+1.000,0.673,0.771
+1.000,0.661,0.750
+1.000,0.648,0.729
+1.000,0.635,0.707
+1.000,0.621,0.686
+1.000,0.607,0.664
+1.000,0.593,0.643
+1.000,0.579,0.621
+1.000,0.564,0.600
+1.000,0.549,0.578
+1.000,0.535,0.557
+1.000,0.520,0.536
+1.000,0.505,0.515
+1.000,0.489,0.494
+1.000,0.474,0.473
+1.000,0.458,0.452
+1.000,0.443,0.431
+1.000,0.427,0.411
+1.000,0.411,0.390
+1.000,0.395,0.370
+1.000,0.378,0.350
+1.000,0.362,0.330
+1.000,0.346,0.310
+1.000,0.329,0.291
+0.999,0.313,0.272
+0.995,0.297,0.254
+0.991,0.282,0.235
+0.987,0.267,0.218
+0.984,0.253,0.201
+0.980,0.240,0.185
+0.977,0.230,0.169
+0.974,0.221,0.154
+0.972,0.215,0.140
+0.970,0.212,0.127
+0.968,0.211,0.115
+0.967,0.214,0.103
+0.967,0.220,0.092
+0.966,0.228,0.082
+0.967,0.239,0.072
+0.967,0.252,0.063
+0.968,0.266,0.055
+0.969,0.282,0.047
+0.971,0.298,0.040
+0.972,0.315,0.033
+0.974,0.333,0.027
+0.976,0.350,0.023
+0.978,0.368,0.019
+0.980,0.386,0.015
+0.983,0.403,0.012
+0.985,0.421,0.010
+0.987,0.438,0.007
+0.989,0.455,0.005
+0.991,0.472,0.003
+0.992,0.489,0.001
+0.994,0.505,0.000
+0.996,0.522,0.000
+0.998,0.538,0.000
+0.999,0.554,0.000
+1.000,0.569,0.000
+1.000,0.585,0.000
+1.000,0.600,0.000
+1.000,0.616,0.000
+1.000,0.631,0.000
+1.000,0.646,0.000
+1.000,0.660,0.000
+1.000,0.675,0.000
+1.000,0.689,0.000
+1.000,0.703,0.000
+1.000,0.717,0.000
+1.000,0.730,0.000
+1.000,0.743,0.000
+0.997,0.755,0.000
+0.993,0.766,0.000
+0.988,0.777,0.000
+0.983,0.787,0.000
+0.976,0.795,0.000
+0.968,0.803,0.000
+0.959,0.809,0.000
+0.949,0.814,0.000
+0.938,0.817,0.000
+0.925,0.820,0.000
+0.912,0.821,0.000
+0.898,0.821,0.000
+0.883,0.820,0.000
+0.868,0.817,0.000
+0.852,0.814,0.000
+0.835,0.810,0.000
+0.818,0.805,0.000
+0.801,0.800,0.000
+0.783,0.794,0.000
+0.765,0.788,0.000
+0.747,0.781,0.000
+0.729,0.774,0.000
+0.711,0.767,0.000
+0.692,0.760,0.000
+0.674,0.752,0.000
+0.655,0.745,0.000
+0.637,0.737,0.000
+0.618,0.730,0.000
+0.600,0.722,0.000
+0.581,0.714,0.000
+0.562,0.707,0.001
+0.543,0.699,0.003
+0.524,0.691,0.004
+0.505,0.684,0.006
+0.486,0.676,0.008
+0.467,0.668,0.010
+0.448,0.661,0.014
+0.429,0.654,0.017
+0.409,0.647,0.022
+0.390,0.640,0.027
+0.371,0.633,0.034
+0.352,0.627,0.042
+0.334,0.621,0.051
+0.316,0.616,0.061
+0.298,0.611,0.071
+0.281,0.607,0.082
+0.265,0.604,0.094
+0.249,0.602,0.106
+0.235,0.601,0.119
+0.222,0.601,0.133
+0.210,0.601,0.147
+0.199,0.603,0.162
+0.190,0.606,0.177
+0.183,0.610,0.193
+0.177,0.614,0.210
+0.173,0.620,0.227
+0.170,0.626,0.244
+0.169,0.632,0.262
+0.169,0.640,0.281
+0.169,0.648,0.299
+0.171,0.656,0.318
+0.173,0.665,0.337
+0.176,0.674,0.356
+0.179,0.683,0.375
+0.181,0.692,0.395
+0.184,0.702,0.414
+0.187,0.711,0.434
+0.190,0.721,0.454
+0.192,0.731,0.473
+0.194,0.741,0.493
+0.195,0.751,0.513
+0.196,0.760,0.533
+0.197,0.770,0.552
+0.198,0.780,0.572
+0.197,0.790,0.592
+0.197,0.800,0.612
+0.196,0.810,0.632
+0.194,0.820,0.652
+0.192,0.830,0.672
+0.190,0.839,0.692
+0.187,0.848,0.712
+0.183,0.858,0.732
+0.180,0.866,0.752
+0.176,0.874,0.771
+0.172,0.882,0.790
+0.167,0.889,0.809
+0.163,0.895,0.827
+0.159,0.901,0.845
+0.155,0.905,0.862
+0.151,0.908,0.878
+0.149,0.910,0.893
+0.147,0.911,0.907
+0.146,0.911,0.920
+0.146,0.909,0.932
+0.147,0.906,0.943
+0.149,0.901,0.953
+0.152,0.896,0.961
+0.156,0.889,0.969
+0.160,0.881,0.975
+0.164,0.873,0.980
+0.168,0.863,0.985
+0.172,0.853,0.989
+0.176,0.843,0.992
+0.180,0.832,0.995
+0.183,0.820,0.997
+0.186,0.809,0.999
+0.188,0.797,1.000
+0.190,0.785,1.000
+0.192,0.773,1.000
+0.193,0.760,1.000
+0.193,0.748,1.000
+0.193,0.736,1.000
+0.192,0.723,1.000
+0.191,0.711,1.000
+0.189,0.699,1.000
+0.187,0.687,1.000
+0.184,0.674,1.000
+0.181,0.662,1.000
+0.177,0.650,1.000
+0.173,0.638,1.000
+0.169,0.626,1.000
+0.165,0.614,1.000
+0.161,0.603,1.000
+0.158,0.591,1.000
+0.156,0.580,1.000
+0.155,0.570,1.000
+0.155,0.559,1.000
+0.158,0.550,1.000
+0.163,0.541,1.000
+0.170,0.533,1.000
+0.180,0.525,1.000
+0.193,0.519,1.000
+0.207,0.513,1.000
+0.224,0.509,1.000
+0.242,0.506,1.000
+0.262,0.504,1.000
+0.283,0.503,1.000
+0.304,0.503,1.000
+0.326,0.504,1.000
+0.348,0.507,1.000
+0.370,0.510,1.000
+0.392,0.514,1.000
+0.414,0.519,1.000
+0.435,0.525,1.000
+0.457,0.531,1.000
+0.478,0.538,1.000
+0.498,0.546,1.000
+0.518,0.553,1.000
+0.538,0.561,1.000
+0.558,0.570,1.000
+0.577,0.578,1.000
+0.595,0.586,1.000
+0.614,0.595,1.000
+0.632,0.604,1.000
+0.649,0.613,1.000
+0.667,0.622,1.000
diff --git a/pyqtgraph/colors/maps/CET-C7.csv b/pyqtgraph/colors/maps/CET-C7.csv
new file mode 100644
index 00000000..f0136b55
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-C7.csv
@@ -0,0 +1,256 @@
+0.914,0.894,0.098
+0.920,0.891,0.123
+0.926,0.887,0.147
+0.932,0.882,0.171
+0.937,0.876,0.193
+0.942,0.869,0.215
+0.947,0.862,0.236
+0.951,0.854,0.256
+0.955,0.846,0.275
+0.959,0.837,0.294
+0.963,0.829,0.312
+0.966,0.820,0.330
+0.970,0.811,0.346
+0.973,0.802,0.363
+0.976,0.793,0.379
+0.980,0.784,0.394
+0.983,0.774,0.409
+0.985,0.765,0.423
+0.988,0.756,0.438
+0.991,0.747,0.452
+0.993,0.737,0.465
+0.996,0.728,0.479
+0.998,0.718,0.492
+1.000,0.709,0.505
+1.000,0.699,0.518
+1.000,0.689,0.531
+1.000,0.680,0.544
+1.000,0.670,0.556
+1.000,0.660,0.568
+1.000,0.650,0.581
+1.000,0.640,0.593
+1.000,0.630,0.605
+1.000,0.619,0.617
+1.000,0.609,0.629
+1.000,0.598,0.641
+1.000,0.588,0.652
+1.000,0.577,0.664
+1.000,0.566,0.676
+1.000,0.555,0.687
+1.000,0.544,0.699
+1.000,0.533,0.710
+1.000,0.522,0.722
+1.000,0.510,0.733
+1.000,0.498,0.745
+1.000,0.486,0.756
+1.000,0.474,0.767
+1.000,0.462,0.779
+1.000,0.449,0.790
+1.000,0.436,0.801
+1.000,0.423,0.812
+1.000,0.409,0.824
+1.000,0.395,0.835
+1.000,0.381,0.846
+1.000,0.366,0.857
+1.000,0.351,0.868
+1.000,0.336,0.879
+1.000,0.321,0.890
+1.000,0.306,0.901
+1.000,0.291,0.912
+1.000,0.277,0.923
+1.000,0.265,0.933
+0.999,0.255,0.942
+0.996,0.248,0.951
+0.992,0.245,0.960
+0.987,0.246,0.967
+0.983,0.250,0.974
+0.978,0.259,0.979
+0.973,0.270,0.984
+0.967,0.284,0.988
+0.962,0.300,0.990
+0.956,0.316,0.993
+0.950,0.334,0.994
+0.944,0.351,0.995
+0.938,0.369,0.996
+0.932,0.386,0.997
+0.926,0.402,0.997
+0.920,0.419,0.997
+0.913,0.435,0.997
+0.907,0.450,0.997
+0.900,0.465,0.997
+0.893,0.480,0.997
+0.886,0.494,0.997
+0.879,0.507,0.997
+0.872,0.521,0.997
+0.865,0.534,0.997
+0.858,0.547,0.997
+0.850,0.560,0.997
+0.842,0.572,0.996
+0.835,0.584,0.996
+0.827,0.596,0.996
+0.818,0.608,0.996
+0.810,0.620,0.996
+0.802,0.631,0.996
+0.793,0.642,0.996
+0.784,0.653,0.996
+0.775,0.664,0.995
+0.766,0.675,0.995
+0.756,0.686,0.995
+0.747,0.697,0.995
+0.737,0.707,0.995
+0.726,0.718,0.995
+0.716,0.728,0.994
+0.705,0.738,0.994
+0.694,0.748,0.994
+0.683,0.758,0.994
+0.671,0.768,0.994
+0.659,0.778,0.993
+0.647,0.788,0.993
+0.634,0.798,0.993
+0.620,0.807,0.993
+0.607,0.817,0.992
+0.592,0.826,0.992
+0.578,0.836,0.992
+0.562,0.845,0.992
+0.546,0.855,0.991
+0.529,0.864,0.991
+0.511,0.873,0.990
+0.493,0.882,0.990
+0.473,0.891,0.989
+0.453,0.900,0.988
+0.431,0.908,0.987
+0.408,0.916,0.985
+0.385,0.924,0.983
+0.360,0.931,0.980
+0.334,0.937,0.976
+0.308,0.943,0.972
+0.282,0.947,0.966
+0.257,0.951,0.959
+0.232,0.953,0.951
+0.209,0.955,0.942
+0.189,0.955,0.933
+0.173,0.954,0.922
+0.160,0.952,0.910
+0.152,0.949,0.898
+0.148,0.946,0.886
+0.147,0.942,0.873
+0.149,0.938,0.860
+0.153,0.934,0.847
+0.157,0.929,0.834
+0.162,0.924,0.820
+0.167,0.919,0.807
+0.172,0.914,0.793
+0.177,0.909,0.780
+0.181,0.904,0.767
+0.185,0.899,0.753
+0.188,0.894,0.740
+0.191,0.889,0.726
+0.194,0.884,0.713
+0.196,0.879,0.700
+0.198,0.873,0.687
+0.199,0.868,0.673
+0.201,0.863,0.660
+0.202,0.858,0.647
+0.202,0.853,0.633
+0.203,0.848,0.620
+0.203,0.843,0.607
+0.203,0.838,0.594
+0.203,0.833,0.581
+0.202,0.828,0.567
+0.201,0.823,0.554
+0.200,0.819,0.541
+0.199,0.814,0.528
+0.198,0.809,0.515
+0.196,0.804,0.501
+0.194,0.799,0.488
+0.192,0.794,0.475
+0.189,0.789,0.462
+0.187,0.784,0.448
+0.184,0.779,0.435
+0.181,0.774,0.422
+0.177,0.769,0.408
+0.174,0.764,0.395
+0.170,0.760,0.381
+0.166,0.755,0.368
+0.161,0.750,0.354
+0.156,0.745,0.340
+0.151,0.740,0.326
+0.146,0.735,0.312
+0.140,0.730,0.298
+0.134,0.726,0.284
+0.128,0.721,0.269
+0.122,0.716,0.255
+0.116,0.712,0.240
+0.111,0.707,0.224
+0.107,0.703,0.209
+0.104,0.699,0.193
+0.103,0.695,0.177
+0.105,0.692,0.160
+0.109,0.690,0.144
+0.116,0.688,0.128
+0.126,0.686,0.111
+0.138,0.686,0.095
+0.152,0.686,0.078
+0.167,0.686,0.062
+0.183,0.688,0.046
+0.199,0.690,0.031
+0.216,0.692,0.019
+0.232,0.695,0.009
+0.249,0.698,0.002
+0.265,0.702,0.000
+0.281,0.705,0.000
+0.296,0.709,0.000
+0.311,0.713,0.000
+0.326,0.717,0.000
+0.340,0.721,0.000
+0.354,0.725,0.000
+0.368,0.729,0.000
+0.382,0.733,0.000
+0.395,0.737,0.000
+0.408,0.741,0.000
+0.421,0.745,0.000
+0.433,0.749,0.000
+0.446,0.753,0.000
+0.458,0.757,0.000
+0.470,0.761,0.000
+0.482,0.765,0.000
+0.494,0.769,0.000
+0.506,0.773,0.000
+0.518,0.777,0.000
+0.529,0.781,0.000
+0.541,0.785,0.000
+0.552,0.789,0.000
+0.564,0.792,0.000
+0.575,0.796,0.000
+0.586,0.800,0.000
+0.597,0.804,0.000
+0.609,0.808,0.000
+0.620,0.812,0.000
+0.631,0.816,0.000
+0.642,0.820,0.000
+0.653,0.823,0.000
+0.664,0.827,0.000
+0.675,0.831,0.000
+0.686,0.835,0.000
+0.696,0.839,0.000
+0.707,0.842,0.000
+0.718,0.846,0.000
+0.729,0.850,0.000
+0.740,0.854,0.000
+0.750,0.858,0.000
+0.761,0.861,0.000
+0.772,0.865,0.000
+0.782,0.869,0.000
+0.793,0.873,0.000
+0.803,0.876,0.000
+0.814,0.880,0.000
+0.824,0.883,0.000
+0.835,0.887,0.000
+0.845,0.890,0.000
+0.855,0.892,0.000
+0.864,0.895,0.000
+0.874,0.897,0.000
+0.883,0.898,0.000
+0.891,0.898,0.012
+0.899,0.898,0.042
+0.907,0.897,0.072
diff --git a/pyqtgraph/colors/maps/CET-C7s.csv b/pyqtgraph/colors/maps/CET-C7s.csv
new file mode 100644
index 00000000..fb46113d
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-C7s.csv
@@ -0,0 +1,256 @@
+0.152,0.686,0.078
+0.167,0.686,0.062
+0.183,0.688,0.046
+0.199,0.690,0.031
+0.216,0.692,0.019
+0.232,0.695,0.009
+0.249,0.698,0.002
+0.265,0.702,0.000
+0.281,0.705,0.000
+0.296,0.709,0.000
+0.311,0.713,0.000
+0.326,0.717,0.000
+0.340,0.721,0.000
+0.354,0.725,0.000
+0.368,0.729,0.000
+0.382,0.733,0.000
+0.395,0.737,0.000
+0.408,0.741,0.000
+0.421,0.745,0.000
+0.433,0.749,0.000
+0.446,0.753,0.000
+0.458,0.757,0.000
+0.470,0.761,0.000
+0.482,0.765,0.000
+0.494,0.769,0.000
+0.506,0.773,0.000
+0.518,0.777,0.000
+0.529,0.781,0.000
+0.541,0.785,0.000
+0.552,0.789,0.000
+0.564,0.792,0.000
+0.575,0.796,0.000
+0.586,0.800,0.000
+0.597,0.804,0.000
+0.609,0.808,0.000
+0.620,0.812,0.000
+0.631,0.816,0.000
+0.642,0.820,0.000
+0.653,0.823,0.000
+0.664,0.827,0.000
+0.675,0.831,0.000
+0.686,0.835,0.000
+0.696,0.839,0.000
+0.707,0.842,0.000
+0.718,0.846,0.000
+0.729,0.850,0.000
+0.740,0.854,0.000
+0.750,0.858,0.000
+0.761,0.861,0.000
+0.772,0.865,0.000
+0.782,0.869,0.000
+0.793,0.873,0.000
+0.803,0.876,0.000
+0.814,0.880,0.000
+0.824,0.883,0.000
+0.835,0.887,0.000
+0.845,0.890,0.000
+0.855,0.892,0.000
+0.864,0.895,0.000
+0.874,0.897,0.000
+0.883,0.898,0.000
+0.891,0.898,0.012
+0.899,0.898,0.042
+0.907,0.897,0.072
+0.914,0.894,0.098
+0.920,0.891,0.123
+0.926,0.887,0.147
+0.932,0.882,0.171
+0.937,0.876,0.193
+0.942,0.869,0.215
+0.947,0.862,0.236
+0.951,0.854,0.256
+0.955,0.846,0.275
+0.959,0.837,0.294
+0.963,0.829,0.312
+0.966,0.820,0.330
+0.970,0.811,0.346
+0.973,0.802,0.363
+0.976,0.793,0.379
+0.980,0.784,0.394
+0.983,0.774,0.409
+0.985,0.765,0.423
+0.988,0.756,0.438
+0.991,0.747,0.452
+0.993,0.737,0.465
+0.996,0.728,0.479
+0.998,0.718,0.492
+1.000,0.709,0.505
+1.000,0.699,0.518
+1.000,0.689,0.531
+1.000,0.680,0.544
+1.000,0.670,0.556
+1.000,0.660,0.568
+1.000,0.650,0.581
+1.000,0.640,0.593
+1.000,0.630,0.605
+1.000,0.619,0.617
+1.000,0.609,0.629
+1.000,0.598,0.641
+1.000,0.588,0.652
+1.000,0.577,0.664
+1.000,0.566,0.676
+1.000,0.555,0.687
+1.000,0.544,0.699
+1.000,0.533,0.710
+1.000,0.522,0.722
+1.000,0.510,0.733
+1.000,0.498,0.745
+1.000,0.486,0.756
+1.000,0.474,0.767
+1.000,0.462,0.779
+1.000,0.449,0.790
+1.000,0.436,0.801
+1.000,0.423,0.812
+1.000,0.409,0.824
+1.000,0.395,0.835
+1.000,0.381,0.846
+1.000,0.366,0.857
+1.000,0.351,0.868
+1.000,0.336,0.879
+1.000,0.321,0.890
+1.000,0.306,0.901
+1.000,0.291,0.912
+1.000,0.277,0.923
+1.000,0.265,0.933
+0.999,0.255,0.942
+0.996,0.248,0.951
+0.992,0.245,0.960
+0.987,0.246,0.967
+0.983,0.250,0.974
+0.978,0.259,0.979
+0.973,0.270,0.984
+0.967,0.284,0.988
+0.962,0.300,0.990
+0.956,0.316,0.993
+0.950,0.334,0.994
+0.944,0.351,0.995
+0.938,0.369,0.996
+0.932,0.386,0.997
+0.926,0.402,0.997
+0.920,0.419,0.997
+0.913,0.435,0.997
+0.907,0.450,0.997
+0.900,0.465,0.997
+0.893,0.480,0.997
+0.886,0.494,0.997
+0.879,0.507,0.997
+0.872,0.521,0.997
+0.865,0.534,0.997
+0.858,0.547,0.997
+0.850,0.560,0.997
+0.842,0.572,0.996
+0.835,0.584,0.996
+0.827,0.596,0.996
+0.818,0.608,0.996
+0.810,0.620,0.996
+0.802,0.631,0.996
+0.793,0.642,0.996
+0.784,0.653,0.996
+0.775,0.664,0.995
+0.766,0.675,0.995
+0.756,0.686,0.995
+0.747,0.697,0.995
+0.737,0.707,0.995
+0.726,0.718,0.995
+0.716,0.728,0.994
+0.705,0.738,0.994
+0.694,0.748,0.994
+0.683,0.758,0.994
+0.671,0.768,0.994
+0.659,0.778,0.993
+0.647,0.788,0.993
+0.634,0.798,0.993
+0.620,0.807,0.993
+0.607,0.817,0.992
+0.592,0.826,0.992
+0.578,0.836,0.992
+0.562,0.845,0.992
+0.546,0.855,0.991
+0.529,0.864,0.991
+0.511,0.873,0.990
+0.493,0.882,0.990
+0.473,0.891,0.989
+0.453,0.900,0.988
+0.431,0.908,0.987
+0.408,0.916,0.985
+0.385,0.924,0.983
+0.360,0.931,0.980
+0.334,0.937,0.976
+0.308,0.943,0.972
+0.282,0.947,0.966
+0.257,0.951,0.959
+0.232,0.953,0.951
+0.209,0.955,0.942
+0.189,0.955,0.933
+0.173,0.954,0.922
+0.160,0.952,0.910
+0.152,0.949,0.898
+0.148,0.946,0.886
+0.147,0.942,0.873
+0.149,0.938,0.860
+0.153,0.934,0.847
+0.157,0.929,0.834
+0.162,0.924,0.820
+0.167,0.919,0.807
+0.172,0.914,0.793
+0.177,0.909,0.780
+0.181,0.904,0.767
+0.185,0.899,0.753
+0.188,0.894,0.740
+0.191,0.889,0.726
+0.194,0.884,0.713
+0.196,0.879,0.700
+0.198,0.873,0.687
+0.199,0.868,0.673
+0.201,0.863,0.660
+0.202,0.858,0.647
+0.202,0.853,0.633
+0.203,0.848,0.620
+0.203,0.843,0.607
+0.203,0.838,0.594
+0.203,0.833,0.581
+0.202,0.828,0.567
+0.201,0.823,0.554
+0.200,0.819,0.541
+0.199,0.814,0.528
+0.198,0.809,0.515
+0.196,0.804,0.501
+0.194,0.799,0.488
+0.192,0.794,0.475
+0.189,0.789,0.462
+0.187,0.784,0.448
+0.184,0.779,0.435
+0.181,0.774,0.422
+0.177,0.769,0.408
+0.174,0.764,0.395
+0.170,0.760,0.381
+0.166,0.755,0.368
+0.161,0.750,0.354
+0.156,0.745,0.340
+0.151,0.740,0.326
+0.146,0.735,0.312
+0.140,0.730,0.298
+0.134,0.726,0.284
+0.128,0.721,0.269
+0.122,0.716,0.255
+0.116,0.712,0.240
+0.111,0.707,0.224
+0.107,0.703,0.209
+0.104,0.699,0.193
+0.103,0.695,0.177
+0.105,0.692,0.160
+0.109,0.690,0.144
+0.116,0.688,0.128
+0.126,0.686,0.111
+0.138,0.686,0.095
diff --git a/pyqtgraph/colors/maps/CET-CBC1.csv b/pyqtgraph/colors/maps/CET-CBC1.csv
new file mode 100644
index 00000000..8f92542d
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-CBC1.csv
@@ -0,0 +1,256 @@
+0.244,0.528,0.918
+0.254,0.534,0.923
+0.267,0.539,0.928
+0.280,0.545,0.931
+0.294,0.551,0.934
+0.309,0.557,0.936
+0.324,0.563,0.938
+0.340,0.569,0.939
+0.355,0.575,0.940
+0.370,0.581,0.941
+0.384,0.587,0.942
+0.399,0.593,0.942
+0.413,0.599,0.943
+0.426,0.606,0.943
+0.440,0.612,0.944
+0.453,0.618,0.944
+0.466,0.624,0.945
+0.478,0.631,0.945
+0.491,0.637,0.945
+0.503,0.644,0.946
+0.515,0.650,0.946
+0.526,0.656,0.947
+0.538,0.663,0.947
+0.549,0.669,0.947
+0.561,0.676,0.948
+0.572,0.682,0.948
+0.583,0.689,0.948
+0.593,0.695,0.949
+0.604,0.702,0.949
+0.615,0.708,0.949
+0.625,0.715,0.950
+0.636,0.722,0.950
+0.646,0.728,0.950
+0.656,0.735,0.951
+0.666,0.742,0.951
+0.676,0.748,0.951
+0.686,0.755,0.951
+0.696,0.762,0.952
+0.706,0.768,0.952
+0.716,0.775,0.952
+0.726,0.782,0.952
+0.735,0.789,0.952
+0.745,0.795,0.953
+0.754,0.802,0.953
+0.764,0.809,0.953
+0.773,0.816,0.953
+0.783,0.823,0.953
+0.792,0.829,0.954
+0.801,0.836,0.954
+0.811,0.843,0.954
+0.820,0.850,0.954
+0.829,0.857,0.954
+0.838,0.864,0.954
+0.847,0.870,0.954
+0.856,0.877,0.953
+0.865,0.884,0.953
+0.873,0.890,0.952
+0.882,0.896,0.950
+0.890,0.901,0.948
+0.897,0.906,0.945
+0.904,0.910,0.941
+0.910,0.914,0.936
+0.915,0.916,0.930
+0.919,0.917,0.923
+0.922,0.917,0.915
+0.924,0.916,0.906
+0.925,0.914,0.895
+0.925,0.911,0.884
+0.924,0.908,0.872
+0.922,0.903,0.860
+0.920,0.898,0.847
+0.917,0.892,0.834
+0.913,0.886,0.821
+0.909,0.879,0.807
+0.905,0.872,0.794
+0.901,0.866,0.780
+0.897,0.859,0.766
+0.892,0.852,0.753
+0.888,0.845,0.739
+0.883,0.838,0.726
+0.878,0.831,0.712
+0.873,0.824,0.699
+0.869,0.818,0.685
+0.864,0.811,0.672
+0.859,0.804,0.658
+0.854,0.797,0.645
+0.849,0.790,0.631
+0.844,0.784,0.618
+0.839,0.777,0.605
+0.834,0.770,0.591
+0.829,0.763,0.578
+0.824,0.757,0.565
+0.819,0.750,0.552
+0.814,0.743,0.538
+0.808,0.736,0.525
+0.803,0.730,0.512
+0.798,0.723,0.499
+0.792,0.717,0.486
+0.787,0.710,0.472
+0.782,0.703,0.459
+0.776,0.697,0.446
+0.771,0.690,0.433
+0.765,0.684,0.420
+0.759,0.677,0.406
+0.754,0.670,0.393
+0.748,0.664,0.380
+0.742,0.657,0.367
+0.737,0.651,0.353
+0.731,0.645,0.340
+0.725,0.638,0.327
+0.719,0.632,0.313
+0.713,0.625,0.299
+0.707,0.619,0.286
+0.701,0.612,0.272
+0.695,0.606,0.258
+0.689,0.600,0.244
+0.683,0.593,0.230
+0.677,0.587,0.216
+0.671,0.581,0.201
+0.665,0.574,0.187
+0.658,0.568,0.172
+0.652,0.562,0.157
+0.645,0.556,0.143
+0.639,0.550,0.129
+0.632,0.543,0.115
+0.626,0.537,0.102
+0.619,0.531,0.090
+0.612,0.525,0.079
+0.605,0.519,0.071
+0.598,0.512,0.064
+0.591,0.506,0.059
+0.584,0.500,0.057
+0.577,0.494,0.057
+0.570,0.488,0.058
+0.563,0.482,0.061
+0.556,0.476,0.065
+0.549,0.470,0.069
+0.542,0.464,0.073
+0.534,0.458,0.077
+0.527,0.452,0.081
+0.520,0.446,0.085
+0.513,0.440,0.089
+0.506,0.434,0.093
+0.499,0.428,0.096
+0.492,0.422,0.099
+0.485,0.416,0.102
+0.478,0.410,0.105
+0.470,0.404,0.108
+0.463,0.398,0.111
+0.456,0.392,0.113
+0.449,0.386,0.116
+0.442,0.380,0.118
+0.435,0.375,0.120
+0.428,0.369,0.122
+0.421,0.363,0.124
+0.414,0.357,0.126
+0.407,0.352,0.128
+0.400,0.346,0.130
+0.393,0.340,0.131
+0.387,0.334,0.133
+0.380,0.329,0.134
+0.373,0.323,0.136
+0.366,0.317,0.137
+0.359,0.312,0.138
+0.352,0.306,0.140
+0.345,0.301,0.141
+0.338,0.295,0.142
+0.331,0.289,0.143
+0.325,0.284,0.144
+0.318,0.278,0.145
+0.311,0.273,0.146
+0.304,0.267,0.147
+0.297,0.262,0.148
+0.290,0.256,0.148
+0.283,0.251,0.149
+0.277,0.246,0.150
+0.270,0.240,0.150
+0.263,0.235,0.151
+0.256,0.230,0.152
+0.249,0.224,0.152
+0.242,0.219,0.153
+0.236,0.214,0.154
+0.229,0.209,0.155
+0.223,0.204,0.156
+0.216,0.200,0.157
+0.210,0.195,0.159
+0.205,0.192,0.161
+0.199,0.188,0.163
+0.195,0.186,0.167
+0.190,0.183,0.171
+0.187,0.182,0.176
+0.184,0.182,0.181
+0.183,0.182,0.188
+0.181,0.183,0.195
+0.181,0.185,0.203
+0.181,0.187,0.212
+0.182,0.191,0.221
+0.184,0.194,0.231
+0.186,0.198,0.241
+0.188,0.203,0.251
+0.190,0.208,0.261
+0.192,0.213,0.272
+0.195,0.218,0.283
+0.198,0.223,0.294
+0.200,0.228,0.305
+0.203,0.233,0.316
+0.205,0.239,0.327
+0.207,0.244,0.338
+0.210,0.250,0.350
+0.212,0.255,0.361
+0.214,0.260,0.373
+0.216,0.266,0.384
+0.218,0.271,0.396
+0.220,0.277,0.407
+0.222,0.283,0.419
+0.224,0.288,0.431
+0.225,0.294,0.442
+0.227,0.299,0.454
+0.228,0.305,0.466
+0.229,0.311,0.478
+0.231,0.316,0.490
+0.232,0.322,0.502
+0.233,0.328,0.514
+0.234,0.333,0.526
+0.235,0.339,0.538
+0.235,0.345,0.550
+0.236,0.351,0.563
+0.236,0.356,0.575
+0.237,0.362,0.587
+0.237,0.368,0.600
+0.237,0.374,0.612
+0.237,0.380,0.625
+0.237,0.386,0.637
+0.237,0.392,0.650
+0.237,0.397,0.662
+0.236,0.403,0.675
+0.236,0.409,0.688
+0.235,0.415,0.701
+0.234,0.421,0.713
+0.233,0.427,0.726
+0.232,0.433,0.739
+0.230,0.439,0.752
+0.229,0.445,0.765
+0.227,0.452,0.778
+0.225,0.458,0.791
+0.223,0.464,0.804
+0.221,0.470,0.816
+0.220,0.476,0.829
+0.218,0.482,0.841
+0.217,0.488,0.853
+0.216,0.494,0.865
+0.217,0.499,0.876
+0.219,0.505,0.886
+0.222,0.511,0.895
+0.228,0.517,0.904
+0.235,0.522,0.911
diff --git a/pyqtgraph/colors/maps/CET-CBC2.csv b/pyqtgraph/colors/maps/CET-CBC2.csv
new file mode 100644
index 00000000..8cd0edad
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-CBC2.csv
@@ -0,0 +1,256 @@
+0.933,0.930,0.927
+0.935,0.929,0.918
+0.935,0.926,0.909
+0.935,0.923,0.899
+0.933,0.919,0.887
+0.931,0.914,0.875
+0.929,0.909,0.863
+0.925,0.903,0.849
+0.922,0.896,0.836
+0.918,0.890,0.822
+0.914,0.883,0.808
+0.910,0.876,0.793
+0.906,0.869,0.779
+0.901,0.862,0.765
+0.897,0.855,0.750
+0.893,0.848,0.736
+0.888,0.841,0.721
+0.883,0.834,0.707
+0.879,0.827,0.693
+0.874,0.820,0.678
+0.869,0.813,0.664
+0.864,0.806,0.650
+0.860,0.799,0.636
+0.855,0.792,0.622
+0.850,0.785,0.607
+0.845,0.779,0.593
+0.840,0.772,0.579
+0.835,0.765,0.565
+0.829,0.758,0.551
+0.824,0.751,0.537
+0.819,0.744,0.523
+0.814,0.738,0.509
+0.808,0.731,0.495
+0.803,0.724,0.481
+0.798,0.717,0.467
+0.792,0.711,0.452
+0.787,0.704,0.438
+0.781,0.697,0.424
+0.775,0.691,0.410
+0.770,0.684,0.396
+0.764,0.677,0.382
+0.758,0.671,0.368
+0.753,0.664,0.353
+0.747,0.658,0.339
+0.741,0.651,0.325
+0.735,0.644,0.310
+0.729,0.638,0.296
+0.723,0.631,0.281
+0.717,0.625,0.266
+0.711,0.618,0.251
+0.704,0.612,0.235
+0.698,0.605,0.220
+0.692,0.599,0.204
+0.686,0.593,0.187
+0.680,0.587,0.171
+0.674,0.580,0.154
+0.668,0.575,0.136
+0.662,0.569,0.118
+0.657,0.564,0.099
+0.652,0.559,0.080
+0.647,0.555,0.060
+0.643,0.551,0.040
+0.641,0.548,0.023
+0.639,0.546,0.011
+0.638,0.546,0.006
+0.638,0.546,0.007
+0.639,0.547,0.014
+0.641,0.549,0.027
+0.644,0.552,0.046
+0.648,0.556,0.066
+0.653,0.560,0.085
+0.658,0.565,0.104
+0.663,0.570,0.123
+0.669,0.576,0.141
+0.675,0.582,0.158
+0.681,0.588,0.175
+0.688,0.594,0.192
+0.694,0.601,0.208
+0.700,0.607,0.224
+0.706,0.614,0.240
+0.712,0.620,0.255
+0.718,0.627,0.270
+0.724,0.633,0.285
+0.730,0.640,0.300
+0.736,0.646,0.314
+0.742,0.653,0.329
+0.748,0.659,0.343
+0.754,0.666,0.357
+0.760,0.672,0.372
+0.766,0.679,0.386
+0.771,0.686,0.400
+0.777,0.692,0.414
+0.783,0.699,0.428
+0.788,0.706,0.442
+0.794,0.712,0.456
+0.799,0.719,0.470
+0.805,0.726,0.484
+0.810,0.733,0.498
+0.815,0.739,0.512
+0.820,0.746,0.527
+0.826,0.753,0.541
+0.831,0.760,0.555
+0.836,0.767,0.569
+0.841,0.773,0.583
+0.846,0.780,0.597
+0.851,0.787,0.611
+0.856,0.794,0.625
+0.861,0.801,0.640
+0.866,0.808,0.654
+0.871,0.815,0.668
+0.875,0.822,0.682
+0.880,0.829,0.697
+0.885,0.836,0.711
+0.889,0.843,0.725
+0.894,0.850,0.740
+0.898,0.857,0.754
+0.902,0.864,0.768
+0.907,0.871,0.783
+0.911,0.877,0.797
+0.915,0.884,0.812
+0.918,0.890,0.826
+0.921,0.897,0.840
+0.924,0.902,0.854
+0.926,0.907,0.867
+0.927,0.912,0.880
+0.927,0.915,0.892
+0.927,0.918,0.903
+0.925,0.919,0.913
+0.922,0.919,0.922
+0.918,0.919,0.930
+0.913,0.917,0.937
+0.908,0.914,0.943
+0.901,0.910,0.948
+0.894,0.905,0.951
+0.886,0.900,0.954
+0.877,0.894,0.956
+0.869,0.888,0.958
+0.860,0.881,0.960
+0.850,0.874,0.961
+0.841,0.868,0.961
+0.832,0.861,0.962
+0.822,0.854,0.963
+0.812,0.847,0.963
+0.803,0.840,0.964
+0.793,0.833,0.964
+0.783,0.826,0.964
+0.773,0.819,0.965
+0.763,0.812,0.965
+0.753,0.805,0.966
+0.743,0.798,0.966
+0.733,0.791,0.966
+0.723,0.785,0.967
+0.713,0.778,0.967
+0.703,0.771,0.968
+0.692,0.764,0.968
+0.682,0.757,0.968
+0.671,0.750,0.969
+0.660,0.744,0.969
+0.650,0.737,0.969
+0.639,0.730,0.969
+0.628,0.724,0.970
+0.616,0.717,0.970
+0.605,0.710,0.970
+0.594,0.704,0.971
+0.582,0.697,0.971
+0.570,0.690,0.971
+0.559,0.684,0.971
+0.546,0.677,0.971
+0.534,0.671,0.972
+0.522,0.664,0.972
+0.509,0.657,0.972
+0.496,0.651,0.972
+0.483,0.644,0.972
+0.469,0.638,0.973
+0.455,0.632,0.973
+0.441,0.625,0.973
+0.426,0.619,0.973
+0.411,0.612,0.973
+0.396,0.606,0.973
+0.380,0.600,0.973
+0.363,0.594,0.973
+0.346,0.588,0.973
+0.329,0.582,0.974
+0.311,0.576,0.974
+0.293,0.571,0.974
+0.276,0.566,0.974
+0.259,0.561,0.974
+0.244,0.557,0.974
+0.231,0.554,0.974
+0.221,0.552,0.974
+0.214,0.551,0.974
+0.212,0.550,0.974
+0.215,0.551,0.974
+0.222,0.552,0.974
+0.233,0.555,0.974
+0.247,0.558,0.974
+0.263,0.562,0.974
+0.280,0.567,0.974
+0.297,0.572,0.974
+0.315,0.577,0.974
+0.333,0.583,0.974
+0.350,0.589,0.973
+0.367,0.595,0.973
+0.383,0.601,0.973
+0.399,0.607,0.973
+0.415,0.614,0.973
+0.430,0.620,0.973
+0.444,0.627,0.973
+0.458,0.633,0.973
+0.472,0.639,0.972
+0.486,0.646,0.972
+0.499,0.652,0.972
+0.512,0.659,0.972
+0.524,0.665,0.972
+0.537,0.672,0.972
+0.549,0.679,0.971
+0.561,0.685,0.971
+0.573,0.692,0.971
+0.585,0.698,0.971
+0.596,0.705,0.970
+0.608,0.712,0.970
+0.619,0.718,0.970
+0.630,0.725,0.970
+0.641,0.732,0.969
+0.652,0.738,0.969
+0.663,0.745,0.969
+0.673,0.752,0.968
+0.684,0.759,0.968
+0.694,0.766,0.968
+0.705,0.772,0.968
+0.715,0.779,0.967
+0.725,0.786,0.967
+0.736,0.793,0.966
+0.746,0.800,0.966
+0.756,0.807,0.966
+0.766,0.814,0.965
+0.775,0.820,0.965
+0.785,0.827,0.964
+0.795,0.834,0.964
+0.805,0.841,0.963
+0.814,0.848,0.963
+0.824,0.855,0.963
+0.834,0.862,0.962
+0.843,0.869,0.962
+0.852,0.876,0.961
+0.862,0.883,0.960
+0.871,0.890,0.960
+0.880,0.896,0.959
+0.888,0.903,0.957
+0.896,0.909,0.956
+0.904,0.914,0.954
+0.911,0.919,0.952
+0.918,0.923,0.948
+0.923,0.926,0.944
+0.928,0.929,0.940
+0.931,0.930,0.934
diff --git a/pyqtgraph/colors/maps/CET-CBD1.csv b/pyqtgraph/colors/maps/CET-CBD1.csv
new file mode 100644
index 00000000..3ba00bde
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-CBD1.csv
@@ -0,0 +1,256 @@
+0.229,0.566,0.997
+0.242,0.569,0.996
+0.253,0.571,0.996
+0.265,0.574,0.996
+0.276,0.577,0.996
+0.286,0.580,0.995
+0.296,0.582,0.995
+0.306,0.585,0.995
+0.315,0.588,0.994
+0.324,0.590,0.994
+0.333,0.593,0.994
+0.342,0.596,0.993
+0.350,0.599,0.993
+0.359,0.601,0.993
+0.367,0.604,0.993
+0.375,0.607,0.992
+0.382,0.610,0.992
+0.390,0.612,0.992
+0.397,0.615,0.991
+0.405,0.618,0.991
+0.412,0.621,0.991
+0.419,0.624,0.990
+0.426,0.626,0.990
+0.433,0.629,0.990
+0.440,0.632,0.989
+0.446,0.635,0.989
+0.453,0.638,0.989
+0.459,0.640,0.988
+0.466,0.643,0.988
+0.472,0.646,0.988
+0.478,0.649,0.987
+0.485,0.652,0.987
+0.491,0.654,0.987
+0.497,0.657,0.986
+0.503,0.660,0.986
+0.509,0.663,0.986
+0.515,0.666,0.985
+0.520,0.669,0.985
+0.526,0.672,0.985
+0.532,0.674,0.984
+0.538,0.677,0.984
+0.543,0.680,0.983
+0.549,0.683,0.983
+0.554,0.686,0.983
+0.560,0.689,0.982
+0.565,0.692,0.982
+0.571,0.694,0.982
+0.576,0.697,0.981
+0.581,0.700,0.981
+0.587,0.703,0.980
+0.592,0.706,0.980
+0.597,0.709,0.980
+0.602,0.712,0.979
+0.608,0.715,0.979
+0.613,0.718,0.979
+0.618,0.721,0.978
+0.623,0.724,0.978
+0.628,0.726,0.977
+0.633,0.729,0.977
+0.638,0.732,0.977
+0.643,0.735,0.976
+0.648,0.738,0.976
+0.653,0.741,0.975
+0.658,0.744,0.975
+0.663,0.747,0.975
+0.667,0.750,0.974
+0.672,0.753,0.974
+0.677,0.756,0.973
+0.682,0.759,0.973
+0.687,0.762,0.973
+0.691,0.765,0.972
+0.696,0.768,0.972
+0.701,0.771,0.971
+0.705,0.774,0.971
+0.710,0.777,0.970
+0.715,0.780,0.970
+0.719,0.783,0.970
+0.724,0.786,0.969
+0.728,0.789,0.969
+0.733,0.792,0.968
+0.738,0.795,0.968
+0.742,0.798,0.967
+0.747,0.801,0.967
+0.751,0.804,0.966
+0.756,0.807,0.966
+0.760,0.810,0.966
+0.765,0.813,0.965
+0.769,0.816,0.965
+0.773,0.819,0.964
+0.778,0.822,0.964
+0.782,0.825,0.963
+0.787,0.828,0.963
+0.791,0.831,0.962
+0.795,0.834,0.962
+0.800,0.837,0.961
+0.804,0.840,0.961
+0.808,0.843,0.960
+0.813,0.846,0.960
+0.817,0.849,0.959
+0.821,0.852,0.959
+0.826,0.855,0.958
+0.830,0.858,0.958
+0.834,0.862,0.957
+0.838,0.865,0.957
+0.843,0.868,0.956
+0.847,0.871,0.956
+0.851,0.874,0.955
+0.855,0.877,0.955
+0.860,0.880,0.954
+0.864,0.883,0.954
+0.868,0.886,0.953
+0.872,0.889,0.953
+0.876,0.892,0.952
+0.880,0.896,0.952
+0.885,0.899,0.951
+0.889,0.902,0.951
+0.893,0.905,0.950
+0.897,0.908,0.949
+0.901,0.911,0.949
+0.905,0.914,0.948
+0.909,0.916,0.947
+0.912,0.919,0.946
+0.916,0.922,0.944
+0.919,0.924,0.942
+0.922,0.925,0.940
+0.925,0.927,0.937
+0.927,0.928,0.934
+0.929,0.928,0.930
+0.931,0.928,0.926
+0.932,0.928,0.922
+0.932,0.927,0.917
+0.932,0.925,0.911
+0.932,0.924,0.905
+0.931,0.921,0.899
+0.931,0.919,0.893
+0.929,0.916,0.887
+0.928,0.914,0.880
+0.927,0.911,0.874
+0.925,0.908,0.867
+0.924,0.905,0.860
+0.922,0.902,0.854
+0.920,0.898,0.847
+0.919,0.895,0.840
+0.917,0.892,0.834
+0.915,0.889,0.827
+0.914,0.886,0.820
+0.912,0.883,0.814
+0.910,0.880,0.807
+0.908,0.877,0.801
+0.907,0.874,0.794
+0.905,0.870,0.787
+0.903,0.867,0.781
+0.901,0.864,0.774
+0.899,0.861,0.768
+0.898,0.858,0.761
+0.896,0.855,0.754
+0.894,0.852,0.748
+0.892,0.849,0.741
+0.890,0.846,0.735
+0.888,0.843,0.728
+0.886,0.840,0.722
+0.884,0.837,0.715
+0.882,0.834,0.709
+0.881,0.831,0.702
+0.879,0.827,0.695
+0.877,0.824,0.689
+0.875,0.821,0.682
+0.873,0.818,0.676
+0.871,0.815,0.669
+0.869,0.812,0.663
+0.867,0.809,0.656
+0.865,0.806,0.650
+0.863,0.803,0.643
+0.861,0.800,0.637
+0.859,0.797,0.630
+0.856,0.794,0.624
+0.854,0.791,0.617
+0.852,0.788,0.611
+0.850,0.785,0.604
+0.848,0.782,0.598
+0.846,0.779,0.592
+0.844,0.776,0.585
+0.842,0.773,0.579
+0.840,0.770,0.572
+0.837,0.767,0.566
+0.835,0.764,0.559
+0.833,0.761,0.553
+0.831,0.758,0.546
+0.829,0.755,0.540
+0.826,0.752,0.533
+0.824,0.749,0.527
+0.822,0.746,0.521
+0.820,0.743,0.514
+0.817,0.740,0.508
+0.815,0.737,0.501
+0.813,0.734,0.495
+0.811,0.731,0.488
+0.808,0.728,0.482
+0.806,0.726,0.476
+0.804,0.723,0.469
+0.801,0.720,0.463
+0.799,0.717,0.456
+0.797,0.714,0.450
+0.794,0.711,0.443
+0.792,0.708,0.437
+0.789,0.705,0.430
+0.787,0.702,0.424
+0.785,0.699,0.418
+0.782,0.696,0.411
+0.780,0.693,0.405
+0.777,0.690,0.398
+0.775,0.688,0.392
+0.772,0.685,0.385
+0.770,0.682,0.379
+0.767,0.679,0.372
+0.765,0.676,0.366
+0.762,0.673,0.359
+0.760,0.670,0.352
+0.757,0.667,0.346
+0.755,0.664,0.339
+0.752,0.662,0.333
+0.750,0.659,0.326
+0.747,0.656,0.319
+0.745,0.653,0.313
+0.742,0.650,0.306
+0.740,0.647,0.299
+0.737,0.644,0.292
+0.734,0.641,0.286
+0.732,0.639,0.279
+0.729,0.636,0.272
+0.726,0.633,0.265
+0.724,0.630,0.258
+0.721,0.627,0.251
+0.718,0.624,0.244
+0.716,0.622,0.237
+0.713,0.619,0.230
+0.710,0.616,0.222
+0.708,0.613,0.215
+0.705,0.610,0.207
+0.702,0.608,0.200
+0.700,0.605,0.192
+0.697,0.602,0.184
+0.694,0.599,0.176
+0.691,0.596,0.168
+0.689,0.594,0.160
+0.686,0.591,0.151
+0.683,0.588,0.142
+0.680,0.585,0.133
+0.677,0.582,0.124
+0.675,0.580,0.114
+0.672,0.577,0.103
+0.669,0.574,0.092
+0.666,0.571,0.080
+0.663,0.569,0.067
+0.660,0.566,0.051
+0.657,0.563,0.033
diff --git a/pyqtgraph/colors/maps/CET-CBL1.csv b/pyqtgraph/colors/maps/CET-CBL1.csv
new file mode 100644
index 00000000..4e9df604
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-CBL1.csv
@@ -0,0 +1,256 @@
+0.066,0.066,0.066
+0.068,0.069,0.075
+0.070,0.073,0.084
+0.072,0.076,0.091
+0.073,0.079,0.099
+0.075,0.082,0.106
+0.076,0.085,0.113
+0.077,0.088,0.120
+0.077,0.090,0.127
+0.077,0.093,0.135
+0.078,0.096,0.142
+0.078,0.098,0.149
+0.078,0.101,0.157
+0.078,0.104,0.164
+0.078,0.107,0.171
+0.078,0.109,0.179
+0.077,0.112,0.186
+0.077,0.115,0.193
+0.076,0.118,0.200
+0.075,0.120,0.208
+0.075,0.123,0.215
+0.074,0.126,0.222
+0.072,0.129,0.229
+0.071,0.132,0.237
+0.070,0.135,0.244
+0.068,0.138,0.251
+0.067,0.140,0.258
+0.065,0.143,0.265
+0.063,0.146,0.272
+0.061,0.149,0.279
+0.059,0.152,0.286
+0.056,0.155,0.293
+0.054,0.158,0.300
+0.051,0.161,0.307
+0.048,0.164,0.314
+0.045,0.167,0.321
+0.042,0.170,0.328
+0.039,0.173,0.335
+0.036,0.176,0.341
+0.032,0.179,0.348
+0.029,0.182,0.355
+0.025,0.185,0.361
+0.022,0.188,0.368
+0.019,0.191,0.374
+0.015,0.194,0.381
+0.012,0.197,0.387
+0.009,0.200,0.393
+0.006,0.203,0.400
+0.004,0.206,0.406
+0.001,0.209,0.412
+0.000,0.212,0.418
+0.000,0.215,0.424
+0.000,0.218,0.430
+0.000,0.221,0.436
+0.000,0.224,0.441
+0.000,0.228,0.447
+0.000,0.231,0.452
+0.000,0.234,0.458
+0.000,0.237,0.463
+0.000,0.240,0.468
+0.000,0.243,0.474
+0.000,0.246,0.479
+0.000,0.249,0.484
+0.002,0.252,0.488
+0.005,0.255,0.493
+0.010,0.259,0.498
+0.015,0.262,0.502
+0.021,0.265,0.507
+0.028,0.268,0.511
+0.035,0.271,0.515
+0.043,0.274,0.519
+0.052,0.277,0.523
+0.060,0.281,0.526
+0.068,0.284,0.530
+0.076,0.287,0.533
+0.084,0.290,0.536
+0.092,0.293,0.539
+0.100,0.296,0.542
+0.108,0.299,0.545
+0.117,0.303,0.547
+0.125,0.306,0.549
+0.133,0.309,0.552
+0.141,0.312,0.553
+0.149,0.315,0.555
+0.158,0.319,0.556
+0.166,0.322,0.558
+0.175,0.325,0.558
+0.183,0.328,0.559
+0.191,0.331,0.560
+0.200,0.335,0.560
+0.209,0.338,0.559
+0.217,0.341,0.559
+0.226,0.344,0.558
+0.235,0.348,0.557
+0.243,0.351,0.556
+0.252,0.354,0.554
+0.261,0.357,0.551
+0.270,0.361,0.549
+0.279,0.364,0.546
+0.287,0.367,0.544
+0.295,0.370,0.541
+0.303,0.374,0.539
+0.311,0.377,0.536
+0.318,0.380,0.533
+0.326,0.384,0.531
+0.333,0.387,0.528
+0.340,0.390,0.525
+0.347,0.394,0.523
+0.354,0.397,0.520
+0.361,0.401,0.517
+0.368,0.404,0.515
+0.374,0.407,0.512
+0.381,0.411,0.509
+0.387,0.414,0.507
+0.394,0.418,0.504
+0.400,0.421,0.501
+0.406,0.424,0.498
+0.412,0.428,0.496
+0.419,0.431,0.493
+0.425,0.435,0.490
+0.431,0.438,0.487
+0.437,0.442,0.484
+0.442,0.445,0.481
+0.448,0.448,0.479
+0.454,0.452,0.476
+0.460,0.455,0.473
+0.466,0.459,0.470
+0.471,0.462,0.467
+0.477,0.466,0.464
+0.483,0.469,0.461
+0.488,0.473,0.458
+0.494,0.476,0.455
+0.499,0.480,0.452
+0.505,0.483,0.449
+0.510,0.487,0.446
+0.516,0.490,0.443
+0.521,0.494,0.440
+0.527,0.497,0.437
+0.532,0.501,0.434
+0.537,0.504,0.431
+0.543,0.508,0.428
+0.548,0.511,0.425
+0.553,0.515,0.422
+0.559,0.518,0.418
+0.564,0.522,0.415
+0.569,0.525,0.412
+0.574,0.529,0.409
+0.580,0.532,0.405
+0.585,0.536,0.402
+0.590,0.539,0.399
+0.595,0.543,0.395
+0.600,0.547,0.392
+0.606,0.550,0.389
+0.611,0.554,0.385
+0.616,0.557,0.382
+0.621,0.561,0.378
+0.626,0.564,0.375
+0.631,0.568,0.371
+0.637,0.571,0.367
+0.642,0.575,0.364
+0.647,0.578,0.361
+0.652,0.582,0.358
+0.657,0.586,0.355
+0.661,0.589,0.353
+0.666,0.593,0.351
+0.671,0.596,0.350
+0.675,0.600,0.349
+0.680,0.604,0.348
+0.684,0.607,0.348
+0.689,0.611,0.347
+0.693,0.614,0.348
+0.698,0.618,0.348
+0.702,0.622,0.349
+0.706,0.625,0.350
+0.710,0.629,0.351
+0.715,0.633,0.353
+0.719,0.636,0.354
+0.723,0.640,0.357
+0.727,0.644,0.359
+0.731,0.647,0.361
+0.735,0.651,0.364
+0.739,0.655,0.367
+0.743,0.658,0.370
+0.747,0.662,0.373
+0.751,0.666,0.377
+0.755,0.670,0.381
+0.759,0.673,0.385
+0.763,0.677,0.389
+0.766,0.681,0.393
+0.770,0.685,0.398
+0.774,0.688,0.402
+0.778,0.692,0.407
+0.781,0.696,0.412
+0.785,0.699,0.417
+0.789,0.703,0.422
+0.792,0.707,0.428
+0.796,0.711,0.433
+0.800,0.715,0.439
+0.803,0.718,0.445
+0.807,0.722,0.451
+0.810,0.726,0.457
+0.814,0.730,0.463
+0.817,0.733,0.470
+0.820,0.737,0.476
+0.824,0.741,0.483
+0.827,0.745,0.489
+0.830,0.749,0.496
+0.834,0.753,0.503
+0.837,0.756,0.510
+0.840,0.760,0.517
+0.843,0.764,0.525
+0.847,0.768,0.532
+0.850,0.772,0.540
+0.853,0.776,0.547
+0.856,0.780,0.555
+0.859,0.783,0.563
+0.862,0.787,0.571
+0.865,0.791,0.579
+0.868,0.795,0.587
+0.871,0.799,0.595
+0.873,0.803,0.603
+0.876,0.807,0.611
+0.879,0.811,0.620
+0.882,0.815,0.628
+0.884,0.818,0.637
+0.887,0.822,0.646
+0.890,0.826,0.655
+0.892,0.830,0.664
+0.895,0.834,0.672
+0.897,0.838,0.682
+0.900,0.842,0.691
+0.902,0.846,0.700
+0.904,0.850,0.709
+0.907,0.854,0.719
+0.909,0.858,0.728
+0.911,0.862,0.738
+0.913,0.866,0.747
+0.915,0.870,0.757
+0.917,0.874,0.767
+0.919,0.878,0.776
+0.921,0.882,0.786
+0.923,0.886,0.796
+0.925,0.890,0.806
+0.927,0.894,0.816
+0.928,0.898,0.827
+0.930,0.902,0.837
+0.932,0.907,0.847
+0.933,0.911,0.858
+0.935,0.915,0.868
+0.936,0.919,0.879
+0.937,0.923,0.889
+0.939,0.927,0.900
+0.940,0.931,0.911
+0.941,0.935,0.922
+0.942,0.939,0.933
+0.943,0.944,0.943
diff --git a/pyqtgraph/colors/maps/CET-CBL2.csv b/pyqtgraph/colors/maps/CET-CBL2.csv
new file mode 100644
index 00000000..f221f71a
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-CBL2.csv
@@ -0,0 +1,256 @@
+0.066,0.066,0.066
+0.068,0.070,0.074
+0.071,0.073,0.082
+0.073,0.076,0.089
+0.075,0.079,0.095
+0.077,0.082,0.101
+0.079,0.085,0.108
+0.080,0.088,0.114
+0.081,0.091,0.121
+0.082,0.094,0.128
+0.083,0.097,0.134
+0.084,0.099,0.141
+0.085,0.102,0.148
+0.086,0.105,0.154
+0.087,0.108,0.161
+0.087,0.111,0.168
+0.088,0.114,0.175
+0.088,0.116,0.182
+0.089,0.119,0.189
+0.089,0.122,0.196
+0.089,0.125,0.203
+0.089,0.128,0.210
+0.089,0.131,0.217
+0.089,0.134,0.224
+0.088,0.137,0.231
+0.088,0.140,0.238
+0.087,0.143,0.246
+0.087,0.146,0.253
+0.086,0.149,0.260
+0.085,0.152,0.267
+0.084,0.155,0.274
+0.083,0.158,0.281
+0.082,0.161,0.289
+0.081,0.164,0.296
+0.080,0.167,0.303
+0.078,0.170,0.310
+0.077,0.173,0.317
+0.076,0.176,0.324
+0.074,0.179,0.331
+0.073,0.182,0.338
+0.072,0.185,0.344
+0.070,0.189,0.351
+0.069,0.192,0.358
+0.068,0.195,0.364
+0.067,0.198,0.371
+0.066,0.201,0.377
+0.065,0.204,0.383
+0.064,0.207,0.390
+0.063,0.210,0.396
+0.062,0.214,0.402
+0.062,0.217,0.408
+0.061,0.220,0.414
+0.061,0.223,0.421
+0.060,0.226,0.427
+0.060,0.230,0.433
+0.060,0.233,0.439
+0.060,0.236,0.445
+0.060,0.239,0.451
+0.060,0.242,0.456
+0.060,0.246,0.462
+0.060,0.249,0.468
+0.060,0.252,0.474
+0.060,0.255,0.480
+0.060,0.259,0.486
+0.060,0.262,0.492
+0.060,0.265,0.498
+0.060,0.268,0.504
+0.060,0.272,0.510
+0.059,0.275,0.516
+0.059,0.278,0.522
+0.059,0.282,0.528
+0.059,0.285,0.534
+0.059,0.288,0.541
+0.059,0.292,0.547
+0.059,0.295,0.553
+0.058,0.298,0.559
+0.058,0.302,0.565
+0.058,0.305,0.571
+0.057,0.308,0.577
+0.057,0.312,0.583
+0.057,0.315,0.590
+0.056,0.318,0.596
+0.056,0.322,0.602
+0.056,0.325,0.608
+0.055,0.329,0.614
+0.055,0.332,0.621
+0.054,0.335,0.627
+0.053,0.339,0.633
+0.053,0.342,0.639
+0.052,0.346,0.646
+0.051,0.349,0.652
+0.051,0.352,0.658
+0.050,0.356,0.664
+0.049,0.359,0.671
+0.048,0.363,0.677
+0.047,0.366,0.683
+0.046,0.370,0.690
+0.045,0.373,0.696
+0.044,0.377,0.703
+0.043,0.380,0.709
+0.042,0.384,0.715
+0.041,0.387,0.722
+0.040,0.391,0.728
+0.038,0.394,0.735
+0.037,0.398,0.741
+0.036,0.401,0.747
+0.034,0.405,0.754
+0.032,0.408,0.760
+0.031,0.412,0.767
+0.029,0.415,0.773
+0.027,0.419,0.780
+0.026,0.422,0.786
+0.024,0.426,0.793
+0.022,0.429,0.799
+0.020,0.433,0.806
+0.018,0.436,0.812
+0.016,0.440,0.819
+0.014,0.444,0.826
+0.012,0.447,0.832
+0.010,0.451,0.839
+0.008,0.454,0.845
+0.006,0.458,0.852
+0.005,0.462,0.858
+0.003,0.465,0.865
+0.002,0.469,0.871
+0.001,0.472,0.878
+0.001,0.476,0.884
+0.002,0.480,0.891
+0.004,0.483,0.897
+0.007,0.487,0.903
+0.012,0.490,0.909
+0.019,0.494,0.915
+0.029,0.498,0.920
+0.042,0.501,0.925
+0.056,0.505,0.930
+0.071,0.509,0.935
+0.087,0.512,0.939
+0.104,0.516,0.942
+0.121,0.519,0.945
+0.138,0.523,0.947
+0.156,0.526,0.949
+0.175,0.530,0.950
+0.194,0.534,0.950
+0.213,0.537,0.949
+0.232,0.541,0.947
+0.252,0.544,0.945
+0.271,0.548,0.941
+0.291,0.551,0.937
+0.310,0.555,0.932
+0.329,0.558,0.926
+0.348,0.562,0.919
+0.366,0.565,0.911
+0.385,0.569,0.903
+0.402,0.573,0.894
+0.419,0.576,0.884
+0.436,0.580,0.874
+0.452,0.584,0.864
+0.468,0.587,0.853
+0.483,0.591,0.841
+0.498,0.595,0.829
+0.512,0.598,0.817
+0.525,0.602,0.805
+0.539,0.606,0.793
+0.551,0.610,0.781
+0.563,0.614,0.768
+0.575,0.617,0.756
+0.587,0.621,0.743
+0.598,0.625,0.730
+0.608,0.629,0.718
+0.619,0.633,0.705
+0.629,0.637,0.693
+0.639,0.640,0.681
+0.648,0.644,0.668
+0.658,0.648,0.656
+0.667,0.652,0.644
+0.676,0.656,0.632
+0.685,0.660,0.620
+0.693,0.663,0.608
+0.702,0.667,0.596
+0.710,0.671,0.584
+0.718,0.675,0.573
+0.726,0.678,0.561
+0.734,0.682,0.549
+0.742,0.686,0.537
+0.750,0.690,0.525
+0.758,0.693,0.514
+0.765,0.697,0.502
+0.772,0.701,0.490
+0.780,0.705,0.478
+0.787,0.708,0.466
+0.794,0.712,0.454
+0.801,0.716,0.442
+0.808,0.720,0.429
+0.815,0.723,0.417
+0.821,0.727,0.404
+0.828,0.731,0.391
+0.834,0.735,0.378
+0.841,0.739,0.365
+0.847,0.743,0.351
+0.853,0.746,0.337
+0.859,0.750,0.324
+0.865,0.754,0.309
+0.871,0.758,0.295
+0.877,0.762,0.281
+0.883,0.766,0.266
+0.889,0.770,0.251
+0.894,0.774,0.236
+0.900,0.778,0.222
+0.905,0.782,0.207
+0.910,0.786,0.193
+0.916,0.790,0.179
+0.921,0.794,0.166
+0.926,0.798,0.155
+0.931,0.802,0.145
+0.935,0.806,0.138
+0.940,0.809,0.134
+0.945,0.813,0.134
+0.949,0.817,0.137
+0.954,0.821,0.144
+0.958,0.825,0.155
+0.962,0.829,0.168
+0.966,0.833,0.185
+0.970,0.837,0.203
+0.973,0.841,0.223
+0.977,0.845,0.244
+0.980,0.849,0.267
+0.983,0.853,0.290
+0.986,0.857,0.314
+0.989,0.861,0.339
+0.991,0.865,0.364
+0.993,0.869,0.389
+0.995,0.873,0.415
+0.997,0.877,0.441
+0.998,0.882,0.467
+0.999,0.886,0.493
+1.000,0.890,0.519
+1.000,0.894,0.545
+1.000,0.898,0.571
+1.000,0.903,0.597
+1.000,0.907,0.622
+1.000,0.911,0.647
+1.000,0.915,0.672
+0.999,0.920,0.696
+0.998,0.924,0.720
+0.997,0.928,0.743
+0.996,0.933,0.765
+0.995,0.937,0.787
+0.994,0.942,0.808
+0.993,0.946,0.829
+0.992,0.950,0.849
+0.991,0.955,0.868
+0.990,0.959,0.886
+0.989,0.964,0.904
+0.988,0.968,0.921
+0.988,0.972,0.937
+0.987,0.977,0.953
diff --git a/pyqtgraph/colors/maps/CET-CBTC1.csv b/pyqtgraph/colors/maps/CET-CBTC1.csv
new file mode 100644
index 00000000..fe8c1838
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-CBTC1.csv
@@ -0,0 +1,256 @@
+0.149,0.735,0.842
+0.163,0.740,0.847
+0.179,0.744,0.851
+0.198,0.748,0.854
+0.217,0.752,0.857
+0.237,0.757,0.860
+0.257,0.761,0.863
+0.277,0.765,0.866
+0.296,0.769,0.868
+0.315,0.773,0.871
+0.333,0.777,0.873
+0.351,0.781,0.875
+0.368,0.785,0.878
+0.385,0.789,0.880
+0.401,0.793,0.882
+0.416,0.797,0.885
+0.432,0.801,0.887
+0.446,0.806,0.889
+0.461,0.810,0.891
+0.475,0.814,0.894
+0.489,0.818,0.896
+0.503,0.822,0.898
+0.516,0.826,0.901
+0.529,0.830,0.903
+0.542,0.834,0.905
+0.555,0.838,0.908
+0.568,0.842,0.910
+0.580,0.846,0.912
+0.593,0.850,0.915
+0.605,0.854,0.917
+0.617,0.858,0.919
+0.629,0.862,0.922
+0.641,0.867,0.924
+0.653,0.871,0.926
+0.664,0.875,0.928
+0.676,0.879,0.931
+0.688,0.883,0.933
+0.699,0.887,0.935
+0.710,0.891,0.938
+0.722,0.895,0.940
+0.733,0.899,0.942
+0.744,0.903,0.945
+0.755,0.907,0.947
+0.766,0.911,0.949
+0.777,0.915,0.952
+0.788,0.919,0.954
+0.799,0.923,0.956
+0.810,0.927,0.958
+0.821,0.931,0.961
+0.832,0.935,0.963
+0.842,0.939,0.965
+0.853,0.943,0.968
+0.864,0.947,0.970
+0.874,0.951,0.972
+0.885,0.955,0.974
+0.895,0.959,0.976
+0.906,0.962,0.978
+0.916,0.965,0.979
+0.926,0.968,0.980
+0.936,0.970,0.980
+0.945,0.972,0.980
+0.953,0.973,0.980
+0.961,0.973,0.978
+0.969,0.973,0.976
+0.975,0.972,0.973
+0.981,0.969,0.969
+0.985,0.966,0.964
+0.989,0.963,0.959
+0.992,0.958,0.953
+0.994,0.953,0.947
+0.995,0.948,0.940
+0.996,0.942,0.934
+0.997,0.936,0.926
+0.997,0.930,0.919
+0.997,0.923,0.912
+0.997,0.917,0.904
+0.997,0.911,0.897
+0.996,0.904,0.890
+0.996,0.898,0.882
+0.995,0.891,0.875
+0.995,0.885,0.867
+0.994,0.878,0.860
+0.993,0.871,0.852
+0.993,0.865,0.845
+0.992,0.858,0.838
+0.991,0.852,0.830
+0.990,0.845,0.823
+0.990,0.839,0.816
+0.989,0.832,0.808
+0.988,0.826,0.801
+0.987,0.819,0.794
+0.986,0.813,0.786
+0.985,0.806,0.779
+0.984,0.800,0.772
+0.983,0.793,0.765
+0.982,0.787,0.757
+0.981,0.780,0.750
+0.980,0.774,0.743
+0.979,0.767,0.736
+0.978,0.761,0.728
+0.976,0.754,0.721
+0.975,0.748,0.714
+0.974,0.741,0.707
+0.973,0.735,0.700
+0.971,0.728,0.693
+0.970,0.722,0.685
+0.969,0.715,0.678
+0.967,0.709,0.671
+0.966,0.702,0.664
+0.964,0.696,0.657
+0.963,0.689,0.650
+0.961,0.683,0.643
+0.960,0.676,0.636
+0.958,0.670,0.629
+0.957,0.663,0.622
+0.955,0.657,0.615
+0.953,0.650,0.608
+0.951,0.644,0.601
+0.949,0.638,0.594
+0.947,0.631,0.587
+0.945,0.625,0.581
+0.943,0.619,0.574
+0.940,0.612,0.568
+0.937,0.607,0.561
+0.934,0.601,0.556
+0.930,0.595,0.550
+0.926,0.590,0.545
+0.921,0.585,0.540
+0.915,0.580,0.535
+0.909,0.575,0.531
+0.903,0.571,0.527
+0.896,0.567,0.523
+0.888,0.563,0.520
+0.880,0.560,0.517
+0.872,0.556,0.514
+0.864,0.553,0.511
+0.856,0.550,0.508
+0.847,0.546,0.505
+0.838,0.543,0.503
+0.830,0.540,0.500
+0.821,0.537,0.498
+0.812,0.534,0.495
+0.804,0.531,0.493
+0.795,0.527,0.490
+0.786,0.524,0.488
+0.777,0.521,0.485
+0.769,0.518,0.483
+0.760,0.515,0.480
+0.751,0.512,0.478
+0.743,0.509,0.475
+0.734,0.505,0.473
+0.725,0.502,0.470
+0.717,0.499,0.468
+0.708,0.496,0.465
+0.699,0.493,0.463
+0.691,0.490,0.460
+0.682,0.486,0.458
+0.673,0.483,0.456
+0.665,0.480,0.453
+0.656,0.477,0.451
+0.648,0.474,0.448
+0.639,0.471,0.446
+0.630,0.467,0.443
+0.622,0.464,0.441
+0.613,0.461,0.438
+0.605,0.458,0.436
+0.596,0.455,0.433
+0.588,0.451,0.431
+0.579,0.448,0.429
+0.570,0.445,0.426
+0.562,0.442,0.424
+0.553,0.439,0.421
+0.545,0.435,0.419
+0.536,0.432,0.416
+0.528,0.429,0.414
+0.519,0.426,0.411
+0.510,0.423,0.409
+0.502,0.419,0.407
+0.493,0.416,0.404
+0.485,0.413,0.402
+0.476,0.410,0.400
+0.468,0.407,0.397
+0.459,0.404,0.395
+0.451,0.401,0.393
+0.442,0.398,0.392
+0.434,0.396,0.390
+0.426,0.394,0.389
+0.419,0.392,0.389
+0.411,0.391,0.389
+0.405,0.391,0.389
+0.398,0.391,0.391
+0.393,0.392,0.393
+0.388,0.393,0.396
+0.384,0.395,0.400
+0.380,0.398,0.404
+0.377,0.402,0.409
+0.374,0.405,0.414
+0.372,0.410,0.420
+0.371,0.414,0.426
+0.369,0.419,0.433
+0.368,0.424,0.439
+0.367,0.430,0.446
+0.366,0.435,0.453
+0.365,0.440,0.460
+0.364,0.446,0.467
+0.363,0.451,0.474
+0.362,0.457,0.481
+0.361,0.462,0.488
+0.360,0.468,0.495
+0.359,0.473,0.503
+0.357,0.479,0.510
+0.356,0.484,0.517
+0.354,0.490,0.524
+0.352,0.495,0.532
+0.351,0.501,0.539
+0.349,0.507,0.546
+0.347,0.512,0.553
+0.344,0.518,0.561
+0.342,0.523,0.568
+0.340,0.529,0.575
+0.337,0.535,0.583
+0.334,0.540,0.590
+0.332,0.546,0.597
+0.329,0.551,0.605
+0.325,0.557,0.612
+0.322,0.563,0.620
+0.319,0.568,0.627
+0.315,0.574,0.635
+0.311,0.580,0.642
+0.307,0.585,0.650
+0.303,0.591,0.657
+0.298,0.597,0.665
+0.294,0.603,0.672
+0.289,0.608,0.680
+0.284,0.614,0.687
+0.278,0.620,0.695
+0.272,0.626,0.703
+0.266,0.631,0.710
+0.260,0.637,0.718
+0.253,0.643,0.725
+0.246,0.649,0.733
+0.238,0.654,0.741
+0.230,0.660,0.748
+0.222,0.666,0.756
+0.212,0.672,0.764
+0.203,0.677,0.771
+0.193,0.683,0.779
+0.182,0.689,0.787
+0.171,0.694,0.794
+0.161,0.700,0.801
+0.151,0.705,0.808
+0.142,0.711,0.815
+0.136,0.716,0.821
+0.133,0.721,0.827
+0.134,0.726,0.833
+0.139,0.731,0.838
diff --git a/pyqtgraph/colors/maps/CET-CBTC2.csv b/pyqtgraph/colors/maps/CET-CBTC2.csv
new file mode 100644
index 00000000..b04636a6
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-CBTC2.csv
@@ -0,0 +1,256 @@
+0.985,0.981,0.982
+0.989,0.979,0.978
+0.992,0.976,0.974
+0.995,0.973,0.970
+0.997,0.968,0.964
+0.998,0.964,0.958
+0.999,0.958,0.952
+1.000,0.953,0.945
+1.000,0.947,0.938
+1.000,0.940,0.931
+1.000,0.934,0.924
+1.000,0.928,0.916
+1.000,0.921,0.909
+1.000,0.915,0.901
+1.000,0.908,0.894
+1.000,0.902,0.886
+1.000,0.895,0.879
+0.999,0.889,0.871
+0.999,0.882,0.864
+0.998,0.876,0.857
+0.998,0.869,0.849
+0.997,0.863,0.842
+0.997,0.856,0.834
+0.996,0.850,0.827
+0.996,0.843,0.819
+0.995,0.836,0.812
+0.995,0.830,0.805
+0.994,0.823,0.797
+0.993,0.817,0.790
+0.992,0.810,0.783
+0.992,0.804,0.775
+0.991,0.797,0.768
+0.990,0.791,0.761
+0.989,0.784,0.753
+0.988,0.778,0.746
+0.987,0.771,0.739
+0.986,0.765,0.732
+0.985,0.758,0.724
+0.984,0.752,0.717
+0.983,0.745,0.710
+0.982,0.739,0.703
+0.981,0.732,0.695
+0.980,0.726,0.688
+0.979,0.719,0.681
+0.977,0.713,0.674
+0.976,0.706,0.667
+0.975,0.700,0.660
+0.974,0.693,0.653
+0.972,0.687,0.646
+0.971,0.680,0.638
+0.970,0.673,0.631
+0.968,0.667,0.624
+0.967,0.660,0.617
+0.965,0.654,0.610
+0.964,0.648,0.604
+0.962,0.641,0.597
+0.961,0.635,0.590
+0.959,0.629,0.584
+0.958,0.624,0.578
+0.957,0.619,0.573
+0.956,0.614,0.568
+0.955,0.611,0.564
+0.954,0.608,0.561
+0.954,0.606,0.559
+0.953,0.605,0.558
+0.953,0.605,0.558
+0.954,0.606,0.560
+0.954,0.609,0.562
+0.955,0.612,0.565
+0.956,0.616,0.569
+0.957,0.620,0.574
+0.958,0.625,0.580
+0.960,0.631,0.586
+0.961,0.637,0.592
+0.963,0.643,0.599
+0.964,0.649,0.605
+0.966,0.656,0.612
+0.967,0.662,0.619
+0.969,0.669,0.626
+0.970,0.675,0.633
+0.971,0.682,0.640
+0.973,0.688,0.647
+0.974,0.695,0.655
+0.975,0.701,0.662
+0.977,0.708,0.669
+0.978,0.714,0.676
+0.979,0.721,0.683
+0.980,0.727,0.690
+0.981,0.734,0.697
+0.982,0.740,0.705
+0.984,0.747,0.712
+0.985,0.754,0.719
+0.986,0.760,0.726
+0.987,0.767,0.734
+0.988,0.773,0.741
+0.988,0.780,0.748
+0.989,0.786,0.755
+0.990,0.793,0.763
+0.991,0.799,0.770
+0.992,0.806,0.777
+0.993,0.812,0.785
+0.993,0.819,0.792
+0.994,0.825,0.799
+0.995,0.832,0.807
+0.995,0.838,0.814
+0.996,0.845,0.821
+0.997,0.851,0.829
+0.997,0.858,0.836
+0.998,0.864,0.844
+0.998,0.871,0.851
+0.999,0.877,0.858
+0.999,0.884,0.866
+0.999,0.890,0.873
+1.000,0.897,0.881
+1.000,0.903,0.888
+1.000,0.910,0.896
+1.000,0.916,0.903
+1.000,0.923,0.911
+1.000,0.929,0.918
+1.000,0.936,0.926
+0.999,0.942,0.933
+0.998,0.948,0.940
+0.996,0.953,0.947
+0.994,0.958,0.953
+0.992,0.963,0.959
+0.988,0.967,0.964
+0.984,0.970,0.969
+0.979,0.973,0.973
+0.973,0.975,0.977
+0.966,0.976,0.979
+0.959,0.976,0.981
+0.950,0.975,0.982
+0.941,0.973,0.983
+0.932,0.971,0.982
+0.922,0.969,0.982
+0.912,0.966,0.981
+0.902,0.963,0.979
+0.891,0.959,0.978
+0.881,0.956,0.976
+0.870,0.952,0.974
+0.859,0.948,0.972
+0.848,0.944,0.970
+0.837,0.940,0.968
+0.826,0.936,0.965
+0.815,0.932,0.963
+0.804,0.928,0.961
+0.793,0.924,0.959
+0.782,0.920,0.957
+0.771,0.916,0.955
+0.760,0.912,0.953
+0.748,0.908,0.950
+0.737,0.905,0.948
+0.725,0.901,0.946
+0.714,0.897,0.944
+0.702,0.893,0.942
+0.691,0.889,0.940
+0.679,0.885,0.938
+0.667,0.881,0.935
+0.655,0.877,0.933
+0.643,0.873,0.931
+0.631,0.869,0.929
+0.618,0.865,0.927
+0.606,0.861,0.925
+0.593,0.857,0.923
+0.581,0.853,0.920
+0.568,0.849,0.918
+0.555,0.845,0.916
+0.542,0.841,0.914
+0.528,0.837,0.912
+0.515,0.833,0.910
+0.501,0.829,0.907
+0.487,0.825,0.905
+0.472,0.821,0.903
+0.457,0.817,0.901
+0.442,0.813,0.899
+0.427,0.809,0.897
+0.411,0.805,0.895
+0.395,0.801,0.892
+0.378,0.797,0.890
+0.360,0.793,0.888
+0.342,0.789,0.886
+0.324,0.785,0.884
+0.305,0.782,0.882
+0.285,0.778,0.880
+0.265,0.774,0.878
+0.246,0.771,0.876
+0.227,0.768,0.875
+0.209,0.766,0.874
+0.193,0.764,0.872
+0.181,0.762,0.872
+0.174,0.762,0.871
+0.171,0.761,0.871
+0.175,0.762,0.871
+0.184,0.763,0.872
+0.197,0.764,0.873
+0.213,0.766,0.874
+0.231,0.769,0.875
+0.250,0.772,0.877
+0.270,0.775,0.879
+0.289,0.779,0.880
+0.309,0.782,0.882
+0.328,0.786,0.884
+0.346,0.790,0.887
+0.364,0.794,0.889
+0.381,0.798,0.891
+0.398,0.802,0.893
+0.414,0.806,0.895
+0.430,0.810,0.897
+0.446,0.814,0.899
+0.461,0.818,0.901
+0.475,0.822,0.904
+0.490,0.826,0.906
+0.504,0.830,0.908
+0.518,0.834,0.910
+0.531,0.838,0.912
+0.545,0.842,0.914
+0.558,0.846,0.917
+0.571,0.850,0.919
+0.584,0.854,0.921
+0.596,0.858,0.923
+0.609,0.862,0.925
+0.621,0.866,0.927
+0.633,0.870,0.929
+0.646,0.874,0.932
+0.658,0.878,0.934
+0.670,0.882,0.936
+0.681,0.886,0.938
+0.693,0.890,0.940
+0.705,0.893,0.942
+0.716,0.897,0.944
+0.728,0.901,0.947
+0.739,0.905,0.949
+0.751,0.909,0.951
+0.762,0.913,0.953
+0.773,0.917,0.955
+0.785,0.921,0.957
+0.796,0.925,0.959
+0.807,0.929,0.962
+0.818,0.933,0.964
+0.829,0.937,0.966
+0.840,0.941,0.968
+0.851,0.945,0.970
+0.861,0.949,0.972
+0.872,0.953,0.974
+0.883,0.957,0.976
+0.893,0.960,0.978
+0.904,0.964,0.980
+0.914,0.968,0.982
+0.924,0.971,0.984
+0.934,0.974,0.985
+0.943,0.977,0.986
+0.952,0.979,0.987
+0.960,0.981,0.987
+0.967,0.982,0.987
+0.974,0.983,0.986
+0.980,0.982,0.984
diff --git a/pyqtgraph/colors/maps/CET-CBTD1.csv b/pyqtgraph/colors/maps/CET-CBTD1.csv
new file mode 100644
index 00000000..504f1dee
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-CBTD1.csv
@@ -0,0 +1,256 @@
+0.161,0.791,0.905
+0.179,0.792,0.906
+0.195,0.794,0.907
+0.210,0.795,0.907
+0.224,0.797,0.908
+0.237,0.798,0.908
+0.250,0.799,0.909
+0.261,0.801,0.909
+0.273,0.802,0.910
+0.284,0.804,0.911
+0.294,0.805,0.911
+0.304,0.807,0.912
+0.314,0.808,0.912
+0.324,0.810,0.913
+0.333,0.811,0.913
+0.342,0.813,0.914
+0.351,0.814,0.915
+0.359,0.816,0.915
+0.368,0.817,0.916
+0.376,0.819,0.916
+0.384,0.820,0.917
+0.392,0.822,0.917
+0.400,0.823,0.918
+0.408,0.825,0.919
+0.415,0.826,0.919
+0.423,0.828,0.920
+0.430,0.829,0.920
+0.437,0.831,0.921
+0.444,0.832,0.921
+0.451,0.834,0.922
+0.458,0.835,0.923
+0.465,0.837,0.923
+0.472,0.838,0.924
+0.479,0.840,0.924
+0.485,0.841,0.925
+0.492,0.843,0.925
+0.498,0.844,0.926
+0.505,0.845,0.927
+0.511,0.847,0.927
+0.518,0.848,0.928
+0.524,0.850,0.928
+0.530,0.851,0.929
+0.536,0.853,0.929
+0.542,0.854,0.930
+0.549,0.856,0.930
+0.555,0.857,0.931
+0.561,0.859,0.932
+0.566,0.860,0.932
+0.572,0.862,0.933
+0.578,0.863,0.933
+0.584,0.865,0.934
+0.590,0.866,0.934
+0.596,0.867,0.935
+0.601,0.869,0.936
+0.607,0.870,0.936
+0.613,0.872,0.937
+0.618,0.873,0.937
+0.624,0.875,0.938
+0.629,0.876,0.938
+0.635,0.878,0.939
+0.640,0.879,0.939
+0.646,0.881,0.940
+0.651,0.882,0.941
+0.657,0.884,0.941
+0.662,0.885,0.942
+0.667,0.886,0.942
+0.673,0.888,0.943
+0.678,0.889,0.943
+0.683,0.891,0.944
+0.689,0.892,0.945
+0.694,0.894,0.945
+0.699,0.895,0.946
+0.704,0.897,0.946
+0.710,0.898,0.947
+0.715,0.899,0.947
+0.720,0.901,0.948
+0.725,0.902,0.948
+0.730,0.904,0.949
+0.735,0.905,0.950
+0.740,0.907,0.950
+0.746,0.908,0.951
+0.751,0.910,0.951
+0.756,0.911,0.952
+0.761,0.912,0.952
+0.766,0.914,0.953
+0.771,0.915,0.953
+0.776,0.917,0.954
+0.781,0.918,0.955
+0.786,0.920,0.955
+0.791,0.921,0.956
+0.795,0.923,0.956
+0.800,0.924,0.957
+0.805,0.925,0.957
+0.810,0.927,0.958
+0.815,0.928,0.958
+0.820,0.930,0.959
+0.825,0.931,0.960
+0.830,0.933,0.960
+0.834,0.934,0.961
+0.839,0.936,0.961
+0.844,0.937,0.962
+0.849,0.938,0.962
+0.854,0.940,0.963
+0.858,0.941,0.963
+0.863,0.943,0.964
+0.868,0.944,0.965
+0.873,0.946,0.965
+0.878,0.947,0.966
+0.882,0.948,0.966
+0.887,0.950,0.967
+0.892,0.951,0.967
+0.896,0.953,0.968
+0.901,0.954,0.968
+0.906,0.956,0.969
+0.911,0.957,0.969
+0.915,0.958,0.970
+0.920,0.960,0.970
+0.925,0.961,0.971
+0.929,0.962,0.971
+0.934,0.964,0.972
+0.938,0.965,0.972
+0.943,0.966,0.972
+0.947,0.967,0.972
+0.951,0.968,0.972
+0.956,0.968,0.972
+0.959,0.968,0.971
+0.963,0.968,0.970
+0.966,0.968,0.969
+0.969,0.967,0.967
+0.972,0.966,0.966
+0.974,0.965,0.964
+0.976,0.963,0.961
+0.978,0.961,0.959
+0.979,0.959,0.956
+0.980,0.957,0.953
+0.981,0.954,0.950
+0.982,0.952,0.947
+0.983,0.949,0.944
+0.984,0.947,0.941
+0.984,0.944,0.938
+0.985,0.941,0.934
+0.985,0.939,0.931
+0.986,0.936,0.928
+0.986,0.933,0.925
+0.987,0.931,0.922
+0.987,0.928,0.918
+0.988,0.925,0.915
+0.988,0.922,0.912
+0.988,0.920,0.909
+0.989,0.917,0.906
+0.989,0.914,0.903
+0.990,0.912,0.899
+0.990,0.909,0.896
+0.991,0.906,0.893
+0.991,0.904,0.890
+0.991,0.901,0.887
+0.992,0.898,0.884
+0.992,0.895,0.880
+0.992,0.893,0.877
+0.993,0.890,0.874
+0.993,0.887,0.871
+0.993,0.885,0.868
+0.994,0.882,0.865
+0.994,0.879,0.861
+0.994,0.877,0.858
+0.995,0.874,0.855
+0.995,0.871,0.852
+0.995,0.869,0.849
+0.995,0.866,0.846
+0.996,0.863,0.843
+0.996,0.860,0.839
+0.996,0.858,0.836
+0.996,0.855,0.833
+0.997,0.852,0.830
+0.997,0.850,0.827
+0.997,0.847,0.824
+0.997,0.844,0.821
+0.998,0.842,0.817
+0.998,0.839,0.814
+0.998,0.836,0.811
+0.998,0.833,0.808
+0.998,0.831,0.805
+0.998,0.828,0.802
+0.999,0.825,0.799
+0.999,0.823,0.796
+0.999,0.820,0.793
+0.999,0.817,0.789
+0.999,0.815,0.786
+0.999,0.812,0.783
+0.999,0.809,0.780
+0.999,0.806,0.777
+1.000,0.804,0.774
+1.000,0.801,0.771
+1.000,0.798,0.768
+1.000,0.796,0.765
+1.000,0.793,0.762
+1.000,0.790,0.759
+1.000,0.787,0.755
+1.000,0.785,0.752
+1.000,0.782,0.749
+1.000,0.779,0.746
+1.000,0.777,0.743
+1.000,0.774,0.740
+1.000,0.771,0.737
+1.000,0.769,0.734
+1.000,0.766,0.731
+1.000,0.763,0.728
+1.000,0.760,0.725
+1.000,0.758,0.722
+1.000,0.755,0.719
+1.000,0.752,0.716
+1.000,0.750,0.713
+1.000,0.747,0.709
+1.000,0.744,0.706
+1.000,0.741,0.703
+1.000,0.739,0.700
+1.000,0.736,0.697
+1.000,0.733,0.694
+0.999,0.731,0.691
+0.999,0.728,0.688
+0.999,0.725,0.685
+0.999,0.722,0.682
+0.999,0.720,0.679
+0.999,0.717,0.676
+0.999,0.714,0.673
+0.999,0.711,0.670
+0.998,0.709,0.667
+0.998,0.706,0.664
+0.998,0.703,0.661
+0.998,0.701,0.658
+0.998,0.698,0.655
+0.998,0.695,0.652
+0.997,0.692,0.649
+0.997,0.690,0.646
+0.997,0.687,0.643
+0.997,0.684,0.640
+0.997,0.681,0.637
+0.996,0.679,0.634
+0.996,0.676,0.631
+0.996,0.673,0.628
+0.996,0.670,0.625
+0.996,0.668,0.622
+0.995,0.665,0.619
+0.995,0.662,0.616
+0.995,0.659,0.613
+0.995,0.657,0.610
+0.994,0.654,0.607
+0.994,0.651,0.604
+0.994,0.648,0.601
+0.993,0.646,0.598
+0.993,0.643,0.595
+0.993,0.640,0.592
+0.993,0.637,0.589
+0.992,0.635,0.586
+0.992,0.632,0.583
+0.992,0.629,0.580
diff --git a/pyqtgraph/colors/maps/CET-CBTL1.csv b/pyqtgraph/colors/maps/CET-CBTL1.csv
new file mode 100644
index 00000000..315c8481
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-CBTL1.csv
@@ -0,0 +1,256 @@
+0.066,0.066,0.066
+0.078,0.067,0.065
+0.089,0.069,0.065
+0.099,0.070,0.064
+0.108,0.071,0.064
+0.116,0.072,0.063
+0.124,0.073,0.063
+0.133,0.074,0.062
+0.141,0.075,0.061
+0.149,0.075,0.061
+0.157,0.075,0.060
+0.165,0.075,0.060
+0.173,0.075,0.059
+0.181,0.075,0.058
+0.190,0.075,0.058
+0.198,0.075,0.057
+0.206,0.074,0.057
+0.214,0.074,0.056
+0.222,0.073,0.055
+0.230,0.072,0.055
+0.238,0.071,0.054
+0.246,0.070,0.053
+0.254,0.069,0.053
+0.262,0.068,0.052
+0.270,0.066,0.052
+0.278,0.065,0.051
+0.286,0.063,0.050
+0.294,0.061,0.050
+0.302,0.059,0.049
+0.310,0.057,0.049
+0.318,0.054,0.048
+0.326,0.052,0.048
+0.333,0.049,0.047
+0.341,0.046,0.047
+0.349,0.043,0.047
+0.357,0.040,0.047
+0.364,0.036,0.047
+0.372,0.033,0.047
+0.379,0.030,0.047
+0.386,0.027,0.048
+0.393,0.024,0.048
+0.401,0.021,0.049
+0.408,0.018,0.049
+0.414,0.016,0.050
+0.421,0.014,0.051
+0.428,0.012,0.052
+0.435,0.010,0.053
+0.441,0.009,0.054
+0.447,0.007,0.056
+0.454,0.006,0.057
+0.460,0.005,0.058
+0.466,0.005,0.060
+0.473,0.004,0.061
+0.479,0.004,0.063
+0.485,0.004,0.064
+0.491,0.004,0.065
+0.497,0.004,0.067
+0.503,0.004,0.068
+0.509,0.004,0.070
+0.515,0.005,0.071
+0.521,0.005,0.072
+0.527,0.006,0.074
+0.533,0.007,0.075
+0.539,0.007,0.077
+0.545,0.008,0.078
+0.551,0.009,0.080
+0.557,0.009,0.081
+0.563,0.010,0.083
+0.569,0.011,0.084
+0.575,0.012,0.086
+0.581,0.013,0.087
+0.588,0.014,0.089
+0.594,0.015,0.090
+0.600,0.016,0.092
+0.606,0.017,0.093
+0.612,0.018,0.095
+0.618,0.019,0.096
+0.624,0.020,0.098
+0.631,0.021,0.099
+0.637,0.022,0.101
+0.643,0.023,0.103
+0.649,0.025,0.104
+0.655,0.026,0.106
+0.662,0.027,0.107
+0.668,0.028,0.109
+0.674,0.030,0.110
+0.680,0.031,0.112
+0.687,0.032,0.113
+0.693,0.034,0.115
+0.699,0.035,0.117
+0.705,0.037,0.118
+0.712,0.038,0.120
+0.718,0.040,0.121
+0.724,0.041,0.123
+0.731,0.043,0.124
+0.737,0.044,0.126
+0.743,0.046,0.128
+0.750,0.047,0.129
+0.756,0.049,0.131
+0.763,0.050,0.132
+0.769,0.052,0.134
+0.775,0.053,0.136
+0.782,0.055,0.137
+0.788,0.056,0.139
+0.795,0.057,0.140
+0.801,0.059,0.142
+0.808,0.060,0.144
+0.814,0.062,0.145
+0.821,0.063,0.147
+0.827,0.065,0.149
+0.834,0.066,0.150
+0.840,0.068,0.152
+0.847,0.069,0.153
+0.853,0.071,0.155
+0.860,0.072,0.157
+0.866,0.074,0.158
+0.873,0.075,0.160
+0.879,0.077,0.162
+0.886,0.079,0.164
+0.892,0.081,0.165
+0.899,0.083,0.167
+0.905,0.085,0.169
+0.912,0.087,0.171
+0.918,0.090,0.173
+0.924,0.093,0.175
+0.930,0.097,0.177
+0.936,0.101,0.179
+0.942,0.105,0.181
+0.948,0.110,0.184
+0.953,0.116,0.187
+0.958,0.122,0.190
+0.963,0.130,0.193
+0.968,0.137,0.197
+0.972,0.146,0.201
+0.976,0.155,0.205
+0.979,0.165,0.210
+0.982,0.176,0.215
+0.984,0.187,0.220
+0.986,0.199,0.226
+0.988,0.211,0.233
+0.988,0.224,0.240
+0.989,0.236,0.247
+0.988,0.250,0.255
+0.987,0.263,0.263
+0.986,0.277,0.272
+0.983,0.290,0.281
+0.981,0.304,0.291
+0.978,0.318,0.301
+0.974,0.331,0.311
+0.970,0.345,0.322
+0.965,0.358,0.333
+0.960,0.371,0.344
+0.954,0.384,0.356
+0.948,0.397,0.368
+0.942,0.410,0.380
+0.935,0.422,0.392
+0.929,0.435,0.404
+0.921,0.447,0.417
+0.914,0.458,0.429
+0.906,0.470,0.442
+0.898,0.481,0.454
+0.889,0.493,0.467
+0.881,0.504,0.480
+0.872,0.514,0.493
+0.863,0.525,0.506
+0.853,0.535,0.519
+0.843,0.546,0.532
+0.833,0.556,0.545
+0.823,0.566,0.558
+0.812,0.576,0.571
+0.801,0.586,0.585
+0.789,0.595,0.598
+0.777,0.605,0.611
+0.765,0.614,0.625
+0.752,0.624,0.638
+0.739,0.633,0.651
+0.725,0.642,0.665
+0.710,0.651,0.678
+0.696,0.660,0.692
+0.680,0.669,0.705
+0.664,0.677,0.719
+0.647,0.686,0.732
+0.630,0.695,0.745
+0.612,0.703,0.759
+0.593,0.711,0.772
+0.573,0.720,0.785
+0.552,0.728,0.798
+0.531,0.736,0.811
+0.509,0.744,0.824
+0.485,0.751,0.837
+0.461,0.759,0.849
+0.437,0.766,0.861
+0.411,0.773,0.872
+0.385,0.780,0.884
+0.358,0.787,0.894
+0.330,0.794,0.905
+0.302,0.800,0.914
+0.274,0.806,0.924
+0.246,0.812,0.932
+0.218,0.818,0.940
+0.192,0.823,0.947
+0.169,0.829,0.954
+0.149,0.834,0.960
+0.136,0.838,0.966
+0.131,0.843,0.970
+0.134,0.847,0.975
+0.146,0.851,0.978
+0.163,0.855,0.982
+0.184,0.859,0.984
+0.207,0.862,0.986
+0.232,0.866,0.988
+0.257,0.869,0.990
+0.282,0.872,0.991
+0.307,0.875,0.992
+0.331,0.878,0.992
+0.354,0.881,0.993
+0.377,0.884,0.993
+0.400,0.886,0.993
+0.421,0.889,0.993
+0.442,0.892,0.993
+0.463,0.894,0.993
+0.483,0.897,0.992
+0.502,0.899,0.992
+0.521,0.902,0.992
+0.539,0.905,0.991
+0.557,0.907,0.991
+0.574,0.909,0.991
+0.591,0.912,0.990
+0.608,0.914,0.990
+0.624,0.917,0.989
+0.640,0.919,0.989
+0.655,0.922,0.989
+0.671,0.924,0.988
+0.686,0.927,0.988
+0.701,0.929,0.987
+0.715,0.931,0.987
+0.730,0.934,0.986
+0.744,0.936,0.986
+0.758,0.938,0.985
+0.772,0.941,0.985
+0.785,0.943,0.985
+0.799,0.945,0.984
+0.812,0.948,0.984
+0.826,0.950,0.983
+0.839,0.952,0.983
+0.852,0.955,0.982
+0.865,0.957,0.982
+0.878,0.959,0.981
+0.890,0.962,0.981
+0.903,0.964,0.980
+0.916,0.966,0.980
+0.928,0.968,0.979
+0.940,0.971,0.979
+0.953,0.973,0.978
+0.965,0.975,0.978
+0.977,0.977,0.977
diff --git a/pyqtgraph/colors/maps/CET-CBTL2.csv b/pyqtgraph/colors/maps/CET-CBTL2.csv
new file mode 100644
index 00000000..3fec486e
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-CBTL2.csv
@@ -0,0 +1,256 @@
+0.066,0.066,0.066
+0.077,0.068,0.066
+0.086,0.069,0.066
+0.095,0.071,0.066
+0.103,0.072,0.066
+0.111,0.074,0.066
+0.118,0.075,0.067
+0.125,0.076,0.067
+0.132,0.078,0.067
+0.139,0.078,0.067
+0.146,0.079,0.068
+0.152,0.080,0.068
+0.159,0.081,0.069
+0.166,0.082,0.069
+0.173,0.083,0.070
+0.179,0.084,0.070
+0.186,0.084,0.070
+0.192,0.085,0.071
+0.199,0.086,0.072
+0.205,0.087,0.072
+0.212,0.087,0.073
+0.218,0.088,0.074
+0.225,0.089,0.074
+0.231,0.090,0.075
+0.237,0.090,0.076
+0.244,0.091,0.076
+0.250,0.092,0.077
+0.256,0.093,0.078
+0.262,0.094,0.079
+0.268,0.094,0.080
+0.274,0.095,0.081
+0.280,0.096,0.082
+0.286,0.097,0.082
+0.292,0.098,0.083
+0.298,0.099,0.084
+0.304,0.100,0.085
+0.310,0.101,0.086
+0.316,0.102,0.088
+0.322,0.103,0.089
+0.327,0.105,0.090
+0.333,0.106,0.091
+0.339,0.107,0.093
+0.344,0.109,0.094
+0.350,0.110,0.095
+0.355,0.112,0.097
+0.361,0.113,0.098
+0.366,0.115,0.100
+0.371,0.117,0.101
+0.376,0.118,0.103
+0.382,0.120,0.105
+0.387,0.122,0.107
+0.392,0.124,0.108
+0.397,0.126,0.110
+0.402,0.128,0.112
+0.407,0.131,0.114
+0.411,0.133,0.116
+0.416,0.135,0.119
+0.421,0.138,0.121
+0.425,0.140,0.123
+0.430,0.143,0.125
+0.434,0.146,0.128
+0.439,0.149,0.130
+0.443,0.152,0.133
+0.447,0.155,0.135
+0.451,0.158,0.138
+0.455,0.161,0.141
+0.459,0.164,0.144
+0.463,0.168,0.147
+0.467,0.171,0.150
+0.470,0.175,0.153
+0.474,0.178,0.156
+0.477,0.182,0.159
+0.480,0.186,0.163
+0.483,0.190,0.166
+0.486,0.194,0.170
+0.489,0.198,0.173
+0.492,0.202,0.177
+0.495,0.207,0.181
+0.497,0.211,0.185
+0.500,0.215,0.189
+0.502,0.220,0.193
+0.504,0.224,0.197
+0.506,0.229,0.202
+0.508,0.234,0.206
+0.509,0.239,0.211
+0.510,0.244,0.216
+0.512,0.249,0.220
+0.513,0.254,0.225
+0.513,0.259,0.230
+0.514,0.264,0.236
+0.514,0.270,0.241
+0.514,0.275,0.247
+0.514,0.281,0.252
+0.514,0.286,0.258
+0.514,0.292,0.264
+0.513,0.297,0.270
+0.513,0.303,0.276
+0.513,0.308,0.281
+0.512,0.314,0.287
+0.511,0.319,0.293
+0.511,0.324,0.299
+0.510,0.330,0.305
+0.509,0.335,0.311
+0.509,0.340,0.317
+0.508,0.345,0.323
+0.507,0.351,0.329
+0.506,0.356,0.335
+0.505,0.361,0.341
+0.504,0.366,0.348
+0.503,0.371,0.354
+0.501,0.377,0.360
+0.500,0.382,0.366
+0.499,0.387,0.372
+0.497,0.392,0.379
+0.496,0.397,0.385
+0.494,0.402,0.391
+0.493,0.407,0.398
+0.491,0.412,0.404
+0.489,0.417,0.410
+0.487,0.422,0.417
+0.485,0.427,0.423
+0.483,0.433,0.430
+0.481,0.438,0.436
+0.479,0.443,0.443
+0.477,0.448,0.449
+0.475,0.453,0.456
+0.472,0.458,0.462
+0.470,0.463,0.469
+0.467,0.468,0.476
+0.464,0.473,0.482
+0.461,0.478,0.489
+0.458,0.483,0.496
+0.455,0.488,0.502
+0.452,0.493,0.509
+0.449,0.498,0.516
+0.445,0.503,0.523
+0.442,0.508,0.530
+0.438,0.513,0.537
+0.434,0.517,0.543
+0.430,0.522,0.550
+0.426,0.527,0.557
+0.421,0.532,0.564
+0.417,0.537,0.571
+0.412,0.542,0.578
+0.407,0.547,0.585
+0.402,0.552,0.592
+0.397,0.557,0.599
+0.392,0.562,0.606
+0.386,0.567,0.613
+0.380,0.572,0.621
+0.374,0.577,0.628
+0.368,0.582,0.635
+0.361,0.587,0.642
+0.354,0.592,0.649
+0.346,0.597,0.657
+0.339,0.602,0.664
+0.331,0.607,0.671
+0.322,0.612,0.679
+0.313,0.617,0.686
+0.304,0.622,0.693
+0.294,0.627,0.701
+0.283,0.631,0.708
+0.271,0.636,0.716
+0.259,0.641,0.723
+0.247,0.646,0.730
+0.234,0.651,0.738
+0.221,0.656,0.745
+0.208,0.661,0.752
+0.195,0.665,0.758
+0.182,0.670,0.765
+0.169,0.675,0.771
+0.156,0.679,0.777
+0.142,0.684,0.784
+0.129,0.688,0.790
+0.116,0.693,0.795
+0.102,0.697,0.801
+0.089,0.701,0.807
+0.076,0.706,0.812
+0.064,0.710,0.817
+0.053,0.714,0.822
+0.043,0.718,0.827
+0.036,0.722,0.832
+0.032,0.726,0.837
+0.031,0.730,0.842
+0.034,0.734,0.846
+0.042,0.738,0.851
+0.051,0.742,0.855
+0.062,0.746,0.859
+0.075,0.750,0.863
+0.088,0.754,0.867
+0.101,0.758,0.871
+0.115,0.762,0.875
+0.129,0.765,0.878
+0.142,0.769,0.882
+0.156,0.773,0.885
+0.170,0.776,0.889
+0.184,0.780,0.892
+0.198,0.784,0.895
+0.211,0.787,0.898
+0.225,0.791,0.901
+0.239,0.794,0.904
+0.252,0.798,0.907
+0.266,0.801,0.909
+0.279,0.805,0.912
+0.293,0.808,0.914
+0.306,0.811,0.917
+0.319,0.815,0.919
+0.333,0.818,0.921
+0.346,0.821,0.923
+0.359,0.825,0.925
+0.372,0.828,0.927
+0.385,0.831,0.929
+0.398,0.834,0.931
+0.411,0.837,0.933
+0.424,0.840,0.934
+0.437,0.843,0.936
+0.450,0.846,0.937
+0.463,0.849,0.939
+0.476,0.852,0.940
+0.489,0.855,0.941
+0.502,0.858,0.943
+0.515,0.861,0.944
+0.528,0.864,0.945
+0.540,0.867,0.946
+0.553,0.870,0.947
+0.566,0.873,0.948
+0.578,0.875,0.948
+0.591,0.878,0.949
+0.604,0.881,0.950
+0.617,0.884,0.950
+0.629,0.886,0.951
+0.642,0.889,0.951
+0.654,0.891,0.952
+0.667,0.894,0.952
+0.680,0.897,0.952
+0.692,0.899,0.952
+0.705,0.902,0.952
+0.717,0.904,0.952
+0.730,0.907,0.952
+0.743,0.909,0.952
+0.755,0.911,0.952
+0.768,0.914,0.952
+0.780,0.916,0.952
+0.793,0.918,0.951
+0.805,0.921,0.951
+0.818,0.923,0.951
+0.831,0.925,0.950
+0.843,0.927,0.950
+0.856,0.929,0.949
+0.868,0.931,0.948
+0.881,0.934,0.948
+0.893,0.936,0.947
+0.906,0.938,0.946
+0.918,0.940,0.945
+0.931,0.942,0.944
+0.943,0.944,0.943
diff --git a/pyqtgraph/colors/maps/CET-D1.csv b/pyqtgraph/colors/maps/CET-D1.csv
new file mode 100644
index 00000000..96755d9e
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-D1.csv
@@ -0,0 +1,256 @@
+0.128,0.316,0.858
+0.147,0.320,0.859
+0.164,0.325,0.860
+0.179,0.329,0.861
+0.194,0.333,0.862
+0.207,0.338,0.863
+0.220,0.342,0.864
+0.232,0.346,0.864
+0.243,0.351,0.865
+0.254,0.355,0.866
+0.264,0.360,0.867
+0.274,0.364,0.868
+0.284,0.369,0.869
+0.294,0.373,0.869
+0.303,0.377,0.870
+0.312,0.382,0.871
+0.321,0.386,0.872
+0.329,0.391,0.873
+0.337,0.395,0.874
+0.346,0.400,0.874
+0.354,0.404,0.875
+0.362,0.409,0.876
+0.369,0.414,0.877
+0.377,0.418,0.878
+0.384,0.423,0.878
+0.392,0.427,0.879
+0.399,0.432,0.880
+0.406,0.436,0.881
+0.413,0.441,0.882
+0.420,0.446,0.882
+0.427,0.450,0.883
+0.434,0.455,0.884
+0.440,0.460,0.885
+0.447,0.464,0.886
+0.454,0.469,0.886
+0.460,0.474,0.887
+0.467,0.478,0.888
+0.473,0.483,0.889
+0.479,0.488,0.889
+0.485,0.492,0.890
+0.492,0.497,0.891
+0.498,0.502,0.892
+0.504,0.507,0.892
+0.510,0.511,0.893
+0.516,0.516,0.894
+0.522,0.521,0.895
+0.528,0.526,0.895
+0.534,0.530,0.896
+0.540,0.535,0.897
+0.545,0.540,0.898
+0.551,0.545,0.898
+0.557,0.550,0.899
+0.563,0.555,0.900
+0.568,0.559,0.900
+0.574,0.564,0.901
+0.580,0.569,0.902
+0.585,0.574,0.903
+0.591,0.579,0.903
+0.596,0.584,0.904
+0.602,0.588,0.905
+0.607,0.593,0.905
+0.613,0.598,0.906
+0.618,0.603,0.907
+0.623,0.608,0.907
+0.629,0.613,0.908
+0.634,0.618,0.909
+0.639,0.623,0.909
+0.645,0.628,0.910
+0.650,0.633,0.911
+0.655,0.638,0.911
+0.660,0.643,0.912
+0.666,0.648,0.913
+0.671,0.653,0.913
+0.676,0.658,0.914
+0.681,0.663,0.915
+0.686,0.668,0.915
+0.691,0.673,0.916
+0.697,0.678,0.917
+0.702,0.683,0.917
+0.707,0.688,0.918
+0.712,0.693,0.918
+0.717,0.698,0.919
+0.722,0.703,0.920
+0.727,0.708,0.920
+0.732,0.713,0.921
+0.737,0.718,0.921
+0.742,0.723,0.922
+0.747,0.728,0.923
+0.752,0.733,0.923
+0.757,0.738,0.924
+0.762,0.743,0.924
+0.766,0.748,0.925
+0.771,0.754,0.926
+0.776,0.759,0.926
+0.781,0.764,0.927
+0.786,0.769,0.927
+0.791,0.774,0.928
+0.796,0.779,0.928
+0.801,0.784,0.929
+0.805,0.789,0.929
+0.810,0.795,0.930
+0.815,0.800,0.930
+0.820,0.805,0.931
+0.825,0.810,0.932
+0.829,0.815,0.932
+0.834,0.821,0.933
+0.839,0.826,0.933
+0.844,0.831,0.934
+0.848,0.836,0.934
+0.853,0.841,0.935
+0.858,0.846,0.935
+0.863,0.852,0.935
+0.867,0.857,0.936
+0.872,0.862,0.936
+0.877,0.867,0.936
+0.881,0.872,0.937
+0.886,0.876,0.937
+0.890,0.881,0.936
+0.895,0.885,0.936
+0.899,0.890,0.936
+0.903,0.893,0.935
+0.908,0.897,0.934
+0.912,0.900,0.932
+0.916,0.903,0.931
+0.919,0.905,0.928
+0.923,0.906,0.926
+0.926,0.907,0.923
+0.929,0.907,0.919
+0.932,0.907,0.915
+0.935,0.905,0.911
+0.937,0.904,0.906
+0.939,0.901,0.900
+0.941,0.898,0.895
+0.942,0.895,0.888
+0.944,0.891,0.882
+0.945,0.887,0.875
+0.946,0.882,0.869
+0.946,0.877,0.861
+0.947,0.872,0.854
+0.947,0.866,0.847
+0.948,0.861,0.840
+0.948,0.855,0.832
+0.948,0.849,0.825
+0.948,0.843,0.817
+0.948,0.837,0.810
+0.948,0.831,0.802
+0.948,0.825,0.794
+0.948,0.819,0.787
+0.948,0.813,0.779
+0.947,0.807,0.772
+0.947,0.800,0.764
+0.947,0.794,0.757
+0.947,0.788,0.749
+0.946,0.782,0.742
+0.946,0.776,0.734
+0.945,0.770,0.727
+0.945,0.764,0.719
+0.944,0.758,0.712
+0.944,0.752,0.704
+0.943,0.746,0.697
+0.942,0.740,0.689
+0.942,0.733,0.682
+0.941,0.727,0.675
+0.940,0.721,0.667
+0.940,0.715,0.660
+0.939,0.709,0.653
+0.938,0.703,0.645
+0.937,0.697,0.638
+0.936,0.691,0.631
+0.935,0.685,0.623
+0.934,0.679,0.616
+0.933,0.673,0.609
+0.932,0.666,0.601
+0.931,0.660,0.594
+0.930,0.654,0.587
+0.929,0.648,0.580
+0.928,0.642,0.573
+0.927,0.636,0.565
+0.925,0.630,0.558
+0.924,0.624,0.551
+0.923,0.618,0.544
+0.922,0.612,0.537
+0.920,0.605,0.530
+0.919,0.599,0.522
+0.917,0.593,0.515
+0.916,0.587,0.508
+0.915,0.581,0.501
+0.913,0.575,0.494
+0.912,0.569,0.487
+0.910,0.562,0.480
+0.908,0.556,0.473
+0.907,0.550,0.466
+0.905,0.544,0.459
+0.904,0.538,0.452
+0.902,0.531,0.445
+0.900,0.525,0.438
+0.898,0.519,0.431
+0.897,0.513,0.424
+0.895,0.507,0.417
+0.893,0.500,0.410
+0.891,0.494,0.403
+0.889,0.488,0.396
+0.887,0.481,0.390
+0.885,0.475,0.383
+0.884,0.469,0.376
+0.882,0.463,0.369
+0.880,0.456,0.362
+0.878,0.450,0.355
+0.875,0.443,0.349
+0.873,0.437,0.342
+0.871,0.431,0.335
+0.869,0.424,0.328
+0.867,0.418,0.322
+0.865,0.411,0.315
+0.863,0.405,0.308
+0.860,0.398,0.301
+0.858,0.391,0.295
+0.856,0.385,0.288
+0.854,0.378,0.281
+0.851,0.372,0.275
+0.849,0.365,0.268
+0.846,0.358,0.261
+0.844,0.351,0.255
+0.842,0.344,0.248
+0.839,0.337,0.241
+0.837,0.331,0.235
+0.834,0.323,0.228
+0.832,0.316,0.222
+0.829,0.309,0.215
+0.827,0.302,0.208
+0.824,0.295,0.202
+0.821,0.287,0.195
+0.819,0.280,0.188
+0.816,0.272,0.182
+0.813,0.265,0.175
+0.811,0.257,0.169
+0.808,0.249,0.162
+0.805,0.241,0.155
+0.803,0.233,0.148
+0.800,0.224,0.142
+0.797,0.216,0.135
+0.794,0.207,0.128
+0.791,0.198,0.121
+0.788,0.189,0.115
+0.786,0.179,0.108
+0.783,0.169,0.101
+0.780,0.159,0.093
+0.777,0.148,0.086
+0.774,0.137,0.079
+0.771,0.124,0.071
+0.768,0.111,0.064
+0.765,0.096,0.056
+0.762,0.080,0.047
+0.759,0.061,0.039
+0.756,0.036,0.030
+0.752,0.008,0.022
diff --git a/pyqtgraph/colors/maps/CET-D10.csv b/pyqtgraph/colors/maps/CET-D10.csv
new file mode 100644
index 00000000..cbf4feae
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-D10.csv
@@ -0,0 +1,256 @@
+0.000,0.851,1.000
+0.000,0.852,1.000
+0.056,0.853,1.000
+0.100,0.854,1.000
+0.132,0.856,1.000
+0.157,0.857,1.000
+0.179,0.858,1.000
+0.198,0.859,1.000
+0.216,0.860,1.000
+0.232,0.862,1.000
+0.248,0.863,1.000
+0.262,0.864,1.000
+0.275,0.865,1.000
+0.288,0.867,1.000
+0.300,0.868,1.000
+0.312,0.869,1.000
+0.323,0.870,1.000
+0.334,0.871,1.000
+0.345,0.873,1.000
+0.355,0.874,1.000
+0.365,0.875,1.000
+0.375,0.876,1.000
+0.384,0.877,1.000
+0.394,0.879,1.000
+0.403,0.880,1.000
+0.411,0.881,1.000
+0.420,0.882,1.000
+0.429,0.883,1.000
+0.437,0.885,1.000
+0.445,0.886,1.000
+0.453,0.887,1.000
+0.461,0.888,1.000
+0.469,0.889,1.000
+0.477,0.891,1.000
+0.484,0.892,1.000
+0.492,0.893,1.000
+0.499,0.894,1.000
+0.506,0.895,1.000
+0.513,0.897,1.000
+0.520,0.898,1.000
+0.527,0.899,1.000
+0.534,0.900,1.000
+0.541,0.901,1.000
+0.548,0.903,1.000
+0.555,0.904,1.000
+0.561,0.905,1.000
+0.568,0.906,1.000
+0.574,0.907,1.000
+0.581,0.908,1.000
+0.587,0.910,1.000
+0.594,0.911,1.000
+0.600,0.912,1.000
+0.606,0.913,1.000
+0.612,0.914,1.000
+0.618,0.916,1.000
+0.625,0.917,1.000
+0.631,0.918,1.000
+0.637,0.919,1.000
+0.643,0.920,1.000
+0.649,0.921,1.000
+0.654,0.923,1.000
+0.660,0.924,1.000
+0.666,0.925,1.000
+0.672,0.926,1.000
+0.678,0.927,1.000
+0.683,0.928,1.000
+0.689,0.930,1.000
+0.695,0.931,1.000
+0.700,0.932,1.000
+0.706,0.933,1.000
+0.711,0.934,1.000
+0.717,0.935,1.000
+0.722,0.937,1.000
+0.728,0.938,1.000
+0.733,0.939,1.000
+0.739,0.940,1.000
+0.744,0.941,1.000
+0.749,0.942,1.000
+0.755,0.944,1.000
+0.760,0.945,1.000
+0.765,0.946,1.000
+0.771,0.947,1.000
+0.776,0.948,1.000
+0.781,0.949,1.000
+0.786,0.950,1.000
+0.792,0.952,1.000
+0.797,0.953,1.000
+0.802,0.954,1.000
+0.807,0.955,1.000
+0.812,0.956,1.000
+0.817,0.957,1.000
+0.822,0.958,1.000
+0.827,0.960,1.000
+0.833,0.961,1.000
+0.838,0.962,1.000
+0.843,0.963,1.000
+0.848,0.964,1.000
+0.853,0.965,1.000
+0.858,0.966,1.000
+0.863,0.968,1.000
+0.867,0.969,1.000
+0.872,0.970,1.000
+0.877,0.971,1.000
+0.882,0.972,1.000
+0.887,0.973,1.000
+0.892,0.974,1.000
+0.897,0.976,1.000
+0.902,0.977,1.000
+0.907,0.978,1.000
+0.911,0.979,1.000
+0.916,0.980,1.000
+0.921,0.981,1.000
+0.926,0.982,1.000
+0.931,0.984,1.000
+0.935,0.985,1.000
+0.940,0.986,1.000
+0.945,0.987,1.000
+0.950,0.988,1.000
+0.954,0.989,1.000
+0.959,0.990,1.000
+0.964,0.991,1.000
+0.968,0.993,1.000
+0.973,0.994,1.000
+0.978,0.995,1.000
+0.982,0.996,1.000
+0.987,0.997,1.000
+0.991,0.998,1.000
+0.997,0.999,1.000
+1.000,0.998,1.000
+1.000,0.996,0.999
+1.000,0.993,0.999
+1.000,0.991,0.998
+1.000,0.988,0.998
+1.000,0.986,0.998
+1.000,0.983,0.997
+1.000,0.981,0.997
+1.000,0.979,0.996
+1.000,0.976,0.996
+1.000,0.974,0.995
+1.000,0.971,0.995
+1.000,0.969,0.994
+1.000,0.966,0.994
+1.000,0.964,0.994
+1.000,0.961,0.993
+1.000,0.959,0.993
+1.000,0.956,0.992
+1.000,0.954,0.992
+1.000,0.952,0.991
+1.000,0.949,0.991
+1.000,0.947,0.991
+1.000,0.944,0.990
+1.000,0.942,0.990
+1.000,0.939,0.989
+1.000,0.937,0.989
+1.000,0.934,0.988
+0.999,0.932,0.988
+0.999,0.929,0.987
+0.999,0.927,0.987
+0.999,0.924,0.987
+0.999,0.922,0.986
+0.999,0.919,0.986
+0.999,0.917,0.985
+0.999,0.915,0.985
+0.999,0.912,0.984
+0.999,0.910,0.984
+0.999,0.907,0.983
+0.999,0.905,0.983
+0.999,0.902,0.983
+0.998,0.900,0.982
+0.998,0.897,0.982
+0.998,0.895,0.981
+0.998,0.892,0.981
+0.998,0.890,0.980
+0.998,0.887,0.980
+0.998,0.885,0.979
+0.998,0.882,0.979
+0.998,0.880,0.978
+0.997,0.877,0.978
+0.997,0.875,0.978
+0.997,0.872,0.977
+0.997,0.870,0.977
+0.997,0.868,0.976
+0.997,0.865,0.976
+0.997,0.863,0.975
+0.997,0.860,0.975
+0.996,0.858,0.974
+0.996,0.855,0.974
+0.996,0.853,0.974
+0.996,0.850,0.973
+0.996,0.848,0.973
+0.996,0.845,0.972
+0.996,0.843,0.972
+0.995,0.840,0.971
+0.995,0.838,0.971
+0.995,0.835,0.970
+0.995,0.833,0.970
+0.995,0.830,0.969
+0.995,0.828,0.969
+0.994,0.825,0.968
+0.994,0.823,0.968
+0.994,0.820,0.968
+0.994,0.818,0.967
+0.994,0.815,0.967
+0.993,0.813,0.966
+0.993,0.810,0.966
+0.993,0.808,0.965
+0.993,0.805,0.965
+0.993,0.803,0.964
+0.992,0.800,0.964
+0.992,0.798,0.963
+0.992,0.795,0.963
+0.992,0.793,0.962
+0.992,0.790,0.962
+0.991,0.788,0.962
+0.991,0.785,0.961
+0.991,0.783,0.961
+0.991,0.780,0.960
+0.990,0.777,0.960
+0.990,0.775,0.959
+0.990,0.772,0.959
+0.990,0.770,0.958
+0.990,0.767,0.958
+0.989,0.765,0.957
+0.989,0.762,0.957
+0.989,0.760,0.956
+0.989,0.757,0.956
+0.988,0.755,0.955
+0.988,0.752,0.955
+0.988,0.750,0.954
+0.988,0.747,0.954
+0.987,0.745,0.954
+0.987,0.742,0.953
+0.987,0.739,0.953
+0.987,0.737,0.952
+0.986,0.734,0.952
+0.986,0.732,0.951
+0.986,0.729,0.951
+0.985,0.727,0.950
+0.985,0.724,0.950
+0.985,0.722,0.949
+0.985,0.719,0.949
+0.984,0.717,0.948
+0.984,0.714,0.948
+0.984,0.711,0.947
+0.983,0.709,0.947
+0.983,0.706,0.946
+0.983,0.704,0.946
+0.982,0.701,0.945
+0.982,0.699,0.945
+0.982,0.696,0.944
+0.982,0.693,0.944
+0.981,0.691,0.943
+0.981,0.688,0.943
+0.981,0.686,0.943
+0.980,0.683,0.942
+0.980,0.680,0.942
diff --git a/pyqtgraph/colors/maps/CET-D11.csv b/pyqtgraph/colors/maps/CET-D11.csv
new file mode 100644
index 00000000..881e843f
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-D11.csv
@@ -0,0 +1,256 @@
+0.000,0.715,1.000
+0.000,0.715,1.000
+0.000,0.715,1.000
+0.000,0.714,1.000
+0.024,0.714,1.000
+0.068,0.713,0.999
+0.098,0.713,0.996
+0.121,0.713,0.994
+0.140,0.712,0.991
+0.157,0.712,0.988
+0.172,0.712,0.986
+0.186,0.711,0.983
+0.199,0.711,0.980
+0.211,0.711,0.977
+0.222,0.710,0.975
+0.232,0.710,0.972
+0.242,0.709,0.969
+0.252,0.709,0.967
+0.261,0.709,0.964
+0.270,0.708,0.961
+0.278,0.708,0.958
+0.286,0.708,0.956
+0.294,0.707,0.953
+0.301,0.707,0.950
+0.309,0.707,0.948
+0.316,0.706,0.945
+0.323,0.706,0.942
+0.329,0.705,0.939
+0.336,0.705,0.937
+0.342,0.705,0.934
+0.348,0.704,0.931
+0.355,0.704,0.929
+0.360,0.704,0.926
+0.366,0.703,0.923
+0.372,0.703,0.921
+0.377,0.703,0.918
+0.383,0.702,0.915
+0.388,0.702,0.912
+0.393,0.702,0.910
+0.398,0.701,0.907
+0.403,0.701,0.904
+0.408,0.701,0.902
+0.413,0.700,0.899
+0.418,0.700,0.896
+0.423,0.699,0.894
+0.427,0.699,0.891
+0.432,0.699,0.888
+0.436,0.698,0.886
+0.441,0.698,0.883
+0.445,0.698,0.880
+0.449,0.697,0.878
+0.453,0.697,0.875
+0.458,0.697,0.872
+0.462,0.696,0.869
+0.466,0.696,0.867
+0.470,0.696,0.864
+0.473,0.695,0.861
+0.477,0.695,0.859
+0.481,0.695,0.856
+0.485,0.694,0.853
+0.489,0.694,0.851
+0.492,0.693,0.848
+0.496,0.693,0.845
+0.500,0.693,0.843
+0.503,0.692,0.840
+0.507,0.692,0.837
+0.510,0.692,0.835
+0.513,0.691,0.832
+0.517,0.691,0.829
+0.520,0.691,0.827
+0.524,0.690,0.824
+0.527,0.690,0.821
+0.530,0.690,0.819
+0.533,0.689,0.816
+0.536,0.689,0.813
+0.540,0.689,0.811
+0.543,0.688,0.808
+0.546,0.688,0.805
+0.549,0.688,0.803
+0.552,0.687,0.800
+0.555,0.687,0.797
+0.558,0.687,0.795
+0.561,0.686,0.792
+0.564,0.686,0.789
+0.566,0.686,0.787
+0.569,0.685,0.784
+0.572,0.685,0.781
+0.575,0.685,0.779
+0.578,0.684,0.776
+0.580,0.684,0.773
+0.583,0.683,0.771
+0.586,0.683,0.768
+0.588,0.683,0.765
+0.591,0.682,0.763
+0.594,0.682,0.760
+0.596,0.682,0.757
+0.599,0.681,0.755
+0.601,0.681,0.752
+0.604,0.681,0.749
+0.607,0.680,0.747
+0.609,0.680,0.744
+0.612,0.680,0.741
+0.614,0.679,0.739
+0.616,0.679,0.736
+0.619,0.679,0.733
+0.621,0.678,0.731
+0.624,0.678,0.728
+0.626,0.678,0.725
+0.628,0.677,0.723
+0.631,0.677,0.720
+0.633,0.677,0.717
+0.635,0.676,0.715
+0.638,0.676,0.712
+0.640,0.676,0.709
+0.642,0.675,0.707
+0.644,0.675,0.704
+0.647,0.675,0.701
+0.649,0.674,0.699
+0.651,0.674,0.696
+0.653,0.674,0.694
+0.656,0.673,0.691
+0.658,0.673,0.689
+0.660,0.672,0.686
+0.662,0.672,0.684
+0.665,0.671,0.681
+0.667,0.671,0.679
+0.670,0.671,0.676
+0.672,0.670,0.674
+0.675,0.670,0.672
+0.677,0.669,0.669
+0.680,0.668,0.667
+0.682,0.668,0.665
+0.685,0.667,0.663
+0.688,0.667,0.661
+0.691,0.666,0.659
+0.693,0.665,0.657
+0.696,0.665,0.655
+0.699,0.664,0.653
+0.702,0.663,0.651
+0.704,0.663,0.649
+0.707,0.662,0.647
+0.710,0.661,0.645
+0.713,0.660,0.643
+0.715,0.660,0.641
+0.718,0.659,0.639
+0.721,0.658,0.637
+0.724,0.658,0.635
+0.726,0.657,0.633
+0.729,0.656,0.631
+0.732,0.655,0.630
+0.734,0.655,0.628
+0.737,0.654,0.626
+0.740,0.653,0.624
+0.742,0.652,0.622
+0.745,0.652,0.620
+0.748,0.651,0.618
+0.750,0.650,0.616
+0.753,0.649,0.614
+0.755,0.649,0.612
+0.758,0.648,0.610
+0.761,0.647,0.609
+0.763,0.646,0.607
+0.766,0.646,0.605
+0.768,0.645,0.603
+0.771,0.644,0.601
+0.773,0.643,0.599
+0.776,0.643,0.597
+0.778,0.642,0.595
+0.781,0.641,0.593
+0.783,0.640,0.591
+0.786,0.639,0.589
+0.788,0.639,0.588
+0.790,0.638,0.586
+0.793,0.637,0.584
+0.795,0.636,0.582
+0.798,0.636,0.580
+0.800,0.635,0.578
+0.802,0.634,0.576
+0.805,0.633,0.574
+0.807,0.632,0.572
+0.810,0.632,0.570
+0.812,0.631,0.568
+0.814,0.630,0.567
+0.817,0.629,0.565
+0.819,0.628,0.563
+0.821,0.628,0.561
+0.824,0.627,0.559
+0.826,0.626,0.557
+0.828,0.625,0.555
+0.830,0.624,0.553
+0.833,0.623,0.551
+0.835,0.623,0.549
+0.837,0.622,0.547
+0.839,0.621,0.546
+0.842,0.620,0.544
+0.844,0.619,0.542
+0.846,0.619,0.540
+0.848,0.618,0.538
+0.851,0.617,0.536
+0.853,0.616,0.534
+0.855,0.615,0.532
+0.857,0.614,0.530
+0.859,0.613,0.528
+0.862,0.613,0.527
+0.864,0.612,0.525
+0.866,0.611,0.523
+0.868,0.610,0.521
+0.870,0.609,0.519
+0.872,0.608,0.517
+0.874,0.608,0.515
+0.877,0.607,0.513
+0.879,0.606,0.511
+0.881,0.605,0.509
+0.883,0.604,0.507
+0.885,0.603,0.505
+0.887,0.602,0.504
+0.889,0.601,0.502
+0.891,0.601,0.500
+0.893,0.600,0.498
+0.895,0.599,0.496
+0.898,0.598,0.494
+0.900,0.597,0.492
+0.902,0.596,0.490
+0.904,0.595,0.488
+0.906,0.594,0.486
+0.908,0.593,0.484
+0.910,0.593,0.483
+0.912,0.592,0.481
+0.914,0.591,0.479
+0.916,0.590,0.477
+0.918,0.589,0.475
+0.920,0.588,0.473
+0.922,0.587,0.471
+0.924,0.586,0.469
+0.926,0.585,0.467
+0.928,0.584,0.465
+0.930,0.583,0.463
+0.932,0.582,0.461
+0.934,0.581,0.460
+0.936,0.581,0.458
+0.938,0.580,0.456
+0.940,0.579,0.454
+0.942,0.578,0.452
+0.943,0.577,0.450
+0.945,0.576,0.448
+0.947,0.575,0.446
+0.949,0.574,0.444
+0.951,0.573,0.442
+0.953,0.572,0.440
+0.955,0.571,0.438
+0.957,0.570,0.436
+0.959,0.569,0.434
+0.961,0.568,0.433
+0.963,0.567,0.431
+0.965,0.566,0.429
+0.966,0.565,0.427
diff --git a/pyqtgraph/colors/maps/CET-D12.csv b/pyqtgraph/colors/maps/CET-D12.csv
new file mode 100644
index 00000000..3e39ba1b
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-D12.csv
@@ -0,0 +1,256 @@
+0.000,0.787,1.000
+0.000,0.786,1.000
+0.000,0.786,0.998
+0.000,0.785,0.995
+0.000,0.785,0.993
+0.000,0.784,0.991
+0.000,0.784,0.989
+0.051,0.783,0.987
+0.088,0.783,0.984
+0.115,0.782,0.982
+0.137,0.782,0.980
+0.156,0.781,0.978
+0.173,0.781,0.976
+0.188,0.781,0.973
+0.202,0.780,0.971
+0.215,0.780,0.969
+0.227,0.779,0.967
+0.238,0.779,0.965
+0.249,0.778,0.962
+0.259,0.778,0.960
+0.269,0.777,0.958
+0.279,0.777,0.956
+0.288,0.776,0.954
+0.296,0.776,0.951
+0.305,0.775,0.949
+0.313,0.775,0.947
+0.321,0.774,0.945
+0.328,0.774,0.943
+0.336,0.773,0.940
+0.343,0.773,0.938
+0.350,0.773,0.936
+0.357,0.772,0.934
+0.364,0.772,0.932
+0.370,0.771,0.930
+0.377,0.771,0.927
+0.383,0.770,0.925
+0.389,0.770,0.923
+0.395,0.769,0.921
+0.401,0.769,0.919
+0.407,0.768,0.916
+0.412,0.768,0.914
+0.418,0.767,0.912
+0.423,0.767,0.910
+0.429,0.766,0.908
+0.434,0.766,0.905
+0.439,0.765,0.903
+0.444,0.765,0.901
+0.449,0.764,0.899
+0.454,0.764,0.897
+0.459,0.763,0.895
+0.464,0.763,0.892
+0.469,0.762,0.890
+0.474,0.762,0.888
+0.478,0.761,0.886
+0.483,0.761,0.884
+0.487,0.761,0.881
+0.492,0.760,0.879
+0.496,0.760,0.877
+0.500,0.759,0.875
+0.505,0.759,0.873
+0.509,0.758,0.871
+0.513,0.758,0.868
+0.517,0.757,0.866
+0.521,0.757,0.864
+0.525,0.756,0.862
+0.529,0.756,0.860
+0.533,0.755,0.858
+0.537,0.755,0.855
+0.541,0.754,0.853
+0.545,0.754,0.851
+0.549,0.753,0.849
+0.553,0.753,0.847
+0.556,0.752,0.845
+0.560,0.752,0.842
+0.564,0.751,0.840
+0.567,0.751,0.838
+0.571,0.750,0.836
+0.574,0.750,0.834
+0.578,0.749,0.831
+0.582,0.749,0.829
+0.585,0.748,0.827
+0.588,0.748,0.825
+0.592,0.747,0.823
+0.595,0.747,0.821
+0.599,0.746,0.818
+0.602,0.746,0.816
+0.605,0.745,0.814
+0.608,0.745,0.812
+0.612,0.744,0.810
+0.615,0.744,0.808
+0.618,0.743,0.805
+0.621,0.743,0.803
+0.624,0.742,0.801
+0.628,0.742,0.799
+0.631,0.741,0.797
+0.634,0.741,0.795
+0.637,0.740,0.792
+0.640,0.740,0.790
+0.643,0.739,0.788
+0.646,0.739,0.786
+0.649,0.738,0.784
+0.652,0.738,0.782
+0.655,0.737,0.780
+0.657,0.737,0.777
+0.660,0.736,0.775
+0.663,0.736,0.773
+0.666,0.735,0.771
+0.669,0.735,0.769
+0.672,0.734,0.767
+0.674,0.734,0.764
+0.677,0.733,0.762
+0.680,0.733,0.760
+0.683,0.732,0.758
+0.685,0.732,0.756
+0.688,0.731,0.754
+0.691,0.731,0.752
+0.693,0.730,0.750
+0.696,0.729,0.748
+0.699,0.729,0.746
+0.701,0.728,0.744
+0.704,0.728,0.742
+0.706,0.727,0.741
+0.709,0.727,0.739
+0.711,0.726,0.738
+0.714,0.726,0.737
+0.716,0.725,0.736
+0.718,0.724,0.735
+0.721,0.724,0.734
+0.723,0.723,0.734
+0.725,0.723,0.734
+0.727,0.722,0.734
+0.729,0.721,0.734
+0.731,0.721,0.734
+0.733,0.720,0.735
+0.735,0.719,0.735
+0.737,0.719,0.736
+0.739,0.718,0.737
+0.741,0.717,0.738
+0.743,0.717,0.739
+0.744,0.716,0.740
+0.746,0.715,0.741
+0.748,0.715,0.742
+0.750,0.714,0.744
+0.751,0.713,0.745
+0.753,0.713,0.746
+0.755,0.712,0.747
+0.757,0.711,0.749
+0.758,0.710,0.750
+0.760,0.710,0.751
+0.762,0.709,0.753
+0.763,0.708,0.754
+0.765,0.708,0.755
+0.767,0.707,0.757
+0.769,0.706,0.758
+0.770,0.706,0.759
+0.772,0.705,0.761
+0.774,0.704,0.762
+0.775,0.703,0.763
+0.777,0.703,0.765
+0.779,0.702,0.766
+0.780,0.701,0.767
+0.782,0.701,0.769
+0.784,0.700,0.770
+0.785,0.699,0.771
+0.787,0.698,0.773
+0.789,0.698,0.774
+0.790,0.697,0.775
+0.792,0.696,0.777
+0.794,0.695,0.778
+0.795,0.695,0.779
+0.797,0.694,0.781
+0.799,0.693,0.782
+0.800,0.692,0.783
+0.802,0.692,0.785
+0.804,0.691,0.786
+0.805,0.690,0.787
+0.807,0.689,0.788
+0.809,0.689,0.790
+0.810,0.688,0.791
+0.812,0.687,0.792
+0.814,0.686,0.794
+0.815,0.686,0.795
+0.817,0.685,0.796
+0.819,0.684,0.798
+0.820,0.683,0.799
+0.822,0.682,0.800
+0.823,0.682,0.802
+0.825,0.681,0.803
+0.827,0.680,0.804
+0.828,0.679,0.806
+0.830,0.678,0.807
+0.831,0.678,0.808
+0.833,0.677,0.810
+0.835,0.676,0.811
+0.836,0.675,0.812
+0.838,0.675,0.814
+0.840,0.674,0.815
+0.841,0.673,0.816
+0.843,0.672,0.818
+0.844,0.671,0.819
+0.846,0.670,0.820
+0.848,0.670,0.822
+0.849,0.669,0.823
+0.851,0.668,0.824
+0.852,0.667,0.825
+0.854,0.666,0.827
+0.855,0.666,0.828
+0.857,0.665,0.829
+0.859,0.664,0.831
+0.860,0.663,0.832
+0.862,0.662,0.833
+0.863,0.661,0.835
+0.865,0.660,0.836
+0.866,0.660,0.837
+0.868,0.659,0.839
+0.870,0.658,0.840
+0.871,0.657,0.841
+0.873,0.656,0.843
+0.874,0.655,0.844
+0.876,0.654,0.845
+0.877,0.654,0.847
+0.879,0.653,0.848
+0.881,0.652,0.849
+0.882,0.651,0.851
+0.884,0.650,0.852
+0.885,0.649,0.853
+0.887,0.648,0.855
+0.888,0.647,0.856
+0.890,0.647,0.857
+0.891,0.646,0.859
+0.893,0.645,0.860
+0.895,0.644,0.861
+0.896,0.643,0.862
+0.898,0.642,0.864
+0.899,0.641,0.865
+0.901,0.640,0.866
+0.902,0.639,0.868
+0.904,0.638,0.869
+0.905,0.638,0.870
+0.907,0.637,0.872
+0.908,0.636,0.873
+0.910,0.635,0.874
+0.911,0.634,0.876
+0.913,0.633,0.877
+0.914,0.632,0.878
+0.916,0.631,0.880
+0.917,0.630,0.881
+0.919,0.629,0.882
+0.920,0.628,0.884
+0.922,0.627,0.885
+0.924,0.626,0.886
+0.925,0.625,0.888
+0.927,0.624,0.889
+0.928,0.623,0.890
+0.930,0.622,0.892
+0.931,0.621,0.893
diff --git a/pyqtgraph/colors/maps/CET-D13.csv b/pyqtgraph/colors/maps/CET-D13.csv
new file mode 100644
index 00000000..6f569c8b
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-D13.csv
@@ -0,0 +1,256 @@
+0.066,0.176,0.408
+0.070,0.181,0.416
+0.074,0.186,0.424
+0.078,0.191,0.433
+0.083,0.196,0.441
+0.087,0.200,0.449
+0.091,0.205,0.458
+0.095,0.210,0.466
+0.099,0.215,0.475
+0.103,0.220,0.483
+0.107,0.225,0.491
+0.111,0.230,0.500
+0.114,0.235,0.508
+0.118,0.241,0.516
+0.122,0.246,0.525
+0.126,0.251,0.533
+0.129,0.256,0.542
+0.133,0.261,0.550
+0.136,0.267,0.558
+0.140,0.272,0.567
+0.143,0.277,0.575
+0.147,0.283,0.583
+0.150,0.288,0.591
+0.154,0.294,0.600
+0.157,0.299,0.608
+0.160,0.305,0.616
+0.163,0.310,0.624
+0.166,0.316,0.633
+0.169,0.321,0.641
+0.172,0.327,0.649
+0.175,0.333,0.657
+0.178,0.338,0.665
+0.181,0.344,0.673
+0.184,0.350,0.681
+0.186,0.356,0.689
+0.189,0.362,0.697
+0.191,0.368,0.705
+0.194,0.374,0.713
+0.196,0.380,0.721
+0.198,0.386,0.729
+0.200,0.392,0.736
+0.202,0.398,0.744
+0.204,0.404,0.752
+0.206,0.410,0.759
+0.207,0.416,0.767
+0.209,0.423,0.774
+0.210,0.429,0.781
+0.211,0.436,0.789
+0.212,0.442,0.796
+0.213,0.449,0.803
+0.213,0.455,0.810
+0.214,0.462,0.817
+0.214,0.468,0.824
+0.214,0.475,0.831
+0.214,0.482,0.838
+0.213,0.489,0.844
+0.212,0.496,0.851
+0.211,0.502,0.857
+0.210,0.509,0.863
+0.208,0.517,0.869
+0.206,0.524,0.875
+0.205,0.531,0.881
+0.203,0.538,0.887
+0.200,0.545,0.892
+0.199,0.552,0.898
+0.197,0.560,0.903
+0.196,0.567,0.908
+0.195,0.574,0.913
+0.194,0.581,0.917
+0.195,0.588,0.922
+0.196,0.596,0.926
+0.198,0.603,0.931
+0.201,0.610,0.935
+0.206,0.617,0.939
+0.211,0.624,0.942
+0.217,0.631,0.946
+0.224,0.637,0.950
+0.231,0.644,0.953
+0.240,0.651,0.956
+0.249,0.658,0.959
+0.259,0.665,0.962
+0.270,0.671,0.965
+0.281,0.678,0.967
+0.293,0.684,0.970
+0.305,0.691,0.972
+0.317,0.697,0.974
+0.330,0.704,0.976
+0.343,0.710,0.978
+0.356,0.716,0.979
+0.370,0.723,0.981
+0.384,0.729,0.982
+0.398,0.735,0.983
+0.412,0.741,0.984
+0.427,0.747,0.985
+0.441,0.753,0.985
+0.456,0.759,0.986
+0.471,0.765,0.986
+0.486,0.771,0.986
+0.502,0.777,0.986
+0.517,0.783,0.986
+0.532,0.788,0.986
+0.548,0.794,0.985
+0.563,0.800,0.985
+0.579,0.805,0.984
+0.595,0.811,0.983
+0.610,0.816,0.982
+0.626,0.822,0.981
+0.641,0.827,0.979
+0.657,0.833,0.978
+0.672,0.838,0.977
+0.687,0.844,0.975
+0.702,0.849,0.974
+0.717,0.855,0.972
+0.732,0.860,0.970
+0.747,0.865,0.969
+0.761,0.871,0.967
+0.776,0.876,0.965
+0.789,0.881,0.963
+0.803,0.887,0.961
+0.816,0.892,0.959
+0.828,0.897,0.957
+0.840,0.902,0.955
+0.850,0.906,0.952
+0.859,0.910,0.949
+0.866,0.914,0.945
+0.872,0.917,0.941
+0.875,0.919,0.937
+0.876,0.921,0.932
+0.875,0.922,0.926
+0.871,0.922,0.921
+0.865,0.921,0.914
+0.857,0.920,0.908
+0.848,0.918,0.901
+0.836,0.916,0.894
+0.824,0.913,0.886
+0.810,0.910,0.879
+0.796,0.906,0.871
+0.781,0.902,0.864
+0.766,0.899,0.856
+0.750,0.895,0.848
+0.734,0.891,0.841
+0.718,0.886,0.833
+0.702,0.882,0.825
+0.685,0.878,0.818
+0.669,0.874,0.810
+0.653,0.870,0.802
+0.636,0.865,0.795
+0.620,0.861,0.787
+0.603,0.856,0.779
+0.587,0.852,0.772
+0.570,0.848,0.764
+0.554,0.843,0.756
+0.537,0.838,0.748
+0.521,0.834,0.740
+0.505,0.829,0.732
+0.489,0.824,0.724
+0.473,0.819,0.716
+0.458,0.814,0.707
+0.442,0.809,0.699
+0.427,0.804,0.690
+0.412,0.799,0.682
+0.397,0.794,0.673
+0.383,0.789,0.664
+0.368,0.783,0.655
+0.354,0.778,0.647
+0.341,0.772,0.638
+0.327,0.767,0.628
+0.314,0.761,0.619
+0.301,0.756,0.610
+0.288,0.750,0.601
+0.276,0.745,0.591
+0.264,0.739,0.581
+0.252,0.733,0.572
+0.241,0.727,0.562
+0.230,0.721,0.552
+0.220,0.715,0.542
+0.211,0.709,0.532
+0.201,0.703,0.522
+0.193,0.697,0.512
+0.185,0.691,0.502
+0.178,0.685,0.492
+0.171,0.679,0.481
+0.165,0.673,0.471
+0.160,0.667,0.460
+0.155,0.660,0.450
+0.152,0.654,0.439
+0.149,0.648,0.428
+0.146,0.641,0.418
+0.145,0.635,0.407
+0.143,0.629,0.396
+0.142,0.622,0.386
+0.142,0.616,0.375
+0.141,0.609,0.365
+0.141,0.603,0.355
+0.140,0.597,0.345
+0.140,0.590,0.335
+0.139,0.584,0.325
+0.139,0.577,0.315
+0.138,0.571,0.306
+0.137,0.564,0.297
+0.136,0.558,0.288
+0.135,0.552,0.279
+0.134,0.545,0.271
+0.132,0.539,0.263
+0.131,0.533,0.255
+0.129,0.526,0.247
+0.127,0.520,0.239
+0.125,0.514,0.232
+0.123,0.507,0.225
+0.121,0.501,0.217
+0.119,0.495,0.211
+0.116,0.488,0.204
+0.114,0.482,0.197
+0.112,0.476,0.191
+0.109,0.470,0.184
+0.107,0.463,0.178
+0.104,0.457,0.172
+0.101,0.451,0.166
+0.099,0.445,0.160
+0.096,0.438,0.154
+0.093,0.432,0.149
+0.090,0.426,0.143
+0.087,0.420,0.138
+0.084,0.414,0.132
+0.082,0.408,0.127
+0.078,0.402,0.122
+0.075,0.395,0.117
+0.072,0.389,0.112
+0.069,0.383,0.108
+0.066,0.377,0.103
+0.063,0.371,0.098
+0.060,0.365,0.094
+0.057,0.359,0.089
+0.053,0.353,0.085
+0.050,0.347,0.081
+0.047,0.341,0.076
+0.043,0.335,0.072
+0.040,0.329,0.068
+0.037,0.324,0.064
+0.033,0.318,0.060
+0.030,0.312,0.057
+0.027,0.306,0.053
+0.024,0.300,0.049
+0.021,0.294,0.045
+0.019,0.289,0.042
+0.016,0.283,0.038
+0.013,0.277,0.035
+0.011,0.271,0.032
+0.009,0.265,0.029
+0.007,0.260,0.026
+0.005,0.254,0.023
+0.004,0.248,0.020
+0.002,0.243,0.016
+0.001,0.237,0.013
+0.001,0.232,0.009
+0.000,0.226,0.006
diff --git a/pyqtgraph/colors/maps/CET-D1A.csv b/pyqtgraph/colors/maps/CET-D1A.csv
new file mode 100644
index 00000000..23b03b69
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-D1A.csv
@@ -0,0 +1,256 @@
+0.092,0.161,0.447
+0.093,0.165,0.458
+0.095,0.170,0.469
+0.096,0.174,0.481
+0.098,0.178,0.492
+0.099,0.182,0.504
+0.101,0.187,0.515
+0.102,0.191,0.527
+0.103,0.196,0.538
+0.104,0.200,0.550
+0.106,0.204,0.562
+0.107,0.209,0.573
+0.108,0.213,0.585
+0.109,0.218,0.597
+0.111,0.222,0.609
+0.112,0.227,0.621
+0.113,0.231,0.633
+0.114,0.236,0.645
+0.115,0.240,0.657
+0.116,0.245,0.669
+0.118,0.249,0.681
+0.119,0.254,0.693
+0.121,0.259,0.704
+0.122,0.263,0.716
+0.124,0.268,0.728
+0.127,0.273,0.740
+0.129,0.278,0.751
+0.133,0.282,0.762
+0.137,0.287,0.773
+0.141,0.292,0.784
+0.147,0.297,0.794
+0.153,0.302,0.804
+0.159,0.307,0.813
+0.167,0.312,0.822
+0.175,0.317,0.830
+0.184,0.322,0.838
+0.194,0.328,0.845
+0.203,0.333,0.852
+0.214,0.338,0.858
+0.224,0.344,0.864
+0.235,0.349,0.870
+0.246,0.355,0.875
+0.257,0.361,0.879
+0.268,0.366,0.884
+0.279,0.372,0.888
+0.290,0.378,0.892
+0.300,0.384,0.896
+0.311,0.390,0.899
+0.321,0.395,0.903
+0.332,0.401,0.906
+0.342,0.407,0.910
+0.352,0.413,0.913
+0.361,0.419,0.916
+0.371,0.425,0.920
+0.380,0.431,0.923
+0.390,0.437,0.926
+0.399,0.443,0.930
+0.408,0.449,0.933
+0.417,0.455,0.936
+0.426,0.462,0.939
+0.434,0.468,0.943
+0.443,0.474,0.946
+0.452,0.480,0.949
+0.460,0.486,0.952
+0.469,0.492,0.956
+0.477,0.498,0.959
+0.485,0.505,0.962
+0.494,0.511,0.965
+0.502,0.517,0.968
+0.510,0.523,0.970
+0.518,0.530,0.973
+0.526,0.536,0.976
+0.535,0.543,0.978
+0.543,0.549,0.980
+0.551,0.555,0.982
+0.559,0.562,0.984
+0.567,0.568,0.986
+0.576,0.575,0.987
+0.584,0.582,0.988
+0.592,0.588,0.989
+0.600,0.595,0.990
+0.608,0.602,0.990
+0.617,0.608,0.991
+0.625,0.615,0.991
+0.633,0.622,0.990
+0.641,0.629,0.990
+0.649,0.636,0.990
+0.657,0.643,0.989
+0.665,0.650,0.989
+0.672,0.657,0.988
+0.680,0.664,0.987
+0.688,0.671,0.986
+0.696,0.678,0.985
+0.703,0.685,0.985
+0.711,0.692,0.984
+0.718,0.699,0.983
+0.726,0.706,0.982
+0.733,0.713,0.981
+0.740,0.720,0.980
+0.747,0.727,0.979
+0.755,0.734,0.978
+0.762,0.742,0.977
+0.769,0.749,0.976
+0.776,0.756,0.975
+0.783,0.763,0.973
+0.790,0.770,0.972
+0.797,0.778,0.971
+0.804,0.785,0.970
+0.810,0.792,0.969
+0.817,0.799,0.968
+0.824,0.806,0.967
+0.831,0.814,0.965
+0.837,0.821,0.964
+0.844,0.828,0.963
+0.851,0.835,0.961
+0.857,0.841,0.960
+0.864,0.848,0.958
+0.871,0.854,0.956
+0.877,0.861,0.953
+0.883,0.866,0.951
+0.890,0.872,0.948
+0.896,0.876,0.944
+0.902,0.881,0.940
+0.909,0.884,0.936
+0.914,0.887,0.931
+0.920,0.889,0.926
+0.926,0.889,0.920
+0.931,0.890,0.913
+0.936,0.889,0.906
+0.941,0.887,0.898
+0.946,0.884,0.889
+0.950,0.880,0.881
+0.954,0.876,0.871
+0.958,0.871,0.861
+0.961,0.865,0.851
+0.965,0.858,0.841
+0.968,0.851,0.830
+0.970,0.844,0.820
+0.973,0.836,0.809
+0.975,0.828,0.798
+0.977,0.820,0.786
+0.979,0.811,0.775
+0.980,0.802,0.764
+0.982,0.794,0.753
+0.983,0.785,0.742
+0.984,0.776,0.730
+0.986,0.767,0.719
+0.987,0.758,0.708
+0.988,0.748,0.697
+0.988,0.739,0.686
+0.989,0.730,0.675
+0.990,0.721,0.664
+0.990,0.712,0.652
+0.991,0.703,0.641
+0.991,0.694,0.630
+0.991,0.684,0.619
+0.991,0.675,0.609
+0.991,0.666,0.598
+0.991,0.657,0.587
+0.991,0.647,0.576
+0.991,0.638,0.565
+0.991,0.629,0.554
+0.990,0.619,0.543
+0.990,0.610,0.533
+0.989,0.601,0.522
+0.989,0.591,0.511
+0.988,0.582,0.501
+0.987,0.572,0.490
+0.986,0.563,0.480
+0.985,0.554,0.470
+0.983,0.544,0.459
+0.982,0.535,0.449
+0.980,0.525,0.439
+0.978,0.516,0.429
+0.976,0.507,0.419
+0.974,0.498,0.410
+0.971,0.488,0.400
+0.969,0.479,0.391
+0.966,0.470,0.382
+0.963,0.461,0.373
+0.959,0.453,0.364
+0.956,0.444,0.356
+0.952,0.435,0.347
+0.948,0.426,0.339
+0.944,0.418,0.330
+0.940,0.409,0.322
+0.936,0.401,0.314
+0.931,0.392,0.306
+0.927,0.384,0.299
+0.922,0.375,0.291
+0.917,0.367,0.283
+0.912,0.358,0.276
+0.908,0.350,0.268
+0.903,0.341,0.260
+0.898,0.333,0.253
+0.893,0.324,0.245
+0.888,0.315,0.238
+0.883,0.306,0.230
+0.878,0.297,0.223
+0.873,0.288,0.215
+0.868,0.279,0.208
+0.863,0.270,0.200
+0.858,0.260,0.193
+0.853,0.251,0.186
+0.848,0.241,0.178
+0.843,0.231,0.171
+0.837,0.221,0.164
+0.832,0.211,0.156
+0.827,0.200,0.149
+0.821,0.190,0.142
+0.816,0.179,0.135
+0.810,0.168,0.128
+0.804,0.156,0.121
+0.798,0.145,0.114
+0.792,0.133,0.108
+0.786,0.121,0.101
+0.779,0.109,0.095
+0.772,0.097,0.090
+0.765,0.085,0.084
+0.757,0.073,0.079
+0.750,0.061,0.074
+0.742,0.049,0.070
+0.733,0.037,0.065
+0.724,0.027,0.062
+0.715,0.019,0.058
+0.706,0.012,0.056
+0.697,0.007,0.053
+0.687,0.004,0.051
+0.677,0.002,0.049
+0.667,0.001,0.047
+0.657,0.001,0.045
+0.646,0.001,0.044
+0.636,0.002,0.043
+0.625,0.003,0.042
+0.615,0.004,0.041
+0.604,0.006,0.040
+0.594,0.008,0.039
+0.583,0.009,0.038
+0.573,0.011,0.037
+0.562,0.013,0.036
+0.552,0.014,0.034
+0.542,0.016,0.033
+0.531,0.017,0.032
+0.521,0.019,0.030
+0.511,0.020,0.029
+0.500,0.021,0.027
+0.490,0.022,0.026
+0.480,0.023,0.024
+0.470,0.024,0.023
+0.460,0.025,0.021
+0.450,0.026,0.019
+0.440,0.026,0.017
+0.430,0.027,0.015
+0.420,0.027,0.013
+0.410,0.028,0.011
+0.400,0.028,0.009
diff --git a/pyqtgraph/colors/maps/CET-D2.csv b/pyqtgraph/colors/maps/CET-D2.csv
new file mode 100644
index 00000000..65e14c4d
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-D2.csv
@@ -0,0 +1,256 @@
+0.222,0.591,0.055
+0.230,0.594,0.069
+0.238,0.597,0.081
+0.245,0.600,0.093
+0.253,0.602,0.103
+0.260,0.605,0.113
+0.268,0.608,0.123
+0.275,0.611,0.132
+0.282,0.614,0.140
+0.289,0.616,0.149
+0.296,0.619,0.157
+0.303,0.622,0.165
+0.310,0.625,0.173
+0.316,0.628,0.181
+0.323,0.630,0.189
+0.329,0.633,0.196
+0.336,0.636,0.203
+0.342,0.639,0.211
+0.349,0.642,0.218
+0.355,0.644,0.225
+0.361,0.647,0.232
+0.367,0.650,0.239
+0.373,0.653,0.246
+0.380,0.655,0.253
+0.386,0.658,0.260
+0.392,0.661,0.267
+0.398,0.664,0.274
+0.404,0.667,0.280
+0.410,0.669,0.287
+0.415,0.672,0.294
+0.421,0.675,0.300
+0.427,0.678,0.307
+0.433,0.681,0.314
+0.439,0.683,0.320
+0.445,0.686,0.327
+0.450,0.689,0.333
+0.456,0.692,0.340
+0.462,0.694,0.346
+0.467,0.697,0.353
+0.473,0.700,0.359
+0.479,0.703,0.366
+0.484,0.705,0.372
+0.490,0.708,0.379
+0.496,0.711,0.385
+0.501,0.714,0.392
+0.507,0.716,0.398
+0.512,0.719,0.405
+0.518,0.722,0.411
+0.523,0.725,0.417
+0.529,0.728,0.424
+0.534,0.730,0.430
+0.540,0.733,0.437
+0.545,0.736,0.443
+0.550,0.739,0.449
+0.556,0.741,0.456
+0.561,0.744,0.462
+0.567,0.747,0.469
+0.572,0.750,0.475
+0.578,0.752,0.482
+0.583,0.755,0.488
+0.588,0.758,0.494
+0.594,0.760,0.501
+0.599,0.763,0.507
+0.604,0.766,0.514
+0.610,0.769,0.520
+0.615,0.771,0.526
+0.620,0.774,0.533
+0.626,0.777,0.539
+0.631,0.780,0.546
+0.636,0.782,0.552
+0.641,0.785,0.559
+0.647,0.788,0.565
+0.652,0.791,0.571
+0.657,0.793,0.578
+0.663,0.796,0.584
+0.668,0.799,0.591
+0.673,0.802,0.597
+0.678,0.804,0.604
+0.684,0.807,0.610
+0.689,0.810,0.617
+0.694,0.812,0.623
+0.699,0.815,0.630
+0.704,0.818,0.636
+0.710,0.821,0.643
+0.715,0.823,0.649
+0.720,0.826,0.656
+0.725,0.829,0.662
+0.730,0.832,0.669
+0.736,0.834,0.675
+0.741,0.837,0.682
+0.746,0.840,0.688
+0.751,0.842,0.695
+0.756,0.845,0.701
+0.762,0.848,0.708
+0.767,0.851,0.714
+0.772,0.853,0.721
+0.777,0.856,0.728
+0.782,0.859,0.734
+0.787,0.861,0.741
+0.793,0.864,0.747
+0.798,0.867,0.754
+0.803,0.870,0.760
+0.808,0.872,0.767
+0.813,0.875,0.774
+0.818,0.878,0.780
+0.823,0.880,0.787
+0.829,0.883,0.794
+0.834,0.886,0.800
+0.839,0.888,0.807
+0.844,0.891,0.813
+0.849,0.894,0.820
+0.854,0.897,0.827
+0.859,0.899,0.833
+0.864,0.902,0.840
+0.869,0.904,0.847
+0.874,0.907,0.853
+0.879,0.909,0.860
+0.884,0.911,0.866
+0.889,0.914,0.872
+0.893,0.915,0.878
+0.898,0.917,0.884
+0.902,0.919,0.890
+0.906,0.920,0.896
+0.910,0.921,0.901
+0.913,0.922,0.906
+0.917,0.922,0.911
+0.919,0.922,0.915
+0.922,0.921,0.919
+0.924,0.920,0.923
+0.926,0.919,0.926
+0.927,0.917,0.929
+0.928,0.915,0.931
+0.929,0.912,0.933
+0.929,0.909,0.935
+0.929,0.906,0.936
+0.929,0.903,0.937
+0.929,0.899,0.938
+0.928,0.895,0.939
+0.927,0.891,0.939
+0.926,0.887,0.939
+0.925,0.883,0.939
+0.924,0.879,0.939
+0.923,0.874,0.939
+0.921,0.870,0.939
+0.920,0.865,0.939
+0.919,0.861,0.939
+0.917,0.856,0.939
+0.916,0.852,0.938
+0.915,0.847,0.938
+0.913,0.843,0.938
+0.912,0.838,0.938
+0.910,0.834,0.937
+0.909,0.830,0.937
+0.907,0.825,0.937
+0.906,0.821,0.936
+0.905,0.816,0.936
+0.903,0.812,0.936
+0.902,0.807,0.935
+0.900,0.803,0.935
+0.899,0.798,0.935
+0.897,0.794,0.935
+0.896,0.789,0.934
+0.894,0.785,0.934
+0.893,0.780,0.934
+0.891,0.776,0.933
+0.890,0.771,0.933
+0.888,0.767,0.933
+0.886,0.762,0.932
+0.885,0.758,0.932
+0.883,0.753,0.932
+0.882,0.749,0.931
+0.880,0.744,0.931
+0.879,0.740,0.931
+0.877,0.735,0.930
+0.875,0.731,0.930
+0.874,0.726,0.930
+0.872,0.722,0.929
+0.871,0.717,0.929
+0.869,0.713,0.929
+0.867,0.708,0.928
+0.866,0.704,0.928
+0.864,0.699,0.928
+0.862,0.695,0.927
+0.861,0.690,0.927
+0.859,0.686,0.926
+0.857,0.681,0.926
+0.856,0.677,0.926
+0.854,0.672,0.925
+0.852,0.668,0.925
+0.850,0.663,0.925
+0.849,0.659,0.924
+0.847,0.654,0.924
+0.845,0.650,0.923
+0.844,0.645,0.923
+0.842,0.640,0.923
+0.840,0.636,0.922
+0.838,0.631,0.922
+0.836,0.627,0.921
+0.835,0.622,0.921
+0.833,0.618,0.921
+0.831,0.613,0.920
+0.829,0.609,0.920
+0.828,0.604,0.919
+0.826,0.599,0.919
+0.824,0.595,0.919
+0.822,0.590,0.918
+0.820,0.586,0.918
+0.818,0.581,0.917
+0.816,0.577,0.917
+0.815,0.572,0.917
+0.813,0.567,0.916
+0.811,0.563,0.916
+0.809,0.558,0.915
+0.807,0.554,0.915
+0.805,0.549,0.914
+0.803,0.544,0.914
+0.801,0.540,0.914
+0.799,0.535,0.913
+0.797,0.530,0.913
+0.796,0.526,0.912
+0.794,0.521,0.912
+0.792,0.516,0.911
+0.790,0.512,0.911
+0.788,0.507,0.910
+0.786,0.502,0.910
+0.784,0.498,0.910
+0.782,0.493,0.909
+0.780,0.488,0.909
+0.778,0.483,0.908
+0.776,0.479,0.908
+0.774,0.474,0.907
+0.772,0.469,0.907
+0.769,0.464,0.906
+0.767,0.460,0.906
+0.765,0.455,0.905
+0.763,0.450,0.905
+0.761,0.445,0.904
+0.759,0.440,0.904
+0.757,0.435,0.903
+0.755,0.431,0.903
+0.753,0.426,0.902
+0.751,0.421,0.902
+0.749,0.416,0.902
+0.746,0.411,0.901
+0.744,0.406,0.901
+0.742,0.401,0.900
+0.740,0.396,0.900
+0.738,0.391,0.899
+0.736,0.386,0.899
+0.733,0.381,0.898
+0.731,0.376,0.898
+0.729,0.371,0.897
+0.727,0.365,0.897
+0.724,0.360,0.896
+0.722,0.355,0.895
+0.720,0.350,0.895
diff --git a/pyqtgraph/colors/maps/CET-D3.csv b/pyqtgraph/colors/maps/CET-D3.csv
new file mode 100644
index 00000000..20b5477d
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-D3.csv
@@ -0,0 +1,256 @@
+0.222,0.591,0.055
+0.230,0.594,0.069
+0.238,0.597,0.081
+0.245,0.600,0.093
+0.253,0.602,0.103
+0.260,0.605,0.113
+0.268,0.608,0.123
+0.275,0.611,0.132
+0.282,0.614,0.140
+0.289,0.616,0.149
+0.296,0.619,0.157
+0.303,0.622,0.165
+0.310,0.625,0.173
+0.316,0.628,0.181
+0.323,0.630,0.189
+0.329,0.633,0.196
+0.336,0.636,0.203
+0.342,0.639,0.211
+0.349,0.642,0.218
+0.355,0.644,0.225
+0.361,0.647,0.232
+0.367,0.650,0.239
+0.373,0.653,0.246
+0.380,0.655,0.253
+0.386,0.658,0.260
+0.392,0.661,0.267
+0.398,0.664,0.274
+0.404,0.667,0.280
+0.410,0.669,0.287
+0.415,0.672,0.294
+0.421,0.675,0.300
+0.427,0.678,0.307
+0.433,0.681,0.314
+0.439,0.683,0.320
+0.445,0.686,0.327
+0.450,0.689,0.333
+0.456,0.692,0.340
+0.462,0.694,0.346
+0.467,0.697,0.353
+0.473,0.700,0.359
+0.479,0.703,0.366
+0.484,0.705,0.372
+0.490,0.708,0.379
+0.496,0.711,0.385
+0.501,0.714,0.392
+0.507,0.716,0.398
+0.512,0.719,0.405
+0.518,0.722,0.411
+0.523,0.725,0.417
+0.529,0.728,0.424
+0.534,0.730,0.430
+0.540,0.733,0.437
+0.545,0.736,0.443
+0.550,0.739,0.449
+0.556,0.741,0.456
+0.561,0.744,0.462
+0.567,0.747,0.469
+0.572,0.750,0.475
+0.578,0.752,0.482
+0.583,0.755,0.488
+0.588,0.758,0.494
+0.594,0.760,0.501
+0.599,0.763,0.507
+0.604,0.766,0.514
+0.610,0.769,0.520
+0.615,0.771,0.526
+0.620,0.774,0.533
+0.626,0.777,0.539
+0.631,0.780,0.546
+0.636,0.782,0.552
+0.641,0.785,0.559
+0.647,0.788,0.565
+0.652,0.791,0.571
+0.657,0.793,0.578
+0.663,0.796,0.584
+0.668,0.799,0.591
+0.673,0.802,0.597
+0.678,0.804,0.604
+0.684,0.807,0.610
+0.689,0.810,0.617
+0.694,0.812,0.623
+0.699,0.815,0.630
+0.704,0.818,0.636
+0.710,0.821,0.643
+0.715,0.823,0.649
+0.720,0.826,0.656
+0.725,0.829,0.662
+0.730,0.832,0.669
+0.736,0.834,0.675
+0.741,0.837,0.682
+0.746,0.840,0.688
+0.751,0.842,0.695
+0.756,0.845,0.701
+0.762,0.848,0.708
+0.767,0.851,0.714
+0.772,0.853,0.721
+0.777,0.856,0.728
+0.782,0.859,0.734
+0.787,0.861,0.741
+0.793,0.864,0.747
+0.798,0.867,0.754
+0.803,0.870,0.760
+0.808,0.872,0.767
+0.813,0.875,0.774
+0.818,0.878,0.780
+0.823,0.880,0.787
+0.829,0.883,0.794
+0.834,0.886,0.800
+0.839,0.888,0.807
+0.844,0.891,0.813
+0.849,0.894,0.820
+0.854,0.897,0.827
+0.859,0.899,0.833
+0.865,0.902,0.840
+0.870,0.904,0.846
+0.875,0.907,0.852
+0.880,0.909,0.859
+0.885,0.911,0.865
+0.890,0.913,0.870
+0.895,0.915,0.876
+0.900,0.917,0.881
+0.904,0.919,0.886
+0.909,0.920,0.890
+0.914,0.921,0.894
+0.918,0.921,0.897
+0.922,0.921,0.900
+0.926,0.921,0.902
+0.930,0.920,0.903
+0.934,0.919,0.904
+0.937,0.917,0.904
+0.940,0.915,0.903
+0.943,0.913,0.901
+0.946,0.910,0.899
+0.948,0.907,0.897
+0.950,0.904,0.893
+0.952,0.900,0.890
+0.954,0.896,0.886
+0.956,0.892,0.881
+0.957,0.888,0.876
+0.959,0.884,0.872
+0.960,0.879,0.866
+0.961,0.874,0.861
+0.962,0.870,0.856
+0.964,0.865,0.850
+0.965,0.860,0.845
+0.966,0.856,0.839
+0.966,0.851,0.834
+0.967,0.846,0.828
+0.968,0.841,0.823
+0.969,0.837,0.817
+0.970,0.832,0.812
+0.971,0.827,0.806
+0.971,0.822,0.800
+0.972,0.817,0.795
+0.973,0.813,0.789
+0.973,0.808,0.784
+0.974,0.803,0.778
+0.975,0.798,0.773
+0.975,0.793,0.767
+0.976,0.789,0.762
+0.976,0.784,0.756
+0.977,0.779,0.751
+0.977,0.774,0.745
+0.978,0.769,0.740
+0.978,0.765,0.734
+0.979,0.760,0.729
+0.979,0.755,0.723
+0.979,0.750,0.718
+0.980,0.745,0.712
+0.980,0.740,0.707
+0.980,0.736,0.701
+0.980,0.731,0.696
+0.981,0.726,0.691
+0.981,0.721,0.685
+0.981,0.716,0.680
+0.981,0.711,0.674
+0.981,0.707,0.669
+0.981,0.702,0.664
+0.982,0.697,0.658
+0.982,0.692,0.653
+0.982,0.687,0.647
+0.982,0.682,0.642
+0.982,0.677,0.637
+0.982,0.672,0.631
+0.982,0.668,0.626
+0.981,0.663,0.621
+0.981,0.658,0.615
+0.981,0.653,0.610
+0.981,0.648,0.605
+0.981,0.643,0.600
+0.981,0.638,0.594
+0.981,0.633,0.589
+0.980,0.628,0.584
+0.980,0.623,0.578
+0.980,0.618,0.573
+0.980,0.613,0.568
+0.979,0.608,0.563
+0.979,0.603,0.557
+0.979,0.598,0.552
+0.978,0.593,0.547
+0.978,0.588,0.542
+0.977,0.583,0.536
+0.977,0.578,0.531
+0.977,0.573,0.526
+0.976,0.568,0.521
+0.976,0.563,0.516
+0.975,0.558,0.511
+0.975,0.553,0.505
+0.974,0.548,0.500
+0.974,0.543,0.495
+0.973,0.538,0.490
+0.972,0.532,0.485
+0.972,0.527,0.480
+0.971,0.522,0.475
+0.970,0.517,0.469
+0.970,0.512,0.464
+0.969,0.507,0.459
+0.968,0.501,0.454
+0.968,0.496,0.449
+0.967,0.491,0.444
+0.966,0.486,0.439
+0.965,0.480,0.434
+0.965,0.475,0.429
+0.964,0.470,0.424
+0.963,0.464,0.419
+0.962,0.459,0.414
+0.961,0.453,0.409
+0.960,0.448,0.404
+0.960,0.442,0.399
+0.959,0.437,0.394
+0.958,0.431,0.389
+0.957,0.426,0.384
+0.956,0.420,0.379
+0.955,0.415,0.374
+0.954,0.409,0.369
+0.953,0.403,0.364
+0.952,0.398,0.359
+0.951,0.392,0.354
+0.950,0.386,0.349
+0.949,0.380,0.344
+0.947,0.374,0.340
+0.946,0.368,0.335
+0.945,0.363,0.330
+0.944,0.356,0.325
+0.943,0.350,0.320
+0.942,0.344,0.315
+0.941,0.338,0.310
+0.939,0.332,0.306
+0.938,0.325,0.301
+0.937,0.319,0.296
+0.936,0.312,0.291
+0.934,0.306,0.286
+0.933,0.299,0.281
+0.932,0.292,0.277
+0.931,0.286,0.272
+0.929,0.279,0.267
diff --git a/pyqtgraph/colors/maps/CET-D4.csv b/pyqtgraph/colors/maps/CET-D4.csv
new file mode 100644
index 00000000..00668e2b
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-D4.csv
@@ -0,0 +1,256 @@
+0.097,0.507,0.982
+0.103,0.504,0.974
+0.109,0.500,0.967
+0.114,0.497,0.959
+0.118,0.493,0.951
+0.123,0.490,0.943
+0.127,0.487,0.936
+0.131,0.483,0.928
+0.135,0.480,0.920
+0.138,0.476,0.913
+0.141,0.473,0.905
+0.145,0.469,0.897
+0.148,0.466,0.890
+0.150,0.463,0.882
+0.153,0.459,0.874
+0.156,0.456,0.867
+0.158,0.452,0.859
+0.161,0.449,0.852
+0.163,0.445,0.844
+0.165,0.442,0.837
+0.167,0.439,0.829
+0.169,0.435,0.822
+0.171,0.432,0.814
+0.172,0.429,0.807
+0.174,0.425,0.799
+0.176,0.422,0.792
+0.177,0.418,0.784
+0.179,0.415,0.777
+0.180,0.412,0.769
+0.181,0.408,0.762
+0.182,0.405,0.754
+0.184,0.402,0.747
+0.185,0.398,0.740
+0.186,0.395,0.732
+0.187,0.392,0.725
+0.188,0.389,0.718
+0.188,0.385,0.710
+0.189,0.382,0.703
+0.190,0.379,0.696
+0.191,0.375,0.688
+0.191,0.372,0.681
+0.192,0.369,0.674
+0.192,0.365,0.667
+0.193,0.362,0.659
+0.193,0.359,0.652
+0.194,0.356,0.645
+0.194,0.352,0.638
+0.194,0.349,0.631
+0.194,0.346,0.624
+0.195,0.343,0.616
+0.195,0.340,0.609
+0.195,0.336,0.602
+0.195,0.333,0.595
+0.195,0.330,0.588
+0.195,0.327,0.581
+0.195,0.323,0.574
+0.195,0.320,0.567
+0.195,0.317,0.560
+0.195,0.314,0.553
+0.194,0.311,0.546
+0.194,0.308,0.539
+0.194,0.304,0.532
+0.194,0.301,0.525
+0.193,0.298,0.518
+0.193,0.295,0.511
+0.192,0.292,0.504
+0.192,0.289,0.497
+0.192,0.286,0.491
+0.191,0.282,0.484
+0.190,0.279,0.477
+0.190,0.276,0.470
+0.189,0.273,0.463
+0.189,0.270,0.457
+0.188,0.267,0.450
+0.187,0.264,0.443
+0.187,0.261,0.436
+0.186,0.258,0.430
+0.185,0.255,0.423
+0.184,0.252,0.416
+0.183,0.249,0.410
+0.182,0.245,0.403
+0.182,0.242,0.396
+0.181,0.239,0.390
+0.180,0.236,0.383
+0.179,0.233,0.377
+0.178,0.230,0.370
+0.177,0.227,0.364
+0.176,0.224,0.357
+0.174,0.221,0.351
+0.173,0.218,0.344
+0.172,0.215,0.338
+0.171,0.213,0.331
+0.170,0.210,0.325
+0.168,0.207,0.319
+0.167,0.204,0.312
+0.166,0.201,0.306
+0.165,0.198,0.300
+0.163,0.195,0.293
+0.162,0.192,0.287
+0.160,0.189,0.281
+0.159,0.186,0.275
+0.158,0.183,0.268
+0.156,0.180,0.262
+0.155,0.178,0.256
+0.153,0.175,0.250
+0.151,0.172,0.244
+0.150,0.169,0.238
+0.148,0.166,0.232
+0.147,0.163,0.226
+0.145,0.161,0.220
+0.143,0.158,0.214
+0.142,0.155,0.208
+0.140,0.152,0.202
+0.139,0.150,0.196
+0.137,0.147,0.190
+0.135,0.144,0.184
+0.134,0.142,0.179
+0.133,0.139,0.173
+0.132,0.137,0.168
+0.131,0.134,0.163
+0.130,0.132,0.158
+0.129,0.130,0.153
+0.129,0.128,0.148
+0.129,0.127,0.144
+0.129,0.125,0.140
+0.130,0.124,0.137
+0.132,0.123,0.133
+0.133,0.123,0.131
+0.135,0.122,0.128
+0.138,0.122,0.126
+0.141,0.122,0.124
+0.144,0.122,0.123
+0.148,0.123,0.122
+0.152,0.124,0.121
+0.156,0.125,0.121
+0.161,0.126,0.121
+0.165,0.127,0.121
+0.170,0.129,0.122
+0.176,0.130,0.122
+0.181,0.132,0.123
+0.186,0.133,0.124
+0.192,0.135,0.125
+0.197,0.137,0.126
+0.203,0.139,0.127
+0.209,0.140,0.128
+0.214,0.142,0.129
+0.220,0.144,0.130
+0.226,0.146,0.131
+0.232,0.148,0.132
+0.237,0.149,0.133
+0.243,0.151,0.135
+0.249,0.153,0.136
+0.255,0.155,0.137
+0.260,0.156,0.138
+0.266,0.158,0.139
+0.272,0.160,0.140
+0.278,0.162,0.142
+0.284,0.163,0.143
+0.289,0.165,0.144
+0.295,0.167,0.145
+0.301,0.169,0.146
+0.307,0.170,0.147
+0.313,0.172,0.148
+0.319,0.174,0.150
+0.325,0.176,0.151
+0.330,0.177,0.152
+0.336,0.179,0.153
+0.342,0.181,0.154
+0.348,0.182,0.155
+0.354,0.184,0.157
+0.360,0.186,0.158
+0.366,0.187,0.159
+0.372,0.189,0.160
+0.378,0.191,0.161
+0.384,0.192,0.162
+0.390,0.194,0.163
+0.396,0.196,0.165
+0.402,0.197,0.166
+0.408,0.199,0.167
+0.414,0.201,0.168
+0.420,0.202,0.169
+0.426,0.204,0.170
+0.432,0.206,0.172
+0.438,0.207,0.173
+0.444,0.209,0.174
+0.450,0.210,0.175
+0.456,0.212,0.176
+0.463,0.214,0.177
+0.469,0.215,0.179
+0.475,0.217,0.180
+0.481,0.218,0.181
+0.487,0.220,0.182
+0.493,0.222,0.183
+0.499,0.223,0.184
+0.506,0.225,0.185
+0.512,0.226,0.187
+0.518,0.228,0.188
+0.524,0.229,0.189
+0.530,0.231,0.190
+0.537,0.232,0.191
+0.543,0.234,0.192
+0.549,0.236,0.194
+0.556,0.237,0.195
+0.562,0.239,0.196
+0.568,0.240,0.197
+0.574,0.242,0.198
+0.581,0.243,0.199
+0.587,0.245,0.201
+0.593,0.246,0.202
+0.600,0.248,0.203
+0.606,0.249,0.204
+0.612,0.251,0.205
+0.619,0.252,0.206
+0.625,0.254,0.208
+0.632,0.255,0.209
+0.638,0.257,0.210
+0.644,0.258,0.211
+0.651,0.260,0.212
+0.657,0.261,0.213
+0.664,0.263,0.215
+0.670,0.264,0.216
+0.677,0.266,0.217
+0.683,0.267,0.218
+0.690,0.268,0.219
+0.696,0.270,0.220
+0.703,0.271,0.222
+0.709,0.273,0.223
+0.716,0.274,0.224
+0.722,0.276,0.225
+0.729,0.277,0.226
+0.735,0.278,0.227
+0.742,0.280,0.229
+0.748,0.281,0.230
+0.755,0.283,0.231
+0.762,0.284,0.232
+0.768,0.286,0.233
+0.775,0.287,0.234
+0.782,0.288,0.236
+0.788,0.290,0.237
+0.795,0.291,0.238
+0.801,0.292,0.239
+0.808,0.294,0.240
+0.815,0.295,0.241
+0.821,0.297,0.243
+0.828,0.298,0.244
+0.835,0.299,0.245
+0.842,0.301,0.246
+0.848,0.302,0.247
+0.855,0.303,0.249
+0.862,0.305,0.250
+0.868,0.306,0.251
+0.875,0.307,0.252
+0.882,0.309,0.253
+0.889,0.310,0.254
+0.896,0.311,0.256
+0.902,0.313,0.257
diff --git a/pyqtgraph/colors/maps/CET-D6.csv b/pyqtgraph/colors/maps/CET-D6.csv
new file mode 100644
index 00000000..72e90a9b
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-D6.csv
@@ -0,0 +1,256 @@
+0.057,0.580,0.981
+0.066,0.575,0.973
+0.074,0.571,0.966
+0.082,0.567,0.958
+0.089,0.563,0.950
+0.095,0.559,0.943
+0.101,0.555,0.935
+0.106,0.551,0.927
+0.111,0.547,0.919
+0.116,0.543,0.912
+0.120,0.539,0.904
+0.124,0.535,0.896
+0.128,0.531,0.889
+0.132,0.526,0.881
+0.135,0.522,0.874
+0.138,0.518,0.866
+0.141,0.514,0.858
+0.144,0.510,0.851
+0.147,0.506,0.843
+0.150,0.502,0.836
+0.152,0.498,0.828
+0.155,0.494,0.821
+0.157,0.490,0.813
+0.159,0.486,0.806
+0.161,0.482,0.798
+0.163,0.478,0.791
+0.165,0.474,0.783
+0.167,0.470,0.776
+0.168,0.466,0.768
+0.170,0.462,0.761
+0.172,0.458,0.754
+0.173,0.455,0.746
+0.174,0.451,0.739
+0.176,0.447,0.732
+0.177,0.443,0.724
+0.178,0.439,0.717
+0.179,0.435,0.710
+0.180,0.431,0.702
+0.181,0.427,0.695
+0.182,0.423,0.688
+0.183,0.419,0.680
+0.184,0.415,0.673
+0.184,0.412,0.666
+0.185,0.408,0.659
+0.186,0.404,0.651
+0.186,0.400,0.644
+0.187,0.396,0.637
+0.187,0.392,0.630
+0.188,0.388,0.623
+0.188,0.385,0.616
+0.188,0.381,0.609
+0.189,0.377,0.601
+0.189,0.373,0.594
+0.189,0.369,0.587
+0.189,0.366,0.580
+0.189,0.362,0.573
+0.189,0.358,0.566
+0.189,0.354,0.559
+0.189,0.351,0.552
+0.189,0.347,0.545
+0.189,0.343,0.538
+0.189,0.339,0.531
+0.189,0.336,0.524
+0.189,0.332,0.517
+0.188,0.328,0.510
+0.188,0.324,0.504
+0.188,0.321,0.497
+0.187,0.317,0.490
+0.187,0.313,0.483
+0.186,0.310,0.476
+0.186,0.306,0.469
+0.186,0.302,0.463
+0.185,0.299,0.456
+0.184,0.295,0.449
+0.184,0.291,0.442
+0.183,0.288,0.436
+0.182,0.284,0.429
+0.182,0.281,0.422
+0.181,0.277,0.416
+0.180,0.273,0.409
+0.180,0.270,0.402
+0.179,0.266,0.396
+0.178,0.263,0.389
+0.177,0.259,0.383
+0.176,0.255,0.376
+0.175,0.252,0.370
+0.174,0.248,0.363
+0.173,0.245,0.357
+0.172,0.241,0.350
+0.171,0.238,0.344
+0.170,0.234,0.337
+0.169,0.231,0.331
+0.168,0.227,0.324
+0.166,0.224,0.318
+0.165,0.220,0.312
+0.164,0.217,0.305
+0.163,0.214,0.299
+0.162,0.210,0.293
+0.160,0.207,0.287
+0.159,0.203,0.280
+0.157,0.200,0.274
+0.156,0.196,0.268
+0.155,0.193,0.262
+0.153,0.190,0.256
+0.152,0.186,0.249
+0.150,0.183,0.243
+0.149,0.180,0.237
+0.147,0.176,0.231
+0.146,0.173,0.225
+0.144,0.170,0.219
+0.142,0.166,0.213
+0.141,0.163,0.207
+0.139,0.160,0.201
+0.138,0.157,0.195
+0.136,0.154,0.190
+0.135,0.151,0.184
+0.133,0.148,0.178
+0.132,0.145,0.173
+0.130,0.142,0.167
+0.129,0.139,0.162
+0.128,0.137,0.157
+0.127,0.135,0.152
+0.127,0.133,0.148
+0.127,0.131,0.143
+0.127,0.129,0.139
+0.127,0.128,0.135
+0.127,0.128,0.132
+0.128,0.127,0.129
+0.130,0.127,0.126
+0.131,0.127,0.124
+0.133,0.128,0.122
+0.135,0.129,0.120
+0.138,0.130,0.119
+0.141,0.131,0.118
+0.144,0.133,0.117
+0.147,0.135,0.116
+0.151,0.137,0.116
+0.155,0.140,0.116
+0.159,0.142,0.116
+0.162,0.145,0.116
+0.167,0.148,0.116
+0.171,0.151,0.116
+0.175,0.154,0.117
+0.179,0.157,0.117
+0.183,0.160,0.117
+0.188,0.163,0.118
+0.192,0.166,0.118
+0.196,0.169,0.119
+0.201,0.172,0.119
+0.205,0.175,0.120
+0.209,0.178,0.120
+0.214,0.181,0.121
+0.218,0.184,0.121
+0.222,0.187,0.121
+0.227,0.191,0.122
+0.231,0.194,0.122
+0.236,0.197,0.123
+0.240,0.200,0.123
+0.244,0.203,0.123
+0.249,0.207,0.124
+0.253,0.210,0.124
+0.257,0.213,0.125
+0.262,0.216,0.125
+0.266,0.219,0.125
+0.271,0.223,0.126
+0.275,0.226,0.126
+0.280,0.229,0.126
+0.284,0.232,0.126
+0.288,0.236,0.127
+0.293,0.239,0.127
+0.297,0.242,0.127
+0.302,0.245,0.128
+0.306,0.249,0.128
+0.311,0.252,0.128
+0.315,0.255,0.128
+0.320,0.259,0.129
+0.324,0.262,0.129
+0.329,0.265,0.129
+0.333,0.269,0.129
+0.338,0.272,0.129
+0.342,0.275,0.129
+0.347,0.279,0.130
+0.352,0.282,0.130
+0.356,0.286,0.130
+0.361,0.289,0.130
+0.365,0.292,0.130
+0.370,0.296,0.130
+0.374,0.299,0.130
+0.379,0.303,0.131
+0.384,0.306,0.131
+0.388,0.309,0.131
+0.393,0.313,0.131
+0.397,0.316,0.131
+0.402,0.320,0.131
+0.407,0.323,0.131
+0.411,0.327,0.131
+0.416,0.330,0.131
+0.421,0.334,0.131
+0.425,0.337,0.131
+0.430,0.341,0.131
+0.435,0.344,0.131
+0.439,0.348,0.131
+0.444,0.351,0.131
+0.449,0.355,0.130
+0.453,0.358,0.130
+0.458,0.362,0.130
+0.463,0.365,0.130
+0.468,0.369,0.130
+0.472,0.372,0.130
+0.477,0.376,0.130
+0.482,0.379,0.129
+0.487,0.383,0.129
+0.491,0.386,0.129
+0.496,0.390,0.129
+0.501,0.394,0.129
+0.506,0.397,0.128
+0.510,0.401,0.128
+0.515,0.404,0.128
+0.520,0.408,0.127
+0.525,0.412,0.127
+0.530,0.415,0.127
+0.534,0.419,0.126
+0.539,0.422,0.126
+0.544,0.426,0.126
+0.549,0.430,0.125
+0.554,0.433,0.125
+0.559,0.437,0.124
+0.564,0.441,0.124
+0.568,0.444,0.123
+0.573,0.448,0.123
+0.578,0.452,0.122
+0.583,0.455,0.122
+0.588,0.459,0.121
+0.593,0.463,0.121
+0.598,0.466,0.120
+0.603,0.470,0.120
+0.608,0.474,0.119
+0.613,0.477,0.118
+0.618,0.481,0.118
+0.622,0.485,0.117
+0.627,0.489,0.116
+0.632,0.492,0.115
+0.637,0.496,0.115
+0.642,0.500,0.114
+0.647,0.503,0.113
+0.652,0.507,0.112
+0.657,0.511,0.111
+0.662,0.515,0.110
+0.667,0.518,0.109
+0.672,0.522,0.108
+0.677,0.526,0.107
+0.682,0.530,0.106
+0.687,0.534,0.105
+0.692,0.537,0.104
+0.697,0.541,0.103
+0.702,0.545,0.102
diff --git a/pyqtgraph/colors/maps/CET-D7.csv b/pyqtgraph/colors/maps/CET-D7.csv
new file mode 100644
index 00000000..76b62bee
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-D7.csv
@@ -0,0 +1,256 @@
+0.078,0.193,0.758
+0.095,0.196,0.757
+0.110,0.199,0.756
+0.123,0.202,0.754
+0.135,0.205,0.753
+0.146,0.208,0.751
+0.156,0.210,0.750
+0.166,0.213,0.749
+0.175,0.216,0.747
+0.183,0.219,0.746
+0.191,0.222,0.745
+0.199,0.225,0.743
+0.206,0.228,0.742
+0.213,0.230,0.740
+0.220,0.233,0.739
+0.227,0.236,0.738
+0.233,0.239,0.736
+0.240,0.242,0.735
+0.246,0.245,0.733
+0.251,0.248,0.732
+0.257,0.250,0.731
+0.263,0.253,0.729
+0.268,0.256,0.728
+0.273,0.259,0.727
+0.278,0.262,0.725
+0.283,0.265,0.724
+0.288,0.268,0.722
+0.293,0.271,0.721
+0.298,0.273,0.719
+0.303,0.276,0.718
+0.307,0.279,0.717
+0.312,0.282,0.715
+0.316,0.285,0.714
+0.320,0.288,0.712
+0.324,0.291,0.711
+0.329,0.294,0.710
+0.333,0.296,0.708
+0.337,0.299,0.707
+0.341,0.302,0.705
+0.345,0.305,0.704
+0.348,0.308,0.703
+0.352,0.311,0.701
+0.356,0.314,0.700
+0.360,0.317,0.698
+0.363,0.320,0.697
+0.367,0.322,0.695
+0.370,0.325,0.694
+0.374,0.328,0.692
+0.377,0.331,0.691
+0.381,0.334,0.690
+0.384,0.337,0.688
+0.387,0.340,0.687
+0.391,0.343,0.685
+0.394,0.346,0.684
+0.397,0.349,0.682
+0.400,0.351,0.681
+0.403,0.354,0.679
+0.406,0.357,0.678
+0.410,0.360,0.676
+0.413,0.363,0.675
+0.416,0.366,0.674
+0.418,0.369,0.672
+0.421,0.372,0.671
+0.424,0.375,0.669
+0.427,0.378,0.668
+0.430,0.381,0.666
+0.433,0.384,0.665
+0.436,0.387,0.663
+0.438,0.389,0.662
+0.441,0.392,0.660
+0.444,0.395,0.659
+0.447,0.398,0.657
+0.449,0.401,0.656
+0.452,0.404,0.654
+0.454,0.407,0.653
+0.457,0.410,0.651
+0.460,0.413,0.650
+0.462,0.416,0.648
+0.465,0.419,0.647
+0.467,0.422,0.645
+0.470,0.425,0.644
+0.472,0.428,0.642
+0.474,0.431,0.641
+0.477,0.434,0.639
+0.479,0.437,0.637
+0.482,0.440,0.636
+0.484,0.443,0.634
+0.486,0.445,0.633
+0.489,0.448,0.631
+0.491,0.451,0.630
+0.493,0.454,0.628
+0.495,0.457,0.627
+0.498,0.460,0.625
+0.500,0.463,0.624
+0.502,0.466,0.622
+0.504,0.469,0.620
+0.506,0.472,0.619
+0.509,0.475,0.617
+0.511,0.478,0.616
+0.513,0.481,0.614
+0.515,0.484,0.612
+0.517,0.487,0.611
+0.519,0.490,0.609
+0.521,0.493,0.608
+0.523,0.496,0.606
+0.525,0.499,0.604
+0.527,0.502,0.603
+0.529,0.505,0.601
+0.531,0.508,0.600
+0.533,0.511,0.598
+0.535,0.514,0.596
+0.537,0.517,0.595
+0.539,0.520,0.593
+0.541,0.523,0.591
+0.543,0.526,0.590
+0.544,0.529,0.588
+0.546,0.532,0.586
+0.548,0.535,0.585
+0.550,0.538,0.583
+0.552,0.541,0.581
+0.554,0.544,0.580
+0.555,0.547,0.578
+0.557,0.550,0.576
+0.559,0.553,0.575
+0.561,0.556,0.573
+0.562,0.559,0.571
+0.564,0.562,0.569
+0.566,0.565,0.568
+0.569,0.568,0.566
+0.573,0.570,0.563
+0.577,0.573,0.561
+0.581,0.575,0.559
+0.585,0.578,0.556
+0.589,0.580,0.554
+0.593,0.582,0.552
+0.597,0.585,0.549
+0.601,0.587,0.547
+0.605,0.590,0.544
+0.609,0.592,0.542
+0.613,0.595,0.539
+0.616,0.597,0.537
+0.620,0.599,0.535
+0.624,0.602,0.532
+0.628,0.604,0.530
+0.632,0.607,0.527
+0.635,0.609,0.525
+0.639,0.612,0.522
+0.643,0.614,0.520
+0.646,0.616,0.517
+0.650,0.619,0.515
+0.654,0.621,0.512
+0.657,0.624,0.510
+0.661,0.626,0.507
+0.665,0.629,0.505
+0.668,0.631,0.502
+0.672,0.634,0.500
+0.676,0.636,0.497
+0.679,0.639,0.495
+0.683,0.641,0.492
+0.686,0.644,0.489
+0.690,0.646,0.487
+0.693,0.649,0.484
+0.697,0.651,0.482
+0.700,0.654,0.479
+0.704,0.656,0.476
+0.707,0.659,0.474
+0.711,0.661,0.471
+0.714,0.664,0.468
+0.718,0.666,0.466
+0.721,0.669,0.463
+0.724,0.671,0.460
+0.728,0.674,0.457
+0.731,0.676,0.455
+0.735,0.679,0.452
+0.738,0.681,0.449
+0.741,0.684,0.446
+0.745,0.686,0.443
+0.748,0.689,0.441
+0.752,0.691,0.438
+0.755,0.694,0.435
+0.758,0.696,0.432
+0.761,0.699,0.429
+0.765,0.702,0.426
+0.768,0.704,0.423
+0.771,0.707,0.420
+0.775,0.709,0.417
+0.778,0.712,0.414
+0.781,0.714,0.411
+0.784,0.717,0.408
+0.788,0.719,0.405
+0.791,0.722,0.402
+0.794,0.725,0.399
+0.797,0.727,0.396
+0.801,0.730,0.393
+0.804,0.732,0.390
+0.807,0.735,0.387
+0.810,0.737,0.383
+0.814,0.740,0.380
+0.817,0.743,0.377
+0.820,0.745,0.374
+0.823,0.748,0.370
+0.826,0.750,0.367
+0.829,0.753,0.364
+0.833,0.756,0.360
+0.836,0.758,0.357
+0.839,0.761,0.353
+0.842,0.763,0.350
+0.845,0.766,0.346
+0.848,0.769,0.343
+0.851,0.771,0.339
+0.855,0.774,0.336
+0.858,0.777,0.332
+0.861,0.779,0.328
+0.864,0.782,0.324
+0.867,0.784,0.320
+0.870,0.787,0.317
+0.873,0.790,0.313
+0.876,0.792,0.309
+0.879,0.795,0.305
+0.883,0.798,0.301
+0.886,0.800,0.297
+0.889,0.803,0.292
+0.892,0.805,0.288
+0.895,0.808,0.284
+0.898,0.811,0.279
+0.901,0.813,0.275
+0.904,0.816,0.270
+0.907,0.819,0.266
+0.910,0.821,0.261
+0.913,0.824,0.256
+0.916,0.827,0.251
+0.919,0.829,0.246
+0.922,0.832,0.241
+0.925,0.835,0.236
+0.928,0.837,0.231
+0.931,0.840,0.225
+0.934,0.843,0.220
+0.937,0.845,0.214
+0.940,0.848,0.208
+0.943,0.851,0.202
+0.946,0.853,0.195
+0.949,0.856,0.189
+0.952,0.859,0.182
+0.955,0.861,0.175
+0.958,0.864,0.168
+0.961,0.867,0.160
+0.964,0.870,0.152
+0.967,0.872,0.143
+0.970,0.875,0.134
+0.973,0.878,0.124
+0.976,0.880,0.114
+0.979,0.883,0.102
+0.982,0.886,0.090
+0.985,0.888,0.075
+0.988,0.891,0.058
+0.991,0.894,0.036
diff --git a/pyqtgraph/colors/maps/CET-D8.csv b/pyqtgraph/colors/maps/CET-D8.csv
new file mode 100644
index 00000000..b1b02402
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-D8.csv
@@ -0,0 +1,256 @@
+0.000,0.165,0.844
+0.000,0.167,0.840
+0.000,0.169,0.837
+0.000,0.171,0.833
+0.000,0.173,0.829
+0.000,0.175,0.826
+0.000,0.177,0.822
+0.000,0.179,0.819
+0.026,0.181,0.815
+0.053,0.183,0.811
+0.073,0.185,0.808
+0.090,0.187,0.804
+0.104,0.189,0.801
+0.116,0.191,0.797
+0.128,0.193,0.794
+0.138,0.195,0.790
+0.147,0.197,0.786
+0.156,0.199,0.783
+0.164,0.201,0.779
+0.172,0.203,0.776
+0.179,0.205,0.772
+0.186,0.207,0.768
+0.192,0.208,0.765
+0.199,0.210,0.761
+0.205,0.212,0.758
+0.210,0.214,0.754
+0.216,0.216,0.751
+0.221,0.218,0.747
+0.226,0.220,0.744
+0.231,0.222,0.740
+0.236,0.223,0.736
+0.240,0.225,0.733
+0.245,0.227,0.729
+0.249,0.229,0.726
+0.253,0.231,0.722
+0.257,0.233,0.719
+0.261,0.235,0.715
+0.265,0.236,0.712
+0.269,0.238,0.708
+0.272,0.240,0.705
+0.276,0.242,0.701
+0.279,0.244,0.697
+0.283,0.246,0.694
+0.286,0.247,0.690
+0.289,0.249,0.687
+0.292,0.251,0.683
+0.295,0.253,0.680
+0.298,0.255,0.676
+0.301,0.256,0.673
+0.304,0.258,0.669
+0.306,0.260,0.666
+0.309,0.262,0.662
+0.311,0.264,0.659
+0.314,0.265,0.655
+0.316,0.267,0.652
+0.319,0.269,0.648
+0.321,0.271,0.645
+0.323,0.273,0.641
+0.326,0.274,0.638
+0.328,0.276,0.634
+0.330,0.278,0.631
+0.332,0.280,0.627
+0.334,0.282,0.623
+0.336,0.283,0.620
+0.338,0.285,0.616
+0.340,0.287,0.613
+0.342,0.289,0.609
+0.343,0.290,0.606
+0.345,0.292,0.602
+0.347,0.294,0.599
+0.349,0.296,0.595
+0.350,0.297,0.592
+0.352,0.299,0.588
+0.353,0.301,0.585
+0.355,0.303,0.581
+0.356,0.304,0.578
+0.358,0.306,0.574
+0.359,0.308,0.571
+0.361,0.310,0.567
+0.362,0.311,0.564
+0.363,0.313,0.560
+0.365,0.315,0.557
+0.366,0.316,0.553
+0.367,0.318,0.550
+0.368,0.320,0.546
+0.369,0.322,0.543
+0.371,0.323,0.539
+0.372,0.325,0.536
+0.373,0.327,0.532
+0.374,0.329,0.529
+0.375,0.330,0.525
+0.376,0.332,0.522
+0.377,0.334,0.518
+0.378,0.335,0.515
+0.378,0.337,0.511
+0.379,0.339,0.508
+0.380,0.340,0.505
+0.381,0.342,0.501
+0.382,0.344,0.498
+0.382,0.346,0.494
+0.383,0.347,0.490
+0.384,0.349,0.487
+0.384,0.351,0.483
+0.385,0.352,0.480
+0.386,0.354,0.476
+0.386,0.356,0.473
+0.387,0.357,0.469
+0.387,0.359,0.466
+0.388,0.361,0.462
+0.388,0.362,0.459
+0.389,0.364,0.455
+0.389,0.366,0.452
+0.390,0.368,0.448
+0.390,0.369,0.445
+0.390,0.371,0.441
+0.391,0.373,0.438
+0.391,0.374,0.434
+0.391,0.376,0.431
+0.392,0.378,0.427
+0.392,0.379,0.424
+0.392,0.381,0.420
+0.392,0.383,0.417
+0.393,0.384,0.413
+0.393,0.386,0.409
+0.393,0.388,0.406
+0.393,0.389,0.402
+0.393,0.391,0.399
+0.393,0.393,0.395
+0.397,0.393,0.392
+0.403,0.393,0.390
+0.410,0.392,0.387
+0.417,0.392,0.385
+0.423,0.391,0.382
+0.429,0.391,0.380
+0.436,0.390,0.377
+0.442,0.390,0.375
+0.448,0.389,0.373
+0.454,0.388,0.370
+0.460,0.388,0.368
+0.466,0.387,0.365
+0.472,0.387,0.363
+0.478,0.386,0.360
+0.484,0.385,0.358
+0.490,0.385,0.355
+0.496,0.384,0.353
+0.501,0.383,0.350
+0.507,0.383,0.348
+0.513,0.382,0.346
+0.518,0.381,0.343
+0.524,0.380,0.341
+0.529,0.380,0.338
+0.535,0.379,0.336
+0.540,0.378,0.333
+0.545,0.377,0.331
+0.551,0.376,0.328
+0.556,0.376,0.326
+0.561,0.375,0.323
+0.567,0.374,0.321
+0.572,0.373,0.318
+0.577,0.372,0.316
+0.582,0.371,0.313
+0.587,0.370,0.311
+0.593,0.369,0.308
+0.598,0.368,0.306
+0.603,0.367,0.303
+0.608,0.366,0.301
+0.613,0.365,0.298
+0.618,0.364,0.296
+0.623,0.363,0.293
+0.628,0.362,0.291
+0.633,0.361,0.288
+0.638,0.360,0.286
+0.643,0.359,0.283
+0.648,0.358,0.281
+0.653,0.356,0.278
+0.657,0.355,0.275
+0.662,0.354,0.273
+0.667,0.353,0.270
+0.672,0.351,0.268
+0.677,0.350,0.265
+0.682,0.349,0.263
+0.686,0.347,0.260
+0.691,0.346,0.257
+0.696,0.345,0.255
+0.701,0.343,0.252
+0.705,0.342,0.250
+0.710,0.340,0.247
+0.715,0.339,0.244
+0.720,0.337,0.242
+0.724,0.336,0.239
+0.729,0.334,0.237
+0.734,0.333,0.234
+0.738,0.331,0.231
+0.743,0.330,0.229
+0.748,0.328,0.226
+0.752,0.326,0.223
+0.757,0.324,0.221
+0.761,0.323,0.218
+0.766,0.321,0.215
+0.771,0.319,0.212
+0.775,0.317,0.210
+0.780,0.315,0.207
+0.784,0.313,0.204
+0.789,0.311,0.201
+0.794,0.309,0.199
+0.798,0.307,0.196
+0.803,0.305,0.193
+0.807,0.303,0.190
+0.812,0.301,0.187
+0.816,0.299,0.184
+0.821,0.296,0.182
+0.825,0.294,0.179
+0.830,0.292,0.176
+0.834,0.290,0.173
+0.839,0.287,0.170
+0.843,0.285,0.167
+0.848,0.282,0.164
+0.852,0.280,0.161
+0.857,0.277,0.158
+0.861,0.274,0.155
+0.866,0.271,0.152
+0.870,0.269,0.149
+0.875,0.266,0.145
+0.879,0.263,0.142
+0.884,0.260,0.139
+0.888,0.257,0.136
+0.892,0.254,0.132
+0.897,0.250,0.129
+0.901,0.247,0.126
+0.906,0.244,0.122
+0.910,0.240,0.119
+0.915,0.237,0.115
+0.919,0.233,0.112
+0.923,0.229,0.108
+0.928,0.225,0.104
+0.932,0.222,0.100
+0.937,0.217,0.096
+0.941,0.213,0.092
+0.945,0.209,0.088
+0.950,0.204,0.084
+0.954,0.200,0.080
+0.959,0.195,0.075
+0.963,0.190,0.070
+0.967,0.185,0.066
+0.972,0.179,0.060
+0.976,0.174,0.055
+0.981,0.168,0.050
+0.985,0.162,0.043
+0.989,0.156,0.037
+0.994,0.149,0.030
+0.998,0.142,0.024
+1.000,0.134,0.018
+1.000,0.126,0.012
+1.000,0.117,0.005
+1.000,0.108,0.000
+1.000,0.097,0.000
diff --git a/pyqtgraph/colors/maps/CET-D9.csv b/pyqtgraph/colors/maps/CET-D9.csv
new file mode 100644
index 00000000..e9f1138a
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-D9.csv
@@ -0,0 +1,256 @@
+0.141,0.501,0.998
+0.162,0.504,0.998
+0.181,0.508,0.998
+0.198,0.511,0.998
+0.214,0.514,0.998
+0.228,0.518,0.998
+0.242,0.521,0.998
+0.255,0.524,0.998
+0.267,0.528,0.998
+0.279,0.531,0.998
+0.290,0.535,0.998
+0.301,0.538,0.998
+0.311,0.541,0.998
+0.321,0.545,0.998
+0.331,0.548,0.998
+0.340,0.552,0.998
+0.350,0.555,0.998
+0.359,0.559,0.998
+0.367,0.562,0.998
+0.376,0.565,0.998
+0.385,0.569,0.998
+0.393,0.572,0.998
+0.401,0.576,0.998
+0.409,0.579,0.998
+0.417,0.583,0.998
+0.424,0.586,0.997
+0.432,0.590,0.997
+0.439,0.593,0.997
+0.447,0.597,0.997
+0.454,0.600,0.997
+0.461,0.604,0.997
+0.468,0.608,0.997
+0.475,0.611,0.997
+0.482,0.615,0.997
+0.489,0.618,0.997
+0.495,0.622,0.997
+0.502,0.625,0.997
+0.509,0.629,0.997
+0.515,0.633,0.997
+0.521,0.636,0.997
+0.528,0.640,0.996
+0.534,0.643,0.996
+0.540,0.647,0.996
+0.547,0.651,0.996
+0.553,0.654,0.996
+0.559,0.658,0.996
+0.565,0.661,0.996
+0.571,0.665,0.996
+0.577,0.669,0.996
+0.583,0.672,0.996
+0.589,0.676,0.995
+0.594,0.680,0.995
+0.600,0.683,0.995
+0.606,0.687,0.995
+0.612,0.691,0.995
+0.617,0.694,0.995
+0.623,0.698,0.995
+0.629,0.702,0.995
+0.634,0.705,0.994
+0.640,0.709,0.994
+0.645,0.713,0.994
+0.651,0.717,0.994
+0.656,0.720,0.994
+0.661,0.724,0.994
+0.667,0.728,0.994
+0.672,0.731,0.993
+0.678,0.735,0.993
+0.683,0.739,0.993
+0.688,0.743,0.993
+0.693,0.746,0.993
+0.699,0.750,0.993
+0.704,0.754,0.992
+0.709,0.758,0.992
+0.714,0.762,0.992
+0.719,0.765,0.992
+0.724,0.769,0.992
+0.730,0.773,0.992
+0.735,0.777,0.991
+0.740,0.780,0.991
+0.745,0.784,0.991
+0.750,0.788,0.991
+0.755,0.792,0.991
+0.760,0.796,0.990
+0.765,0.800,0.990
+0.770,0.803,0.990
+0.775,0.807,0.990
+0.780,0.811,0.989
+0.784,0.815,0.989
+0.789,0.819,0.989
+0.794,0.823,0.989
+0.799,0.826,0.989
+0.804,0.830,0.988
+0.809,0.834,0.988
+0.814,0.838,0.988
+0.818,0.842,0.988
+0.823,0.846,0.987
+0.828,0.850,0.987
+0.833,0.853,0.987
+0.837,0.857,0.987
+0.842,0.861,0.986
+0.847,0.865,0.986
+0.852,0.869,0.986
+0.856,0.873,0.986
+0.861,0.877,0.985
+0.866,0.881,0.985
+0.870,0.885,0.985
+0.875,0.889,0.985
+0.880,0.893,0.984
+0.884,0.896,0.984
+0.889,0.900,0.984
+0.894,0.904,0.983
+0.898,0.908,0.983
+0.903,0.912,0.983
+0.908,0.916,0.982
+0.912,0.920,0.982
+0.917,0.924,0.982
+0.921,0.928,0.982
+0.926,0.932,0.981
+0.930,0.936,0.981
+0.935,0.940,0.981
+0.939,0.944,0.980
+0.944,0.948,0.980
+0.949,0.952,0.980
+0.953,0.956,0.979
+0.958,0.960,0.978
+0.962,0.963,0.977
+0.967,0.966,0.975
+0.972,0.967,0.972
+0.975,0.966,0.967
+0.978,0.964,0.962
+0.980,0.960,0.956
+0.981,0.955,0.949
+0.982,0.951,0.943
+0.983,0.946,0.936
+0.984,0.941,0.930
+0.985,0.936,0.924
+0.986,0.931,0.917
+0.986,0.926,0.911
+0.987,0.921,0.905
+0.988,0.916,0.898
+0.988,0.911,0.892
+0.989,0.906,0.886
+0.990,0.901,0.879
+0.990,0.896,0.873
+0.991,0.891,0.867
+0.991,0.886,0.860
+0.992,0.881,0.854
+0.992,0.876,0.848
+0.992,0.871,0.841
+0.993,0.866,0.835
+0.993,0.861,0.829
+0.993,0.857,0.823
+0.994,0.852,0.816
+0.994,0.847,0.810
+0.994,0.842,0.804
+0.994,0.837,0.798
+0.995,0.832,0.791
+0.995,0.827,0.785
+0.995,0.822,0.779
+0.995,0.817,0.773
+0.995,0.812,0.767
+0.995,0.807,0.760
+0.995,0.802,0.754
+0.995,0.797,0.748
+0.995,0.792,0.742
+0.995,0.787,0.736
+0.995,0.782,0.730
+0.995,0.777,0.724
+0.995,0.772,0.717
+0.995,0.767,0.711
+0.994,0.762,0.705
+0.994,0.757,0.699
+0.994,0.753,0.693
+0.994,0.748,0.687
+0.994,0.743,0.681
+0.993,0.738,0.675
+0.993,0.733,0.669
+0.993,0.728,0.663
+0.992,0.723,0.657
+0.992,0.718,0.651
+0.991,0.713,0.645
+0.991,0.708,0.639
+0.990,0.703,0.633
+0.990,0.698,0.627
+0.989,0.693,0.621
+0.989,0.688,0.615
+0.988,0.683,0.609
+0.988,0.678,0.603
+0.987,0.673,0.597
+0.987,0.668,0.591
+0.986,0.663,0.585
+0.985,0.658,0.579
+0.985,0.653,0.573
+0.984,0.648,0.567
+0.983,0.643,0.561
+0.982,0.638,0.555
+0.982,0.633,0.549
+0.981,0.628,0.543
+0.980,0.623,0.537
+0.979,0.618,0.532
+0.978,0.613,0.526
+0.978,0.608,0.520
+0.977,0.603,0.514
+0.976,0.598,0.508
+0.975,0.592,0.502
+0.974,0.587,0.496
+0.973,0.582,0.491
+0.972,0.577,0.485
+0.971,0.572,0.479
+0.970,0.567,0.473
+0.969,0.562,0.468
+0.968,0.557,0.462
+0.967,0.552,0.456
+0.966,0.547,0.450
+0.964,0.541,0.444
+0.963,0.536,0.439
+0.962,0.531,0.433
+0.961,0.526,0.427
+0.960,0.521,0.422
+0.958,0.516,0.416
+0.957,0.510,0.410
+0.956,0.505,0.404
+0.955,0.500,0.399
+0.953,0.495,0.393
+0.952,0.489,0.387
+0.951,0.484,0.382
+0.949,0.479,0.376
+0.948,0.474,0.370
+0.947,0.468,0.365
+0.945,0.463,0.359
+0.944,0.458,0.354
+0.942,0.452,0.348
+0.941,0.447,0.342
+0.940,0.441,0.337
+0.938,0.436,0.331
+0.937,0.431,0.325
+0.935,0.425,0.320
+0.933,0.420,0.314
+0.932,0.414,0.309
+0.930,0.409,0.303
+0.929,0.403,0.298
+0.927,0.397,0.292
+0.926,0.392,0.286
+0.924,0.386,0.281
+0.922,0.380,0.275
+0.921,0.375,0.270
+0.919,0.369,0.264
+0.917,0.363,0.259
+0.915,0.357,0.253
+0.914,0.351,0.248
+0.912,0.345,0.242
+0.910,0.339,0.237
+0.908,0.333,0.231
+0.907,0.327,0.226
+0.905,0.321,0.220
+0.903,0.315,0.214
diff --git a/pyqtgraph/colors/maps/CET-I1.csv b/pyqtgraph/colors/maps/CET-I1.csv
new file mode 100644
index 00000000..ee06085c
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-I1.csv
@@ -0,0 +1,256 @@
+0.216,0.718,0.926
+0.218,0.718,0.923
+0.220,0.718,0.919
+0.223,0.719,0.916
+0.225,0.719,0.912
+0.227,0.719,0.909
+0.230,0.720,0.906
+0.232,0.720,0.902
+0.234,0.720,0.899
+0.236,0.721,0.895
+0.238,0.721,0.892
+0.240,0.721,0.888
+0.242,0.721,0.885
+0.245,0.722,0.882
+0.247,0.722,0.878
+0.249,0.722,0.875
+0.251,0.723,0.871
+0.253,0.723,0.868
+0.255,0.723,0.864
+0.257,0.723,0.861
+0.259,0.724,0.857
+0.261,0.724,0.854
+0.263,0.724,0.850
+0.265,0.724,0.847
+0.267,0.725,0.843
+0.269,0.725,0.840
+0.271,0.725,0.836
+0.273,0.725,0.833
+0.274,0.726,0.829
+0.276,0.726,0.826
+0.278,0.726,0.822
+0.280,0.726,0.819
+0.282,0.727,0.815
+0.284,0.727,0.812
+0.286,0.727,0.808
+0.288,0.727,0.805
+0.290,0.728,0.801
+0.291,0.728,0.798
+0.293,0.728,0.794
+0.295,0.728,0.791
+0.297,0.729,0.787
+0.299,0.729,0.784
+0.301,0.729,0.780
+0.303,0.729,0.776
+0.304,0.729,0.773
+0.306,0.730,0.769
+0.308,0.730,0.766
+0.310,0.730,0.762
+0.312,0.730,0.759
+0.314,0.730,0.755
+0.316,0.731,0.751
+0.318,0.731,0.748
+0.319,0.731,0.744
+0.321,0.731,0.740
+0.323,0.731,0.737
+0.325,0.731,0.733
+0.327,0.732,0.730
+0.329,0.732,0.726
+0.331,0.732,0.722
+0.333,0.732,0.719
+0.335,0.732,0.715
+0.337,0.732,0.711
+0.339,0.732,0.708
+0.341,0.733,0.704
+0.343,0.733,0.700
+0.345,0.733,0.696
+0.347,0.733,0.693
+0.349,0.733,0.689
+0.351,0.733,0.685
+0.353,0.733,0.682
+0.355,0.733,0.678
+0.357,0.733,0.674
+0.359,0.734,0.670
+0.361,0.734,0.667
+0.363,0.734,0.663
+0.366,0.734,0.659
+0.368,0.734,0.655
+0.370,0.734,0.652
+0.372,0.734,0.648
+0.375,0.734,0.644
+0.377,0.734,0.640
+0.379,0.734,0.636
+0.381,0.734,0.633
+0.384,0.734,0.629
+0.386,0.734,0.625
+0.389,0.734,0.621
+0.391,0.734,0.617
+0.394,0.734,0.613
+0.396,0.734,0.610
+0.399,0.734,0.606
+0.401,0.734,0.602
+0.404,0.734,0.598
+0.406,0.734,0.594
+0.409,0.734,0.590
+0.412,0.734,0.586
+0.415,0.733,0.582
+0.417,0.733,0.579
+0.420,0.733,0.575
+0.423,0.733,0.571
+0.426,0.733,0.567
+0.429,0.733,0.563
+0.432,0.733,0.559
+0.435,0.732,0.555
+0.438,0.732,0.552
+0.441,0.732,0.548
+0.444,0.732,0.544
+0.448,0.731,0.540
+0.451,0.731,0.536
+0.454,0.731,0.532
+0.458,0.731,0.529
+0.461,0.730,0.525
+0.465,0.730,0.521
+0.468,0.730,0.517
+0.472,0.729,0.513
+0.475,0.729,0.510
+0.479,0.729,0.506
+0.483,0.728,0.502
+0.486,0.728,0.499
+0.490,0.727,0.495
+0.494,0.727,0.492
+0.498,0.726,0.488
+0.502,0.726,0.485
+0.506,0.725,0.481
+0.510,0.725,0.478
+0.514,0.724,0.474
+0.518,0.724,0.471
+0.522,0.723,0.468
+0.526,0.722,0.465
+0.530,0.722,0.462
+0.534,0.721,0.459
+0.538,0.720,0.456
+0.542,0.720,0.453
+0.547,0.719,0.450
+0.551,0.718,0.447
+0.555,0.717,0.444
+0.559,0.717,0.441
+0.563,0.716,0.439
+0.568,0.715,0.436
+0.572,0.714,0.434
+0.576,0.713,0.431
+0.580,0.713,0.429
+0.585,0.712,0.427
+0.589,0.711,0.424
+0.593,0.710,0.422
+0.597,0.709,0.420
+0.601,0.708,0.418
+0.606,0.707,0.416
+0.610,0.706,0.414
+0.614,0.706,0.412
+0.618,0.705,0.410
+0.622,0.704,0.408
+0.626,0.703,0.406
+0.630,0.702,0.404
+0.634,0.701,0.402
+0.638,0.700,0.401
+0.642,0.699,0.399
+0.646,0.698,0.397
+0.650,0.697,0.395
+0.654,0.696,0.394
+0.658,0.695,0.392
+0.662,0.694,0.391
+0.666,0.693,0.389
+0.670,0.692,0.388
+0.674,0.691,0.386
+0.678,0.690,0.385
+0.681,0.689,0.384
+0.685,0.688,0.383
+0.689,0.687,0.381
+0.693,0.685,0.380
+0.697,0.684,0.379
+0.700,0.683,0.378
+0.704,0.682,0.377
+0.708,0.681,0.376
+0.712,0.680,0.375
+0.715,0.679,0.374
+0.719,0.678,0.373
+0.723,0.676,0.373
+0.726,0.675,0.372
+0.730,0.674,0.371
+0.734,0.673,0.371
+0.737,0.672,0.370
+0.741,0.671,0.370
+0.745,0.669,0.369
+0.748,0.668,0.369
+0.752,0.667,0.368
+0.755,0.666,0.368
+0.759,0.664,0.367
+0.762,0.663,0.367
+0.766,0.662,0.367
+0.769,0.661,0.367
+0.773,0.660,0.367
+0.776,0.658,0.367
+0.780,0.657,0.366
+0.783,0.656,0.366
+0.787,0.654,0.366
+0.790,0.653,0.367
+0.793,0.652,0.367
+0.797,0.651,0.367
+0.800,0.649,0.367
+0.803,0.648,0.367
+0.807,0.647,0.367
+0.810,0.645,0.368
+0.813,0.644,0.368
+0.816,0.643,0.369
+0.820,0.641,0.369
+0.823,0.640,0.369
+0.826,0.639,0.370
+0.829,0.637,0.370
+0.833,0.636,0.371
+0.836,0.634,0.372
+0.839,0.633,0.372
+0.842,0.632,0.373
+0.845,0.630,0.374
+0.848,0.629,0.374
+0.851,0.628,0.375
+0.854,0.626,0.376
+0.857,0.625,0.377
+0.861,0.623,0.377
+0.864,0.622,0.378
+0.867,0.620,0.379
+0.870,0.619,0.380
+0.873,0.618,0.381
+0.876,0.616,0.382
+0.878,0.615,0.383
+0.881,0.613,0.384
+0.884,0.612,0.385
+0.887,0.610,0.386
+0.890,0.609,0.387
+0.893,0.607,0.389
+0.896,0.606,0.390
+0.899,0.604,0.391
+0.902,0.603,0.392
+0.905,0.601,0.393
+0.907,0.600,0.395
+0.910,0.598,0.396
+0.913,0.597,0.397
+0.916,0.595,0.398
+0.919,0.594,0.400
+0.921,0.592,0.401
+0.924,0.591,0.402
+0.927,0.589,0.404
+0.930,0.587,0.405
+0.932,0.586,0.407
+0.935,0.584,0.408
+0.938,0.583,0.410
+0.940,0.581,0.411
+0.943,0.580,0.413
+0.946,0.578,0.414
+0.948,0.576,0.416
+0.951,0.575,0.417
+0.954,0.573,0.419
+0.956,0.572,0.420
+0.959,0.570,0.422
+0.961,0.568,0.423
+0.964,0.567,0.425
+0.966,0.565,0.427
diff --git a/pyqtgraph/colors/maps/CET-I2.csv b/pyqtgraph/colors/maps/CET-I2.csv
new file mode 100644
index 00000000..5b58b9d1
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-I2.csv
@@ -0,0 +1,256 @@
+0.438,0.821,1.000
+0.438,0.822,1.000
+0.438,0.822,1.000
+0.439,0.823,1.000
+0.439,0.823,1.000
+0.439,0.823,0.998
+0.439,0.824,0.995
+0.440,0.824,0.992
+0.440,0.824,0.989
+0.440,0.825,0.985
+0.441,0.825,0.982
+0.441,0.825,0.979
+0.441,0.826,0.976
+0.442,0.826,0.973
+0.442,0.826,0.970
+0.442,0.827,0.967
+0.443,0.827,0.964
+0.443,0.827,0.960
+0.443,0.828,0.957
+0.444,0.828,0.954
+0.444,0.828,0.951
+0.445,0.829,0.948
+0.445,0.829,0.945
+0.445,0.829,0.942
+0.446,0.830,0.938
+0.446,0.830,0.935
+0.447,0.830,0.932
+0.447,0.831,0.929
+0.448,0.831,0.926
+0.448,0.831,0.922
+0.449,0.832,0.919
+0.449,0.832,0.916
+0.450,0.832,0.913
+0.450,0.833,0.910
+0.451,0.833,0.906
+0.451,0.833,0.903
+0.452,0.833,0.900
+0.452,0.834,0.897
+0.453,0.834,0.893
+0.454,0.834,0.890
+0.454,0.834,0.887
+0.455,0.835,0.884
+0.455,0.835,0.880
+0.456,0.835,0.877
+0.457,0.836,0.874
+0.457,0.836,0.871
+0.458,0.836,0.867
+0.459,0.836,0.864
+0.460,0.837,0.861
+0.460,0.837,0.857
+0.461,0.837,0.854
+0.462,0.837,0.851
+0.463,0.838,0.847
+0.463,0.838,0.844
+0.464,0.838,0.841
+0.465,0.838,0.838
+0.466,0.838,0.834
+0.467,0.839,0.831
+0.468,0.839,0.827
+0.469,0.839,0.824
+0.470,0.839,0.821
+0.470,0.839,0.817
+0.471,0.840,0.814
+0.472,0.840,0.811
+0.473,0.840,0.807
+0.474,0.840,0.804
+0.476,0.840,0.800
+0.477,0.841,0.797
+0.478,0.841,0.793
+0.479,0.841,0.790
+0.480,0.841,0.787
+0.481,0.841,0.783
+0.482,0.841,0.780
+0.484,0.841,0.776
+0.485,0.842,0.773
+0.486,0.842,0.769
+0.488,0.842,0.766
+0.489,0.842,0.762
+0.490,0.842,0.759
+0.492,0.842,0.755
+0.493,0.842,0.752
+0.495,0.842,0.748
+0.496,0.842,0.745
+0.498,0.842,0.741
+0.499,0.842,0.738
+0.501,0.843,0.734
+0.502,0.843,0.730
+0.504,0.843,0.727
+0.506,0.843,0.723
+0.508,0.843,0.720
+0.509,0.843,0.716
+0.511,0.843,0.713
+0.513,0.843,0.709
+0.515,0.843,0.705
+0.517,0.843,0.702
+0.519,0.843,0.698
+0.521,0.843,0.694
+0.523,0.843,0.691
+0.525,0.843,0.687
+0.527,0.842,0.684
+0.530,0.842,0.680
+0.532,0.842,0.676
+0.534,0.842,0.673
+0.537,0.842,0.669
+0.539,0.842,0.665
+0.541,0.842,0.662
+0.544,0.842,0.658
+0.547,0.841,0.655
+0.549,0.841,0.651
+0.552,0.841,0.647
+0.555,0.841,0.644
+0.557,0.841,0.640
+0.560,0.840,0.636
+0.563,0.840,0.633
+0.566,0.840,0.629
+0.569,0.840,0.626
+0.572,0.839,0.622
+0.575,0.839,0.619
+0.578,0.839,0.615
+0.582,0.838,0.612
+0.585,0.838,0.608
+0.588,0.837,0.605
+0.592,0.837,0.601
+0.595,0.837,0.598
+0.598,0.836,0.595
+0.602,0.836,0.591
+0.606,0.835,0.588
+0.609,0.835,0.585
+0.613,0.834,0.582
+0.616,0.834,0.579
+0.620,0.833,0.575
+0.624,0.832,0.572
+0.628,0.832,0.569
+0.631,0.831,0.566
+0.635,0.831,0.564
+0.639,0.830,0.561
+0.643,0.829,0.558
+0.647,0.829,0.555
+0.651,0.828,0.552
+0.655,0.827,0.550
+0.659,0.827,0.547
+0.663,0.826,0.545
+0.667,0.825,0.542
+0.671,0.824,0.540
+0.674,0.824,0.537
+0.678,0.823,0.535
+0.682,0.822,0.533
+0.686,0.821,0.531
+0.690,0.820,0.529
+0.694,0.820,0.526
+0.698,0.819,0.524
+0.702,0.818,0.522
+0.706,0.817,0.520
+0.710,0.816,0.518
+0.714,0.815,0.516
+0.718,0.815,0.514
+0.722,0.814,0.513
+0.726,0.813,0.511
+0.729,0.812,0.509
+0.733,0.811,0.507
+0.737,0.810,0.505
+0.741,0.809,0.503
+0.745,0.808,0.502
+0.748,0.807,0.500
+0.752,0.806,0.498
+0.756,0.805,0.497
+0.760,0.805,0.495
+0.763,0.804,0.493
+0.767,0.803,0.492
+0.771,0.802,0.490
+0.774,0.801,0.489
+0.778,0.800,0.487
+0.782,0.799,0.486
+0.785,0.798,0.485
+0.789,0.797,0.483
+0.793,0.796,0.482
+0.796,0.795,0.481
+0.800,0.794,0.479
+0.804,0.793,0.478
+0.807,0.792,0.477
+0.811,0.791,0.476
+0.814,0.790,0.475
+0.818,0.789,0.474
+0.821,0.788,0.473
+0.825,0.786,0.472
+0.829,0.785,0.471
+0.832,0.784,0.470
+0.836,0.783,0.469
+0.839,0.782,0.468
+0.843,0.781,0.468
+0.846,0.780,0.467
+0.849,0.779,0.466
+0.853,0.778,0.466
+0.856,0.777,0.465
+0.860,0.775,0.465
+0.863,0.774,0.464
+0.866,0.773,0.464
+0.870,0.772,0.463
+0.873,0.771,0.463
+0.877,0.770,0.462
+0.880,0.769,0.462
+0.883,0.767,0.462
+0.887,0.766,0.462
+0.890,0.765,0.462
+0.893,0.764,0.461
+0.896,0.763,0.461
+0.900,0.761,0.461
+0.903,0.760,0.461
+0.906,0.759,0.462
+0.909,0.758,0.462
+0.912,0.757,0.462
+0.916,0.755,0.462
+0.919,0.754,0.462
+0.922,0.753,0.463
+0.925,0.752,0.463
+0.928,0.750,0.463
+0.931,0.749,0.464
+0.934,0.748,0.464
+0.937,0.747,0.465
+0.940,0.745,0.465
+0.943,0.744,0.466
+0.946,0.743,0.466
+0.949,0.742,0.467
+0.952,0.740,0.468
+0.955,0.739,0.468
+0.958,0.738,0.469
+0.961,0.737,0.470
+0.964,0.735,0.471
+0.967,0.734,0.472
+0.970,0.733,0.473
+0.973,0.732,0.474
+0.975,0.730,0.475
+0.978,0.729,0.476
+0.981,0.728,0.477
+0.984,0.726,0.478
+0.986,0.725,0.479
+0.989,0.724,0.480
+0.992,0.723,0.481
+0.995,0.721,0.483
+0.997,0.720,0.484
+1.000,0.719,0.485
+1.000,0.717,0.486
+1.000,0.716,0.488
+1.000,0.715,0.489
+1.000,0.713,0.490
+1.000,0.712,0.492
+1.000,0.711,0.493
+1.000,0.710,0.495
+1.000,0.708,0.496
+1.000,0.707,0.498
+1.000,0.706,0.499
+1.000,0.704,0.501
+1.000,0.703,0.503
+1.000,0.702,0.504
+1.000,0.700,0.506
+1.000,0.699,0.508
diff --git a/pyqtgraph/colors/maps/CET-I3.csv b/pyqtgraph/colors/maps/CET-I3.csv
new file mode 100644
index 00000000..1787192d
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-I3.csv
@@ -0,0 +1,256 @@
+0.078,0.727,0.901
+0.097,0.727,0.901
+0.112,0.726,0.902
+0.126,0.726,0.902
+0.139,0.725,0.903
+0.150,0.725,0.903
+0.161,0.724,0.904
+0.171,0.723,0.904
+0.181,0.723,0.905
+0.190,0.722,0.905
+0.198,0.722,0.906
+0.207,0.721,0.906
+0.215,0.720,0.907
+0.222,0.720,0.907
+0.230,0.719,0.908
+0.237,0.719,0.908
+0.244,0.718,0.909
+0.251,0.717,0.909
+0.257,0.717,0.910
+0.264,0.716,0.910
+0.270,0.716,0.911
+0.276,0.715,0.911
+0.282,0.714,0.912
+0.288,0.714,0.912
+0.294,0.713,0.913
+0.300,0.712,0.913
+0.305,0.712,0.914
+0.311,0.711,0.914
+0.316,0.711,0.914
+0.322,0.710,0.915
+0.327,0.709,0.915
+0.332,0.709,0.916
+0.337,0.708,0.916
+0.342,0.707,0.916
+0.347,0.707,0.917
+0.352,0.706,0.917
+0.357,0.705,0.918
+0.362,0.705,0.918
+0.366,0.704,0.918
+0.371,0.703,0.919
+0.376,0.703,0.919
+0.380,0.702,0.919
+0.385,0.701,0.920
+0.389,0.701,0.920
+0.394,0.700,0.920
+0.398,0.699,0.921
+0.403,0.699,0.921
+0.407,0.698,0.921
+0.411,0.697,0.922
+0.416,0.697,0.922
+0.420,0.696,0.922
+0.424,0.695,0.922
+0.428,0.694,0.923
+0.432,0.694,0.923
+0.436,0.693,0.923
+0.441,0.692,0.923
+0.445,0.692,0.924
+0.449,0.691,0.924
+0.453,0.690,0.924
+0.457,0.689,0.924
+0.461,0.689,0.924
+0.465,0.688,0.925
+0.468,0.687,0.925
+0.472,0.686,0.925
+0.476,0.686,0.925
+0.480,0.685,0.925
+0.484,0.684,0.925
+0.488,0.683,0.925
+0.492,0.683,0.926
+0.495,0.682,0.926
+0.499,0.681,0.926
+0.503,0.680,0.926
+0.507,0.680,0.926
+0.510,0.679,0.926
+0.514,0.678,0.926
+0.518,0.677,0.926
+0.521,0.677,0.926
+0.525,0.676,0.926
+0.529,0.675,0.926
+0.532,0.674,0.926
+0.536,0.673,0.926
+0.540,0.673,0.926
+0.543,0.672,0.926
+0.547,0.671,0.926
+0.550,0.670,0.925
+0.554,0.669,0.925
+0.558,0.669,0.925
+0.561,0.668,0.925
+0.565,0.667,0.925
+0.568,0.666,0.925
+0.572,0.665,0.924
+0.575,0.664,0.924
+0.579,0.664,0.924
+0.582,0.663,0.924
+0.586,0.662,0.923
+0.589,0.661,0.923
+0.593,0.660,0.923
+0.596,0.659,0.922
+0.600,0.659,0.922
+0.603,0.658,0.921
+0.607,0.657,0.921
+0.610,0.656,0.921
+0.614,0.655,0.920
+0.617,0.654,0.920
+0.621,0.653,0.919
+0.624,0.653,0.919
+0.627,0.652,0.918
+0.631,0.651,0.917
+0.634,0.650,0.917
+0.638,0.649,0.916
+0.641,0.648,0.915
+0.644,0.647,0.915
+0.648,0.646,0.914
+0.651,0.645,0.913
+0.655,0.645,0.912
+0.658,0.644,0.911
+0.661,0.643,0.910
+0.665,0.642,0.910
+0.668,0.641,0.909
+0.671,0.640,0.908
+0.675,0.639,0.907
+0.678,0.638,0.905
+0.681,0.638,0.904
+0.684,0.637,0.903
+0.688,0.636,0.902
+0.691,0.635,0.901
+0.694,0.634,0.900
+0.697,0.633,0.898
+0.700,0.632,0.897
+0.704,0.631,0.896
+0.707,0.631,0.894
+0.710,0.630,0.893
+0.713,0.629,0.892
+0.716,0.628,0.890
+0.719,0.627,0.889
+0.722,0.626,0.887
+0.725,0.625,0.886
+0.728,0.625,0.885
+0.731,0.624,0.883
+0.734,0.623,0.882
+0.737,0.622,0.880
+0.740,0.621,0.879
+0.743,0.620,0.877
+0.746,0.619,0.876
+0.749,0.619,0.874
+0.752,0.618,0.873
+0.754,0.617,0.871
+0.757,0.616,0.870
+0.760,0.615,0.868
+0.763,0.614,0.867
+0.766,0.613,0.865
+0.768,0.613,0.863
+0.771,0.612,0.862
+0.774,0.611,0.860
+0.777,0.610,0.859
+0.779,0.609,0.857
+0.782,0.608,0.855
+0.785,0.608,0.854
+0.787,0.607,0.852
+0.790,0.606,0.850
+0.793,0.605,0.849
+0.795,0.604,0.847
+0.798,0.603,0.846
+0.800,0.602,0.844
+0.803,0.602,0.842
+0.806,0.601,0.841
+0.808,0.600,0.839
+0.811,0.599,0.837
+0.813,0.598,0.835
+0.816,0.597,0.834
+0.818,0.596,0.832
+0.821,0.596,0.830
+0.823,0.595,0.829
+0.826,0.594,0.827
+0.828,0.593,0.825
+0.830,0.592,0.824
+0.833,0.591,0.822
+0.835,0.590,0.820
+0.838,0.590,0.818
+0.840,0.589,0.817
+0.842,0.588,0.815
+0.845,0.587,0.813
+0.847,0.586,0.811
+0.849,0.585,0.810
+0.852,0.584,0.808
+0.854,0.584,0.806
+0.856,0.583,0.804
+0.859,0.582,0.803
+0.861,0.581,0.801
+0.863,0.580,0.799
+0.866,0.579,0.797
+0.868,0.578,0.796
+0.870,0.578,0.794
+0.872,0.577,0.792
+0.874,0.576,0.790
+0.877,0.575,0.788
+0.879,0.574,0.787
+0.881,0.573,0.785
+0.883,0.572,0.783
+0.885,0.572,0.781
+0.888,0.571,0.780
+0.890,0.570,0.778
+0.892,0.569,0.776
+0.894,0.568,0.774
+0.896,0.567,0.772
+0.898,0.566,0.770
+0.900,0.565,0.769
+0.903,0.565,0.767
+0.905,0.564,0.765
+0.907,0.563,0.763
+0.909,0.562,0.761
+0.911,0.561,0.760
+0.913,0.560,0.758
+0.915,0.559,0.756
+0.917,0.558,0.754
+0.919,0.558,0.752
+0.921,0.557,0.750
+0.923,0.556,0.749
+0.925,0.555,0.747
+0.927,0.554,0.745
+0.929,0.553,0.743
+0.931,0.552,0.741
+0.933,0.551,0.739
+0.935,0.550,0.738
+0.937,0.550,0.736
+0.939,0.549,0.734
+0.941,0.548,0.732
+0.943,0.547,0.730
+0.945,0.546,0.728
+0.947,0.545,0.727
+0.949,0.544,0.725
+0.950,0.543,0.723
+0.952,0.542,0.721
+0.954,0.541,0.719
+0.956,0.541,0.717
+0.958,0.540,0.715
+0.960,0.539,0.714
+0.962,0.538,0.712
+0.964,0.537,0.710
+0.965,0.536,0.708
+0.967,0.535,0.706
+0.969,0.534,0.704
+0.971,0.533,0.702
+0.973,0.532,0.701
+0.975,0.531,0.699
+0.976,0.531,0.697
+0.978,0.530,0.695
+0.980,0.529,0.693
+0.982,0.528,0.691
+0.984,0.527,0.689
+0.985,0.526,0.687
+0.987,0.525,0.686
+0.989,0.524,0.684
+0.991,0.523,0.682
+0.992,0.522,0.680
+0.994,0.521,0.678
diff --git a/pyqtgraph/colors/maps/CET-L1.csv b/pyqtgraph/colors/maps/CET-L1.csv
new file mode 100644
index 00000000..c7005f38
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-L1.csv
@@ -0,0 +1,256 @@
+0.000,0.000,0.000
+0.006,0.006,0.006
+0.011,0.011,0.011
+0.017,0.017,0.017
+0.022,0.022,0.022
+0.028,0.028,0.028
+0.034,0.034,0.034
+0.039,0.039,0.039
+0.045,0.045,0.045
+0.050,0.050,0.050
+0.054,0.054,0.054
+0.059,0.059,0.059
+0.063,0.063,0.063
+0.067,0.067,0.067
+0.071,0.071,0.071
+0.074,0.075,0.075
+0.078,0.078,0.078
+0.081,0.081,0.081
+0.085,0.085,0.085
+0.088,0.088,0.088
+0.091,0.091,0.091
+0.094,0.094,0.094
+0.097,0.097,0.097
+0.100,0.100,0.100
+0.103,0.103,0.103
+0.106,0.106,0.106
+0.109,0.109,0.109
+0.112,0.112,0.112
+0.115,0.115,0.115
+0.119,0.119,0.119
+0.122,0.122,0.122
+0.125,0.125,0.125
+0.128,0.128,0.128
+0.131,0.131,0.131
+0.134,0.134,0.134
+0.137,0.137,0.137
+0.141,0.141,0.141
+0.144,0.144,0.144
+0.147,0.147,0.147
+0.150,0.150,0.150
+0.153,0.153,0.153
+0.157,0.157,0.157
+0.160,0.160,0.160
+0.163,0.163,0.163
+0.166,0.166,0.166
+0.170,0.170,0.170
+0.173,0.173,0.173
+0.176,0.176,0.176
+0.179,0.179,0.179
+0.183,0.183,0.183
+0.186,0.186,0.186
+0.189,0.189,0.189
+0.193,0.193,0.193
+0.196,0.196,0.196
+0.199,0.199,0.199
+0.203,0.203,0.203
+0.206,0.206,0.206
+0.209,0.210,0.209
+0.213,0.213,0.213
+0.216,0.216,0.216
+0.220,0.220,0.220
+0.223,0.223,0.223
+0.226,0.227,0.227
+0.230,0.230,0.230
+0.233,0.233,0.233
+0.237,0.237,0.237
+0.240,0.240,0.240
+0.244,0.244,0.244
+0.247,0.247,0.247
+0.251,0.251,0.251
+0.254,0.254,0.254
+0.258,0.258,0.258
+0.261,0.261,0.261
+0.265,0.265,0.265
+0.268,0.268,0.268
+0.272,0.272,0.272
+0.275,0.275,0.275
+0.279,0.279,0.279
+0.282,0.282,0.282
+0.286,0.286,0.286
+0.289,0.289,0.289
+0.293,0.293,0.293
+0.297,0.297,0.297
+0.300,0.300,0.300
+0.304,0.304,0.304
+0.307,0.307,0.307
+0.311,0.311,0.311
+0.314,0.315,0.315
+0.318,0.318,0.318
+0.322,0.322,0.322
+0.325,0.325,0.325
+0.329,0.329,0.329
+0.333,0.333,0.333
+0.336,0.336,0.336
+0.340,0.340,0.340
+0.344,0.344,0.344
+0.347,0.347,0.347
+0.351,0.351,0.351
+0.355,0.355,0.355
+0.358,0.358,0.358
+0.362,0.362,0.362
+0.366,0.366,0.366
+0.369,0.370,0.370
+0.373,0.373,0.373
+0.377,0.377,0.377
+0.381,0.381,0.381
+0.384,0.384,0.384
+0.388,0.388,0.388
+0.392,0.392,0.392
+0.396,0.396,0.396
+0.399,0.399,0.399
+0.403,0.403,0.403
+0.407,0.407,0.407
+0.411,0.411,0.411
+0.415,0.415,0.415
+0.418,0.418,0.418
+0.422,0.422,0.422
+0.426,0.426,0.426
+0.430,0.430,0.430
+0.434,0.434,0.434
+0.437,0.437,0.437
+0.441,0.441,0.441
+0.445,0.445,0.445
+0.449,0.449,0.449
+0.453,0.453,0.453
+0.457,0.457,0.457
+0.460,0.461,0.461
+0.464,0.464,0.464
+0.468,0.468,0.468
+0.472,0.472,0.472
+0.476,0.476,0.476
+0.480,0.480,0.480
+0.484,0.484,0.484
+0.488,0.488,0.488
+0.492,0.492,0.492
+0.495,0.496,0.496
+0.499,0.499,0.499
+0.503,0.503,0.503
+0.507,0.507,0.507
+0.511,0.511,0.511
+0.515,0.515,0.515
+0.519,0.519,0.519
+0.523,0.523,0.523
+0.527,0.527,0.527
+0.531,0.531,0.531
+0.535,0.535,0.535
+0.539,0.539,0.539
+0.543,0.543,0.543
+0.547,0.547,0.547
+0.551,0.551,0.551
+0.555,0.555,0.555
+0.559,0.559,0.559
+0.563,0.563,0.563
+0.567,0.567,0.567
+0.571,0.571,0.571
+0.575,0.575,0.575
+0.579,0.579,0.579
+0.583,0.583,0.583
+0.587,0.587,0.587
+0.591,0.591,0.591
+0.595,0.595,0.595
+0.599,0.599,0.599
+0.603,0.603,0.603
+0.607,0.607,0.607
+0.611,0.611,0.611
+0.615,0.615,0.615
+0.619,0.619,0.619
+0.623,0.624,0.624
+0.628,0.628,0.628
+0.632,0.632,0.632
+0.636,0.636,0.636
+0.640,0.640,0.640
+0.644,0.644,0.644
+0.648,0.648,0.648
+0.652,0.652,0.652
+0.656,0.656,0.656
+0.660,0.660,0.660
+0.664,0.665,0.665
+0.669,0.669,0.669
+0.673,0.673,0.673
+0.677,0.677,0.677
+0.681,0.681,0.681
+0.685,0.685,0.685
+0.689,0.689,0.689
+0.694,0.694,0.694
+0.698,0.698,0.698
+0.702,0.702,0.702
+0.706,0.706,0.706
+0.710,0.710,0.710
+0.714,0.715,0.714
+0.719,0.719,0.719
+0.723,0.723,0.723
+0.727,0.727,0.727
+0.731,0.731,0.731
+0.735,0.735,0.735
+0.740,0.740,0.740
+0.744,0.744,0.744
+0.748,0.748,0.748
+0.752,0.752,0.752
+0.756,0.757,0.757
+0.761,0.761,0.761
+0.765,0.765,0.765
+0.769,0.769,0.769
+0.773,0.774,0.774
+0.778,0.778,0.778
+0.782,0.782,0.782
+0.786,0.786,0.786
+0.790,0.791,0.791
+0.795,0.795,0.795
+0.799,0.799,0.799
+0.803,0.803,0.803
+0.808,0.808,0.808
+0.812,0.812,0.812
+0.816,0.816,0.816
+0.820,0.821,0.821
+0.825,0.825,0.825
+0.829,0.829,0.829
+0.833,0.833,0.833
+0.838,0.838,0.838
+0.842,0.842,0.842
+0.846,0.846,0.846
+0.851,0.851,0.851
+0.855,0.855,0.855
+0.859,0.859,0.859
+0.864,0.864,0.864
+0.868,0.868,0.868
+0.872,0.872,0.872
+0.877,0.877,0.877
+0.881,0.881,0.881
+0.885,0.885,0.885
+0.890,0.890,0.890
+0.894,0.894,0.894
+0.898,0.899,0.898
+0.903,0.903,0.903
+0.907,0.907,0.907
+0.911,0.912,0.912
+0.916,0.916,0.916
+0.920,0.920,0.920
+0.925,0.925,0.925
+0.929,0.929,0.929
+0.933,0.934,0.934
+0.938,0.938,0.938
+0.942,0.942,0.942
+0.947,0.947,0.947
+0.951,0.951,0.951
+0.955,0.956,0.956
+0.960,0.960,0.960
+0.964,0.965,0.964
+0.969,0.969,0.969
+0.973,0.973,0.973
+0.978,0.978,0.978
+0.982,0.982,0.982
+0.987,0.987,0.987
+0.991,0.991,0.991
+0.995,0.996,0.996
+1.000,1.000,1.000
diff --git a/pyqtgraph/colors/maps/CET-L10.csv b/pyqtgraph/colors/maps/CET-L10.csv
new file mode 100644
index 00000000..a1cb45d4
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-L10.csv
@@ -0,0 +1,256 @@
+0.399,0.606,0.565
+0.402,0.607,0.563
+0.404,0.608,0.561
+0.407,0.609,0.559
+0.410,0.610,0.557
+0.413,0.611,0.555
+0.416,0.612,0.553
+0.419,0.613,0.552
+0.421,0.614,0.550
+0.424,0.615,0.548
+0.427,0.616,0.546
+0.430,0.617,0.544
+0.433,0.617,0.543
+0.436,0.618,0.541
+0.439,0.619,0.539
+0.442,0.620,0.537
+0.445,0.621,0.535
+0.448,0.622,0.534
+0.450,0.623,0.532
+0.453,0.624,0.530
+0.456,0.624,0.528
+0.459,0.625,0.527
+0.462,0.626,0.525
+0.465,0.627,0.523
+0.468,0.628,0.521
+0.471,0.629,0.520
+0.474,0.629,0.518
+0.478,0.630,0.516
+0.481,0.631,0.515
+0.484,0.632,0.513
+0.487,0.633,0.511
+0.490,0.633,0.509
+0.493,0.634,0.508
+0.496,0.635,0.506
+0.500,0.636,0.505
+0.503,0.636,0.503
+0.506,0.637,0.501
+0.509,0.638,0.500
+0.513,0.639,0.498
+0.516,0.639,0.496
+0.519,0.640,0.495
+0.523,0.641,0.493
+0.526,0.641,0.492
+0.530,0.642,0.490
+0.533,0.643,0.489
+0.537,0.643,0.487
+0.540,0.644,0.486
+0.544,0.644,0.484
+0.547,0.645,0.483
+0.551,0.645,0.481
+0.555,0.646,0.480
+0.558,0.647,0.478
+0.562,0.647,0.477
+0.566,0.648,0.475
+0.570,0.648,0.474
+0.574,0.648,0.473
+0.578,0.649,0.471
+0.582,0.649,0.470
+0.586,0.650,0.469
+0.590,0.650,0.467
+0.594,0.650,0.466
+0.598,0.651,0.465
+0.602,0.651,0.463
+0.607,0.651,0.462
+0.611,0.652,0.461
+0.616,0.652,0.460
+0.620,0.652,0.459
+0.625,0.652,0.458
+0.630,0.652,0.457
+0.634,0.652,0.456
+0.639,0.652,0.455
+0.644,0.652,0.454
+0.649,0.652,0.453
+0.654,0.652,0.452
+0.660,0.652,0.451
+0.665,0.652,0.450
+0.671,0.652,0.449
+0.676,0.652,0.449
+0.682,0.651,0.448
+0.687,0.651,0.447
+0.692,0.651,0.447
+0.697,0.651,0.446
+0.702,0.650,0.445
+0.707,0.650,0.445
+0.712,0.650,0.444
+0.717,0.650,0.443
+0.722,0.650,0.443
+0.726,0.650,0.442
+0.730,0.650,0.441
+0.735,0.650,0.440
+0.739,0.650,0.440
+0.743,0.650,0.439
+0.747,0.650,0.438
+0.751,0.650,0.438
+0.755,0.650,0.437
+0.759,0.651,0.436
+0.762,0.651,0.436
+0.766,0.651,0.435
+0.769,0.651,0.434
+0.773,0.652,0.434
+0.776,0.652,0.433
+0.779,0.652,0.432
+0.782,0.653,0.432
+0.785,0.653,0.431
+0.788,0.653,0.430
+0.791,0.654,0.430
+0.794,0.654,0.429
+0.796,0.655,0.428
+0.799,0.656,0.428
+0.801,0.656,0.427
+0.803,0.657,0.426
+0.806,0.657,0.426
+0.808,0.658,0.425
+0.810,0.659,0.424
+0.812,0.660,0.424
+0.814,0.660,0.423
+0.816,0.661,0.422
+0.818,0.662,0.422
+0.819,0.663,0.421
+0.821,0.664,0.420
+0.822,0.665,0.420
+0.824,0.666,0.419
+0.825,0.667,0.418
+0.826,0.668,0.418
+0.827,0.669,0.417
+0.829,0.670,0.416
+0.830,0.672,0.415
+0.830,0.673,0.415
+0.831,0.674,0.414
+0.832,0.675,0.414
+0.833,0.677,0.413
+0.834,0.678,0.413
+0.834,0.679,0.412
+0.835,0.680,0.412
+0.836,0.682,0.412
+0.836,0.683,0.412
+0.837,0.684,0.412
+0.838,0.685,0.412
+0.838,0.687,0.413
+0.839,0.688,0.413
+0.840,0.689,0.414
+0.840,0.690,0.414
+0.841,0.692,0.415
+0.841,0.693,0.416
+0.842,0.694,0.417
+0.842,0.695,0.418
+0.843,0.697,0.419
+0.843,0.698,0.420
+0.844,0.699,0.421
+0.844,0.700,0.423
+0.845,0.702,0.424
+0.845,0.703,0.426
+0.846,0.704,0.427
+0.846,0.706,0.429
+0.846,0.707,0.431
+0.847,0.708,0.433
+0.847,0.709,0.435
+0.847,0.711,0.437
+0.848,0.712,0.440
+0.848,0.713,0.442
+0.848,0.714,0.444
+0.848,0.716,0.447
+0.849,0.717,0.450
+0.849,0.718,0.453
+0.849,0.720,0.455
+0.849,0.721,0.458
+0.849,0.722,0.461
+0.849,0.723,0.465
+0.849,0.725,0.468
+0.850,0.726,0.471
+0.850,0.727,0.475
+0.850,0.729,0.478
+0.850,0.730,0.482
+0.850,0.731,0.486
+0.849,0.733,0.490
+0.849,0.734,0.494
+0.849,0.735,0.498
+0.849,0.737,0.502
+0.849,0.738,0.506
+0.849,0.739,0.510
+0.848,0.740,0.515
+0.848,0.742,0.519
+0.848,0.743,0.523
+0.848,0.744,0.527
+0.848,0.746,0.532
+0.848,0.747,0.536
+0.847,0.748,0.540
+0.847,0.749,0.545
+0.847,0.751,0.549
+0.847,0.752,0.553
+0.847,0.753,0.557
+0.847,0.755,0.562
+0.847,0.756,0.566
+0.846,0.757,0.570
+0.846,0.758,0.574
+0.846,0.760,0.579
+0.846,0.761,0.583
+0.846,0.762,0.587
+0.846,0.763,0.591
+0.846,0.765,0.596
+0.846,0.766,0.600
+0.845,0.767,0.604
+0.845,0.768,0.608
+0.845,0.769,0.613
+0.845,0.771,0.617
+0.845,0.772,0.621
+0.845,0.773,0.625
+0.845,0.774,0.630
+0.844,0.776,0.634
+0.844,0.777,0.638
+0.844,0.778,0.642
+0.844,0.779,0.646
+0.844,0.780,0.651
+0.844,0.782,0.655
+0.843,0.783,0.659
+0.843,0.784,0.663
+0.843,0.785,0.668
+0.843,0.787,0.672
+0.843,0.788,0.676
+0.843,0.789,0.680
+0.842,0.790,0.684
+0.842,0.791,0.689
+0.842,0.793,0.693
+0.842,0.794,0.697
+0.842,0.795,0.701
+0.841,0.796,0.706
+0.841,0.797,0.710
+0.841,0.799,0.714
+0.841,0.800,0.718
+0.841,0.801,0.722
+0.840,0.802,0.727
+0.840,0.804,0.731
+0.840,0.805,0.735
+0.840,0.806,0.739
+0.839,0.807,0.744
+0.839,0.808,0.748
+0.839,0.810,0.752
+0.838,0.811,0.756
+0.838,0.812,0.760
+0.838,0.813,0.765
+0.838,0.814,0.769
+0.837,0.816,0.773
+0.837,0.817,0.777
+0.837,0.818,0.782
+0.836,0.819,0.786
+0.836,0.820,0.790
+0.836,0.822,0.794
+0.835,0.823,0.798
+0.835,0.824,0.803
+0.835,0.825,0.807
+0.834,0.826,0.811
+0.834,0.828,0.815
+0.833,0.829,0.820
+0.833,0.830,0.824
+0.833,0.831,0.828
+0.832,0.832,0.832
diff --git a/pyqtgraph/colors/maps/CET-L11.csv b/pyqtgraph/colors/maps/CET-L11.csv
new file mode 100644
index 00000000..196d703d
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-L11.csv
@@ -0,0 +1,256 @@
+0.438,0.678,0.361
+0.443,0.678,0.361
+0.449,0.679,0.361
+0.454,0.679,0.362
+0.459,0.679,0.362
+0.465,0.680,0.363
+0.470,0.680,0.363
+0.475,0.680,0.364
+0.480,0.680,0.364
+0.485,0.681,0.365
+0.491,0.681,0.365
+0.496,0.681,0.366
+0.501,0.682,0.366
+0.506,0.682,0.366
+0.511,0.682,0.367
+0.515,0.682,0.367
+0.520,0.683,0.368
+0.525,0.683,0.368
+0.530,0.683,0.369
+0.535,0.683,0.369
+0.539,0.684,0.370
+0.544,0.684,0.370
+0.549,0.684,0.371
+0.554,0.684,0.371
+0.558,0.685,0.372
+0.563,0.685,0.372
+0.567,0.685,0.373
+0.572,0.685,0.373
+0.577,0.686,0.374
+0.581,0.686,0.374
+0.585,0.686,0.374
+0.590,0.686,0.375
+0.594,0.687,0.375
+0.599,0.687,0.376
+0.603,0.687,0.376
+0.608,0.687,0.377
+0.612,0.687,0.377
+0.616,0.688,0.378
+0.621,0.688,0.378
+0.625,0.688,0.379
+0.629,0.688,0.379
+0.633,0.689,0.380
+0.638,0.689,0.380
+0.642,0.689,0.381
+0.646,0.689,0.381
+0.650,0.689,0.382
+0.654,0.690,0.382
+0.658,0.690,0.383
+0.662,0.690,0.383
+0.666,0.690,0.384
+0.671,0.690,0.384
+0.675,0.691,0.385
+0.679,0.691,0.385
+0.683,0.691,0.386
+0.687,0.691,0.386
+0.691,0.691,0.387
+0.694,0.692,0.387
+0.698,0.692,0.388
+0.702,0.692,0.388
+0.706,0.692,0.389
+0.710,0.692,0.389
+0.714,0.693,0.390
+0.718,0.693,0.390
+0.722,0.693,0.391
+0.725,0.693,0.391
+0.729,0.694,0.392
+0.733,0.694,0.392
+0.737,0.694,0.393
+0.740,0.694,0.393
+0.744,0.694,0.394
+0.748,0.695,0.394
+0.751,0.695,0.395
+0.755,0.695,0.395
+0.759,0.695,0.396
+0.762,0.695,0.396
+0.766,0.696,0.397
+0.769,0.696,0.398
+0.773,0.696,0.398
+0.776,0.696,0.399
+0.780,0.697,0.399
+0.783,0.697,0.400
+0.787,0.697,0.400
+0.790,0.697,0.401
+0.794,0.698,0.401
+0.797,0.698,0.402
+0.800,0.698,0.402
+0.804,0.698,0.403
+0.807,0.699,0.403
+0.810,0.699,0.404
+0.814,0.699,0.405
+0.817,0.700,0.405
+0.820,0.700,0.406
+0.823,0.700,0.406
+0.826,0.700,0.407
+0.830,0.701,0.407
+0.833,0.701,0.408
+0.836,0.701,0.408
+0.839,0.702,0.409
+0.842,0.702,0.410
+0.845,0.702,0.410
+0.848,0.703,0.411
+0.851,0.703,0.411
+0.853,0.704,0.412
+0.856,0.704,0.412
+0.859,0.704,0.413
+0.862,0.705,0.414
+0.864,0.705,0.414
+0.867,0.706,0.415
+0.870,0.706,0.415
+0.872,0.707,0.416
+0.875,0.707,0.417
+0.877,0.708,0.417
+0.879,0.709,0.418
+0.882,0.709,0.418
+0.884,0.710,0.419
+0.886,0.710,0.420
+0.888,0.711,0.420
+0.890,0.712,0.421
+0.892,0.713,0.421
+0.894,0.713,0.422
+0.896,0.714,0.423
+0.897,0.715,0.423
+0.899,0.716,0.424
+0.900,0.717,0.425
+0.901,0.718,0.425
+0.902,0.719,0.426
+0.903,0.720,0.427
+0.903,0.722,0.428
+0.904,0.723,0.428
+0.904,0.725,0.429
+0.904,0.726,0.430
+0.904,0.727,0.431
+0.904,0.729,0.432
+0.905,0.730,0.433
+0.905,0.732,0.434
+0.905,0.733,0.436
+0.905,0.734,0.437
+0.905,0.736,0.438
+0.906,0.737,0.440
+0.906,0.739,0.441
+0.906,0.740,0.443
+0.906,0.741,0.445
+0.906,0.743,0.446
+0.906,0.744,0.448
+0.906,0.746,0.450
+0.907,0.747,0.452
+0.907,0.748,0.454
+0.907,0.750,0.456
+0.907,0.751,0.458
+0.907,0.753,0.461
+0.907,0.754,0.463
+0.907,0.755,0.465
+0.907,0.757,0.468
+0.907,0.758,0.471
+0.907,0.759,0.473
+0.908,0.761,0.476
+0.908,0.762,0.479
+0.908,0.763,0.481
+0.908,0.765,0.484
+0.908,0.766,0.487
+0.908,0.768,0.490
+0.908,0.769,0.494
+0.908,0.770,0.497
+0.908,0.772,0.500
+0.908,0.773,0.503
+0.908,0.774,0.507
+0.907,0.776,0.510
+0.907,0.777,0.514
+0.907,0.778,0.517
+0.907,0.780,0.521
+0.907,0.781,0.525
+0.907,0.782,0.529
+0.907,0.784,0.532
+0.907,0.785,0.536
+0.907,0.786,0.540
+0.906,0.788,0.545
+0.906,0.789,0.549
+0.906,0.790,0.553
+0.906,0.792,0.557
+0.905,0.793,0.562
+0.905,0.794,0.566
+0.905,0.796,0.570
+0.905,0.797,0.575
+0.905,0.798,0.579
+0.904,0.800,0.583
+0.904,0.801,0.588
+0.904,0.802,0.592
+0.904,0.804,0.596
+0.904,0.805,0.601
+0.903,0.806,0.605
+0.903,0.807,0.609
+0.903,0.809,0.614
+0.903,0.810,0.618
+0.903,0.811,0.622
+0.903,0.813,0.627
+0.902,0.814,0.631
+0.902,0.815,0.635
+0.902,0.816,0.639
+0.902,0.818,0.644
+0.902,0.819,0.648
+0.902,0.820,0.652
+0.901,0.821,0.657
+0.901,0.823,0.661
+0.901,0.824,0.665
+0.901,0.825,0.669
+0.901,0.826,0.674
+0.901,0.828,0.678
+0.900,0.829,0.682
+0.900,0.830,0.687
+0.900,0.831,0.691
+0.900,0.833,0.695
+0.900,0.834,0.699
+0.900,0.835,0.704
+0.899,0.836,0.708
+0.899,0.838,0.712
+0.899,0.839,0.717
+0.899,0.840,0.721
+0.899,0.841,0.725
+0.898,0.842,0.729
+0.898,0.844,0.734
+0.898,0.845,0.738
+0.898,0.846,0.742
+0.898,0.847,0.746
+0.897,0.849,0.751
+0.897,0.850,0.755
+0.897,0.851,0.759
+0.897,0.852,0.763
+0.897,0.854,0.768
+0.896,0.855,0.772
+0.896,0.856,0.776
+0.896,0.857,0.781
+0.896,0.858,0.785
+0.895,0.860,0.789
+0.895,0.861,0.793
+0.895,0.862,0.798
+0.894,0.863,0.802
+0.894,0.865,0.806
+0.894,0.866,0.810
+0.894,0.867,0.815
+0.893,0.868,0.819
+0.893,0.869,0.823
+0.893,0.871,0.828
+0.892,0.872,0.832
+0.892,0.873,0.836
+0.892,0.874,0.840
+0.891,0.875,0.845
+0.891,0.877,0.849
+0.891,0.878,0.853
+0.890,0.879,0.858
+0.890,0.880,0.862
+0.889,0.882,0.866
+0.889,0.883,0.870
+0.889,0.884,0.875
+0.888,0.885,0.879
+0.888,0.886,0.883
+0.887,0.888,0.888
diff --git a/pyqtgraph/colors/maps/CET-L12.csv b/pyqtgraph/colors/maps/CET-L12.csv
new file mode 100644
index 00000000..61d0b20c
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-L12.csv
@@ -0,0 +1,256 @@
+0.943,0.944,0.943
+0.940,0.942,0.943
+0.937,0.940,0.943
+0.934,0.938,0.943
+0.931,0.936,0.943
+0.928,0.934,0.942
+0.925,0.932,0.942
+0.922,0.930,0.942
+0.919,0.929,0.942
+0.917,0.927,0.941
+0.914,0.925,0.941
+0.911,0.923,0.941
+0.908,0.921,0.941
+0.905,0.919,0.940
+0.902,0.917,0.940
+0.899,0.916,0.940
+0.896,0.914,0.939
+0.893,0.912,0.939
+0.890,0.910,0.939
+0.887,0.908,0.939
+0.884,0.906,0.938
+0.881,0.904,0.938
+0.878,0.903,0.938
+0.875,0.901,0.937
+0.872,0.899,0.937
+0.869,0.897,0.937
+0.866,0.895,0.937
+0.863,0.893,0.936
+0.860,0.892,0.936
+0.857,0.890,0.936
+0.854,0.888,0.935
+0.851,0.886,0.935
+0.848,0.884,0.935
+0.845,0.882,0.934
+0.842,0.880,0.934
+0.839,0.879,0.934
+0.836,0.877,0.933
+0.833,0.875,0.933
+0.830,0.873,0.933
+0.827,0.871,0.932
+0.824,0.869,0.932
+0.821,0.868,0.931
+0.818,0.866,0.931
+0.815,0.864,0.931
+0.812,0.862,0.930
+0.809,0.860,0.930
+0.806,0.858,0.930
+0.803,0.857,0.929
+0.800,0.855,0.929
+0.797,0.853,0.928
+0.794,0.851,0.928
+0.791,0.849,0.928
+0.788,0.847,0.927
+0.785,0.846,0.927
+0.782,0.844,0.926
+0.779,0.842,0.926
+0.776,0.840,0.925
+0.773,0.838,0.925
+0.770,0.836,0.925
+0.767,0.835,0.924
+0.764,0.833,0.924
+0.761,0.831,0.923
+0.758,0.829,0.923
+0.755,0.827,0.922
+0.752,0.825,0.922
+0.749,0.824,0.921
+0.746,0.822,0.921
+0.743,0.820,0.920
+0.740,0.818,0.920
+0.737,0.816,0.919
+0.734,0.815,0.919
+0.731,0.813,0.918
+0.728,0.811,0.918
+0.725,0.809,0.917
+0.722,0.807,0.917
+0.719,0.805,0.916
+0.716,0.804,0.915
+0.713,0.802,0.915
+0.710,0.800,0.914
+0.707,0.798,0.914
+0.704,0.796,0.913
+0.701,0.794,0.912
+0.698,0.793,0.912
+0.695,0.791,0.911
+0.692,0.789,0.911
+0.689,0.787,0.910
+0.686,0.785,0.909
+0.684,0.784,0.909
+0.681,0.782,0.908
+0.678,0.780,0.907
+0.675,0.778,0.906
+0.672,0.776,0.906
+0.669,0.774,0.905
+0.666,0.773,0.904
+0.663,0.771,0.903
+0.660,0.769,0.903
+0.658,0.767,0.902
+0.655,0.765,0.901
+0.652,0.764,0.900
+0.649,0.762,0.899
+0.646,0.760,0.898
+0.643,0.758,0.897
+0.641,0.756,0.897
+0.638,0.754,0.896
+0.635,0.753,0.895
+0.632,0.751,0.894
+0.630,0.749,0.893
+0.627,0.747,0.892
+0.624,0.745,0.891
+0.622,0.743,0.889
+0.619,0.742,0.888
+0.617,0.740,0.887
+0.614,0.738,0.886
+0.612,0.736,0.884
+0.609,0.734,0.883
+0.607,0.732,0.882
+0.604,0.731,0.880
+0.602,0.729,0.879
+0.600,0.727,0.878
+0.597,0.725,0.876
+0.595,0.723,0.875
+0.592,0.721,0.874
+0.590,0.720,0.872
+0.588,0.718,0.871
+0.585,0.716,0.869
+0.583,0.714,0.868
+0.581,0.712,0.866
+0.578,0.710,0.865
+0.576,0.708,0.863
+0.574,0.707,0.862
+0.571,0.705,0.860
+0.569,0.703,0.859
+0.567,0.701,0.857
+0.565,0.699,0.856
+0.562,0.697,0.854
+0.560,0.696,0.853
+0.558,0.694,0.851
+0.556,0.692,0.849
+0.553,0.690,0.848
+0.551,0.688,0.846
+0.549,0.686,0.845
+0.547,0.685,0.843
+0.545,0.683,0.841
+0.542,0.681,0.840
+0.540,0.679,0.838
+0.538,0.677,0.836
+0.536,0.675,0.835
+0.534,0.673,0.833
+0.532,0.672,0.831
+0.530,0.670,0.830
+0.528,0.668,0.828
+0.526,0.666,0.826
+0.524,0.664,0.824
+0.521,0.662,0.823
+0.519,0.661,0.821
+0.517,0.659,0.819
+0.515,0.657,0.817
+0.513,0.655,0.816
+0.511,0.653,0.814
+0.509,0.651,0.812
+0.507,0.650,0.810
+0.505,0.648,0.808
+0.503,0.646,0.807
+0.502,0.644,0.805
+0.500,0.642,0.803
+0.498,0.640,0.801
+0.496,0.639,0.799
+0.494,0.637,0.797
+0.492,0.635,0.795
+0.490,0.633,0.793
+0.488,0.631,0.791
+0.486,0.629,0.790
+0.484,0.628,0.788
+0.482,0.626,0.786
+0.480,0.624,0.784
+0.478,0.622,0.782
+0.476,0.620,0.781
+0.474,0.618,0.779
+0.472,0.617,0.777
+0.470,0.615,0.776
+0.468,0.613,0.774
+0.466,0.611,0.773
+0.463,0.609,0.771
+0.461,0.608,0.769
+0.459,0.606,0.768
+0.456,0.604,0.767
+0.454,0.602,0.765
+0.452,0.600,0.764
+0.449,0.599,0.762
+0.447,0.597,0.761
+0.444,0.595,0.760
+0.442,0.593,0.758
+0.439,0.592,0.757
+0.437,0.590,0.756
+0.434,0.588,0.754
+0.432,0.586,0.753
+0.429,0.585,0.752
+0.427,0.583,0.751
+0.424,0.581,0.749
+0.421,0.579,0.748
+0.419,0.578,0.747
+0.416,0.576,0.746
+0.413,0.574,0.745
+0.410,0.572,0.744
+0.408,0.571,0.742
+0.405,0.569,0.741
+0.402,0.567,0.740
+0.399,0.565,0.739
+0.396,0.564,0.738
+0.394,0.562,0.737
+0.391,0.560,0.736
+0.388,0.558,0.735
+0.385,0.557,0.734
+0.382,0.555,0.733
+0.379,0.553,0.732
+0.376,0.552,0.731
+0.373,0.550,0.730
+0.370,0.548,0.729
+0.367,0.546,0.728
+0.364,0.545,0.727
+0.361,0.543,0.726
+0.357,0.541,0.725
+0.354,0.540,0.724
+0.351,0.538,0.723
+0.348,0.536,0.722
+0.345,0.534,0.721
+0.341,0.533,0.721
+0.338,0.531,0.720
+0.335,0.529,0.719
+0.331,0.528,0.718
+0.328,0.526,0.717
+0.324,0.524,0.716
+0.321,0.523,0.715
+0.318,0.521,0.715
+0.314,0.519,0.714
+0.310,0.518,0.713
+0.307,0.516,0.712
+0.303,0.514,0.711
+0.300,0.513,0.710
+0.296,0.511,0.710
+0.292,0.509,0.709
+0.288,0.508,0.708
+0.285,0.506,0.707
+0.281,0.504,0.706
+0.277,0.503,0.706
+0.273,0.501,0.705
+0.269,0.499,0.704
+0.265,0.498,0.703
+0.260,0.496,0.703
+0.256,0.494,0.702
+0.252,0.493,0.701
+0.248,0.491,0.700
+0.243,0.489,0.700
+0.239,0.488,0.699
+0.234,0.486,0.698
+0.230,0.484,0.698
diff --git a/pyqtgraph/colors/maps/CET-L13.csv b/pyqtgraph/colors/maps/CET-L13.csv
new file mode 100644
index 00000000..f4ee4bd7
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-L13.csv
@@ -0,0 +1,256 @@
+0.000,0.000,0.000
+0.008,0.002,0.000
+0.016,0.003,0.000
+0.024,0.005,0.000
+0.032,0.006,0.000
+0.040,0.008,0.000
+0.048,0.009,0.000
+0.055,0.010,0.000
+0.062,0.012,0.000
+0.069,0.013,0.000
+0.075,0.014,0.000
+0.081,0.015,0.000
+0.086,0.016,0.000
+0.092,0.017,0.000
+0.097,0.018,0.000
+0.102,0.019,0.000
+0.107,0.020,0.000
+0.112,0.021,0.000
+0.116,0.022,0.000
+0.121,0.023,0.000
+0.125,0.024,0.000
+0.129,0.024,0.000
+0.133,0.025,0.000
+0.137,0.026,0.000
+0.141,0.027,0.000
+0.145,0.027,0.000
+0.149,0.028,0.000
+0.152,0.029,0.000
+0.156,0.029,0.000
+0.159,0.030,0.000
+0.163,0.031,0.000
+0.166,0.031,0.000
+0.169,0.032,0.000
+0.173,0.033,0.000
+0.176,0.033,0.000
+0.179,0.034,0.000
+0.182,0.034,0.000
+0.185,0.035,0.000
+0.188,0.036,0.000
+0.191,0.036,0.000
+0.194,0.037,0.000
+0.197,0.037,0.000
+0.200,0.038,0.000
+0.203,0.038,0.000
+0.206,0.039,0.000
+0.209,0.039,0.000
+0.212,0.040,0.000
+0.215,0.041,0.000
+0.218,0.041,0.000
+0.221,0.042,0.000
+0.223,0.042,0.000
+0.226,0.043,0.000
+0.229,0.043,0.000
+0.232,0.044,0.000
+0.235,0.044,0.000
+0.238,0.045,0.000
+0.241,0.046,0.000
+0.244,0.046,0.000
+0.247,0.047,0.000
+0.250,0.047,0.000
+0.253,0.048,0.000
+0.256,0.048,0.000
+0.259,0.049,0.000
+0.262,0.049,0.000
+0.265,0.050,0.000
+0.268,0.051,0.000
+0.271,0.051,0.000
+0.274,0.052,0.000
+0.277,0.052,0.000
+0.280,0.053,0.000
+0.283,0.053,0.000
+0.286,0.054,0.000
+0.289,0.055,0.000
+0.292,0.055,0.000
+0.295,0.056,0.000
+0.298,0.056,0.000
+0.301,0.057,0.000
+0.304,0.057,0.000
+0.307,0.058,0.000
+0.310,0.059,0.000
+0.313,0.059,0.000
+0.316,0.060,0.000
+0.319,0.060,0.000
+0.322,0.061,0.000
+0.325,0.061,0.000
+0.328,0.062,0.000
+0.332,0.063,0.000
+0.335,0.063,0.000
+0.338,0.064,0.000
+0.341,0.064,0.000
+0.344,0.065,0.000
+0.347,0.066,0.000
+0.350,0.066,0.000
+0.353,0.067,0.000
+0.356,0.067,0.000
+0.359,0.068,0.000
+0.363,0.068,0.000
+0.366,0.069,0.000
+0.369,0.070,0.000
+0.372,0.070,0.000
+0.375,0.071,0.000
+0.378,0.071,0.000
+0.381,0.072,0.000
+0.384,0.073,0.000
+0.388,0.073,0.000
+0.391,0.074,0.000
+0.394,0.074,0.000
+0.397,0.075,0.000
+0.400,0.076,0.000
+0.403,0.076,0.000
+0.406,0.077,0.000
+0.410,0.077,0.000
+0.413,0.078,0.000
+0.416,0.079,0.000
+0.419,0.079,0.000
+0.422,0.080,0.000
+0.426,0.080,0.000
+0.429,0.081,0.000
+0.432,0.082,0.000
+0.435,0.082,0.000
+0.438,0.083,0.000
+0.441,0.083,0.000
+0.445,0.084,0.000
+0.448,0.085,0.000
+0.451,0.085,0.000
+0.454,0.086,0.000
+0.458,0.086,0.000
+0.461,0.087,0.000
+0.464,0.088,0.000
+0.467,0.088,0.000
+0.470,0.089,0.000
+0.474,0.089,0.000
+0.477,0.090,0.000
+0.480,0.091,0.000
+0.483,0.091,0.000
+0.487,0.092,0.000
+0.490,0.093,0.000
+0.493,0.093,0.000
+0.496,0.094,0.000
+0.500,0.094,0.000
+0.503,0.095,0.000
+0.506,0.096,0.000
+0.510,0.096,0.000
+0.513,0.097,0.000
+0.516,0.098,0.000
+0.519,0.098,0.000
+0.523,0.099,0.000
+0.526,0.099,0.000
+0.529,0.100,0.000
+0.533,0.101,0.000
+0.536,0.101,0.000
+0.539,0.102,0.000
+0.543,0.102,0.000
+0.546,0.103,0.000
+0.549,0.104,0.000
+0.552,0.104,0.000
+0.556,0.105,0.000
+0.559,0.106,0.000
+0.563,0.106,0.000
+0.566,0.107,0.000
+0.569,0.108,0.000
+0.572,0.108,0.000
+0.576,0.109,0.000
+0.579,0.109,0.000
+0.583,0.110,0.000
+0.586,0.111,0.000
+0.589,0.111,0.000
+0.593,0.112,0.000
+0.596,0.113,0.000
+0.599,0.113,0.000
+0.603,0.114,0.000
+0.606,0.114,0.000
+0.609,0.115,0.000
+0.613,0.116,0.000
+0.616,0.116,0.000
+0.620,0.117,0.000
+0.623,0.118,0.000
+0.626,0.118,0.000
+0.630,0.119,0.000
+0.633,0.120,0.000
+0.637,0.120,0.000
+0.640,0.121,0.000
+0.643,0.122,0.000
+0.647,0.122,0.000
+0.650,0.123,0.000
+0.654,0.123,0.000
+0.657,0.124,0.000
+0.660,0.125,0.000
+0.664,0.125,0.000
+0.667,0.126,0.000
+0.671,0.127,0.000
+0.674,0.127,0.000
+0.678,0.128,0.000
+0.681,0.129,0.000
+0.685,0.129,0.000
+0.688,0.130,0.000
+0.691,0.131,0.000
+0.695,0.131,0.000
+0.698,0.132,0.000
+0.702,0.133,0.000
+0.705,0.133,0.000
+0.709,0.134,0.000
+0.712,0.135,0.000
+0.716,0.135,0.000
+0.719,0.136,0.000
+0.723,0.136,0.000
+0.726,0.137,0.000
+0.730,0.138,0.000
+0.733,0.138,0.000
+0.737,0.139,0.000
+0.740,0.140,0.000
+0.744,0.140,0.000
+0.747,0.141,0.000
+0.751,0.142,0.000
+0.754,0.142,0.000
+0.758,0.143,0.000
+0.761,0.144,0.000
+0.765,0.144,0.000
+0.768,0.145,0.000
+0.772,0.146,0.000
+0.775,0.146,0.000
+0.779,0.147,0.000
+0.782,0.148,0.000
+0.786,0.148,0.000
+0.789,0.149,0.000
+0.793,0.150,0.000
+0.796,0.150,0.000
+0.800,0.151,0.000
+0.803,0.152,0.000
+0.807,0.152,0.000
+0.810,0.153,0.000
+0.814,0.154,0.000
+0.818,0.154,0.000
+0.821,0.155,0.000
+0.825,0.156,0.000
+0.828,0.156,0.000
+0.832,0.157,0.000
+0.835,0.158,0.000
+0.839,0.158,0.000
+0.842,0.159,0.000
+0.846,0.160,0.000
+0.850,0.160,0.000
+0.853,0.161,0.000
+0.857,0.162,0.000
+0.860,0.163,0.000
+0.864,0.163,0.000
+0.868,0.164,0.000
+0.871,0.165,0.000
+0.875,0.165,0.000
+0.878,0.166,0.000
+0.882,0.167,0.000
+0.886,0.167,0.000
+0.889,0.168,0.000
+0.893,0.169,0.000
+0.896,0.169,0.000
+0.900,0.170,0.000
diff --git a/pyqtgraph/colors/maps/CET-L14.csv b/pyqtgraph/colors/maps/CET-L14.csv
new file mode 100644
index 00000000..26a09087
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-L14.csv
@@ -0,0 +1,256 @@
+0.000,0.000,0.000
+0.000,0.004,0.000
+0.000,0.007,0.000
+0.000,0.011,0.000
+0.000,0.015,0.000
+0.000,0.018,0.000
+0.000,0.022,0.000
+0.000,0.025,0.000
+0.000,0.029,0.000
+0.000,0.032,0.000
+0.000,0.036,0.000
+0.000,0.040,0.000
+0.000,0.043,0.000
+0.000,0.047,0.000
+0.000,0.050,0.000
+0.000,0.053,0.000
+0.000,0.056,0.000
+0.000,0.059,0.000
+0.000,0.061,0.000
+0.000,0.064,0.000
+0.000,0.067,0.000
+0.000,0.069,0.000
+0.000,0.071,0.000
+0.000,0.074,0.000
+0.000,0.076,0.000
+0.000,0.078,0.000
+0.000,0.081,0.000
+0.000,0.083,0.000
+0.000,0.085,0.000
+0.000,0.087,0.000
+0.000,0.089,0.000
+0.000,0.091,0.000
+0.000,0.093,0.000
+0.000,0.095,0.000
+0.000,0.097,0.000
+0.000,0.098,0.000
+0.000,0.100,0.000
+0.000,0.102,0.000
+0.000,0.104,0.000
+0.000,0.106,0.000
+0.000,0.107,0.000
+0.000,0.109,0.000
+0.000,0.111,0.000
+0.000,0.112,0.000
+0.000,0.114,0.000
+0.000,0.115,0.000
+0.000,0.117,0.000
+0.000,0.119,0.000
+0.000,0.120,0.000
+0.000,0.122,0.000
+0.000,0.123,0.000
+0.000,0.125,0.000
+0.000,0.127,0.000
+0.000,0.128,0.000
+0.000,0.130,0.000
+0.000,0.132,0.000
+0.000,0.133,0.000
+0.000,0.135,0.000
+0.000,0.136,0.000
+0.000,0.138,0.000
+0.000,0.140,0.000
+0.000,0.141,0.000
+0.000,0.143,0.000
+0.000,0.145,0.000
+0.000,0.146,0.000
+0.000,0.148,0.000
+0.000,0.150,0.000
+0.000,0.151,0.000
+0.000,0.153,0.000
+0.000,0.154,0.000
+0.000,0.156,0.000
+0.000,0.158,0.000
+0.000,0.159,0.000
+0.000,0.161,0.000
+0.000,0.163,0.000
+0.000,0.165,0.000
+0.000,0.166,0.000
+0.000,0.168,0.000
+0.000,0.170,0.000
+0.000,0.171,0.000
+0.000,0.173,0.000
+0.000,0.175,0.000
+0.000,0.176,0.000
+0.000,0.178,0.000
+0.000,0.180,0.000
+0.000,0.181,0.000
+0.000,0.183,0.000
+0.000,0.185,0.000
+0.000,0.187,0.000
+0.000,0.188,0.000
+0.000,0.190,0.000
+0.000,0.192,0.000
+0.000,0.193,0.000
+0.000,0.195,0.000
+0.000,0.197,0.000
+0.000,0.199,0.000
+0.000,0.200,0.000
+0.000,0.202,0.000
+0.000,0.204,0.000
+0.000,0.205,0.000
+0.000,0.207,0.000
+0.000,0.209,0.000
+0.000,0.211,0.000
+0.000,0.212,0.000
+0.000,0.214,0.000
+0.000,0.216,0.000
+0.000,0.218,0.000
+0.000,0.219,0.000
+0.000,0.221,0.000
+0.000,0.223,0.000
+0.000,0.225,0.000
+0.000,0.226,0.000
+0.000,0.228,0.000
+0.000,0.230,0.000
+0.000,0.232,0.000
+0.000,0.234,0.000
+0.000,0.235,0.000
+0.000,0.237,0.000
+0.000,0.239,0.000
+0.000,0.241,0.000
+0.000,0.242,0.000
+0.000,0.244,0.000
+0.000,0.246,0.000
+0.000,0.248,0.000
+0.000,0.250,0.000
+0.000,0.251,0.000
+0.000,0.253,0.000
+0.000,0.255,0.000
+0.000,0.257,0.000
+0.000,0.259,0.000
+0.000,0.260,0.000
+0.000,0.262,0.000
+0.000,0.264,0.000
+0.000,0.266,0.000
+0.000,0.268,0.000
+0.000,0.269,0.000
+0.000,0.271,0.000
+0.000,0.273,0.000
+0.000,0.275,0.000
+0.000,0.277,0.000
+0.000,0.278,0.000
+0.000,0.280,0.000
+0.000,0.282,0.000
+0.000,0.284,0.000
+0.000,0.286,0.000
+0.000,0.288,0.000
+0.000,0.289,0.000
+0.000,0.291,0.000
+0.000,0.293,0.000
+0.000,0.295,0.000
+0.000,0.297,0.000
+0.000,0.299,0.000
+0.000,0.300,0.000
+0.000,0.302,0.000
+0.000,0.304,0.000
+0.000,0.306,0.000
+0.000,0.308,0.000
+0.000,0.310,0.000
+0.000,0.312,0.000
+0.000,0.313,0.000
+0.000,0.315,0.000
+0.000,0.317,0.000
+0.000,0.319,0.000
+0.000,0.321,0.000
+0.000,0.323,0.000
+0.000,0.325,0.000
+0.000,0.327,0.000
+0.000,0.328,0.000
+0.000,0.330,0.000
+0.000,0.332,0.000
+0.000,0.334,0.000
+0.000,0.336,0.000
+0.000,0.338,0.000
+0.000,0.340,0.000
+0.000,0.342,0.000
+0.000,0.343,0.000
+0.000,0.345,0.000
+0.000,0.347,0.000
+0.000,0.349,0.000
+0.000,0.351,0.000
+0.000,0.353,0.000
+0.000,0.355,0.000
+0.000,0.357,0.000
+0.000,0.359,0.000
+0.000,0.361,0.000
+0.000,0.362,0.000
+0.000,0.364,0.000
+0.000,0.366,0.000
+0.000,0.368,0.000
+0.000,0.370,0.000
+0.000,0.372,0.000
+0.000,0.374,0.000
+0.000,0.376,0.000
+0.000,0.378,0.000
+0.000,0.380,0.000
+0.000,0.382,0.000
+0.000,0.384,0.000
+0.000,0.385,0.000
+0.000,0.387,0.000
+0.000,0.389,0.000
+0.000,0.391,0.000
+0.000,0.393,0.000
+0.000,0.395,0.000
+0.000,0.397,0.000
+0.000,0.399,0.000
+0.000,0.401,0.000
+0.000,0.403,0.000
+0.000,0.405,0.000
+0.000,0.407,0.000
+0.000,0.409,0.000
+0.000,0.411,0.000
+0.000,0.413,0.000
+0.000,0.415,0.000
+0.000,0.417,0.000
+0.000,0.418,0.000
+0.000,0.420,0.000
+0.000,0.422,0.000
+0.000,0.424,0.000
+0.000,0.426,0.000
+0.000,0.428,0.000
+0.000,0.430,0.000
+0.000,0.432,0.000
+0.000,0.434,0.000
+0.000,0.436,0.000
+0.000,0.438,0.000
+0.000,0.440,0.000
+0.000,0.442,0.000
+0.000,0.444,0.000
+0.000,0.446,0.000
+0.000,0.448,0.000
+0.000,0.450,0.000
+0.000,0.452,0.000
+0.000,0.454,0.000
+0.000,0.456,0.000
+0.000,0.458,0.000
+0.000,0.460,0.000
+0.000,0.462,0.000
+0.000,0.464,0.000
+0.000,0.466,0.000
+0.000,0.468,0.000
+0.000,0.470,0.000
+0.000,0.472,0.000
+0.000,0.474,0.000
+0.000,0.476,0.000
+0.000,0.478,0.000
+0.000,0.480,0.000
+0.000,0.482,0.000
+0.000,0.484,0.000
+0.000,0.486,0.000
+0.000,0.488,0.000
+0.000,0.490,0.000
+0.000,0.492,0.000
+0.000,0.494,0.000
+0.000,0.496,0.000
+0.000,0.498,0.000
+0.000,0.500,0.000
diff --git a/pyqtgraph/colors/maps/CET-L15.csv b/pyqtgraph/colors/maps/CET-L15.csv
new file mode 100644
index 00000000..df666891
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-L15.csv
@@ -0,0 +1,256 @@
+0.000,0.000,0.000
+0.001,0.002,0.007
+0.001,0.005,0.015
+0.002,0.007,0.022
+0.003,0.010,0.030
+0.004,0.012,0.038
+0.004,0.015,0.045
+0.005,0.017,0.052
+0.006,0.020,0.059
+0.007,0.022,0.066
+0.007,0.024,0.073
+0.008,0.026,0.079
+0.009,0.028,0.086
+0.009,0.030,0.092
+0.010,0.032,0.098
+0.010,0.034,0.105
+0.011,0.037,0.111
+0.012,0.038,0.117
+0.012,0.040,0.122
+0.013,0.042,0.128
+0.013,0.044,0.133
+0.014,0.046,0.138
+0.014,0.047,0.144
+0.015,0.049,0.149
+0.015,0.051,0.153
+0.016,0.052,0.158
+0.016,0.054,0.163
+0.017,0.055,0.167
+0.017,0.057,0.172
+0.018,0.058,0.176
+0.018,0.059,0.180
+0.018,0.061,0.184
+0.019,0.062,0.188
+0.019,0.063,0.192
+0.020,0.065,0.196
+0.020,0.066,0.200
+0.020,0.067,0.204
+0.021,0.069,0.208
+0.021,0.070,0.211
+0.021,0.071,0.215
+0.022,0.072,0.218
+0.022,0.073,0.222
+0.023,0.074,0.225
+0.023,0.075,0.229
+0.023,0.077,0.232
+0.024,0.078,0.235
+0.024,0.079,0.238
+0.024,0.080,0.242
+0.025,0.081,0.245
+0.025,0.082,0.248
+0.025,0.083,0.252
+0.025,0.084,0.255
+0.026,0.085,0.258
+0.026,0.086,0.261
+0.026,0.087,0.265
+0.027,0.088,0.268
+0.027,0.089,0.271
+0.027,0.091,0.274
+0.028,0.092,0.278
+0.028,0.093,0.281
+0.028,0.094,0.284
+0.029,0.095,0.288
+0.029,0.096,0.291
+0.029,0.097,0.294
+0.030,0.098,0.297
+0.030,0.099,0.301
+0.030,0.100,0.304
+0.031,0.101,0.307
+0.031,0.103,0.311
+0.031,0.104,0.314
+0.032,0.105,0.317
+0.032,0.106,0.321
+0.032,0.107,0.324
+0.033,0.108,0.327
+0.033,0.109,0.331
+0.033,0.110,0.334
+0.034,0.111,0.338
+0.034,0.113,0.341
+0.034,0.114,0.344
+0.035,0.115,0.348
+0.035,0.116,0.351
+0.035,0.117,0.354
+0.036,0.118,0.358
+0.036,0.119,0.361
+0.036,0.120,0.365
+0.037,0.121,0.368
+0.037,0.123,0.371
+0.037,0.124,0.375
+0.038,0.125,0.378
+0.038,0.126,0.382
+0.039,0.127,0.385
+0.039,0.128,0.389
+0.039,0.129,0.392
+0.040,0.131,0.395
+0.040,0.132,0.399
+0.040,0.133,0.402
+0.041,0.134,0.406
+0.041,0.135,0.409
+0.041,0.136,0.413
+0.042,0.137,0.416
+0.042,0.138,0.420
+0.042,0.140,0.423
+0.043,0.141,0.427
+0.043,0.142,0.430
+0.043,0.143,0.434
+0.044,0.144,0.437
+0.044,0.145,0.441
+0.044,0.147,0.444
+0.045,0.148,0.448
+0.045,0.149,0.451
+0.045,0.150,0.455
+0.046,0.151,0.458
+0.046,0.152,0.462
+0.047,0.153,0.465
+0.047,0.155,0.469
+0.047,0.156,0.472
+0.048,0.157,0.476
+0.048,0.158,0.479
+0.048,0.159,0.483
+0.049,0.160,0.486
+0.049,0.162,0.490
+0.049,0.163,0.493
+0.050,0.164,0.497
+0.050,0.165,0.500
+0.050,0.166,0.504
+0.051,0.168,0.508
+0.051,0.169,0.511
+0.051,0.170,0.515
+0.052,0.171,0.518
+0.052,0.172,0.522
+0.053,0.173,0.526
+0.053,0.175,0.529
+0.053,0.176,0.533
+0.054,0.177,0.536
+0.054,0.178,0.540
+0.054,0.179,0.543
+0.055,0.181,0.547
+0.055,0.182,0.551
+0.055,0.183,0.554
+0.056,0.184,0.558
+0.056,0.185,0.562
+0.057,0.187,0.565
+0.057,0.188,0.569
+0.057,0.189,0.572
+0.058,0.190,0.576
+0.058,0.191,0.580
+0.058,0.193,0.583
+0.059,0.194,0.587
+0.059,0.195,0.591
+0.059,0.196,0.594
+0.060,0.197,0.598
+0.060,0.199,0.602
+0.061,0.200,0.605
+0.061,0.201,0.609
+0.061,0.202,0.613
+0.062,0.203,0.616
+0.062,0.205,0.620
+0.062,0.206,0.624
+0.063,0.207,0.627
+0.063,0.208,0.631
+0.063,0.209,0.635
+0.064,0.211,0.638
+0.064,0.212,0.642
+0.065,0.213,0.646
+0.065,0.214,0.650
+0.065,0.216,0.653
+0.066,0.217,0.657
+0.066,0.218,0.661
+0.066,0.219,0.664
+0.067,0.220,0.668
+0.067,0.222,0.672
+0.068,0.223,0.676
+0.068,0.224,0.679
+0.068,0.225,0.683
+0.069,0.227,0.687
+0.069,0.228,0.691
+0.069,0.229,0.694
+0.070,0.230,0.698
+0.070,0.232,0.702
+0.071,0.233,0.705
+0.071,0.234,0.709
+0.071,0.235,0.713
+0.072,0.237,0.717
+0.072,0.238,0.721
+0.072,0.239,0.724
+0.073,0.240,0.728
+0.073,0.242,0.732
+0.074,0.243,0.736
+0.074,0.244,0.739
+0.074,0.245,0.743
+0.075,0.247,0.747
+0.075,0.248,0.751
+0.075,0.249,0.755
+0.076,0.250,0.758
+0.076,0.252,0.762
+0.077,0.253,0.766
+0.077,0.254,0.770
+0.077,0.255,0.774
+0.078,0.257,0.777
+0.078,0.258,0.781
+0.079,0.259,0.785
+0.079,0.260,0.789
+0.079,0.262,0.793
+0.080,0.263,0.797
+0.080,0.264,0.800
+0.080,0.265,0.804
+0.081,0.267,0.808
+0.081,0.268,0.812
+0.082,0.269,0.816
+0.082,0.270,0.820
+0.082,0.272,0.823
+0.083,0.273,0.827
+0.083,0.274,0.831
+0.084,0.276,0.835
+0.084,0.277,0.839
+0.084,0.278,0.843
+0.085,0.279,0.847
+0.085,0.281,0.851
+0.085,0.282,0.854
+0.086,0.283,0.858
+0.086,0.285,0.862
+0.087,0.286,0.866
+0.087,0.287,0.870
+0.087,0.288,0.874
+0.088,0.290,0.878
+0.088,0.291,0.882
+0.089,0.292,0.886
+0.089,0.294,0.889
+0.089,0.295,0.893
+0.090,0.296,0.897
+0.090,0.297,0.901
+0.091,0.299,0.905
+0.091,0.300,0.909
+0.091,0.301,0.913
+0.092,0.303,0.917
+0.092,0.304,0.921
+0.092,0.305,0.925
+0.093,0.306,0.929
+0.093,0.308,0.933
+0.094,0.309,0.937
+0.094,0.310,0.941
+0.094,0.312,0.944
+0.095,0.313,0.948
+0.095,0.314,0.952
+0.096,0.316,0.956
+0.096,0.317,0.960
+0.096,0.318,0.964
+0.097,0.320,0.968
+0.097,0.321,0.972
+0.098,0.322,0.976
+0.098,0.323,0.980
+0.098,0.325,0.984
+0.099,0.326,0.988
+0.099,0.327,0.992
+0.100,0.329,0.996
+0.100,0.330,1.000
diff --git a/pyqtgraph/colors/maps/CET-L16.csv b/pyqtgraph/colors/maps/CET-L16.csv
new file mode 100644
index 00000000..d26db2d1
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-L16.csv
@@ -0,0 +1,256 @@
+0.108,0.108,0.108
+0.115,0.108,0.125
+0.121,0.107,0.142
+0.127,0.107,0.159
+0.132,0.107,0.176
+0.137,0.106,0.193
+0.141,0.106,0.210
+0.145,0.105,0.226
+0.148,0.104,0.243
+0.151,0.104,0.260
+0.154,0.103,0.276
+0.156,0.103,0.292
+0.158,0.102,0.308
+0.159,0.101,0.324
+0.160,0.101,0.340
+0.161,0.100,0.356
+0.161,0.100,0.371
+0.161,0.099,0.387
+0.161,0.099,0.402
+0.160,0.098,0.416
+0.159,0.098,0.431
+0.158,0.098,0.445
+0.156,0.098,0.460
+0.154,0.098,0.473
+0.152,0.098,0.487
+0.150,0.098,0.500
+0.147,0.099,0.513
+0.144,0.099,0.526
+0.140,0.100,0.539
+0.137,0.101,0.551
+0.133,0.102,0.562
+0.129,0.104,0.574
+0.124,0.106,0.585
+0.120,0.107,0.596
+0.115,0.110,0.606
+0.110,0.112,0.616
+0.105,0.114,0.625
+0.099,0.117,0.634
+0.094,0.120,0.643
+0.088,0.124,0.651
+0.083,0.127,0.659
+0.077,0.131,0.666
+0.071,0.135,0.673
+0.066,0.139,0.679
+0.060,0.143,0.685
+0.055,0.148,0.690
+0.050,0.152,0.695
+0.045,0.157,0.699
+0.041,0.163,0.702
+0.038,0.168,0.705
+0.036,0.173,0.708
+0.034,0.179,0.709
+0.033,0.184,0.711
+0.032,0.190,0.712
+0.031,0.196,0.714
+0.030,0.201,0.715
+0.029,0.207,0.716
+0.028,0.212,0.717
+0.028,0.217,0.718
+0.027,0.223,0.719
+0.027,0.228,0.720
+0.026,0.233,0.720
+0.026,0.239,0.721
+0.026,0.244,0.721
+0.026,0.250,0.721
+0.026,0.255,0.721
+0.026,0.260,0.721
+0.026,0.266,0.721
+0.026,0.271,0.720
+0.026,0.276,0.720
+0.026,0.282,0.719
+0.026,0.287,0.718
+0.027,0.292,0.717
+0.027,0.298,0.716
+0.027,0.303,0.714
+0.028,0.308,0.713
+0.028,0.314,0.711
+0.028,0.319,0.709
+0.028,0.324,0.707
+0.028,0.330,0.704
+0.028,0.335,0.701
+0.028,0.341,0.698
+0.028,0.346,0.695
+0.027,0.352,0.692
+0.026,0.357,0.688
+0.025,0.363,0.684
+0.024,0.368,0.680
+0.023,0.374,0.675
+0.022,0.379,0.670
+0.024,0.385,0.665
+0.027,0.390,0.659
+0.032,0.396,0.654
+0.039,0.401,0.648
+0.047,0.406,0.642
+0.055,0.411,0.635
+0.063,0.417,0.629
+0.071,0.422,0.622
+0.079,0.427,0.615
+0.086,0.432,0.608
+0.094,0.437,0.601
+0.101,0.442,0.594
+0.107,0.447,0.586
+0.114,0.452,0.578
+0.120,0.457,0.570
+0.126,0.462,0.562
+0.132,0.466,0.554
+0.137,0.471,0.546
+0.143,0.476,0.538
+0.147,0.481,0.529
+0.152,0.486,0.520
+0.156,0.491,0.511
+0.160,0.495,0.503
+0.164,0.500,0.493
+0.168,0.505,0.484
+0.171,0.510,0.475
+0.174,0.515,0.465
+0.177,0.519,0.456
+0.179,0.524,0.446
+0.181,0.529,0.436
+0.183,0.534,0.426
+0.185,0.538,0.415
+0.186,0.543,0.405
+0.188,0.548,0.394
+0.188,0.553,0.384
+0.189,0.558,0.373
+0.190,0.562,0.363
+0.192,0.567,0.352
+0.193,0.571,0.343
+0.195,0.576,0.333
+0.197,0.580,0.324
+0.200,0.585,0.315
+0.203,0.589,0.306
+0.206,0.593,0.297
+0.209,0.597,0.289
+0.213,0.601,0.281
+0.217,0.606,0.273
+0.221,0.610,0.265
+0.226,0.614,0.257
+0.231,0.618,0.250
+0.236,0.622,0.242
+0.241,0.625,0.235
+0.247,0.629,0.228
+0.252,0.633,0.221
+0.259,0.637,0.214
+0.265,0.641,0.207
+0.271,0.644,0.200
+0.278,0.648,0.194
+0.285,0.652,0.187
+0.292,0.655,0.180
+0.299,0.659,0.174
+0.306,0.662,0.168
+0.314,0.666,0.161
+0.321,0.669,0.155
+0.329,0.673,0.149
+0.337,0.676,0.143
+0.345,0.679,0.136
+0.353,0.683,0.130
+0.361,0.686,0.124
+0.369,0.689,0.118
+0.378,0.693,0.112
+0.386,0.696,0.106
+0.395,0.699,0.100
+0.403,0.702,0.095
+0.412,0.705,0.089
+0.421,0.708,0.083
+0.430,0.711,0.077
+0.439,0.714,0.071
+0.448,0.717,0.065
+0.457,0.720,0.059
+0.466,0.723,0.053
+0.476,0.726,0.048
+0.485,0.729,0.042
+0.494,0.732,0.036
+0.504,0.735,0.031
+0.513,0.737,0.027
+0.523,0.740,0.023
+0.532,0.743,0.019
+0.542,0.746,0.017
+0.552,0.748,0.014
+0.562,0.751,0.012
+0.571,0.753,0.011
+0.581,0.756,0.010
+0.591,0.758,0.010
+0.601,0.761,0.009
+0.611,0.763,0.009
+0.620,0.766,0.010
+0.630,0.768,0.010
+0.639,0.771,0.010
+0.649,0.773,0.011
+0.658,0.776,0.012
+0.667,0.779,0.014
+0.676,0.781,0.015
+0.685,0.784,0.017
+0.694,0.786,0.019
+0.703,0.789,0.021
+0.712,0.791,0.024
+0.721,0.794,0.026
+0.729,0.796,0.030
+0.738,0.799,0.033
+0.746,0.801,0.037
+0.755,0.804,0.041
+0.763,0.807,0.046
+0.771,0.809,0.050
+0.780,0.812,0.055
+0.788,0.814,0.060
+0.796,0.817,0.064
+0.804,0.820,0.069
+0.812,0.822,0.074
+0.819,0.825,0.079
+0.827,0.828,0.084
+0.835,0.831,0.090
+0.842,0.833,0.095
+0.849,0.836,0.100
+0.857,0.839,0.106
+0.864,0.842,0.112
+0.871,0.845,0.118
+0.878,0.848,0.124
+0.884,0.851,0.130
+0.891,0.854,0.136
+0.897,0.857,0.142
+0.904,0.860,0.149
+0.910,0.863,0.156
+0.916,0.866,0.163
+0.922,0.869,0.170
+0.927,0.873,0.177
+0.932,0.876,0.185
+0.937,0.880,0.193
+0.942,0.883,0.201
+0.946,0.887,0.210
+0.950,0.891,0.219
+0.954,0.895,0.228
+0.957,0.899,0.238
+0.960,0.903,0.248
+0.962,0.907,0.260
+0.965,0.911,0.273
+0.968,0.915,0.288
+0.970,0.919,0.304
+0.973,0.923,0.322
+0.976,0.927,0.341
+0.979,0.931,0.362
+0.982,0.934,0.385
+0.985,0.938,0.408
+0.987,0.941,0.434
+0.990,0.945,0.461
+0.993,0.948,0.490
+0.995,0.951,0.521
+0.997,0.954,0.554
+0.999,0.957,0.589
+1.000,0.960,0.626
+1.000,0.963,0.666
+1.000,0.966,0.709
+0.999,0.968,0.755
+0.997,0.971,0.804
+0.993,0.973,0.858
+0.986,0.975,0.915
+0.977,0.977,0.977
diff --git a/pyqtgraph/colors/maps/CET-L17.csv b/pyqtgraph/colors/maps/CET-L17.csv
new file mode 100644
index 00000000..4c27d94f
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-L17.csv
@@ -0,0 +1,256 @@
+1.000,1.000,1.000
+0.998,0.997,0.989
+0.996,0.994,0.978
+0.995,0.991,0.967
+0.993,0.988,0.956
+0.991,0.985,0.945
+0.989,0.982,0.934
+0.987,0.979,0.923
+0.985,0.976,0.912
+0.983,0.973,0.901
+0.981,0.970,0.890
+0.979,0.967,0.879
+0.977,0.964,0.868
+0.974,0.961,0.857
+0.972,0.958,0.846
+0.970,0.955,0.835
+0.968,0.952,0.824
+0.965,0.949,0.813
+0.963,0.946,0.803
+0.961,0.943,0.792
+0.958,0.940,0.781
+0.956,0.937,0.770
+0.953,0.934,0.759
+0.951,0.931,0.748
+0.950,0.927,0.741
+0.951,0.923,0.734
+0.951,0.919,0.728
+0.951,0.915,0.721
+0.951,0.911,0.714
+0.951,0.906,0.708
+0.951,0.902,0.701
+0.951,0.898,0.695
+0.951,0.894,0.688
+0.951,0.890,0.682
+0.951,0.886,0.675
+0.951,0.882,0.669
+0.951,0.878,0.662
+0.951,0.874,0.655
+0.951,0.870,0.649
+0.951,0.865,0.642
+0.950,0.861,0.636
+0.950,0.857,0.629
+0.950,0.853,0.623
+0.950,0.849,0.616
+0.950,0.845,0.610
+0.949,0.841,0.603
+0.949,0.837,0.597
+0.949,0.832,0.592
+0.950,0.828,0.587
+0.950,0.823,0.582
+0.951,0.819,0.577
+0.951,0.814,0.573
+0.952,0.810,0.568
+0.952,0.805,0.563
+0.953,0.801,0.559
+0.953,0.796,0.554
+0.954,0.792,0.549
+0.954,0.787,0.544
+0.955,0.783,0.540
+0.955,0.778,0.535
+0.955,0.773,0.530
+0.956,0.769,0.526
+0.956,0.764,0.521
+0.956,0.760,0.516
+0.956,0.755,0.512
+0.957,0.751,0.507
+0.957,0.746,0.502
+0.957,0.742,0.498
+0.957,0.737,0.493
+0.957,0.732,0.489
+0.958,0.728,0.485
+0.958,0.723,0.482
+0.958,0.718,0.479
+0.959,0.713,0.476
+0.959,0.708,0.474
+0.959,0.704,0.471
+0.960,0.699,0.468
+0.960,0.694,0.465
+0.960,0.689,0.463
+0.960,0.684,0.460
+0.961,0.679,0.457
+0.961,0.675,0.455
+0.961,0.670,0.452
+0.961,0.665,0.449
+0.961,0.660,0.446
+0.961,0.655,0.444
+0.962,0.650,0.441
+0.962,0.645,0.438
+0.962,0.640,0.435
+0.962,0.635,0.433
+0.962,0.630,0.430
+0.962,0.625,0.427
+0.962,0.620,0.425
+0.962,0.615,0.423
+0.962,0.610,0.422
+0.961,0.605,0.421
+0.961,0.600,0.420
+0.961,0.595,0.419
+0.961,0.590,0.418
+0.960,0.585,0.417
+0.960,0.580,0.417
+0.960,0.575,0.416
+0.959,0.570,0.415
+0.959,0.565,0.414
+0.959,0.560,0.413
+0.958,0.555,0.412
+0.958,0.550,0.412
+0.957,0.544,0.411
+0.957,0.539,0.410
+0.957,0.534,0.409
+0.956,0.529,0.408
+0.956,0.524,0.407
+0.955,0.518,0.406
+0.955,0.513,0.406
+0.954,0.508,0.405
+0.954,0.502,0.404
+0.953,0.497,0.403
+0.952,0.492,0.404
+0.951,0.487,0.405
+0.950,0.482,0.405
+0.948,0.477,0.406
+0.947,0.472,0.407
+0.946,0.467,0.408
+0.945,0.462,0.408
+0.943,0.457,0.409
+0.942,0.451,0.410
+0.941,0.446,0.410
+0.940,0.441,0.411
+0.938,0.436,0.412
+0.937,0.430,0.412
+0.936,0.425,0.413
+0.934,0.420,0.414
+0.933,0.414,0.414
+0.932,0.409,0.415
+0.930,0.404,0.416
+0.929,0.398,0.416
+0.928,0.393,0.417
+0.926,0.387,0.418
+0.925,0.382,0.418
+0.924,0.376,0.419
+0.921,0.371,0.420
+0.919,0.366,0.422
+0.917,0.361,0.424
+0.914,0.356,0.426
+0.912,0.351,0.428
+0.909,0.347,0.430
+0.907,0.342,0.431
+0.904,0.337,0.433
+0.902,0.332,0.435
+0.899,0.326,0.437
+0.897,0.321,0.438
+0.894,0.316,0.440
+0.892,0.311,0.442
+0.889,0.306,0.444
+0.887,0.300,0.445
+0.884,0.295,0.447
+0.882,0.290,0.449
+0.879,0.284,0.450
+0.876,0.279,0.452
+0.874,0.273,0.454
+0.871,0.268,0.455
+0.869,0.262,0.457
+0.866,0.256,0.459
+0.863,0.252,0.461
+0.859,0.247,0.463
+0.855,0.243,0.466
+0.851,0.239,0.468
+0.847,0.235,0.470
+0.843,0.230,0.473
+0.839,0.226,0.475
+0.835,0.222,0.478
+0.831,0.217,0.480
+0.827,0.213,0.482
+0.823,0.208,0.485
+0.819,0.204,0.487
+0.815,0.199,0.489
+0.811,0.194,0.492
+0.807,0.190,0.494
+0.803,0.185,0.496
+0.799,0.180,0.499
+0.795,0.175,0.501
+0.791,0.170,0.503
+0.787,0.165,0.506
+0.783,0.160,0.508
+0.778,0.155,0.510
+0.774,0.150,0.513
+0.769,0.146,0.515
+0.764,0.144,0.518
+0.758,0.141,0.520
+0.753,0.139,0.523
+0.747,0.137,0.525
+0.741,0.134,0.528
+0.736,0.132,0.530
+0.730,0.129,0.533
+0.724,0.127,0.535
+0.718,0.125,0.538
+0.712,0.122,0.541
+0.707,0.120,0.543
+0.701,0.118,0.546
+0.695,0.115,0.548
+0.689,0.113,0.551
+0.683,0.111,0.553
+0.677,0.109,0.556
+0.671,0.106,0.558
+0.665,0.104,0.561
+0.659,0.102,0.563
+0.653,0.100,0.566
+0.647,0.097,0.568
+0.641,0.095,0.571
+0.634,0.094,0.573
+0.626,0.096,0.576
+0.619,0.097,0.578
+0.611,0.099,0.580
+0.603,0.100,0.582
+0.596,0.102,0.585
+0.588,0.103,0.587
+0.580,0.104,0.589
+0.572,0.106,0.591
+0.564,0.107,0.594
+0.555,0.108,0.596
+0.547,0.109,0.598
+0.539,0.111,0.600
+0.531,0.112,0.603
+0.522,0.113,0.605
+0.514,0.114,0.607
+0.505,0.115,0.609
+0.496,0.116,0.612
+0.487,0.117,0.614
+0.478,0.119,0.616
+0.469,0.120,0.618
+0.460,0.121,0.620
+0.450,0.122,0.623
+0.441,0.123,0.625
+0.430,0.126,0.626
+0.419,0.128,0.628
+0.408,0.131,0.629
+0.396,0.133,0.631
+0.384,0.136,0.632
+0.372,0.138,0.633
+0.360,0.140,0.635
+0.347,0.142,0.636
+0.334,0.144,0.638
+0.321,0.146,0.639
+0.307,0.148,0.640
+0.292,0.150,0.642
+0.277,0.152,0.643
+0.261,0.153,0.645
+0.244,0.155,0.646
+0.226,0.156,0.648
+0.206,0.158,0.649
+0.184,0.159,0.650
+0.159,0.161,0.652
+0.131,0.162,0.653
+0.094,0.163,0.655
+0.038,0.164,0.656
+0.000,0.165,0.658
diff --git a/pyqtgraph/colors/maps/CET-L18.csv b/pyqtgraph/colors/maps/CET-L18.csv
new file mode 100644
index 00000000..95e54385
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-L18.csv
@@ -0,0 +1,256 @@
+1.000,1.000,1.000
+0.998,0.998,0.990
+0.995,0.997,0.980
+0.993,0.995,0.969
+0.991,0.993,0.959
+0.989,0.991,0.949
+0.986,0.990,0.939
+0.984,0.988,0.929
+0.981,0.986,0.919
+0.979,0.984,0.909
+0.976,0.983,0.898
+0.974,0.981,0.888
+0.971,0.979,0.878
+0.969,0.977,0.868
+0.966,0.976,0.858
+0.964,0.974,0.848
+0.961,0.972,0.838
+0.958,0.971,0.828
+0.956,0.969,0.818
+0.953,0.967,0.807
+0.950,0.965,0.797
+0.947,0.964,0.787
+0.944,0.962,0.777
+0.941,0.960,0.767
+0.940,0.958,0.760
+0.939,0.955,0.754
+0.938,0.953,0.748
+0.937,0.950,0.742
+0.936,0.947,0.736
+0.935,0.945,0.730
+0.934,0.942,0.724
+0.933,0.940,0.718
+0.932,0.937,0.712
+0.931,0.934,0.706
+0.930,0.932,0.700
+0.929,0.929,0.694
+0.928,0.927,0.688
+0.927,0.924,0.682
+0.926,0.922,0.676
+0.925,0.919,0.670
+0.924,0.916,0.664
+0.923,0.914,0.658
+0.922,0.911,0.652
+0.920,0.909,0.646
+0.919,0.906,0.640
+0.918,0.904,0.634
+0.917,0.901,0.628
+0.916,0.898,0.623
+0.916,0.895,0.617
+0.915,0.893,0.612
+0.915,0.890,0.607
+0.915,0.887,0.602
+0.914,0.884,0.597
+0.914,0.881,0.592
+0.913,0.879,0.586
+0.913,0.876,0.581
+0.912,0.873,0.576
+0.911,0.870,0.571
+0.911,0.867,0.566
+0.910,0.864,0.560
+0.910,0.862,0.555
+0.909,0.859,0.550
+0.909,0.856,0.545
+0.908,0.853,0.540
+0.907,0.850,0.535
+0.907,0.848,0.529
+0.906,0.845,0.524
+0.906,0.842,0.519
+0.905,0.839,0.514
+0.904,0.836,0.509
+0.904,0.833,0.504
+0.904,0.830,0.499
+0.903,0.827,0.495
+0.903,0.824,0.490
+0.903,0.821,0.485
+0.903,0.818,0.481
+0.903,0.815,0.476
+0.902,0.812,0.472
+0.902,0.809,0.467
+0.902,0.806,0.463
+0.902,0.803,0.458
+0.901,0.800,0.453
+0.901,0.797,0.449
+0.901,0.794,0.444
+0.900,0.791,0.440
+0.900,0.788,0.435
+0.900,0.785,0.431
+0.899,0.782,0.426
+0.899,0.779,0.421
+0.899,0.776,0.417
+0.898,0.773,0.412
+0.898,0.771,0.408
+0.897,0.768,0.403
+0.897,0.764,0.399
+0.897,0.761,0.395
+0.897,0.758,0.391
+0.897,0.755,0.387
+0.897,0.752,0.383
+0.897,0.749,0.379
+0.897,0.746,0.375
+0.896,0.742,0.371
+0.896,0.739,0.367
+0.896,0.736,0.363
+0.896,0.733,0.359
+0.896,0.730,0.355
+0.896,0.727,0.351
+0.895,0.724,0.347
+0.895,0.720,0.343
+0.895,0.717,0.339
+0.895,0.714,0.335
+0.895,0.711,0.331
+0.894,0.708,0.327
+0.894,0.705,0.323
+0.894,0.702,0.318
+0.894,0.698,0.314
+0.893,0.695,0.310
+0.893,0.692,0.306
+0.893,0.689,0.303
+0.893,0.686,0.300
+0.893,0.682,0.296
+0.893,0.679,0.293
+0.893,0.676,0.289
+0.893,0.672,0.286
+0.893,0.669,0.283
+0.892,0.666,0.279
+0.892,0.663,0.276
+0.892,0.659,0.272
+0.892,0.656,0.269
+0.892,0.653,0.266
+0.892,0.649,0.262
+0.892,0.646,0.259
+0.891,0.643,0.255
+0.891,0.639,0.252
+0.891,0.636,0.248
+0.891,0.633,0.245
+0.891,0.629,0.241
+0.890,0.626,0.238
+0.890,0.623,0.235
+0.890,0.620,0.231
+0.890,0.616,0.228
+0.890,0.613,0.225
+0.890,0.609,0.222
+0.889,0.606,0.219
+0.889,0.602,0.217
+0.889,0.599,0.214
+0.889,0.596,0.211
+0.889,0.592,0.208
+0.889,0.589,0.206
+0.889,0.585,0.203
+0.888,0.582,0.200
+0.888,0.578,0.197
+0.888,0.575,0.195
+0.888,0.571,0.192
+0.888,0.568,0.189
+0.887,0.564,0.186
+0.887,0.561,0.183
+0.887,0.557,0.181
+0.887,0.554,0.178
+0.886,0.550,0.175
+0.886,0.547,0.172
+0.886,0.543,0.169
+0.886,0.540,0.166
+0.885,0.536,0.164
+0.885,0.533,0.161
+0.885,0.529,0.159
+0.885,0.525,0.158
+0.885,0.522,0.156
+0.884,0.518,0.154
+0.884,0.515,0.152
+0.884,0.511,0.150
+0.884,0.507,0.148
+0.883,0.504,0.146
+0.883,0.500,0.144
+0.883,0.496,0.142
+0.882,0.493,0.140
+0.882,0.489,0.138
+0.882,0.485,0.136
+0.882,0.481,0.134
+0.881,0.478,0.132
+0.881,0.474,0.130
+0.881,0.470,0.128
+0.880,0.466,0.126
+0.880,0.463,0.124
+0.880,0.459,0.122
+0.879,0.455,0.120
+0.879,0.451,0.119
+0.878,0.447,0.117
+0.878,0.443,0.116
+0.878,0.440,0.115
+0.877,0.436,0.114
+0.877,0.432,0.113
+0.877,0.428,0.112
+0.876,0.424,0.111
+0.876,0.420,0.110
+0.875,0.416,0.110
+0.875,0.412,0.109
+0.874,0.408,0.108
+0.874,0.404,0.107
+0.874,0.400,0.106
+0.873,0.396,0.105
+0.873,0.392,0.104
+0.872,0.387,0.103
+0.872,0.383,0.102
+0.871,0.379,0.101
+0.871,0.375,0.100
+0.870,0.371,0.100
+0.870,0.367,0.099
+0.869,0.362,0.098
+0.869,0.358,0.097
+0.868,0.354,0.096
+0.868,0.349,0.097
+0.867,0.345,0.097
+0.867,0.341,0.097
+0.866,0.336,0.097
+0.865,0.332,0.097
+0.865,0.327,0.097
+0.864,0.323,0.097
+0.864,0.318,0.097
+0.863,0.313,0.097
+0.862,0.309,0.098
+0.862,0.304,0.098
+0.861,0.299,0.098
+0.861,0.295,0.098
+0.860,0.290,0.098
+0.859,0.285,0.098
+0.859,0.280,0.098
+0.858,0.275,0.098
+0.857,0.270,0.098
+0.857,0.265,0.098
+0.856,0.259,0.098
+0.855,0.254,0.098
+0.855,0.249,0.098
+0.854,0.243,0.099
+0.853,0.238,0.099
+0.852,0.232,0.100
+0.852,0.226,0.101
+0.851,0.221,0.102
+0.850,0.215,0.103
+0.849,0.209,0.104
+0.848,0.203,0.104
+0.847,0.196,0.105
+0.846,0.190,0.106
+0.846,0.183,0.106
+0.845,0.177,0.107
+0.844,0.169,0.108
+0.843,0.162,0.108
+0.842,0.155,0.109
+0.841,0.147,0.110
+0.840,0.138,0.110
+0.840,0.130,0.111
+0.839,0.120,0.112
+0.838,0.110,0.112
+0.837,0.099,0.113
+0.836,0.088,0.113
+0.835,0.074,0.114
+0.834,0.059,0.114
diff --git a/pyqtgraph/colors/maps/CET-L19.csv b/pyqtgraph/colors/maps/CET-L19.csv
new file mode 100644
index 00000000..652b489c
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-L19.csv
@@ -0,0 +1,256 @@
+1.000,1.000,1.000
+0.995,0.998,1.000
+0.990,0.996,0.999
+0.985,0.994,0.999
+0.980,0.992,0.998
+0.975,0.990,0.998
+0.970,0.989,0.998
+0.965,0.987,0.997
+0.960,0.985,0.997
+0.955,0.983,0.996
+0.950,0.981,0.996
+0.945,0.979,0.996
+0.940,0.977,0.995
+0.935,0.975,0.995
+0.930,0.973,0.994
+0.925,0.971,0.994
+0.920,0.969,0.994
+0.915,0.967,0.993
+0.910,0.965,0.993
+0.905,0.963,0.992
+0.900,0.962,0.992
+0.895,0.960,0.992
+0.890,0.958,0.991
+0.885,0.956,0.991
+0.881,0.954,0.991
+0.877,0.951,0.991
+0.873,0.949,0.991
+0.869,0.947,0.991
+0.865,0.944,0.992
+0.861,0.942,0.992
+0.857,0.940,0.992
+0.853,0.938,0.992
+0.849,0.935,0.993
+0.845,0.933,0.993
+0.840,0.931,0.993
+0.836,0.928,0.993
+0.832,0.926,0.993
+0.828,0.924,0.994
+0.824,0.922,0.994
+0.820,0.919,0.994
+0.816,0.917,0.994
+0.812,0.915,0.994
+0.808,0.913,0.994
+0.804,0.910,0.995
+0.799,0.908,0.995
+0.795,0.906,0.995
+0.791,0.904,0.995
+0.788,0.901,0.995
+0.786,0.898,0.996
+0.783,0.896,0.996
+0.781,0.893,0.996
+0.778,0.890,0.996
+0.776,0.888,0.997
+0.773,0.885,0.997
+0.771,0.882,0.997
+0.768,0.880,0.997
+0.766,0.877,0.998
+0.763,0.874,0.998
+0.761,0.871,0.998
+0.758,0.869,0.998
+0.756,0.866,0.998
+0.753,0.863,0.999
+0.751,0.861,0.999
+0.748,0.858,0.999
+0.746,0.855,0.999
+0.743,0.853,1.000
+0.740,0.850,1.000
+0.738,0.847,1.000
+0.735,0.845,1.000
+0.733,0.842,1.000
+0.731,0.839,1.000
+0.731,0.836,1.000
+0.730,0.833,1.000
+0.730,0.830,0.999
+0.729,0.827,0.999
+0.729,0.824,0.999
+0.728,0.821,0.998
+0.728,0.817,0.998
+0.727,0.814,0.998
+0.727,0.811,0.997
+0.726,0.808,0.997
+0.726,0.805,0.996
+0.725,0.802,0.996
+0.725,0.799,0.996
+0.724,0.796,0.995
+0.724,0.793,0.995
+0.723,0.789,0.995
+0.723,0.786,0.994
+0.722,0.783,0.994
+0.722,0.780,0.994
+0.721,0.777,0.993
+0.721,0.774,0.993
+0.720,0.771,0.992
+0.720,0.767,0.992
+0.722,0.764,0.990
+0.723,0.760,0.989
+0.725,0.757,0.987
+0.726,0.753,0.986
+0.728,0.750,0.985
+0.729,0.746,0.983
+0.731,0.743,0.982
+0.732,0.739,0.980
+0.734,0.735,0.979
+0.735,0.732,0.977
+0.736,0.728,0.976
+0.738,0.725,0.974
+0.739,0.721,0.973
+0.740,0.718,0.971
+0.742,0.714,0.970
+0.743,0.710,0.968
+0.744,0.707,0.967
+0.746,0.703,0.966
+0.747,0.699,0.964
+0.748,0.696,0.963
+0.749,0.692,0.961
+0.750,0.689,0.960
+0.752,0.685,0.958
+0.755,0.681,0.955
+0.758,0.677,0.952
+0.760,0.673,0.949
+0.763,0.669,0.946
+0.766,0.665,0.943
+0.768,0.661,0.940
+0.771,0.657,0.937
+0.774,0.653,0.934
+0.776,0.649,0.931
+0.779,0.645,0.928
+0.781,0.641,0.926
+0.784,0.637,0.923
+0.786,0.633,0.920
+0.789,0.629,0.917
+0.791,0.624,0.914
+0.794,0.620,0.911
+0.796,0.616,0.908
+0.798,0.612,0.905
+0.801,0.608,0.902
+0.803,0.604,0.899
+0.805,0.600,0.896
+0.807,0.595,0.893
+0.809,0.591,0.890
+0.812,0.587,0.886
+0.816,0.582,0.881
+0.819,0.578,0.876
+0.822,0.574,0.872
+0.824,0.569,0.867
+0.827,0.565,0.863
+0.830,0.560,0.858
+0.833,0.556,0.853
+0.836,0.551,0.849
+0.838,0.547,0.844
+0.841,0.542,0.839
+0.844,0.538,0.835
+0.846,0.533,0.830
+0.849,0.529,0.826
+0.851,0.524,0.821
+0.854,0.520,0.817
+0.856,0.515,0.812
+0.859,0.510,0.807
+0.861,0.505,0.803
+0.864,0.501,0.798
+0.866,0.496,0.794
+0.868,0.491,0.789
+0.870,0.486,0.785
+0.873,0.482,0.779
+0.875,0.477,0.773
+0.877,0.473,0.766
+0.879,0.468,0.760
+0.882,0.463,0.754
+0.884,0.458,0.748
+0.886,0.454,0.741
+0.888,0.449,0.735
+0.890,0.444,0.729
+0.892,0.439,0.723
+0.894,0.434,0.717
+0.896,0.429,0.711
+0.898,0.425,0.704
+0.899,0.420,0.698
+0.901,0.415,0.692
+0.903,0.410,0.686
+0.905,0.404,0.680
+0.906,0.399,0.674
+0.908,0.394,0.668
+0.910,0.389,0.662
+0.911,0.384,0.655
+0.913,0.378,0.649
+0.914,0.373,0.643
+0.915,0.368,0.636
+0.916,0.364,0.629
+0.917,0.359,0.621
+0.918,0.354,0.614
+0.918,0.350,0.606
+0.919,0.345,0.599
+0.920,0.340,0.592
+0.920,0.335,0.584
+0.921,0.330,0.577
+0.921,0.326,0.569
+0.922,0.321,0.562
+0.922,0.316,0.555
+0.923,0.311,0.547
+0.923,0.306,0.540
+0.924,0.300,0.532
+0.924,0.295,0.525
+0.924,0.290,0.518
+0.925,0.285,0.510
+0.925,0.279,0.503
+0.925,0.274,0.496
+0.925,0.268,0.489
+0.925,0.263,0.481
+0.925,0.257,0.474
+0.925,0.252,0.467
+0.924,0.248,0.458
+0.923,0.244,0.450
+0.922,0.240,0.442
+0.921,0.237,0.434
+0.919,0.233,0.425
+0.918,0.229,0.417
+0.917,0.224,0.409
+0.916,0.220,0.401
+0.914,0.216,0.393
+0.913,0.212,0.385
+0.912,0.208,0.376
+0.910,0.204,0.368
+0.909,0.200,0.360
+0.908,0.195,0.352
+0.906,0.191,0.344
+0.905,0.186,0.336
+0.903,0.182,0.328
+0.901,0.177,0.320
+0.900,0.173,0.312
+0.898,0.168,0.304
+0.897,0.163,0.295
+0.895,0.159,0.287
+0.893,0.154,0.279
+0.890,0.153,0.271
+0.887,0.152,0.262
+0.884,0.151,0.253
+0.880,0.149,0.245
+0.877,0.148,0.236
+0.874,0.147,0.227
+0.871,0.146,0.218
+0.867,0.145,0.210
+0.864,0.144,0.201
+0.861,0.143,0.192
+0.857,0.141,0.183
+0.854,0.140,0.174
+0.851,0.139,0.164
+0.847,0.138,0.155
+0.844,0.137,0.145
+0.840,0.136,0.136
+0.837,0.135,0.126
+0.833,0.134,0.115
+0.830,0.133,0.105
+0.826,0.132,0.094
+0.823,0.131,0.082
+0.819,0.130,0.069
+0.816,0.130,0.056
diff --git a/pyqtgraph/colors/maps/CET-L2.csv b/pyqtgraph/colors/maps/CET-L2.csv
new file mode 100644
index 00000000..921590d1
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-L2.csv
@@ -0,0 +1,256 @@
+0.108,0.108,0.108
+0.110,0.110,0.110
+0.113,0.113,0.113
+0.116,0.116,0.116
+0.118,0.118,0.118
+0.121,0.121,0.121
+0.123,0.123,0.123
+0.126,0.126,0.126
+0.129,0.129,0.129
+0.131,0.132,0.132
+0.134,0.134,0.134
+0.137,0.137,0.137
+0.140,0.140,0.140
+0.142,0.142,0.142
+0.145,0.145,0.145
+0.148,0.148,0.148
+0.150,0.150,0.150
+0.153,0.153,0.153
+0.156,0.156,0.156
+0.159,0.159,0.159
+0.161,0.161,0.161
+0.164,0.164,0.164
+0.167,0.167,0.167
+0.170,0.170,0.170
+0.172,0.173,0.173
+0.175,0.175,0.175
+0.178,0.178,0.178
+0.181,0.181,0.181
+0.184,0.184,0.184
+0.187,0.187,0.187
+0.189,0.189,0.189
+0.192,0.192,0.192
+0.195,0.195,0.195
+0.198,0.198,0.198
+0.201,0.201,0.201
+0.204,0.204,0.204
+0.206,0.207,0.206
+0.209,0.209,0.209
+0.212,0.212,0.212
+0.215,0.215,0.215
+0.218,0.218,0.218
+0.221,0.221,0.221
+0.224,0.224,0.224
+0.227,0.227,0.227
+0.230,0.230,0.230
+0.232,0.233,0.233
+0.235,0.235,0.235
+0.238,0.238,0.238
+0.241,0.241,0.241
+0.244,0.244,0.244
+0.247,0.247,0.247
+0.250,0.250,0.250
+0.253,0.253,0.253
+0.256,0.256,0.256
+0.259,0.259,0.259
+0.262,0.262,0.262
+0.265,0.265,0.265
+0.268,0.268,0.268
+0.271,0.271,0.271
+0.274,0.274,0.274
+0.277,0.277,0.277
+0.280,0.280,0.280
+0.283,0.283,0.283
+0.286,0.286,0.286
+0.289,0.289,0.289
+0.292,0.292,0.292
+0.295,0.295,0.295
+0.298,0.298,0.298
+0.301,0.301,0.301
+0.304,0.304,0.304
+0.307,0.307,0.307
+0.310,0.310,0.310
+0.313,0.313,0.313
+0.316,0.317,0.317
+0.320,0.320,0.320
+0.323,0.323,0.323
+0.326,0.326,0.326
+0.329,0.329,0.329
+0.332,0.332,0.332
+0.335,0.335,0.335
+0.338,0.338,0.338
+0.341,0.341,0.341
+0.344,0.344,0.344
+0.347,0.348,0.348
+0.351,0.351,0.351
+0.354,0.354,0.354
+0.357,0.357,0.357
+0.360,0.360,0.360
+0.363,0.363,0.363
+0.366,0.366,0.366
+0.369,0.370,0.370
+0.373,0.373,0.373
+0.376,0.376,0.376
+0.379,0.379,0.379
+0.382,0.382,0.382
+0.385,0.385,0.385
+0.389,0.389,0.389
+0.392,0.392,0.392
+0.395,0.395,0.395
+0.398,0.398,0.398
+0.401,0.401,0.401
+0.404,0.405,0.405
+0.408,0.408,0.408
+0.411,0.411,0.411
+0.414,0.414,0.414
+0.417,0.417,0.417
+0.421,0.421,0.421
+0.424,0.424,0.424
+0.427,0.427,0.427
+0.430,0.430,0.430
+0.434,0.434,0.434
+0.437,0.437,0.437
+0.440,0.440,0.440
+0.443,0.443,0.443
+0.447,0.447,0.447
+0.450,0.450,0.450
+0.453,0.453,0.453
+0.456,0.456,0.456
+0.460,0.460,0.460
+0.463,0.463,0.463
+0.466,0.466,0.466
+0.470,0.470,0.470
+0.473,0.473,0.473
+0.476,0.476,0.476
+0.479,0.480,0.480
+0.483,0.483,0.483
+0.486,0.486,0.486
+0.489,0.489,0.489
+0.493,0.493,0.493
+0.496,0.496,0.496
+0.499,0.499,0.499
+0.503,0.503,0.503
+0.506,0.506,0.506
+0.509,0.509,0.509
+0.513,0.513,0.513
+0.516,0.516,0.516
+0.519,0.520,0.520
+0.523,0.523,0.523
+0.526,0.526,0.526
+0.530,0.530,0.530
+0.533,0.533,0.533
+0.536,0.536,0.536
+0.540,0.540,0.540
+0.543,0.543,0.543
+0.546,0.547,0.546
+0.550,0.550,0.550
+0.553,0.553,0.553
+0.557,0.557,0.557
+0.560,0.560,0.560
+0.563,0.563,0.563
+0.567,0.567,0.567
+0.570,0.570,0.570
+0.574,0.574,0.574
+0.577,0.577,0.577
+0.580,0.581,0.581
+0.584,0.584,0.584
+0.587,0.587,0.587
+0.591,0.591,0.591
+0.594,0.594,0.594
+0.598,0.598,0.598
+0.601,0.601,0.601
+0.605,0.605,0.605
+0.608,0.608,0.608
+0.611,0.612,0.612
+0.615,0.615,0.615
+0.618,0.618,0.618
+0.622,0.622,0.622
+0.625,0.625,0.625
+0.629,0.629,0.629
+0.632,0.632,0.632
+0.636,0.636,0.636
+0.639,0.639,0.639
+0.643,0.643,0.643
+0.646,0.646,0.646
+0.650,0.650,0.650
+0.653,0.653,0.653
+0.657,0.657,0.657
+0.660,0.660,0.660
+0.664,0.664,0.664
+0.667,0.667,0.667
+0.671,0.671,0.671
+0.674,0.674,0.674
+0.678,0.678,0.678
+0.681,0.681,0.681
+0.685,0.685,0.685
+0.688,0.688,0.688
+0.692,0.692,0.692
+0.695,0.696,0.695
+0.699,0.699,0.699
+0.702,0.703,0.703
+0.706,0.706,0.706
+0.710,0.710,0.710
+0.713,0.713,0.713
+0.717,0.717,0.717
+0.720,0.720,0.720
+0.724,0.724,0.724
+0.727,0.728,0.727
+0.731,0.731,0.731
+0.735,0.735,0.735
+0.738,0.738,0.738
+0.742,0.742,0.742
+0.745,0.745,0.745
+0.749,0.749,0.749
+0.752,0.753,0.753
+0.756,0.756,0.756
+0.760,0.760,0.760
+0.763,0.763,0.763
+0.767,0.767,0.767
+0.770,0.771,0.771
+0.774,0.774,0.774
+0.778,0.778,0.778
+0.781,0.781,0.781
+0.785,0.785,0.785
+0.789,0.789,0.789
+0.792,0.792,0.792
+0.796,0.796,0.796
+0.799,0.800,0.800
+0.803,0.803,0.803
+0.807,0.807,0.807
+0.810,0.810,0.810
+0.814,0.814,0.814
+0.818,0.818,0.818
+0.821,0.821,0.821
+0.825,0.825,0.825
+0.829,0.829,0.829
+0.832,0.832,0.832
+0.836,0.836,0.836
+0.840,0.840,0.840
+0.843,0.843,0.843
+0.847,0.847,0.847
+0.851,0.851,0.851
+0.854,0.854,0.854
+0.858,0.858,0.858
+0.862,0.862,0.862
+0.865,0.865,0.865
+0.869,0.869,0.869
+0.873,0.873,0.873
+0.876,0.877,0.876
+0.880,0.880,0.880
+0.884,0.884,0.884
+0.887,0.888,0.888
+0.891,0.891,0.891
+0.895,0.895,0.895
+0.899,0.899,0.899
+0.902,0.902,0.902
+0.906,0.906,0.906
+0.910,0.910,0.910
+0.913,0.914,0.914
+0.917,0.917,0.917
+0.921,0.921,0.921
+0.925,0.925,0.925
+0.928,0.929,0.929
+0.932,0.932,0.932
+0.936,0.936,0.936
+0.940,0.940,0.940
+0.943,0.944,0.943
diff --git a/pyqtgraph/colors/maps/CET-L3.csv b/pyqtgraph/colors/maps/CET-L3.csv
new file mode 100644
index 00000000..757974af
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-L3.csv
@@ -0,0 +1,256 @@
+0.000,0.000,0.000
+0.027,0.000,0.000
+0.052,0.000,0.000
+0.072,0.000,0.000
+0.087,0.000,0.000
+0.101,0.000,0.000
+0.113,0.000,0.000
+0.124,0.000,0.000
+0.135,0.001,0.000
+0.144,0.001,0.000
+0.153,0.001,0.000
+0.161,0.001,0.000
+0.169,0.001,0.000
+0.177,0.001,0.000
+0.184,0.002,0.000
+0.191,0.002,0.000
+0.198,0.002,0.000
+0.204,0.002,0.000
+0.210,0.002,0.000
+0.216,0.002,0.000
+0.222,0.002,0.000
+0.228,0.002,0.000
+0.234,0.002,0.000
+0.240,0.002,0.000
+0.245,0.002,0.000
+0.251,0.002,0.000
+0.257,0.002,0.000
+0.263,0.002,0.000
+0.269,0.002,0.000
+0.275,0.002,0.000
+0.280,0.002,0.000
+0.286,0.003,0.000
+0.292,0.003,0.000
+0.298,0.003,0.000
+0.304,0.003,0.000
+0.310,0.003,0.000
+0.316,0.003,0.000
+0.322,0.003,0.000
+0.328,0.003,0.000
+0.334,0.004,0.000
+0.341,0.004,0.000
+0.347,0.004,0.000
+0.353,0.004,0.000
+0.359,0.004,0.000
+0.365,0.004,0.000
+0.371,0.005,0.000
+0.378,0.005,0.000
+0.384,0.005,0.000
+0.390,0.005,0.000
+0.396,0.005,0.000
+0.403,0.005,0.000
+0.409,0.006,0.000
+0.415,0.006,0.000
+0.422,0.006,0.000
+0.428,0.006,0.000
+0.434,0.007,0.000
+0.441,0.007,0.000
+0.447,0.007,0.000
+0.453,0.007,0.000
+0.460,0.007,0.000
+0.466,0.008,0.000
+0.473,0.008,0.000
+0.479,0.008,0.000
+0.486,0.009,0.000
+0.492,0.009,0.000
+0.499,0.009,0.000
+0.505,0.009,0.000
+0.512,0.010,0.000
+0.518,0.010,0.000
+0.525,0.010,0.000
+0.532,0.011,0.000
+0.538,0.011,0.000
+0.545,0.011,0.000
+0.552,0.012,0.000
+0.558,0.012,0.000
+0.565,0.013,0.000
+0.572,0.013,0.000
+0.578,0.013,0.000
+0.585,0.014,0.000
+0.592,0.014,0.000
+0.598,0.015,0.000
+0.605,0.015,0.000
+0.612,0.015,0.000
+0.619,0.016,0.000
+0.625,0.016,0.000
+0.632,0.017,0.000
+0.639,0.017,0.000
+0.646,0.018,0.000
+0.653,0.018,0.000
+0.660,0.019,0.000
+0.666,0.020,0.000
+0.673,0.020,0.000
+0.680,0.021,0.000
+0.687,0.021,0.000
+0.694,0.022,0.000
+0.701,0.023,0.000
+0.708,0.023,0.000
+0.715,0.024,0.000
+0.722,0.025,0.000
+0.729,0.026,0.000
+0.736,0.026,0.000
+0.743,0.027,0.000
+0.750,0.028,0.000
+0.757,0.029,0.000
+0.764,0.030,0.000
+0.771,0.031,0.000
+0.778,0.032,0.000
+0.785,0.033,0.000
+0.792,0.034,0.000
+0.799,0.035,0.000
+0.806,0.036,0.000
+0.813,0.037,0.000
+0.820,0.038,0.000
+0.827,0.040,0.000
+0.834,0.041,0.000
+0.841,0.043,0.000
+0.848,0.044,0.000
+0.855,0.046,0.000
+0.863,0.048,0.000
+0.870,0.050,0.000
+0.877,0.052,0.000
+0.884,0.054,0.000
+0.891,0.056,0.000
+0.898,0.059,0.000
+0.905,0.062,0.000
+0.911,0.065,0.000
+0.918,0.069,0.000
+0.924,0.075,0.000
+0.931,0.081,0.000
+0.936,0.089,0.000
+0.942,0.097,0.000
+0.947,0.107,0.000
+0.952,0.117,0.000
+0.957,0.127,0.000
+0.961,0.138,0.000
+0.965,0.150,0.000
+0.968,0.161,0.000
+0.971,0.173,0.000
+0.974,0.185,0.000
+0.977,0.197,0.000
+0.979,0.208,0.000
+0.981,0.220,0.000
+0.983,0.232,0.000
+0.985,0.243,0.000
+0.987,0.254,0.000
+0.988,0.265,0.000
+0.989,0.276,0.000
+0.991,0.287,0.000
+0.992,0.297,0.000
+0.993,0.308,0.000
+0.993,0.318,0.000
+0.994,0.328,0.000
+0.995,0.338,0.000
+0.996,0.347,0.000
+0.996,0.357,0.000
+0.997,0.366,0.000
+0.997,0.376,0.000
+0.998,0.385,0.000
+0.998,0.394,0.000
+0.998,0.403,0.000
+0.999,0.411,0.000
+0.999,0.420,0.000
+0.999,0.429,0.000
+0.999,0.437,0.000
+1.000,0.446,0.000
+1.000,0.454,0.000
+1.000,0.462,0.000
+1.000,0.470,0.000
+1.000,0.478,0.000
+1.000,0.486,0.000
+1.000,0.494,0.000
+1.000,0.502,0.000
+1.000,0.510,0.000
+1.000,0.518,0.000
+1.000,0.525,0.000
+1.000,0.533,0.000
+1.000,0.540,0.000
+1.000,0.548,0.000
+1.000,0.555,0.000
+1.000,0.562,0.001
+1.000,0.570,0.001
+1.000,0.577,0.001
+1.000,0.584,0.001
+1.000,0.591,0.001
+1.000,0.598,0.002
+1.000,0.605,0.002
+1.000,0.612,0.002
+1.000,0.619,0.003
+1.000,0.626,0.003
+1.000,0.633,0.003
+1.000,0.640,0.004
+1.000,0.647,0.004
+1.000,0.653,0.004
+1.000,0.660,0.005
+1.000,0.667,0.005
+1.000,0.673,0.006
+1.000,0.680,0.006
+1.000,0.687,0.007
+1.000,0.693,0.007
+1.000,0.700,0.008
+1.000,0.706,0.009
+1.000,0.713,0.009
+1.000,0.719,0.010
+1.000,0.726,0.011
+1.000,0.732,0.012
+1.000,0.739,0.012
+1.000,0.745,0.013
+1.000,0.751,0.014
+1.000,0.758,0.015
+1.000,0.764,0.016
+1.000,0.770,0.017
+1.000,0.777,0.018
+1.000,0.783,0.019
+1.000,0.789,0.020
+1.000,0.796,0.021
+1.000,0.802,0.023
+1.000,0.808,0.024
+1.000,0.814,0.025
+1.000,0.820,0.027
+1.000,0.827,0.028
+1.000,0.833,0.030
+1.000,0.839,0.032
+1.000,0.845,0.033
+1.000,0.851,0.035
+1.000,0.857,0.037
+1.000,0.863,0.040
+1.000,0.869,0.042
+1.000,0.876,0.044
+1.000,0.882,0.047
+1.000,0.888,0.050
+1.000,0.894,0.053
+1.000,0.900,0.056
+1.000,0.906,0.060
+1.000,0.912,0.064
+1.000,0.918,0.069
+1.000,0.924,0.074
+1.000,0.930,0.081
+1.000,0.936,0.091
+1.000,0.942,0.104
+1.000,0.948,0.121
+1.000,0.953,0.141
+1.000,0.959,0.167
+1.000,0.965,0.198
+1.000,0.970,0.235
+1.000,0.975,0.279
+1.000,0.980,0.329
+1.000,0.984,0.386
+1.000,0.988,0.449
+1.000,0.991,0.517
+1.000,0.994,0.588
+1.000,0.996,0.660
+1.000,0.998,0.732
+1.000,0.999,0.803
+1.000,1.000,0.871
+1.000,1.000,0.937
+1.000,1.000,1.000
diff --git a/pyqtgraph/colors/maps/CET-L4.csv b/pyqtgraph/colors/maps/CET-L4.csv
new file mode 100644
index 00000000..035a9ff2
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-L4.csv
@@ -0,0 +1,256 @@
+0.000,0.000,0.000
+0.026,0.000,0.000
+0.051,0.000,0.000
+0.070,0.000,0.000
+0.085,0.000,0.000
+0.099,0.000,0.000
+0.111,0.000,0.000
+0.122,0.000,0.000
+0.132,0.000,0.000
+0.142,0.001,0.000
+0.150,0.001,0.000
+0.159,0.001,0.000
+0.166,0.001,0.000
+0.174,0.001,0.000
+0.181,0.001,0.000
+0.188,0.001,0.000
+0.195,0.001,0.000
+0.201,0.001,0.000
+0.207,0.001,0.000
+0.213,0.001,0.000
+0.219,0.002,0.000
+0.224,0.002,0.000
+0.230,0.002,0.000
+0.236,0.002,0.000
+0.241,0.002,0.000
+0.247,0.002,0.000
+0.253,0.002,0.000
+0.258,0.002,0.000
+0.264,0.002,0.000
+0.270,0.002,0.000
+0.275,0.002,0.000
+0.281,0.002,0.000
+0.287,0.003,0.000
+0.293,0.003,0.000
+0.298,0.003,0.000
+0.304,0.003,0.000
+0.310,0.003,0.000
+0.316,0.003,0.000
+0.322,0.003,0.000
+0.328,0.003,0.000
+0.334,0.004,0.000
+0.339,0.004,0.000
+0.345,0.004,0.000
+0.351,0.004,0.000
+0.357,0.004,0.000
+0.363,0.004,0.000
+0.369,0.004,0.000
+0.375,0.005,0.000
+0.381,0.005,0.000
+0.387,0.005,0.000
+0.394,0.005,0.000
+0.400,0.005,0.000
+0.406,0.006,0.000
+0.412,0.006,0.000
+0.418,0.006,0.000
+0.424,0.006,0.000
+0.430,0.006,0.000
+0.437,0.007,0.000
+0.443,0.007,0.000
+0.449,0.007,0.000
+0.455,0.007,0.000
+0.461,0.008,0.000
+0.468,0.008,0.000
+0.474,0.008,0.000
+0.480,0.008,0.000
+0.487,0.009,0.000
+0.493,0.009,0.000
+0.499,0.009,0.000
+0.506,0.009,0.000
+0.512,0.010,0.000
+0.518,0.010,0.000
+0.525,0.010,0.000
+0.531,0.011,0.000
+0.538,0.011,0.000
+0.544,0.011,0.000
+0.551,0.012,0.000
+0.557,0.012,0.000
+0.563,0.012,0.000
+0.570,0.013,0.000
+0.576,0.013,0.000
+0.583,0.014,0.000
+0.589,0.014,0.000
+0.596,0.014,0.000
+0.603,0.015,0.000
+0.609,0.015,0.000
+0.616,0.016,0.000
+0.622,0.016,0.000
+0.629,0.017,0.000
+0.635,0.017,0.000
+0.642,0.018,0.000
+0.649,0.018,0.000
+0.655,0.019,0.000
+0.662,0.019,0.000
+0.669,0.020,0.000
+0.675,0.020,0.000
+0.682,0.021,0.000
+0.689,0.022,0.000
+0.695,0.022,0.000
+0.702,0.023,0.000
+0.709,0.024,0.000
+0.716,0.024,0.000
+0.722,0.025,0.000
+0.729,0.026,0.000
+0.736,0.026,0.000
+0.743,0.027,0.000
+0.750,0.028,0.000
+0.756,0.029,0.000
+0.763,0.030,0.000
+0.770,0.031,0.000
+0.777,0.032,0.000
+0.784,0.033,0.000
+0.790,0.034,0.000
+0.797,0.035,0.000
+0.804,0.036,0.000
+0.811,0.037,0.000
+0.818,0.038,0.000
+0.825,0.039,0.000
+0.832,0.041,0.000
+0.839,0.042,0.000
+0.845,0.044,0.000
+0.852,0.045,0.000
+0.859,0.047,0.000
+0.866,0.049,0.000
+0.873,0.050,0.000
+0.880,0.052,0.000
+0.887,0.055,0.000
+0.893,0.057,0.000
+0.900,0.060,0.000
+0.907,0.063,0.000
+0.913,0.066,0.000
+0.920,0.071,0.000
+0.926,0.076,0.000
+0.932,0.084,0.000
+0.937,0.093,0.000
+0.942,0.104,0.000
+0.946,0.115,0.000
+0.950,0.128,0.000
+0.953,0.140,0.000
+0.956,0.153,0.000
+0.959,0.166,0.000
+0.961,0.179,0.000
+0.963,0.191,0.000
+0.965,0.203,0.000
+0.967,0.215,0.000
+0.969,0.227,0.000
+0.970,0.238,0.000
+0.972,0.249,0.000
+0.973,0.260,0.000
+0.974,0.270,0.000
+0.975,0.281,0.000
+0.976,0.291,0.000
+0.977,0.301,0.000
+0.978,0.311,0.000
+0.979,0.320,0.000
+0.980,0.330,0.000
+0.981,0.339,0.000
+0.982,0.348,0.000
+0.982,0.357,0.000
+0.983,0.366,0.000
+0.984,0.375,0.000
+0.984,0.383,0.000
+0.985,0.392,0.000
+0.985,0.400,0.000
+0.986,0.408,0.000
+0.986,0.416,0.000
+0.987,0.425,0.000
+0.987,0.433,0.000
+0.988,0.440,0.000
+0.988,0.448,0.000
+0.989,0.456,0.000
+0.989,0.464,0.000
+0.989,0.471,0.000
+0.990,0.479,0.000
+0.990,0.486,0.000
+0.991,0.494,0.000
+0.991,0.501,0.000
+0.991,0.508,0.000
+0.991,0.515,0.000
+0.992,0.523,0.000
+0.992,0.530,0.000
+0.992,0.537,0.000
+0.993,0.544,0.000
+0.993,0.551,0.000
+0.993,0.558,0.000
+0.993,0.565,0.000
+0.994,0.571,0.000
+0.994,0.578,0.000
+0.994,0.585,0.000
+0.994,0.592,0.000
+0.995,0.598,0.000
+0.995,0.605,0.000
+0.995,0.612,0.000
+0.995,0.618,0.000
+0.995,0.625,0.000
+0.996,0.632,0.000
+0.996,0.638,0.000
+0.996,0.645,0.000
+0.996,0.651,0.000
+0.996,0.657,0.000
+0.996,0.664,0.000
+0.997,0.670,0.000
+0.997,0.677,0.000
+0.997,0.683,0.000
+0.997,0.689,0.000
+0.997,0.696,0.000
+0.997,0.702,0.000
+0.997,0.708,0.000
+0.997,0.714,0.000
+0.998,0.721,0.000
+0.998,0.727,0.000
+0.998,0.733,0.000
+0.998,0.739,0.000
+0.998,0.745,0.000
+0.998,0.752,0.000
+0.998,0.758,0.000
+0.998,0.764,0.000
+0.998,0.770,0.000
+0.999,0.776,0.000
+0.999,0.782,0.000
+0.999,0.788,0.000
+0.999,0.794,0.000
+0.999,0.800,0.000
+0.999,0.806,0.000
+0.999,0.812,0.000
+0.999,0.818,0.000
+0.999,0.824,0.000
+0.999,0.830,0.000
+0.999,0.836,0.000
+0.999,0.842,0.000
+0.999,0.848,0.000
+0.999,0.854,0.000
+0.999,0.860,0.000
+1.000,0.866,0.000
+1.000,0.872,0.000
+1.000,0.878,0.000
+1.000,0.884,0.000
+1.000,0.890,0.000
+1.000,0.895,0.000
+1.000,0.901,0.000
+1.000,0.907,0.000
+1.000,0.913,0.000
+1.000,0.919,0.000
+1.000,0.925,0.000
+1.000,0.930,0.000
+1.000,0.936,0.000
+1.000,0.942,0.000
+1.000,0.948,0.000
+1.000,0.954,0.000
+1.000,0.960,0.000
+1.000,0.965,0.000
+1.000,0.971,0.000
+1.000,0.977,0.000
+1.000,0.983,0.000
+1.000,0.988,0.000
+1.000,0.994,0.000
+1.000,1.000,0.000
diff --git a/pyqtgraph/colors/maps/CET-L5.csv b/pyqtgraph/colors/maps/CET-L5.csv
new file mode 100644
index 00000000..cd07fae9
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-L5.csv
@@ -0,0 +1,256 @@
+0.002,0.083,0.022
+0.004,0.086,0.022
+0.007,0.090,0.022
+0.009,0.093,0.022
+0.012,0.096,0.022
+0.014,0.100,0.022
+0.017,0.103,0.022
+0.019,0.106,0.022
+0.022,0.109,0.022
+0.024,0.112,0.022
+0.026,0.115,0.022
+0.028,0.118,0.022
+0.030,0.121,0.022
+0.032,0.124,0.022
+0.033,0.127,0.022
+0.034,0.130,0.022
+0.036,0.133,0.022
+0.036,0.136,0.022
+0.037,0.140,0.021
+0.037,0.143,0.021
+0.037,0.146,0.021
+0.037,0.150,0.021
+0.037,0.153,0.021
+0.036,0.156,0.021
+0.036,0.160,0.021
+0.036,0.163,0.020
+0.035,0.167,0.020
+0.035,0.170,0.020
+0.035,0.173,0.020
+0.034,0.177,0.020
+0.034,0.180,0.020
+0.034,0.184,0.019
+0.033,0.187,0.019
+0.033,0.191,0.019
+0.033,0.194,0.019
+0.033,0.197,0.019
+0.033,0.201,0.019
+0.033,0.204,0.019
+0.033,0.208,0.019
+0.034,0.211,0.018
+0.034,0.215,0.018
+0.035,0.218,0.018
+0.036,0.222,0.019
+0.037,0.225,0.019
+0.038,0.228,0.019
+0.039,0.232,0.019
+0.040,0.235,0.019
+0.041,0.239,0.019
+0.042,0.242,0.019
+0.043,0.246,0.019
+0.044,0.249,0.019
+0.045,0.253,0.019
+0.046,0.256,0.019
+0.047,0.260,0.020
+0.048,0.263,0.020
+0.049,0.267,0.020
+0.050,0.270,0.020
+0.051,0.274,0.020
+0.052,0.277,0.020
+0.053,0.281,0.020
+0.054,0.284,0.020
+0.055,0.288,0.020
+0.057,0.292,0.020
+0.058,0.295,0.020
+0.059,0.299,0.020
+0.060,0.302,0.020
+0.061,0.306,0.020
+0.062,0.310,0.020
+0.063,0.313,0.020
+0.064,0.317,0.021
+0.065,0.320,0.021
+0.066,0.324,0.021
+0.067,0.328,0.022
+0.068,0.331,0.022
+0.069,0.335,0.022
+0.070,0.339,0.023
+0.070,0.342,0.023
+0.071,0.346,0.023
+0.072,0.350,0.024
+0.073,0.353,0.024
+0.074,0.357,0.024
+0.075,0.361,0.025
+0.076,0.365,0.025
+0.077,0.368,0.025
+0.078,0.372,0.026
+0.079,0.376,0.026
+0.080,0.380,0.026
+0.081,0.383,0.027
+0.082,0.387,0.027
+0.083,0.391,0.028
+0.084,0.395,0.028
+0.085,0.398,0.028
+0.086,0.402,0.029
+0.087,0.406,0.029
+0.088,0.410,0.030
+0.089,0.413,0.030
+0.090,0.417,0.030
+0.091,0.421,0.031
+0.092,0.425,0.031
+0.093,0.429,0.032
+0.094,0.433,0.032
+0.095,0.436,0.032
+0.096,0.440,0.033
+0.097,0.444,0.033
+0.098,0.448,0.034
+0.099,0.452,0.034
+0.100,0.456,0.034
+0.101,0.460,0.035
+0.102,0.463,0.036
+0.103,0.467,0.036
+0.104,0.471,0.036
+0.105,0.475,0.037
+0.106,0.479,0.037
+0.107,0.483,0.038
+0.108,0.487,0.038
+0.109,0.491,0.039
+0.110,0.495,0.039
+0.111,0.499,0.039
+0.112,0.503,0.040
+0.113,0.506,0.040
+0.114,0.510,0.041
+0.115,0.514,0.041
+0.116,0.518,0.042
+0.117,0.522,0.042
+0.118,0.526,0.043
+0.119,0.530,0.043
+0.120,0.534,0.044
+0.121,0.538,0.044
+0.122,0.542,0.045
+0.123,0.546,0.045
+0.124,0.550,0.045
+0.125,0.554,0.046
+0.126,0.558,0.046
+0.127,0.562,0.047
+0.128,0.566,0.047
+0.129,0.570,0.048
+0.130,0.574,0.048
+0.131,0.578,0.049
+0.132,0.582,0.049
+0.133,0.586,0.050
+0.134,0.590,0.050
+0.135,0.595,0.050
+0.136,0.599,0.051
+0.137,0.603,0.051
+0.138,0.607,0.052
+0.139,0.611,0.052
+0.140,0.615,0.053
+0.141,0.619,0.053
+0.142,0.623,0.054
+0.143,0.627,0.054
+0.144,0.631,0.054
+0.145,0.635,0.055
+0.146,0.639,0.055
+0.147,0.644,0.056
+0.148,0.648,0.056
+0.149,0.652,0.057
+0.150,0.656,0.057
+0.151,0.660,0.058
+0.152,0.664,0.058
+0.153,0.668,0.059
+0.155,0.673,0.059
+0.156,0.677,0.060
+0.157,0.681,0.060
+0.158,0.685,0.060
+0.159,0.689,0.061
+0.160,0.693,0.061
+0.161,0.698,0.062
+0.162,0.702,0.062
+0.163,0.706,0.063
+0.164,0.710,0.063
+0.165,0.714,0.064
+0.166,0.719,0.064
+0.167,0.723,0.064
+0.168,0.727,0.065
+0.169,0.731,0.065
+0.170,0.735,0.066
+0.171,0.740,0.066
+0.172,0.744,0.067
+0.173,0.748,0.067
+0.174,0.752,0.068
+0.175,0.757,0.068
+0.177,0.761,0.069
+0.178,0.765,0.069
+0.179,0.769,0.070
+0.180,0.774,0.070
+0.181,0.778,0.070
+0.182,0.782,0.071
+0.183,0.786,0.071
+0.184,0.791,0.072
+0.185,0.795,0.072
+0.186,0.799,0.073
+0.187,0.803,0.073
+0.188,0.808,0.074
+0.189,0.812,0.074
+0.190,0.816,0.074
+0.191,0.821,0.075
+0.193,0.825,0.075
+0.194,0.829,0.076
+0.195,0.834,0.076
+0.196,0.838,0.077
+0.197,0.842,0.077
+0.198,0.847,0.077
+0.199,0.851,0.078
+0.200,0.855,0.078
+0.201,0.860,0.079
+0.202,0.864,0.079
+0.203,0.868,0.080
+0.204,0.873,0.080
+0.205,0.877,0.081
+0.206,0.881,0.081
+0.208,0.886,0.082
+0.209,0.890,0.082
+0.210,0.895,0.082
+0.212,0.899,0.083
+0.216,0.903,0.083
+0.222,0.907,0.084
+0.231,0.911,0.084
+0.242,0.915,0.084
+0.254,0.919,0.084
+0.267,0.923,0.084
+0.281,0.926,0.085
+0.296,0.930,0.085
+0.311,0.933,0.085
+0.327,0.936,0.085
+0.343,0.940,0.085
+0.359,0.943,0.085
+0.375,0.946,0.085
+0.392,0.949,0.085
+0.408,0.952,0.084
+0.425,0.955,0.084
+0.441,0.958,0.084
+0.458,0.960,0.084
+0.474,0.963,0.084
+0.491,0.966,0.084
+0.507,0.968,0.084
+0.524,0.971,0.083
+0.540,0.973,0.083
+0.557,0.976,0.083
+0.573,0.978,0.083
+0.589,0.980,0.083
+0.606,0.982,0.083
+0.622,0.985,0.082
+0.638,0.987,0.082
+0.655,0.989,0.082
+0.671,0.991,0.082
+0.687,0.993,0.082
+0.703,0.995,0.082
+0.719,0.996,0.082
+0.735,0.998,0.082
+0.751,1.000,0.081
+0.767,1.000,0.081
+0.783,1.000,0.081
+0.800,1.000,0.081
+0.816,1.000,0.081
+0.832,1.000,0.081
+0.848,1.000,0.081
diff --git a/pyqtgraph/colors/maps/CET-L6.csv b/pyqtgraph/colors/maps/CET-L6.csv
new file mode 100644
index 00000000..961b35db
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-L6.csv
@@ -0,0 +1,256 @@
+0.000,0.002,0.307
+0.000,0.004,0.314
+0.000,0.006,0.322
+0.000,0.008,0.330
+0.000,0.009,0.337
+0.000,0.010,0.345
+0.000,0.011,0.352
+0.000,0.011,0.360
+0.000,0.011,0.368
+0.002,0.011,0.376
+0.004,0.011,0.384
+0.007,0.010,0.392
+0.009,0.010,0.400
+0.012,0.010,0.407
+0.015,0.010,0.416
+0.018,0.009,0.424
+0.021,0.009,0.432
+0.024,0.009,0.440
+0.026,0.009,0.448
+0.029,0.008,0.456
+0.032,0.008,0.464
+0.036,0.008,0.473
+0.039,0.007,0.481
+0.041,0.007,0.489
+0.044,0.007,0.498
+0.047,0.007,0.506
+0.049,0.006,0.514
+0.052,0.006,0.523
+0.054,0.006,0.531
+0.056,0.006,0.540
+0.057,0.006,0.549
+0.059,0.005,0.557
+0.061,0.005,0.566
+0.062,0.005,0.575
+0.063,0.005,0.583
+0.064,0.005,0.592
+0.064,0.006,0.601
+0.064,0.006,0.610
+0.064,0.006,0.619
+0.063,0.007,0.628
+0.062,0.007,0.637
+0.060,0.008,0.646
+0.058,0.009,0.656
+0.055,0.010,0.665
+0.052,0.011,0.674
+0.049,0.013,0.683
+0.046,0.014,0.692
+0.043,0.016,0.701
+0.040,0.017,0.710
+0.038,0.019,0.719
+0.036,0.021,0.727
+0.033,0.024,0.736
+0.032,0.026,0.744
+0.031,0.029,0.753
+0.030,0.031,0.761
+0.029,0.034,0.769
+0.029,0.038,0.777
+0.030,0.041,0.785
+0.031,0.044,0.793
+0.032,0.048,0.801
+0.034,0.051,0.808
+0.037,0.055,0.816
+0.040,0.058,0.823
+0.043,0.062,0.831
+0.047,0.065,0.838
+0.052,0.069,0.845
+0.056,0.072,0.852
+0.061,0.076,0.859
+0.066,0.080,0.866
+0.071,0.084,0.873
+0.076,0.087,0.879
+0.082,0.091,0.886
+0.087,0.095,0.892
+0.092,0.099,0.898
+0.097,0.104,0.904
+0.102,0.108,0.910
+0.107,0.113,0.915
+0.111,0.118,0.920
+0.116,0.123,0.925
+0.120,0.128,0.930
+0.124,0.134,0.935
+0.128,0.139,0.939
+0.132,0.145,0.944
+0.135,0.151,0.948
+0.139,0.157,0.951
+0.142,0.163,0.955
+0.146,0.169,0.958
+0.149,0.175,0.962
+0.152,0.181,0.964
+0.155,0.187,0.967
+0.158,0.194,0.970
+0.160,0.200,0.972
+0.163,0.206,0.974
+0.165,0.213,0.976
+0.168,0.220,0.977
+0.170,0.226,0.979
+0.172,0.233,0.980
+0.174,0.239,0.981
+0.175,0.246,0.982
+0.177,0.253,0.982
+0.178,0.260,0.983
+0.179,0.266,0.983
+0.180,0.273,0.984
+0.181,0.280,0.984
+0.182,0.286,0.984
+0.183,0.292,0.985
+0.184,0.299,0.985
+0.185,0.305,0.985
+0.185,0.311,0.986
+0.186,0.317,0.986
+0.186,0.323,0.987
+0.186,0.329,0.987
+0.187,0.335,0.987
+0.187,0.341,0.988
+0.187,0.347,0.988
+0.187,0.353,0.988
+0.187,0.359,0.989
+0.186,0.365,0.989
+0.186,0.371,0.989
+0.186,0.376,0.990
+0.185,0.382,0.990
+0.184,0.388,0.990
+0.184,0.393,0.991
+0.183,0.399,0.991
+0.182,0.405,0.991
+0.181,0.410,0.992
+0.180,0.416,0.992
+0.178,0.421,0.992
+0.177,0.427,0.993
+0.176,0.432,0.993
+0.175,0.438,0.993
+0.174,0.443,0.994
+0.173,0.449,0.994
+0.172,0.454,0.994
+0.171,0.459,0.994
+0.171,0.465,0.994
+0.170,0.470,0.995
+0.170,0.475,0.995
+0.170,0.480,0.995
+0.170,0.486,0.995
+0.170,0.491,0.995
+0.171,0.496,0.995
+0.171,0.501,0.995
+0.172,0.506,0.995
+0.173,0.511,0.995
+0.174,0.516,0.995
+0.175,0.521,0.995
+0.176,0.526,0.995
+0.178,0.531,0.995
+0.179,0.536,0.995
+0.181,0.541,0.995
+0.183,0.546,0.995
+0.185,0.551,0.995
+0.187,0.556,0.994
+0.189,0.561,0.994
+0.192,0.566,0.994
+0.194,0.571,0.994
+0.197,0.575,0.993
+0.199,0.580,0.993
+0.201,0.585,0.993
+0.203,0.590,0.993
+0.205,0.595,0.993
+0.206,0.600,0.992
+0.207,0.605,0.992
+0.208,0.610,0.992
+0.209,0.615,0.992
+0.210,0.620,0.992
+0.211,0.624,0.991
+0.211,0.629,0.991
+0.211,0.634,0.991
+0.211,0.639,0.991
+0.211,0.644,0.991
+0.211,0.649,0.991
+0.210,0.654,0.990
+0.210,0.659,0.990
+0.209,0.664,0.990
+0.208,0.669,0.990
+0.206,0.674,0.990
+0.205,0.679,0.990
+0.203,0.684,0.990
+0.201,0.689,0.990
+0.199,0.694,0.989
+0.197,0.699,0.989
+0.194,0.704,0.989
+0.191,0.709,0.989
+0.188,0.714,0.989
+0.185,0.719,0.989
+0.182,0.724,0.989
+0.179,0.729,0.989
+0.177,0.734,0.989
+0.174,0.739,0.988
+0.172,0.744,0.988
+0.170,0.749,0.988
+0.168,0.754,0.988
+0.166,0.759,0.988
+0.165,0.764,0.987
+0.163,0.769,0.987
+0.162,0.774,0.987
+0.161,0.778,0.987
+0.160,0.783,0.987
+0.160,0.788,0.986
+0.160,0.793,0.986
+0.160,0.798,0.986
+0.160,0.803,0.985
+0.161,0.807,0.985
+0.161,0.812,0.985
+0.162,0.817,0.984
+0.164,0.822,0.984
+0.165,0.827,0.984
+0.167,0.831,0.983
+0.169,0.836,0.983
+0.171,0.841,0.982
+0.174,0.845,0.982
+0.177,0.850,0.982
+0.183,0.855,0.981
+0.190,0.859,0.981
+0.199,0.864,0.980
+0.210,0.868,0.980
+0.221,0.872,0.979
+0.233,0.876,0.979
+0.246,0.880,0.979
+0.260,0.884,0.978
+0.273,0.888,0.978
+0.287,0.892,0.977
+0.301,0.896,0.977
+0.314,0.900,0.976
+0.328,0.904,0.976
+0.342,0.907,0.976
+0.356,0.911,0.975
+0.370,0.915,0.975
+0.384,0.918,0.974
+0.397,0.922,0.974
+0.411,0.925,0.973
+0.424,0.929,0.973
+0.438,0.932,0.973
+0.451,0.936,0.972
+0.464,0.939,0.972
+0.478,0.943,0.971
+0.491,0.946,0.971
+0.504,0.949,0.970
+0.517,0.953,0.970
+0.529,0.956,0.969
+0.542,0.959,0.969
+0.555,0.962,0.968
+0.568,0.966,0.968
+0.580,0.969,0.968
+0.593,0.972,0.967
+0.605,0.975,0.967
+0.618,0.978,0.966
+0.630,0.981,0.966
+0.642,0.984,0.965
+0.654,0.987,0.965
+0.667,0.990,0.964
+0.679,0.993,0.964
+0.691,0.996,0.963
+0.703,0.999,0.963
diff --git a/pyqtgraph/colors/maps/CET-L7.csv b/pyqtgraph/colors/maps/CET-L7.csv
new file mode 100644
index 00000000..023f95e9
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-L7.csv
@@ -0,0 +1,256 @@
+0.000,0.008,0.296
+0.000,0.010,0.303
+0.000,0.012,0.311
+0.000,0.014,0.319
+0.000,0.016,0.327
+0.000,0.017,0.335
+0.000,0.018,0.343
+0.000,0.019,0.351
+0.000,0.019,0.359
+0.000,0.020,0.368
+0.000,0.020,0.376
+0.000,0.020,0.384
+0.000,0.020,0.392
+0.000,0.020,0.401
+0.001,0.020,0.409
+0.002,0.020,0.417
+0.003,0.020,0.426
+0.005,0.021,0.434
+0.006,0.021,0.442
+0.007,0.021,0.451
+0.008,0.021,0.459
+0.009,0.021,0.468
+0.010,0.021,0.476
+0.012,0.021,0.485
+0.013,0.021,0.493
+0.014,0.021,0.502
+0.015,0.021,0.511
+0.016,0.021,0.519
+0.017,0.022,0.528
+0.018,0.022,0.537
+0.019,0.022,0.546
+0.020,0.022,0.554
+0.021,0.022,0.563
+0.022,0.022,0.572
+0.022,0.023,0.581
+0.023,0.023,0.590
+0.023,0.023,0.599
+0.023,0.024,0.607
+0.023,0.024,0.616
+0.023,0.024,0.625
+0.023,0.025,0.634
+0.022,0.025,0.643
+0.021,0.026,0.652
+0.020,0.027,0.661
+0.019,0.028,0.670
+0.018,0.029,0.679
+0.018,0.030,0.688
+0.018,0.031,0.697
+0.019,0.032,0.706
+0.020,0.033,0.714
+0.021,0.035,0.723
+0.023,0.036,0.731
+0.025,0.038,0.740
+0.029,0.039,0.748
+0.032,0.041,0.756
+0.037,0.043,0.764
+0.041,0.044,0.772
+0.046,0.046,0.780
+0.052,0.048,0.788
+0.057,0.050,0.796
+0.063,0.052,0.804
+0.069,0.054,0.811
+0.075,0.056,0.819
+0.081,0.058,0.826
+0.087,0.060,0.833
+0.094,0.063,0.841
+0.100,0.065,0.848
+0.106,0.067,0.855
+0.113,0.070,0.862
+0.119,0.072,0.869
+0.126,0.075,0.876
+0.133,0.077,0.882
+0.140,0.079,0.889
+0.148,0.082,0.895
+0.156,0.084,0.901
+0.165,0.086,0.907
+0.174,0.088,0.913
+0.184,0.090,0.919
+0.194,0.092,0.924
+0.204,0.094,0.929
+0.214,0.095,0.934
+0.225,0.097,0.939
+0.236,0.098,0.943
+0.247,0.099,0.947
+0.258,0.101,0.951
+0.269,0.102,0.955
+0.281,0.103,0.959
+0.292,0.104,0.962
+0.304,0.105,0.966
+0.316,0.106,0.969
+0.327,0.107,0.971
+0.339,0.107,0.974
+0.351,0.108,0.976
+0.363,0.109,0.979
+0.375,0.109,0.980
+0.387,0.110,0.982
+0.399,0.110,0.984
+0.411,0.110,0.985
+0.423,0.111,0.986
+0.435,0.111,0.987
+0.447,0.111,0.988
+0.458,0.111,0.988
+0.470,0.111,0.989
+0.481,0.111,0.989
+0.493,0.111,0.990
+0.504,0.111,0.991
+0.515,0.111,0.991
+0.525,0.111,0.992
+0.536,0.112,0.992
+0.547,0.112,0.993
+0.557,0.112,0.993
+0.568,0.112,0.993
+0.578,0.112,0.994
+0.588,0.112,0.994
+0.598,0.112,0.994
+0.608,0.112,0.995
+0.618,0.112,0.995
+0.628,0.112,0.995
+0.638,0.112,0.995
+0.648,0.112,0.996
+0.657,0.112,0.996
+0.667,0.112,0.996
+0.677,0.112,0.996
+0.686,0.112,0.996
+0.696,0.112,0.996
+0.705,0.112,0.996
+0.715,0.112,0.996
+0.724,0.112,0.996
+0.733,0.112,0.996
+0.742,0.112,0.996
+0.751,0.113,0.996
+0.760,0.114,0.996
+0.769,0.115,0.996
+0.777,0.117,0.996
+0.785,0.119,0.996
+0.793,0.122,0.996
+0.801,0.125,0.996
+0.809,0.128,0.996
+0.816,0.132,0.996
+0.823,0.136,0.996
+0.831,0.140,0.996
+0.838,0.145,0.996
+0.845,0.149,0.996
+0.851,0.154,0.996
+0.858,0.160,0.996
+0.864,0.165,0.996
+0.871,0.171,0.996
+0.877,0.176,0.996
+0.883,0.182,0.996
+0.888,0.188,0.996
+0.894,0.195,0.996
+0.900,0.201,0.996
+0.905,0.208,0.996
+0.910,0.214,0.996
+0.915,0.221,0.996
+0.920,0.228,0.996
+0.925,0.234,0.996
+0.930,0.241,0.996
+0.934,0.249,0.996
+0.939,0.256,0.996
+0.943,0.263,0.997
+0.947,0.270,0.997
+0.951,0.278,0.997
+0.955,0.285,0.997
+0.958,0.293,0.996
+0.961,0.301,0.996
+0.965,0.308,0.996
+0.968,0.316,0.996
+0.971,0.324,0.996
+0.973,0.332,0.996
+0.976,0.340,0.996
+0.978,0.348,0.996
+0.981,0.356,0.996
+0.983,0.364,0.996
+0.985,0.372,0.995
+0.987,0.381,0.995
+0.988,0.389,0.995
+0.990,0.397,0.995
+0.991,0.405,0.995
+0.992,0.414,0.994
+0.993,0.422,0.994
+0.994,0.430,0.994
+0.994,0.439,0.994
+0.995,0.447,0.993
+0.995,0.456,0.993
+0.995,0.464,0.993
+0.995,0.472,0.992
+0.996,0.481,0.992
+0.996,0.489,0.992
+0.996,0.497,0.992
+0.996,0.504,0.991
+0.996,0.512,0.991
+0.996,0.520,0.991
+0.996,0.527,0.991
+0.996,0.535,0.991
+0.996,0.542,0.991
+0.997,0.550,0.991
+0.997,0.557,0.991
+0.997,0.564,0.991
+0.997,0.572,0.991
+0.997,0.579,0.991
+0.997,0.586,0.991
+0.997,0.593,0.991
+0.997,0.600,0.991
+0.997,0.607,0.991
+0.997,0.614,0.991
+0.997,0.620,0.991
+0.997,0.627,0.991
+0.997,0.634,0.992
+0.997,0.641,0.992
+0.997,0.647,0.992
+0.997,0.654,0.992
+0.997,0.660,0.993
+0.997,0.667,0.993
+0.997,0.673,0.993
+0.997,0.680,0.994
+0.997,0.686,0.994
+0.997,0.693,0.994
+0.997,0.699,0.995
+0.997,0.705,0.995
+0.997,0.712,0.995
+0.997,0.718,0.995
+0.997,0.724,0.995
+0.998,0.730,0.996
+0.998,0.736,0.996
+0.998,0.743,0.996
+0.998,0.749,0.996
+0.998,0.755,0.996
+0.998,0.761,0.996
+0.998,0.767,0.997
+0.998,0.773,0.997
+0.998,0.779,0.997
+0.998,0.785,0.997
+0.998,0.791,0.997
+0.998,0.797,0.997
+0.998,0.803,0.997
+0.999,0.809,0.997
+0.999,0.815,0.997
+0.999,0.821,0.997
+0.999,0.827,0.997
+0.999,0.833,0.997
+0.999,0.839,0.998
+0.999,0.845,0.998
+0.999,0.851,0.998
+0.999,0.857,0.998
+0.999,0.863,0.998
+0.999,0.868,0.998
+0.998,0.874,0.998
+0.998,0.880,0.998
+0.998,0.886,0.998
+0.998,0.892,0.998
+0.998,0.898,0.998
+0.998,0.903,0.997
+0.998,0.909,0.997
+0.998,0.915,0.997
+0.998,0.921,0.997
diff --git a/pyqtgraph/colors/maps/CET-L8.csv b/pyqtgraph/colors/maps/CET-L8.csv
new file mode 100644
index 00000000..3a4e3fdf
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-L8.csv
@@ -0,0 +1,256 @@
+0.002,0.058,0.364
+0.002,0.060,0.370
+0.003,0.062,0.377
+0.004,0.064,0.383
+0.006,0.065,0.390
+0.008,0.067,0.396
+0.010,0.069,0.402
+0.013,0.071,0.409
+0.016,0.072,0.415
+0.019,0.074,0.421
+0.023,0.076,0.427
+0.028,0.077,0.433
+0.033,0.079,0.439
+0.039,0.081,0.445
+0.045,0.082,0.451
+0.052,0.084,0.457
+0.058,0.085,0.463
+0.065,0.087,0.468
+0.071,0.088,0.474
+0.078,0.089,0.480
+0.085,0.091,0.485
+0.092,0.092,0.490
+0.099,0.093,0.496
+0.107,0.095,0.501
+0.114,0.096,0.506
+0.122,0.097,0.511
+0.129,0.098,0.516
+0.137,0.099,0.520
+0.145,0.100,0.525
+0.153,0.101,0.529
+0.162,0.102,0.534
+0.170,0.102,0.538
+0.178,0.103,0.542
+0.187,0.104,0.546
+0.196,0.104,0.549
+0.205,0.104,0.553
+0.214,0.105,0.556
+0.224,0.105,0.559
+0.233,0.105,0.562
+0.243,0.105,0.564
+0.253,0.104,0.566
+0.263,0.104,0.568
+0.273,0.103,0.570
+0.284,0.102,0.571
+0.295,0.101,0.572
+0.306,0.100,0.573
+0.317,0.098,0.573
+0.328,0.097,0.573
+0.339,0.095,0.574
+0.350,0.093,0.574
+0.360,0.092,0.574
+0.370,0.090,0.574
+0.380,0.088,0.574
+0.390,0.087,0.573
+0.399,0.085,0.573
+0.409,0.083,0.573
+0.418,0.081,0.573
+0.428,0.079,0.572
+0.437,0.077,0.572
+0.446,0.075,0.572
+0.455,0.074,0.571
+0.464,0.072,0.570
+0.473,0.070,0.570
+0.481,0.068,0.569
+0.490,0.066,0.568
+0.499,0.064,0.568
+0.507,0.062,0.567
+0.515,0.060,0.566
+0.524,0.058,0.565
+0.532,0.056,0.564
+0.540,0.054,0.563
+0.548,0.052,0.562
+0.556,0.051,0.560
+0.564,0.049,0.559
+0.572,0.048,0.558
+0.580,0.046,0.556
+0.588,0.045,0.555
+0.596,0.043,0.554
+0.603,0.042,0.552
+0.611,0.041,0.551
+0.619,0.040,0.549
+0.626,0.039,0.548
+0.634,0.038,0.546
+0.641,0.038,0.545
+0.648,0.037,0.543
+0.656,0.037,0.542
+0.663,0.037,0.540
+0.670,0.037,0.538
+0.677,0.037,0.537
+0.684,0.037,0.535
+0.691,0.038,0.534
+0.698,0.039,0.532
+0.705,0.040,0.530
+0.712,0.041,0.529
+0.719,0.042,0.527
+0.726,0.044,0.525
+0.733,0.045,0.523
+0.739,0.047,0.522
+0.746,0.049,0.520
+0.753,0.051,0.518
+0.759,0.054,0.516
+0.766,0.056,0.514
+0.772,0.059,0.513
+0.779,0.061,0.511
+0.785,0.064,0.509
+0.792,0.067,0.507
+0.798,0.070,0.505
+0.804,0.074,0.503
+0.811,0.078,0.501
+0.817,0.082,0.499
+0.823,0.087,0.496
+0.828,0.092,0.494
+0.834,0.097,0.492
+0.840,0.103,0.489
+0.845,0.108,0.487
+0.850,0.114,0.484
+0.856,0.120,0.481
+0.861,0.126,0.478
+0.866,0.133,0.475
+0.871,0.139,0.472
+0.876,0.146,0.469
+0.880,0.152,0.466
+0.885,0.159,0.463
+0.889,0.166,0.460
+0.894,0.173,0.456
+0.898,0.180,0.453
+0.902,0.187,0.449
+0.906,0.194,0.445
+0.910,0.201,0.441
+0.914,0.208,0.438
+0.918,0.215,0.434
+0.921,0.223,0.429
+0.924,0.230,0.425
+0.928,0.237,0.421
+0.931,0.245,0.417
+0.934,0.252,0.412
+0.937,0.259,0.408
+0.940,0.267,0.403
+0.943,0.274,0.399
+0.945,0.281,0.394
+0.948,0.289,0.390
+0.950,0.296,0.386
+0.952,0.303,0.382
+0.955,0.311,0.378
+0.957,0.318,0.374
+0.959,0.325,0.370
+0.961,0.333,0.366
+0.962,0.340,0.363
+0.964,0.347,0.359
+0.966,0.354,0.355
+0.967,0.361,0.352
+0.968,0.369,0.348
+0.970,0.376,0.345
+0.971,0.383,0.341
+0.972,0.390,0.338
+0.973,0.398,0.335
+0.974,0.405,0.332
+0.974,0.412,0.329
+0.975,0.419,0.325
+0.975,0.426,0.323
+0.976,0.434,0.320
+0.976,0.441,0.317
+0.976,0.448,0.314
+0.976,0.455,0.311
+0.976,0.462,0.309
+0.976,0.469,0.306
+0.976,0.477,0.304
+0.976,0.484,0.301
+0.976,0.491,0.299
+0.976,0.497,0.296
+0.976,0.504,0.294
+0.976,0.511,0.291
+0.976,0.517,0.289
+0.976,0.524,0.286
+0.976,0.530,0.284
+0.976,0.537,0.281
+0.976,0.543,0.278
+0.976,0.549,0.276
+0.976,0.555,0.273
+0.976,0.562,0.271
+0.977,0.568,0.268
+0.977,0.574,0.266
+0.977,0.580,0.263
+0.978,0.585,0.261
+0.978,0.591,0.258
+0.979,0.597,0.256
+0.979,0.603,0.253
+0.980,0.609,0.250
+0.980,0.614,0.248
+0.981,0.620,0.245
+0.981,0.625,0.243
+0.982,0.631,0.240
+0.983,0.636,0.238
+0.983,0.642,0.235
+0.984,0.647,0.232
+0.985,0.653,0.230
+0.986,0.658,0.227
+0.987,0.663,0.225
+0.987,0.669,0.224
+0.988,0.674,0.222
+0.988,0.680,0.221
+0.989,0.685,0.220
+0.989,0.690,0.220
+0.989,0.696,0.219
+0.990,0.701,0.219
+0.990,0.707,0.218
+0.990,0.712,0.218
+0.990,0.718,0.218
+0.990,0.723,0.219
+0.990,0.728,0.219
+0.991,0.734,0.219
+0.991,0.739,0.220
+0.991,0.745,0.221
+0.990,0.750,0.221
+0.990,0.755,0.222
+0.990,0.761,0.223
+0.990,0.766,0.224
+0.990,0.772,0.225
+0.990,0.777,0.226
+0.990,0.783,0.228
+0.989,0.788,0.229
+0.989,0.793,0.230
+0.989,0.799,0.232
+0.988,0.804,0.233
+0.988,0.810,0.235
+0.987,0.815,0.237
+0.987,0.820,0.238
+0.987,0.826,0.240
+0.986,0.831,0.242
+0.986,0.836,0.244
+0.985,0.842,0.245
+0.984,0.847,0.247
+0.984,0.853,0.249
+0.983,0.858,0.251
+0.983,0.863,0.254
+0.982,0.869,0.256
+0.981,0.874,0.258
+0.980,0.879,0.260
+0.980,0.885,0.262
+0.979,0.890,0.264
+0.978,0.895,0.267
+0.977,0.901,0.269
+0.976,0.906,0.271
+0.975,0.912,0.274
+0.974,0.917,0.276
+0.973,0.922,0.279
+0.972,0.928,0.281
+0.971,0.933,0.284
+0.970,0.938,0.286
+0.969,0.944,0.289
+0.968,0.949,0.291
+0.967,0.954,0.294
+0.966,0.960,0.297
+0.964,0.965,0.299
+0.963,0.970,0.302
+0.962,0.976,0.305
diff --git a/pyqtgraph/colors/maps/CET-L9.csv b/pyqtgraph/colors/maps/CET-L9.csv
new file mode 100644
index 00000000..fed08cc9
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-L9.csv
@@ -0,0 +1,256 @@
+0.020,0.000,0.673
+0.022,0.009,0.675
+0.024,0.020,0.676
+0.026,0.032,0.677
+0.028,0.043,0.679
+0.029,0.053,0.680
+0.031,0.063,0.682
+0.033,0.072,0.683
+0.035,0.080,0.684
+0.036,0.087,0.686
+0.038,0.094,0.687
+0.039,0.101,0.688
+0.041,0.108,0.689
+0.042,0.114,0.690
+0.043,0.121,0.692
+0.045,0.127,0.693
+0.046,0.133,0.694
+0.047,0.139,0.695
+0.048,0.144,0.696
+0.048,0.150,0.697
+0.049,0.155,0.698
+0.050,0.161,0.699
+0.051,0.166,0.700
+0.051,0.171,0.701
+0.052,0.177,0.702
+0.052,0.182,0.703
+0.053,0.187,0.703
+0.053,0.192,0.704
+0.053,0.197,0.705
+0.054,0.202,0.705
+0.054,0.207,0.706
+0.054,0.212,0.707
+0.054,0.216,0.707
+0.054,0.221,0.708
+0.054,0.226,0.708
+0.054,0.231,0.709
+0.054,0.236,0.709
+0.054,0.240,0.709
+0.053,0.245,0.709
+0.053,0.250,0.710
+0.053,0.254,0.710
+0.052,0.259,0.710
+0.052,0.264,0.710
+0.051,0.268,0.710
+0.051,0.273,0.710
+0.050,0.278,0.709
+0.049,0.282,0.709
+0.048,0.287,0.709
+0.047,0.292,0.708
+0.046,0.296,0.708
+0.045,0.301,0.707
+0.044,0.305,0.706
+0.043,0.310,0.705
+0.042,0.315,0.704
+0.041,0.319,0.703
+0.039,0.324,0.702
+0.038,0.329,0.700
+0.036,0.333,0.698
+0.035,0.338,0.697
+0.033,0.343,0.695
+0.031,0.347,0.692
+0.030,0.352,0.690
+0.028,0.357,0.687
+0.026,0.362,0.684
+0.025,0.367,0.681
+0.023,0.372,0.677
+0.022,0.377,0.673
+0.022,0.381,0.668
+0.024,0.386,0.663
+0.028,0.391,0.659
+0.032,0.396,0.654
+0.039,0.401,0.648
+0.045,0.405,0.643
+0.052,0.410,0.637
+0.059,0.414,0.632
+0.067,0.419,0.626
+0.074,0.423,0.620
+0.080,0.428,0.614
+0.087,0.432,0.607
+0.094,0.437,0.601
+0.100,0.441,0.594
+0.106,0.446,0.588
+0.112,0.450,0.581
+0.117,0.454,0.574
+0.123,0.459,0.567
+0.128,0.463,0.560
+0.133,0.467,0.553
+0.138,0.472,0.545
+0.142,0.476,0.538
+0.147,0.480,0.530
+0.151,0.485,0.523
+0.155,0.489,0.515
+0.158,0.493,0.507
+0.162,0.497,0.499
+0.165,0.502,0.491
+0.168,0.506,0.482
+0.171,0.510,0.474
+0.174,0.514,0.466
+0.176,0.519,0.457
+0.179,0.523,0.448
+0.181,0.527,0.440
+0.182,0.531,0.431
+0.184,0.536,0.422
+0.185,0.540,0.413
+0.187,0.544,0.403
+0.188,0.548,0.394
+0.188,0.552,0.384
+0.189,0.557,0.375
+0.190,0.561,0.366
+0.191,0.565,0.357
+0.192,0.569,0.348
+0.194,0.573,0.339
+0.196,0.577,0.331
+0.198,0.581,0.323
+0.200,0.585,0.315
+0.202,0.588,0.307
+0.205,0.592,0.299
+0.208,0.596,0.292
+0.211,0.600,0.284
+0.215,0.603,0.277
+0.218,0.607,0.270
+0.222,0.611,0.263
+0.226,0.614,0.256
+0.230,0.618,0.250
+0.235,0.621,0.243
+0.240,0.625,0.237
+0.245,0.628,0.230
+0.250,0.631,0.224
+0.255,0.635,0.218
+0.260,0.638,0.212
+0.266,0.641,0.205
+0.272,0.645,0.200
+0.278,0.648,0.194
+0.284,0.651,0.188
+0.290,0.654,0.182
+0.296,0.657,0.176
+0.303,0.661,0.171
+0.309,0.664,0.165
+0.316,0.667,0.159
+0.323,0.670,0.154
+0.329,0.673,0.148
+0.336,0.676,0.143
+0.343,0.679,0.137
+0.351,0.682,0.132
+0.358,0.685,0.127
+0.365,0.688,0.121
+0.372,0.691,0.116
+0.380,0.694,0.111
+0.387,0.696,0.105
+0.395,0.699,0.100
+0.403,0.702,0.095
+0.411,0.705,0.090
+0.418,0.707,0.084
+0.426,0.710,0.079
+0.434,0.713,0.074
+0.442,0.716,0.069
+0.450,0.718,0.064
+0.458,0.721,0.058
+0.466,0.723,0.053
+0.475,0.726,0.048
+0.483,0.728,0.043
+0.491,0.731,0.038
+0.500,0.733,0.033
+0.508,0.736,0.029
+0.516,0.738,0.025
+0.525,0.741,0.022
+0.533,0.743,0.019
+0.542,0.746,0.016
+0.551,0.748,0.014
+0.559,0.750,0.013
+0.568,0.752,0.011
+0.577,0.755,0.010
+0.586,0.757,0.010
+0.594,0.759,0.010
+0.603,0.761,0.009
+0.611,0.764,0.009
+0.620,0.766,0.010
+0.628,0.768,0.010
+0.637,0.770,0.010
+0.645,0.773,0.011
+0.653,0.775,0.012
+0.662,0.777,0.013
+0.670,0.779,0.014
+0.678,0.781,0.015
+0.686,0.784,0.017
+0.694,0.786,0.019
+0.702,0.788,0.021
+0.709,0.790,0.023
+0.717,0.793,0.025
+0.725,0.795,0.028
+0.733,0.797,0.031
+0.740,0.800,0.034
+0.748,0.802,0.038
+0.755,0.804,0.042
+0.763,0.806,0.045
+0.770,0.809,0.049
+0.777,0.811,0.053
+0.784,0.813,0.057
+0.792,0.816,0.062
+0.799,0.818,0.066
+0.806,0.820,0.070
+0.813,0.823,0.075
+0.820,0.825,0.079
+0.826,0.828,0.084
+0.833,0.830,0.089
+0.840,0.833,0.093
+0.846,0.835,0.098
+0.853,0.837,0.103
+0.859,0.840,0.108
+0.865,0.843,0.113
+0.872,0.845,0.118
+0.878,0.848,0.124
+0.884,0.850,0.129
+0.890,0.853,0.135
+0.895,0.856,0.140
+0.901,0.858,0.146
+0.906,0.861,0.152
+0.912,0.864,0.158
+0.917,0.867,0.164
+0.922,0.870,0.171
+0.927,0.873,0.177
+0.932,0.876,0.184
+0.936,0.879,0.191
+0.940,0.882,0.198
+0.944,0.885,0.206
+0.948,0.888,0.213
+0.952,0.892,0.221
+0.955,0.895,0.230
+0.957,0.899,0.238
+0.960,0.903,0.248
+0.962,0.906,0.258
+0.964,0.910,0.269
+0.967,0.914,0.282
+0.969,0.917,0.296
+0.971,0.921,0.311
+0.974,0.924,0.327
+0.976,0.928,0.345
+0.979,0.931,0.363
+0.981,0.934,0.383
+0.984,0.937,0.404
+0.987,0.940,0.426
+0.989,0.943,0.450
+0.991,0.946,0.475
+0.994,0.949,0.501
+0.996,0.952,0.529
+0.997,0.955,0.558
+0.999,0.957,0.590
+1.000,0.960,0.623
+1.000,0.962,0.658
+1.000,0.965,0.695
+1.000,0.967,0.735
+0.998,0.969,0.777
+0.996,0.971,0.822
+0.991,0.973,0.870
+0.985,0.975,0.922
+0.977,0.977,0.977
diff --git a/pyqtgraph/colors/maps/CET-R1.csv b/pyqtgraph/colors/maps/CET-R1.csv
new file mode 100644
index 00000000..d05c41d2
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-R1.csv
@@ -0,0 +1,256 @@
+0.000,0.187,0.963
+0.000,0.202,0.949
+0.000,0.217,0.935
+0.000,0.231,0.921
+0.011,0.244,0.908
+0.036,0.257,0.894
+0.056,0.269,0.880
+0.069,0.281,0.867
+0.079,0.292,0.853
+0.087,0.302,0.840
+0.092,0.313,0.826
+0.096,0.323,0.813
+0.098,0.333,0.799
+0.100,0.342,0.786
+0.100,0.352,0.772
+0.099,0.361,0.759
+0.098,0.370,0.745
+0.097,0.378,0.732
+0.095,0.386,0.719
+0.093,0.395,0.706
+0.092,0.402,0.693
+0.092,0.410,0.680
+0.092,0.417,0.667
+0.093,0.425,0.654
+0.095,0.432,0.641
+0.099,0.438,0.629
+0.104,0.445,0.616
+0.110,0.451,0.604
+0.117,0.457,0.592
+0.125,0.463,0.580
+0.134,0.469,0.568
+0.142,0.474,0.556
+0.151,0.480,0.544
+0.160,0.485,0.532
+0.169,0.491,0.520
+0.177,0.496,0.509
+0.185,0.501,0.497
+0.193,0.506,0.485
+0.200,0.511,0.473
+0.206,0.516,0.462
+0.213,0.522,0.450
+0.218,0.527,0.438
+0.223,0.532,0.426
+0.228,0.537,0.414
+0.232,0.542,0.402
+0.236,0.547,0.390
+0.239,0.552,0.378
+0.242,0.557,0.365
+0.245,0.562,0.353
+0.247,0.567,0.340
+0.249,0.573,0.327
+0.250,0.578,0.314
+0.252,0.583,0.301
+0.253,0.588,0.288
+0.254,0.593,0.275
+0.255,0.598,0.262
+0.256,0.603,0.248
+0.257,0.608,0.235
+0.258,0.613,0.221
+0.260,0.618,0.208
+0.263,0.623,0.195
+0.266,0.627,0.182
+0.270,0.632,0.169
+0.274,0.636,0.156
+0.280,0.641,0.144
+0.286,0.645,0.133
+0.293,0.649,0.122
+0.302,0.653,0.112
+0.311,0.657,0.102
+0.320,0.660,0.094
+0.331,0.664,0.086
+0.341,0.667,0.080
+0.353,0.671,0.075
+0.364,0.674,0.070
+0.376,0.677,0.067
+0.388,0.680,0.065
+0.400,0.683,0.064
+0.412,0.686,0.064
+0.425,0.689,0.064
+0.437,0.692,0.064
+0.449,0.695,0.065
+0.461,0.698,0.067
+0.473,0.701,0.068
+0.485,0.703,0.070
+0.496,0.706,0.071
+0.508,0.709,0.073
+0.520,0.712,0.075
+0.531,0.715,0.077
+0.542,0.717,0.078
+0.554,0.720,0.080
+0.565,0.723,0.082
+0.576,0.725,0.084
+0.587,0.728,0.086
+0.598,0.731,0.087
+0.609,0.733,0.089
+0.620,0.736,0.091
+0.631,0.739,0.093
+0.642,0.741,0.095
+0.653,0.744,0.096
+0.664,0.746,0.098
+0.674,0.749,0.100
+0.685,0.751,0.102
+0.696,0.754,0.103
+0.707,0.757,0.105
+0.717,0.759,0.107
+0.728,0.762,0.109
+0.738,0.764,0.111
+0.749,0.766,0.112
+0.759,0.769,0.114
+0.770,0.771,0.116
+0.780,0.774,0.118
+0.791,0.776,0.120
+0.801,0.778,0.121
+0.812,0.781,0.123
+0.822,0.783,0.125
+0.832,0.785,0.127
+0.843,0.787,0.128
+0.853,0.789,0.130
+0.863,0.791,0.132
+0.873,0.793,0.133
+0.882,0.794,0.135
+0.892,0.795,0.136
+0.901,0.796,0.137
+0.910,0.797,0.139
+0.918,0.797,0.140
+0.926,0.797,0.141
+0.933,0.796,0.142
+0.940,0.795,0.142
+0.946,0.793,0.143
+0.952,0.791,0.143
+0.957,0.789,0.143
+0.962,0.786,0.143
+0.966,0.782,0.143
+0.969,0.779,0.142
+0.972,0.774,0.142
+0.974,0.770,0.141
+0.976,0.765,0.140
+0.977,0.760,0.139
+0.978,0.754,0.138
+0.979,0.749,0.137
+0.979,0.743,0.136
+0.980,0.737,0.135
+0.980,0.732,0.133
+0.980,0.726,0.132
+0.979,0.720,0.131
+0.979,0.714,0.130
+0.979,0.707,0.128
+0.979,0.701,0.127
+0.978,0.695,0.126
+0.978,0.689,0.124
+0.977,0.683,0.123
+0.977,0.677,0.122
+0.976,0.670,0.121
+0.976,0.664,0.119
+0.975,0.658,0.118
+0.975,0.652,0.117
+0.974,0.645,0.116
+0.974,0.639,0.114
+0.973,0.633,0.113
+0.973,0.627,0.112
+0.972,0.620,0.111
+0.971,0.614,0.110
+0.971,0.608,0.108
+0.970,0.601,0.107
+0.969,0.595,0.106
+0.969,0.588,0.105
+0.968,0.582,0.104
+0.967,0.575,0.103
+0.966,0.569,0.102
+0.966,0.563,0.100
+0.965,0.556,0.099
+0.964,0.549,0.098
+0.963,0.543,0.097
+0.962,0.536,0.096
+0.961,0.530,0.095
+0.961,0.523,0.094
+0.960,0.516,0.093
+0.959,0.510,0.092
+0.958,0.503,0.091
+0.957,0.496,0.090
+0.956,0.489,0.089
+0.955,0.482,0.088
+0.954,0.476,0.087
+0.953,0.469,0.086
+0.952,0.462,0.085
+0.951,0.455,0.084
+0.950,0.448,0.083
+0.949,0.440,0.083
+0.948,0.433,0.082
+0.947,0.426,0.082
+0.946,0.419,0.082
+0.945,0.412,0.082
+0.944,0.405,0.083
+0.943,0.398,0.084
+0.942,0.391,0.086
+0.941,0.384,0.088
+0.941,0.378,0.091
+0.940,0.371,0.095
+0.940,0.365,0.100
+0.940,0.360,0.106
+0.940,0.355,0.113
+0.940,0.350,0.121
+0.941,0.346,0.130
+0.942,0.343,0.139
+0.943,0.340,0.150
+0.944,0.338,0.161
+0.946,0.337,0.173
+0.948,0.337,0.186
+0.950,0.338,0.199
+0.952,0.339,0.213
+0.954,0.341,0.227
+0.957,0.343,0.242
+0.959,0.346,0.257
+0.962,0.350,0.272
+0.965,0.354,0.288
+0.967,0.358,0.304
+0.970,0.362,0.320
+0.973,0.367,0.336
+0.975,0.372,0.352
+0.978,0.377,0.368
+0.980,0.382,0.385
+0.983,0.387,0.401
+0.985,0.392,0.418
+0.987,0.397,0.434
+0.990,0.403,0.451
+0.992,0.408,0.467
+0.993,0.413,0.484
+0.995,0.418,0.500
+0.997,0.424,0.517
+0.999,0.429,0.533
+1.000,0.434,0.550
+1.000,0.440,0.567
+1.000,0.445,0.583
+1.000,0.451,0.600
+1.000,0.456,0.617
+1.000,0.461,0.634
+1.000,0.467,0.651
+1.000,0.472,0.668
+1.000,0.478,0.685
+1.000,0.483,0.702
+1.000,0.488,0.719
+1.000,0.494,0.736
+1.000,0.499,0.753
+1.000,0.505,0.770
+1.000,0.510,0.787
+1.000,0.516,0.805
+1.000,0.521,0.822
+1.000,0.527,0.840
+1.000,0.532,0.857
+1.000,0.538,0.874
+1.000,0.544,0.892
+1.000,0.549,0.910
+0.998,0.555,0.927
+0.997,0.560,0.945
+0.995,0.566,0.963
+0.992,0.572,0.980
diff --git a/pyqtgraph/colors/maps/CET-R2.csv b/pyqtgraph/colors/maps/CET-R2.csv
new file mode 100644
index 00000000..bc36cd8a
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-R2.csv
@@ -0,0 +1,256 @@
+0.000,0.204,0.963
+0.000,0.215,0.951
+0.000,0.226,0.940
+0.000,0.237,0.929
+0.000,0.247,0.918
+0.000,0.256,0.907
+0.000,0.266,0.896
+0.000,0.275,0.885
+0.000,0.283,0.874
+0.000,0.292,0.863
+0.000,0.300,0.852
+0.000,0.309,0.841
+0.000,0.317,0.830
+0.000,0.325,0.819
+0.000,0.332,0.808
+0.000,0.340,0.797
+0.000,0.347,0.786
+0.000,0.355,0.775
+0.000,0.362,0.765
+0.000,0.369,0.754
+0.000,0.376,0.743
+0.000,0.383,0.732
+0.000,0.390,0.721
+0.000,0.396,0.710
+0.000,0.403,0.699
+0.000,0.409,0.689
+0.000,0.416,0.678
+0.000,0.422,0.667
+0.000,0.428,0.657
+0.000,0.433,0.646
+0.000,0.439,0.636
+0.000,0.444,0.626
+0.000,0.449,0.616
+0.000,0.454,0.606
+0.000,0.459,0.596
+0.004,0.464,0.586
+0.030,0.468,0.577
+0.056,0.472,0.567
+0.077,0.477,0.558
+0.095,0.481,0.548
+0.111,0.485,0.539
+0.125,0.489,0.530
+0.138,0.493,0.520
+0.149,0.497,0.511
+0.160,0.501,0.502
+0.169,0.505,0.492
+0.177,0.508,0.483
+0.185,0.512,0.474
+0.192,0.516,0.464
+0.199,0.520,0.455
+0.204,0.524,0.445
+0.210,0.529,0.436
+0.215,0.533,0.426
+0.219,0.537,0.417
+0.223,0.541,0.407
+0.227,0.545,0.397
+0.230,0.549,0.387
+0.233,0.553,0.377
+0.236,0.557,0.367
+0.238,0.561,0.357
+0.240,0.565,0.347
+0.242,0.569,0.336
+0.243,0.574,0.326
+0.245,0.578,0.315
+0.246,0.582,0.304
+0.246,0.586,0.293
+0.247,0.590,0.282
+0.247,0.594,0.271
+0.247,0.599,0.259
+0.247,0.603,0.247
+0.247,0.607,0.235
+0.246,0.611,0.222
+0.246,0.615,0.209
+0.246,0.619,0.196
+0.246,0.623,0.183
+0.246,0.627,0.170
+0.247,0.631,0.156
+0.249,0.635,0.143
+0.252,0.639,0.130
+0.256,0.642,0.117
+0.261,0.646,0.106
+0.267,0.649,0.095
+0.274,0.652,0.085
+0.282,0.655,0.076
+0.291,0.658,0.070
+0.300,0.661,0.065
+0.311,0.664,0.061
+0.321,0.666,0.059
+0.332,0.669,0.058
+0.343,0.671,0.058
+0.354,0.674,0.058
+0.364,0.676,0.060
+0.375,0.679,0.061
+0.386,0.681,0.063
+0.396,0.683,0.065
+0.407,0.686,0.067
+0.417,0.688,0.069
+0.427,0.690,0.071
+0.437,0.693,0.072
+0.447,0.695,0.074
+0.457,0.697,0.076
+0.467,0.700,0.078
+0.476,0.702,0.080
+0.486,0.704,0.082
+0.495,0.706,0.084
+0.505,0.709,0.086
+0.514,0.711,0.088
+0.523,0.713,0.089
+0.533,0.715,0.091
+0.542,0.717,0.093
+0.551,0.720,0.095
+0.560,0.722,0.097
+0.569,0.724,0.098
+0.578,0.726,0.100
+0.587,0.728,0.102
+0.596,0.730,0.104
+0.605,0.733,0.106
+0.614,0.735,0.107
+0.622,0.737,0.109
+0.631,0.739,0.111
+0.640,0.741,0.113
+0.649,0.743,0.115
+0.657,0.745,0.116
+0.666,0.747,0.118
+0.675,0.749,0.120
+0.683,0.751,0.122
+0.692,0.753,0.123
+0.701,0.756,0.125
+0.709,0.758,0.127
+0.718,0.760,0.129
+0.726,0.762,0.130
+0.735,0.764,0.132
+0.743,0.766,0.134
+0.752,0.768,0.136
+0.760,0.770,0.137
+0.769,0.772,0.139
+0.777,0.773,0.141
+0.786,0.775,0.143
+0.794,0.777,0.144
+0.803,0.779,0.146
+0.811,0.781,0.148
+0.819,0.783,0.150
+0.828,0.785,0.151
+0.836,0.787,0.153
+0.845,0.789,0.155
+0.853,0.791,0.157
+0.861,0.793,0.158
+0.870,0.794,0.160
+0.878,0.796,0.162
+0.886,0.798,0.163
+0.895,0.800,0.165
+0.903,0.801,0.167
+0.911,0.802,0.168
+0.919,0.804,0.170
+0.927,0.805,0.171
+0.935,0.805,0.172
+0.942,0.805,0.173
+0.949,0.805,0.174
+0.955,0.804,0.174
+0.961,0.803,0.174
+0.966,0.801,0.174
+0.971,0.798,0.173
+0.975,0.795,0.172
+0.978,0.792,0.171
+0.981,0.788,0.170
+0.983,0.784,0.168
+0.985,0.779,0.167
+0.987,0.775,0.165
+0.988,0.770,0.163
+0.989,0.764,0.161
+0.990,0.759,0.158
+0.991,0.754,0.156
+0.991,0.749,0.154
+0.992,0.744,0.152
+0.993,0.738,0.150
+0.993,0.733,0.148
+0.994,0.728,0.145
+0.995,0.722,0.143
+0.995,0.717,0.141
+0.996,0.712,0.139
+0.996,0.706,0.137
+0.997,0.701,0.134
+0.997,0.695,0.132
+0.998,0.690,0.130
+0.998,0.684,0.128
+0.998,0.679,0.126
+0.999,0.674,0.123
+0.999,0.668,0.121
+1.000,0.663,0.119
+1.000,0.657,0.117
+1.000,0.652,0.115
+1.000,0.646,0.112
+1.000,0.641,0.110
+1.000,0.635,0.108
+1.000,0.629,0.106
+1.000,0.624,0.104
+1.000,0.618,0.101
+1.000,0.613,0.099
+1.000,0.607,0.097
+1.000,0.601,0.095
+1.000,0.596,0.092
+1.000,0.590,0.090
+1.000,0.584,0.088
+1.000,0.578,0.086
+1.000,0.573,0.084
+1.000,0.567,0.081
+1.000,0.561,0.079
+1.000,0.555,0.077
+1.000,0.549,0.075
+1.000,0.543,0.072
+1.000,0.537,0.070
+1.000,0.531,0.068
+1.000,0.525,0.065
+1.000,0.519,0.063
+1.000,0.513,0.061
+1.000,0.507,0.059
+1.000,0.501,0.056
+1.000,0.495,0.054
+1.000,0.489,0.051
+1.000,0.482,0.049
+1.000,0.476,0.047
+1.000,0.470,0.044
+1.000,0.463,0.042
+1.000,0.457,0.040
+1.000,0.450,0.037
+1.000,0.444,0.035
+1.000,0.437,0.032
+1.000,0.430,0.030
+1.000,0.424,0.028
+1.000,0.417,0.026
+1.000,0.410,0.024
+1.000,0.403,0.022
+1.000,0.396,0.020
+1.000,0.389,0.019
+1.000,0.382,0.017
+1.000,0.374,0.015
+0.999,0.367,0.013
+0.999,0.359,0.012
+0.999,0.352,0.010
+0.998,0.344,0.009
+0.998,0.336,0.007
+0.997,0.328,0.006
+0.997,0.320,0.005
+0.997,0.311,0.004
+0.996,0.303,0.002
+0.996,0.294,0.001
+0.995,0.285,0.000
+0.995,0.276,0.000
+0.994,0.266,0.000
+0.994,0.257,0.000
+0.993,0.247,0.000
+0.993,0.236,0.000
+0.992,0.225,0.000
+0.992,0.214,0.000
+0.991,0.202,0.000
+0.990,0.189,0.000
diff --git a/pyqtgraph/colors/maps/CET-R3.csv b/pyqtgraph/colors/maps/CET-R3.csv
new file mode 100644
index 00000000..e45d5731
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-R3.csv
@@ -0,0 +1,256 @@
+0.032,0.362,0.973
+0.058,0.371,0.958
+0.076,0.380,0.943
+0.089,0.389,0.928
+0.098,0.397,0.914
+0.105,0.406,0.899
+0.110,0.414,0.884
+0.114,0.422,0.869
+0.116,0.430,0.854
+0.116,0.438,0.839
+0.115,0.445,0.824
+0.113,0.453,0.809
+0.109,0.461,0.794
+0.105,0.468,0.780
+0.099,0.475,0.765
+0.093,0.482,0.750
+0.086,0.489,0.735
+0.080,0.496,0.720
+0.075,0.503,0.705
+0.071,0.509,0.689
+0.071,0.515,0.674
+0.074,0.521,0.658
+0.080,0.527,0.643
+0.089,0.532,0.627
+0.100,0.538,0.611
+0.113,0.543,0.594
+0.126,0.548,0.578
+0.139,0.553,0.561
+0.152,0.557,0.544
+0.164,0.562,0.527
+0.175,0.566,0.510
+0.185,0.571,0.493
+0.194,0.575,0.475
+0.202,0.580,0.458
+0.209,0.584,0.440
+0.215,0.589,0.422
+0.220,0.593,0.404
+0.224,0.598,0.386
+0.227,0.602,0.368
+0.230,0.607,0.349
+0.232,0.611,0.331
+0.233,0.616,0.312
+0.234,0.620,0.294
+0.236,0.624,0.276
+0.237,0.629,0.258
+0.239,0.633,0.240
+0.241,0.637,0.223
+0.244,0.641,0.207
+0.249,0.644,0.193
+0.254,0.648,0.179
+0.261,0.651,0.167
+0.268,0.655,0.156
+0.277,0.658,0.147
+0.286,0.661,0.140
+0.297,0.663,0.134
+0.307,0.666,0.130
+0.318,0.669,0.126
+0.329,0.671,0.124
+0.340,0.674,0.122
+0.351,0.676,0.120
+0.362,0.678,0.119
+0.373,0.681,0.118
+0.384,0.683,0.117
+0.394,0.686,0.116
+0.405,0.688,0.116
+0.415,0.690,0.115
+0.425,0.693,0.114
+0.435,0.695,0.113
+0.445,0.697,0.113
+0.455,0.699,0.112
+0.465,0.702,0.111
+0.474,0.704,0.110
+0.484,0.706,0.110
+0.493,0.709,0.109
+0.503,0.711,0.108
+0.512,0.713,0.107
+0.521,0.715,0.106
+0.531,0.718,0.105
+0.540,0.720,0.104
+0.549,0.722,0.103
+0.558,0.724,0.103
+0.567,0.726,0.102
+0.576,0.729,0.101
+0.585,0.731,0.100
+0.594,0.733,0.099
+0.603,0.735,0.098
+0.611,0.737,0.097
+0.620,0.739,0.096
+0.629,0.742,0.095
+0.638,0.744,0.094
+0.646,0.746,0.092
+0.655,0.748,0.091
+0.663,0.750,0.090
+0.672,0.752,0.089
+0.681,0.754,0.088
+0.689,0.756,0.087
+0.698,0.758,0.085
+0.706,0.760,0.084
+0.715,0.762,0.083
+0.723,0.765,0.082
+0.732,0.767,0.080
+0.740,0.769,0.079
+0.748,0.771,0.078
+0.757,0.773,0.076
+0.765,0.775,0.075
+0.774,0.777,0.073
+0.782,0.779,0.072
+0.790,0.781,0.070
+0.799,0.783,0.069
+0.807,0.785,0.067
+0.815,0.786,0.065
+0.824,0.788,0.064
+0.832,0.790,0.062
+0.840,0.792,0.060
+0.849,0.794,0.058
+0.857,0.796,0.057
+0.865,0.798,0.055
+0.874,0.800,0.054
+0.882,0.801,0.054
+0.890,0.803,0.054
+0.898,0.804,0.056
+0.907,0.805,0.058
+0.915,0.806,0.063
+0.923,0.806,0.069
+0.930,0.806,0.077
+0.938,0.806,0.087
+0.945,0.805,0.098
+0.951,0.803,0.110
+0.957,0.801,0.123
+0.963,0.798,0.136
+0.968,0.794,0.149
+0.972,0.790,0.162
+0.975,0.786,0.175
+0.978,0.781,0.188
+0.980,0.776,0.200
+0.982,0.771,0.212
+0.984,0.765,0.224
+0.985,0.760,0.235
+0.986,0.754,0.245
+0.987,0.749,0.255
+0.988,0.743,0.265
+0.989,0.738,0.275
+0.990,0.732,0.284
+0.991,0.726,0.293
+0.991,0.720,0.302
+0.992,0.715,0.310
+0.993,0.709,0.319
+0.993,0.703,0.327
+0.994,0.697,0.335
+0.994,0.692,0.343
+0.995,0.686,0.351
+0.995,0.680,0.358
+0.996,0.674,0.366
+0.996,0.668,0.373
+0.996,0.663,0.380
+0.997,0.657,0.387
+0.997,0.651,0.394
+0.997,0.645,0.401
+0.998,0.639,0.408
+0.998,0.633,0.415
+0.998,0.627,0.422
+0.998,0.621,0.428
+0.998,0.615,0.435
+0.998,0.609,0.441
+0.999,0.603,0.448
+0.999,0.596,0.454
+0.999,0.590,0.461
+0.999,0.584,0.467
+0.999,0.578,0.473
+0.998,0.572,0.479
+0.998,0.565,0.486
+0.998,0.559,0.492
+0.998,0.553,0.498
+0.998,0.546,0.504
+0.998,0.540,0.510
+0.997,0.533,0.516
+0.997,0.527,0.522
+0.997,0.520,0.528
+0.997,0.514,0.533
+0.996,0.507,0.539
+0.996,0.500,0.545
+0.995,0.494,0.551
+0.995,0.487,0.557
+0.995,0.480,0.562
+0.994,0.473,0.568
+0.993,0.466,0.574
+0.993,0.459,0.579
+0.992,0.452,0.585
+0.992,0.445,0.591
+0.991,0.437,0.596
+0.990,0.430,0.602
+0.990,0.423,0.608
+0.989,0.415,0.613
+0.988,0.407,0.619
+0.987,0.400,0.624
+0.986,0.392,0.629
+0.986,0.384,0.635
+0.985,0.376,0.640
+0.984,0.368,0.644
+0.983,0.360,0.649
+0.982,0.352,0.653
+0.981,0.344,0.656
+0.980,0.336,0.658
+0.979,0.328,0.660
+0.978,0.320,0.660
+0.976,0.312,0.659
+0.975,0.305,0.656
+0.974,0.298,0.652
+0.973,0.291,0.646
+0.972,0.285,0.639
+0.970,0.279,0.631
+0.969,0.273,0.621
+0.968,0.268,0.610
+0.966,0.262,0.599
+0.965,0.257,0.587
+0.963,0.252,0.574
+0.961,0.248,0.562
+0.959,0.243,0.548
+0.958,0.238,0.535
+0.956,0.233,0.522
+0.954,0.229,0.509
+0.951,0.224,0.495
+0.949,0.219,0.482
+0.947,0.215,0.469
+0.945,0.210,0.456
+0.942,0.205,0.442
+0.940,0.200,0.429
+0.937,0.196,0.416
+0.935,0.191,0.403
+0.932,0.186,0.390
+0.929,0.181,0.377
+0.926,0.176,0.364
+0.923,0.171,0.351
+0.921,0.166,0.338
+0.918,0.161,0.325
+0.915,0.156,0.311
+0.911,0.151,0.298
+0.908,0.146,0.285
+0.905,0.140,0.272
+0.902,0.135,0.259
+0.898,0.129,0.246
+0.895,0.124,0.233
+0.892,0.118,0.220
+0.888,0.112,0.206
+0.885,0.106,0.193
+0.881,0.100,0.179
+0.877,0.094,0.165
+0.874,0.087,0.151
+0.870,0.080,0.136
+0.866,0.073,0.121
+0.862,0.065,0.105
+0.859,0.057,0.088
+0.855,0.048,0.070
+0.851,0.038,0.049
+0.847,0.028,0.024
+0.843,0.018,0.002
diff --git a/pyqtgraph/colors/maps/CET-R4.csv b/pyqtgraph/colors/maps/CET-R4.csv
new file mode 100644
index 00000000..f6ecfd4e
--- /dev/null
+++ b/pyqtgraph/colors/maps/CET-R4.csv
@@ -0,0 +1,256 @@
+0.015,0.002,0.425
+0.015,0.002,0.437
+0.016,0.002,0.448
+0.016,0.002,0.460
+0.016,0.002,0.472
+0.017,0.002,0.483
+0.017,0.001,0.495
+0.017,0.001,0.507
+0.017,0.001,0.519
+0.018,0.001,0.531
+0.018,0.001,0.543
+0.018,0.001,0.555
+0.018,0.001,0.567
+0.019,0.001,0.579
+0.019,0.002,0.590
+0.020,0.002,0.602
+0.020,0.003,0.614
+0.021,0.005,0.625
+0.021,0.007,0.636
+0.022,0.010,0.647
+0.023,0.013,0.657
+0.024,0.017,0.667
+0.025,0.023,0.676
+0.027,0.029,0.685
+0.028,0.036,0.694
+0.030,0.044,0.703
+0.032,0.051,0.711
+0.034,0.059,0.719
+0.036,0.067,0.727
+0.038,0.074,0.735
+0.040,0.081,0.742
+0.042,0.088,0.750
+0.044,0.095,0.757
+0.045,0.102,0.765
+0.047,0.108,0.773
+0.049,0.115,0.780
+0.050,0.121,0.788
+0.052,0.127,0.795
+0.053,0.133,0.803
+0.055,0.139,0.810
+0.056,0.146,0.818
+0.057,0.151,0.825
+0.059,0.157,0.833
+0.060,0.163,0.841
+0.061,0.169,0.848
+0.062,0.174,0.856
+0.063,0.180,0.863
+0.064,0.186,0.871
+0.065,0.191,0.879
+0.066,0.197,0.886
+0.067,0.203,0.894
+0.068,0.208,0.901
+0.069,0.214,0.909
+0.071,0.220,0.916
+0.072,0.226,0.922
+0.074,0.232,0.928
+0.077,0.239,0.933
+0.080,0.246,0.937
+0.084,0.254,0.940
+0.089,0.262,0.941
+0.094,0.271,0.941
+0.099,0.280,0.939
+0.104,0.290,0.934
+0.110,0.301,0.928
+0.114,0.312,0.920
+0.119,0.324,0.910
+0.122,0.335,0.898
+0.123,0.347,0.885
+0.124,0.359,0.871
+0.123,0.371,0.856
+0.120,0.383,0.841
+0.115,0.395,0.824
+0.109,0.406,0.808
+0.101,0.418,0.791
+0.091,0.429,0.774
+0.079,0.439,0.756
+0.066,0.450,0.739
+0.051,0.460,0.721
+0.037,0.470,0.703
+0.026,0.479,0.684
+0.021,0.488,0.665
+0.022,0.497,0.646
+0.030,0.506,0.627
+0.045,0.514,0.607
+0.063,0.522,0.586
+0.081,0.529,0.565
+0.099,0.537,0.544
+0.115,0.544,0.522
+0.129,0.551,0.500
+0.142,0.558,0.478
+0.153,0.565,0.455
+0.163,0.572,0.432
+0.171,0.579,0.408
+0.177,0.586,0.385
+0.181,0.593,0.361
+0.184,0.600,0.337
+0.187,0.607,0.313
+0.188,0.613,0.289
+0.189,0.620,0.265
+0.191,0.626,0.242
+0.193,0.633,0.219
+0.195,0.639,0.196
+0.200,0.645,0.174
+0.206,0.651,0.153
+0.214,0.656,0.133
+0.224,0.662,0.115
+0.235,0.667,0.098
+0.248,0.672,0.082
+0.262,0.677,0.069
+0.276,0.681,0.057
+0.291,0.686,0.047
+0.306,0.690,0.039
+0.321,0.694,0.033
+0.337,0.699,0.029
+0.351,0.703,0.027
+0.366,0.707,0.025
+0.381,0.711,0.024
+0.395,0.715,0.023
+0.409,0.719,0.023
+0.423,0.724,0.022
+0.437,0.728,0.021
+0.450,0.732,0.021
+0.464,0.736,0.020
+0.477,0.740,0.020
+0.490,0.744,0.020
+0.503,0.748,0.019
+0.515,0.752,0.019
+0.528,0.756,0.018
+0.541,0.760,0.018
+0.553,0.764,0.017
+0.566,0.768,0.017
+0.578,0.772,0.016
+0.590,0.776,0.016
+0.602,0.780,0.015
+0.615,0.784,0.015
+0.627,0.788,0.014
+0.639,0.792,0.014
+0.651,0.795,0.013
+0.663,0.799,0.013
+0.674,0.803,0.012
+0.686,0.807,0.012
+0.698,0.811,0.012
+0.710,0.815,0.011
+0.722,0.819,0.011
+0.733,0.823,0.010
+0.745,0.826,0.010
+0.757,0.830,0.009
+0.769,0.834,0.009
+0.780,0.838,0.008
+0.792,0.842,0.008
+0.803,0.845,0.008
+0.815,0.849,0.007
+0.827,0.853,0.007
+0.838,0.856,0.007
+0.850,0.860,0.006
+0.861,0.863,0.006
+0.873,0.866,0.006
+0.884,0.869,0.006
+0.895,0.871,0.006
+0.906,0.873,0.007
+0.916,0.874,0.007
+0.926,0.874,0.008
+0.935,0.873,0.010
+0.943,0.872,0.011
+0.950,0.869,0.013
+0.957,0.866,0.015
+0.962,0.862,0.018
+0.967,0.857,0.020
+0.971,0.851,0.023
+0.974,0.845,0.026
+0.977,0.838,0.029
+0.979,0.831,0.032
+0.980,0.824,0.035
+0.981,0.816,0.038
+0.982,0.809,0.041
+0.983,0.801,0.044
+0.984,0.793,0.047
+0.984,0.785,0.049
+0.985,0.777,0.052
+0.985,0.769,0.054
+0.985,0.761,0.056
+0.986,0.753,0.058
+0.986,0.745,0.060
+0.986,0.737,0.062
+0.986,0.729,0.064
+0.987,0.721,0.066
+0.987,0.713,0.068
+0.987,0.705,0.069
+0.987,0.697,0.071
+0.987,0.689,0.073
+0.987,0.681,0.074
+0.987,0.673,0.075
+0.987,0.664,0.077
+0.987,0.656,0.078
+0.987,0.648,0.079
+0.987,0.640,0.081
+0.987,0.631,0.082
+0.987,0.623,0.083
+0.987,0.614,0.083
+0.987,0.606,0.084
+0.987,0.597,0.084
+0.987,0.588,0.085
+0.987,0.580,0.085
+0.987,0.571,0.084
+0.987,0.561,0.084
+0.988,0.552,0.083
+0.988,0.543,0.082
+0.989,0.533,0.081
+0.990,0.524,0.080
+0.990,0.514,0.079
+0.991,0.504,0.077
+0.992,0.494,0.076
+0.992,0.483,0.074
+0.993,0.473,0.073
+0.994,0.462,0.071
+0.994,0.452,0.070
+0.995,0.441,0.068
+0.995,0.430,0.067
+0.996,0.418,0.065
+0.996,0.407,0.064
+0.997,0.395,0.063
+0.997,0.383,0.061
+0.997,0.371,0.060
+0.998,0.358,0.059
+0.998,0.345,0.058
+0.998,0.332,0.057
+0.998,0.319,0.056
+0.998,0.305,0.055
+0.997,0.291,0.054
+0.996,0.277,0.053
+0.995,0.262,0.053
+0.993,0.248,0.052
+0.991,0.234,0.052
+0.989,0.221,0.051
+0.985,0.207,0.051
+0.981,0.195,0.051
+0.977,0.183,0.051
+0.972,0.172,0.051
+0.966,0.161,0.051
+0.960,0.152,0.051
+0.953,0.143,0.051
+0.947,0.135,0.051
+0.939,0.127,0.051
+0.932,0.120,0.051
+0.925,0.113,0.051
+0.917,0.106,0.052
+0.910,0.099,0.052
+0.902,0.092,0.052
+0.895,0.085,0.052
+0.887,0.077,0.052
+0.880,0.069,0.052
+0.872,0.061,0.052
+0.864,0.052,0.052
+0.857,0.042,0.052
+0.849,0.031,0.052
+0.842,0.020,0.052
diff --git a/pyqtgraph/console/CmdInput.py b/pyqtgraph/console/CmdInput.py
index 21d25382..1148e289 100644
--- a/pyqtgraph/console/CmdInput.py
+++ b/pyqtgraph/console/CmdInput.py
@@ -24,7 +24,7 @@ class CmdInput(QtGui.QLineEdit):
elif ev.key() == QtCore.Qt.Key_Return:
self.execCmd()
else:
- QtGui.QLineEdit.keyPressEvent(self, ev)
+ super().keyPressEvent(ev)
self.history[0] = asUnicode(self.text())
def execCmd(self):
diff --git a/pyqtgraph/console/Console.py b/pyqtgraph/console/Console.py
index 43cfff00..579984c9 100644
--- a/pyqtgraph/console/Console.py
+++ b/pyqtgraph/console/Console.py
@@ -7,14 +7,9 @@ from ..python2_3 import basestring
from .. import exceptionHandling as exceptionHandling
from .. import getConfigOption
from ..functions import SignalBlock
-if QT_LIB == 'PySide':
- from . import template_pyside as template
-elif QT_LIB == 'PySide2':
- from . import template_pyside2 as template
-elif QT_LIB == 'PyQt5':
- from . import template_pyqt5 as template
-else:
- from . import template_pyqt as template
+import importlib
+ui_template = importlib.import_module(
+ f'.template_{QT_LIB.lower()}', package=__package__)
class ConsoleWidget(QtGui.QWidget):
@@ -60,7 +55,7 @@ class ConsoleWidget(QtGui.QWidget):
self.inCmd = False
self.frames = [] # stack frames to access when an item in the stack list is selected
- self.ui = template.Ui_Form()
+ self.ui = ui_template.Ui_Form()
self.ui.setupUi(self)
self.output = self.ui.output
self.input = self.ui.input
diff --git a/pyqtgraph/console/template_pyqt6.py b/pyqtgraph/console/template_pyqt6.py
new file mode 100644
index 00000000..0208f128
--- /dev/null
+++ b/pyqtgraph/console/template_pyqt6.py
@@ -0,0 +1,115 @@
+# Form implementation generated from reading ui file 'pyqtgraph\console\template.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(739, 497)
+ self.gridLayout = QtWidgets.QGridLayout(Form)
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout.setSpacing(0)
+ self.gridLayout.setObjectName("gridLayout")
+ self.splitter = QtWidgets.QSplitter(Form)
+ self.splitter.setOrientation(QtCore.Qt.Orientations.Vertical)
+ self.splitter.setObjectName("splitter")
+ self.layoutWidget = QtWidgets.QWidget(self.splitter)
+ self.layoutWidget.setObjectName("layoutWidget")
+ self.verticalLayout = QtWidgets.QVBoxLayout(self.layoutWidget)
+ self.verticalLayout.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout.setObjectName("verticalLayout")
+ self.output = QtWidgets.QPlainTextEdit(self.layoutWidget)
+ font = QtGui.QFont()
+ font.setFamily("Monospace")
+ self.output.setFont(font)
+ self.output.setReadOnly(True)
+ self.output.setObjectName("output")
+ self.verticalLayout.addWidget(self.output)
+ self.horizontalLayout = QtWidgets.QHBoxLayout()
+ self.horizontalLayout.setObjectName("horizontalLayout")
+ self.input = CmdInput(self.layoutWidget)
+ self.input.setObjectName("input")
+ self.horizontalLayout.addWidget(self.input)
+ self.historyBtn = QtWidgets.QPushButton(self.layoutWidget)
+ self.historyBtn.setCheckable(True)
+ self.historyBtn.setObjectName("historyBtn")
+ self.horizontalLayout.addWidget(self.historyBtn)
+ self.exceptionBtn = QtWidgets.QPushButton(self.layoutWidget)
+ self.exceptionBtn.setCheckable(True)
+ self.exceptionBtn.setObjectName("exceptionBtn")
+ self.horizontalLayout.addWidget(self.exceptionBtn)
+ self.verticalLayout.addLayout(self.horizontalLayout)
+ self.historyList = QtWidgets.QListWidget(self.splitter)
+ font = QtGui.QFont()
+ font.setFamily("Monospace")
+ self.historyList.setFont(font)
+ self.historyList.setObjectName("historyList")
+ self.exceptionGroup = QtWidgets.QGroupBox(self.splitter)
+ self.exceptionGroup.setObjectName("exceptionGroup")
+ self.gridLayout_2 = QtWidgets.QGridLayout(self.exceptionGroup)
+ self.gridLayout_2.setContentsMargins(-1, 0, -1, 0)
+ self.gridLayout_2.setHorizontalSpacing(2)
+ self.gridLayout_2.setVerticalSpacing(0)
+ self.gridLayout_2.setObjectName("gridLayout_2")
+ self.clearExceptionBtn = QtWidgets.QPushButton(self.exceptionGroup)
+ self.clearExceptionBtn.setEnabled(False)
+ self.clearExceptionBtn.setObjectName("clearExceptionBtn")
+ self.gridLayout_2.addWidget(self.clearExceptionBtn, 0, 6, 1, 1)
+ self.catchAllExceptionsBtn = QtWidgets.QPushButton(self.exceptionGroup)
+ self.catchAllExceptionsBtn.setCheckable(True)
+ self.catchAllExceptionsBtn.setObjectName("catchAllExceptionsBtn")
+ self.gridLayout_2.addWidget(self.catchAllExceptionsBtn, 0, 1, 1, 1)
+ self.catchNextExceptionBtn = QtWidgets.QPushButton(self.exceptionGroup)
+ self.catchNextExceptionBtn.setCheckable(True)
+ self.catchNextExceptionBtn.setObjectName("catchNextExceptionBtn")
+ self.gridLayout_2.addWidget(self.catchNextExceptionBtn, 0, 0, 1, 1)
+ self.onlyUncaughtCheck = QtWidgets.QCheckBox(self.exceptionGroup)
+ self.onlyUncaughtCheck.setChecked(True)
+ self.onlyUncaughtCheck.setObjectName("onlyUncaughtCheck")
+ self.gridLayout_2.addWidget(self.onlyUncaughtCheck, 0, 4, 1, 1)
+ self.exceptionStackList = QtWidgets.QListWidget(self.exceptionGroup)
+ self.exceptionStackList.setAlternatingRowColors(True)
+ self.exceptionStackList.setObjectName("exceptionStackList")
+ self.gridLayout_2.addWidget(self.exceptionStackList, 2, 0, 1, 7)
+ self.runSelectedFrameCheck = QtWidgets.QCheckBox(self.exceptionGroup)
+ self.runSelectedFrameCheck.setChecked(True)
+ self.runSelectedFrameCheck.setObjectName("runSelectedFrameCheck")
+ self.gridLayout_2.addWidget(self.runSelectedFrameCheck, 3, 0, 1, 7)
+ self.exceptionInfoLabel = QtWidgets.QLabel(self.exceptionGroup)
+ self.exceptionInfoLabel.setWordWrap(True)
+ self.exceptionInfoLabel.setObjectName("exceptionInfoLabel")
+ self.gridLayout_2.addWidget(self.exceptionInfoLabel, 1, 0, 1, 7)
+ spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
+ self.gridLayout_2.addItem(spacerItem, 0, 5, 1, 1)
+ self.label = QtWidgets.QLabel(self.exceptionGroup)
+ self.label.setObjectName("label")
+ self.gridLayout_2.addWidget(self.label, 0, 2, 1, 1)
+ self.filterText = QtWidgets.QLineEdit(self.exceptionGroup)
+ self.filterText.setObjectName("filterText")
+ self.gridLayout_2.addWidget(self.filterText, 0, 3, 1, 1)
+ self.gridLayout.addWidget(self.splitter, 0, 0, 1, 1)
+
+ self.retranslateUi(Form)
+ QtCore.QMetaObject.connectSlotsByName(Form)
+
+ def retranslateUi(self, Form):
+ _translate = QtCore.QCoreApplication.translate
+ Form.setWindowTitle(_translate("Form", "Console"))
+ self.historyBtn.setText(_translate("Form", "History.."))
+ self.exceptionBtn.setText(_translate("Form", "Exceptions.."))
+ self.exceptionGroup.setTitle(_translate("Form", "Exception Handling"))
+ self.clearExceptionBtn.setText(_translate("Form", "Clear Stack"))
+ self.catchAllExceptionsBtn.setText(_translate("Form", "Show All Exceptions"))
+ self.catchNextExceptionBtn.setText(_translate("Form", "Show Next Exception"))
+ self.onlyUncaughtCheck.setText(_translate("Form", "Only Uncaught Exceptions"))
+ self.runSelectedFrameCheck.setText(_translate("Form", "Run commands in selected stack frame"))
+ self.exceptionInfoLabel.setText(_translate("Form", "Stack Trace"))
+ self.label.setText(_translate("Form", "Filter (regex):"))
+from .CmdInput import CmdInput
diff --git a/pyqtgraph/console/template_pyside6.py b/pyqtgraph/console/template_pyside6.py
new file mode 100644
index 00000000..22a2aba6
--- /dev/null
+++ b/pyqtgraph/console/template_pyside6.py
@@ -0,0 +1,157 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'template.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 .CmdInput import CmdInput
+
+
+class Ui_Form(object):
+ def setupUi(self, Form):
+ if not Form.objectName():
+ Form.setObjectName(u"Form")
+ Form.resize(739, 497)
+ self.gridLayout = QGridLayout(Form)
+ self.gridLayout.setSpacing(0)
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout.setObjectName(u"gridLayout")
+ self.splitter = QSplitter(Form)
+ self.splitter.setObjectName(u"splitter")
+ self.splitter.setOrientation(Qt.Vertical)
+ self.layoutWidget = QWidget(self.splitter)
+ self.layoutWidget.setObjectName(u"layoutWidget")
+ self.verticalLayout = QVBoxLayout(self.layoutWidget)
+ self.verticalLayout.setObjectName(u"verticalLayout")
+ self.verticalLayout.setContentsMargins(0, 0, 0, 0)
+ self.output = QPlainTextEdit(self.layoutWidget)
+ self.output.setObjectName(u"output")
+ font = QFont()
+ font.setFamily(u"Monospace")
+ self.output.setFont(font)
+ self.output.setReadOnly(True)
+
+ self.verticalLayout.addWidget(self.output)
+
+ self.horizontalLayout = QHBoxLayout()
+ self.horizontalLayout.setObjectName(u"horizontalLayout")
+ self.input = CmdInput(self.layoutWidget)
+ self.input.setObjectName(u"input")
+
+ self.horizontalLayout.addWidget(self.input)
+
+ self.historyBtn = QPushButton(self.layoutWidget)
+ self.historyBtn.setObjectName(u"historyBtn")
+ self.historyBtn.setCheckable(True)
+
+ self.horizontalLayout.addWidget(self.historyBtn)
+
+ self.exceptionBtn = QPushButton(self.layoutWidget)
+ self.exceptionBtn.setObjectName(u"exceptionBtn")
+ self.exceptionBtn.setCheckable(True)
+
+ self.horizontalLayout.addWidget(self.exceptionBtn)
+
+
+ self.verticalLayout.addLayout(self.horizontalLayout)
+
+ self.splitter.addWidget(self.layoutWidget)
+ self.historyList = QListWidget(self.splitter)
+ self.historyList.setObjectName(u"historyList")
+ self.historyList.setFont(font)
+ self.splitter.addWidget(self.historyList)
+ self.exceptionGroup = QGroupBox(self.splitter)
+ self.exceptionGroup.setObjectName(u"exceptionGroup")
+ self.gridLayout_2 = QGridLayout(self.exceptionGroup)
+ self.gridLayout_2.setObjectName(u"gridLayout_2")
+ self.gridLayout_2.setHorizontalSpacing(2)
+ self.gridLayout_2.setVerticalSpacing(0)
+ self.gridLayout_2.setContentsMargins(-1, 0, -1, 0)
+ self.clearExceptionBtn = QPushButton(self.exceptionGroup)
+ self.clearExceptionBtn.setObjectName(u"clearExceptionBtn")
+ self.clearExceptionBtn.setEnabled(False)
+
+ self.gridLayout_2.addWidget(self.clearExceptionBtn, 0, 6, 1, 1)
+
+ self.catchAllExceptionsBtn = QPushButton(self.exceptionGroup)
+ self.catchAllExceptionsBtn.setObjectName(u"catchAllExceptionsBtn")
+ self.catchAllExceptionsBtn.setCheckable(True)
+
+ self.gridLayout_2.addWidget(self.catchAllExceptionsBtn, 0, 1, 1, 1)
+
+ self.catchNextExceptionBtn = QPushButton(self.exceptionGroup)
+ self.catchNextExceptionBtn.setObjectName(u"catchNextExceptionBtn")
+ self.catchNextExceptionBtn.setCheckable(True)
+
+ self.gridLayout_2.addWidget(self.catchNextExceptionBtn, 0, 0, 1, 1)
+
+ self.onlyUncaughtCheck = QCheckBox(self.exceptionGroup)
+ self.onlyUncaughtCheck.setObjectName(u"onlyUncaughtCheck")
+ self.onlyUncaughtCheck.setChecked(True)
+
+ self.gridLayout_2.addWidget(self.onlyUncaughtCheck, 0, 4, 1, 1)
+
+ self.exceptionStackList = QListWidget(self.exceptionGroup)
+ self.exceptionStackList.setObjectName(u"exceptionStackList")
+ self.exceptionStackList.setAlternatingRowColors(True)
+
+ self.gridLayout_2.addWidget(self.exceptionStackList, 2, 0, 1, 7)
+
+ self.runSelectedFrameCheck = QCheckBox(self.exceptionGroup)
+ self.runSelectedFrameCheck.setObjectName(u"runSelectedFrameCheck")
+ self.runSelectedFrameCheck.setChecked(True)
+
+ self.gridLayout_2.addWidget(self.runSelectedFrameCheck, 3, 0, 1, 7)
+
+ self.exceptionInfoLabel = QLabel(self.exceptionGroup)
+ self.exceptionInfoLabel.setObjectName(u"exceptionInfoLabel")
+ self.exceptionInfoLabel.setWordWrap(True)
+
+ self.gridLayout_2.addWidget(self.exceptionInfoLabel, 1, 0, 1, 7)
+
+ self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
+
+ self.gridLayout_2.addItem(self.horizontalSpacer, 0, 5, 1, 1)
+
+ self.label = QLabel(self.exceptionGroup)
+ self.label.setObjectName(u"label")
+
+ self.gridLayout_2.addWidget(self.label, 0, 2, 1, 1)
+
+ self.filterText = QLineEdit(self.exceptionGroup)
+ self.filterText.setObjectName(u"filterText")
+
+ self.gridLayout_2.addWidget(self.filterText, 0, 3, 1, 1)
+
+ self.splitter.addWidget(self.exceptionGroup)
+
+ self.gridLayout.addWidget(self.splitter, 0, 0, 1, 1)
+
+
+ self.retranslateUi(Form)
+
+ QMetaObject.connectSlotsByName(Form)
+ # setupUi
+
+ def retranslateUi(self, Form):
+ Form.setWindowTitle(QCoreApplication.translate("Form", u"Console", None))
+ self.historyBtn.setText(QCoreApplication.translate("Form", u"History..", None))
+ self.exceptionBtn.setText(QCoreApplication.translate("Form", u"Exceptions..", None))
+ self.exceptionGroup.setTitle(QCoreApplication.translate("Form", u"Exception Handling", None))
+ self.clearExceptionBtn.setText(QCoreApplication.translate("Form", u"Clear Stack", None))
+ self.catchAllExceptionsBtn.setText(QCoreApplication.translate("Form", u"Show All Exceptions", None))
+ self.catchNextExceptionBtn.setText(QCoreApplication.translate("Form", u"Show Next Exception", None))
+ self.onlyUncaughtCheck.setText(QCoreApplication.translate("Form", u"Only Uncaught Exceptions", None))
+ self.runSelectedFrameCheck.setText(QCoreApplication.translate("Form", u"Run commands in selected stack frame", None))
+ self.exceptionInfoLabel.setText(QCoreApplication.translate("Form", u"Stack Trace", None))
+ self.label.setText(QCoreApplication.translate("Form", u"Filter (regex):", None))
+ # retranslateUi
+
diff --git a/pyqtgraph/dockarea/Container.py b/pyqtgraph/dockarea/Container.py
index bc0b3648..04b775f9 100644
--- a/pyqtgraph/dockarea/Container.py
+++ b/pyqtgraph/dockarea/Container.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-from ..Qt import QtCore, QtGui
+from ..Qt import QtCore, QtGui, QtWidgets
import weakref
class Container(object):
@@ -76,7 +76,11 @@ class Container(object):
self.area.topContainer = None
self.containerChanged(None)
- def childEvent(self, ev):
+ def childEvent_(self, ev):
+ # NOTE: this method has been renamed to avoid having the same method name as
+ # QSplitter.childEvent()
+ # this causes problems for PyQt6 since SplitContainer inherits from
+ # Container and QSplitter.
ch = ev.child()
if ev.removed() and hasattr(ch, 'sigStretchChanged'):
#print "Child", ev.child(), "removed, updating", self
@@ -133,8 +137,8 @@ class SplitContainer(Container, QtGui.QSplitter):
self.setStretchFactor(i, sizes[i])
def childEvent(self, ev):
- QtGui.QSplitter.childEvent(self, ev)
- Container.childEvent(self, ev)
+ super().childEvent(ev) # call QSplitter.childEvent()
+ Container.childEvent_(self, ev)
#def restretchChildren(self):
#sizes = self.sizes()
@@ -204,6 +208,16 @@ class VContainer(SplitContainer):
self.setSizes([int(s*scale) for s in sizes])
+class StackedWidget(QtWidgets.QStackedWidget):
+ def __init__(self, *, container):
+ super().__init__()
+ self.container = container
+
+ def childEvent(self, ev):
+ super().childEvent(ev)
+ self.container.childEvent_(ev)
+
+
class TContainer(Container, QtGui.QWidget):
sigStretchChanged = QtCore.Signal()
def __init__(self, area):
@@ -221,9 +235,8 @@ class TContainer(Container, QtGui.QWidget):
self.hTabLayout.setContentsMargins(0,0,0,0)
self.layout.addWidget(self.hTabBox, 0, 1)
- self.stack = QtGui.QStackedWidget()
+ self.stack = StackedWidget(container=self)
self.layout.addWidget(self.stack, 1, 1)
- self.stack.childEvent = self.stackChildEvent
self.setLayout(self.layout)
@@ -276,8 +289,4 @@ class TContainer(Container, QtGui.QWidget):
y = max(y, wy)
self.setStretch(x, y)
- def stackChildEvent(self, ev):
- QtGui.QStackedWidget.childEvent(self.stack, ev)
- Container.childEvent(self, ev)
-
from . import Dock
diff --git a/pyqtgraph/dockarea/Dock.py b/pyqtgraph/dockarea/Dock.py
index f1dd64f3..a4997b8c 100644
--- a/pyqtgraph/dockarea/Dock.py
+++ b/pyqtgraph/dockarea/Dock.py
@@ -5,6 +5,7 @@ from .DockDrop import *
from ..widgets.VerticalLabel import VerticalLabel
from ..python2_3 import asUnicode
+
class Dock(QtGui.QWidget, DockDrop):
sigStretchChanged = QtCore.Signal()
@@ -328,13 +329,13 @@ class DockLabel(VerticalLabel):
self.updateStyle()
def mousePressEvent(self, ev):
- self.pressPos = ev.pos()
+ self.pressPos = ev.localPos()
self.mouseMoved = False
ev.accept()
def mouseMoveEvent(self, ev):
if not self.mouseMoved:
- self.mouseMoved = (ev.pos() - self.pressPos).manhattanLength() > QtGui.QApplication.startDragDistance()
+ self.mouseMoved = (ev.localPos() - self.pressPos).manhattanLength() > QtGui.QApplication.startDragDistance()
if self.mouseMoved and ev.buttons() == QtCore.Qt.LeftButton:
self.dock.startDrag()
diff --git a/pyqtgraph/dockarea/DockArea.py b/pyqtgraph/dockarea/DockArea.py
index 93841e0a..ee9a5f53 100644
--- a/pyqtgraph/dockarea/DockArea.py
+++ b/pyqtgraph/dockarea/DockArea.py
@@ -382,4 +382,4 @@ class TempAreaWindow(QtGui.QWidget):
dock.orig_area.addDock(dock, )
# clear dock area, and close remaining docks
self.dockarea.clear()
- QtGui.QWidget.closeEvent(self, *args)
+ super().closeEvent(*args)
diff --git a/pyqtgraph/dockarea/DockDrop.py b/pyqtgraph/dockarea/DockDrop.py
index bd364f50..e16f3e7a 100644
--- a/pyqtgraph/dockarea/DockDrop.py
+++ b/pyqtgraph/dockarea/DockDrop.py
@@ -30,9 +30,9 @@ class DockDrop(object):
def dragMoveEvent(self, ev):
#print "drag move"
- ld = ev.pos().x()
+ ld = ev.posF().x()
rd = self.width() - ld
- td = ev.pos().y()
+ td = ev.posF().y()
bd = self.height() - td
mn = min(ld, rd, td, bd)
diff --git a/pyqtgraph/exporters/CSVExporter.py b/pyqtgraph/exporters/CSVExporter.py
index 33c6ec69..aec27a16 100644
--- a/pyqtgraph/exporters/CSVExporter.py
+++ b/pyqtgraph/exporters/CSVExporter.py
@@ -5,6 +5,8 @@ from ..parametertree import Parameter
from .. import PlotItem
from ..python2_3 import asUnicode
+translate = QtCore.QCoreApplication.translate
+
__all__ = ['CSVExporter']
@@ -14,9 +16,9 @@ class CSVExporter(Exporter):
def __init__(self, item):
Exporter.__init__(self, item)
self.params = Parameter(name='params', type='group', children=[
- {'name': 'separator', 'type': 'list', 'value': 'comma', 'values': ['comma', 'tab']},
- {'name': 'precision', 'type': 'int', 'value': 10, 'limits': [0, None]},
- {'name': 'columnMode', 'type': 'list', 'values': ['(x,y) per plot', '(x,y,y,y) for all plots']}
+ {'name': 'separator', 'title': translate("Exporter", 'separator'), 'type': 'list', 'value': 'comma', 'values': ['comma', 'tab']},
+ {'name': 'precision', 'title': translate("Exporter", 'precision'), 'type': 'int', 'value': 10, 'limits': [0, None]},
+ {'name': 'columnMode', 'title': translate("Exporter", 'columnMode'), 'type': 'list', 'values': ['(x,y) per plot', '(x,y,y,y) for all plots']}
])
def parameters(self):
@@ -81,5 +83,3 @@ class CSVExporter(Exporter):
CSVExporter.register()
-
-
diff --git a/pyqtgraph/exporters/Exporter.py b/pyqtgraph/exporters/Exporter.py
index 792e36bd..c89ef050 100644
--- a/pyqtgraph/exporters/Exporter.py
+++ b/pyqtgraph/exporters/Exporter.py
@@ -128,7 +128,8 @@ class Exporter(object):
while len(childs) > 0:
ch = childs.pop(0)
tree = self.getPaintItems(ch)
- if int(ch.flags() & ch.ItemStacksBehindParent) > 0 or (ch.zValue() < 0 and int(ch.flags() & ch.ItemNegativeZStacksBehindParent) > 0):
+ if (ch.flags() & ch.ItemStacksBehindParent) or \
+ (ch.zValue() < 0 and (ch.flags() & ch.ItemNegativeZStacksBehindParent)):
preItems.extend(tree)
else:
postItems.extend(tree)
diff --git a/pyqtgraph/exporters/HDF5Exporter.py b/pyqtgraph/exporters/HDF5Exporter.py
index 2a2ac19c..83499a86 100644
--- a/pyqtgraph/exporters/HDF5Exporter.py
+++ b/pyqtgraph/exporters/HDF5Exporter.py
@@ -9,7 +9,9 @@ try:
HAVE_HDF5 = True
except ImportError:
HAVE_HDF5 = False
-
+
+translate = QtCore.QCoreApplication.translate
+
__all__ = ['HDF5Exporter']
@@ -21,8 +23,9 @@ class HDF5Exporter(Exporter):
def __init__(self, item):
Exporter.__init__(self, item)
self.params = Parameter(name='params', type='group', children=[
- {'name': 'Name', 'type': 'str', 'value': 'Export',},
- {'name': 'columnMode', 'type': 'list', 'values': ['(x,y) per plot', '(x,y,y,y) for all plots']},
+ {'name': 'Name', 'title': translate("Exporter", 'Name'), 'type': 'str', 'value': 'Export', },
+ {'name': 'columnMode', 'title': translate("Exporter", 'columnMode'), 'type': 'list',
+ 'values': ['(x,y) per plot', '(x,y,y,y) for all plots']},
])
def parameters(self):
@@ -40,7 +43,7 @@ class HDF5Exporter(Exporter):
self.fileSaveDialog(filter=["*.h5", "*.hdf", "*.hd5"])
return
dsname = self.params['Name']
- fd = h5py.File(fileName, 'a') # forces append to file... 'w' doesn't seem to "delete/overwrite"
+ fd = h5py.File(fileName, 'a') # forces append to file... 'w' doesn't seem to "delete/overwrite"
data = []
appendAllX = self.params['columnMode'] == '(x,y) per plot'
diff --git a/pyqtgraph/exporters/ImageExporter.py b/pyqtgraph/exporters/ImageExporter.py
index cacddee1..1e1ac103 100644
--- a/pyqtgraph/exporters/ImageExporter.py
+++ b/pyqtgraph/exporters/ImageExporter.py
@@ -4,6 +4,7 @@ from ..Qt import QtGui, QtCore, QtSvg, QT_LIB
from .. import functions as fn
import numpy as np
+translate = QtCore.QCoreApplication.translate
__all__ = ['ImageExporter']
class ImageExporter(Exporter):
@@ -21,13 +22,15 @@ class ImageExporter(Exporter):
bg = bgbrush.color()
if bgbrush.style() == QtCore.Qt.NoBrush:
bg.setAlpha(0)
-
+
self.params = Parameter(name='params', type='group', children=[
- {'name': 'width', 'type': 'int', 'value': int(tr.width()), 'limits': (0, None)},
- {'name': 'height', 'type': 'int', 'value': int(tr.height()), 'limits': (0, None)},
- {'name': 'antialias', 'type': 'bool', 'value': True},
- {'name': 'background', 'type': 'color', 'value': bg},
- {'name': 'invertValue', 'type': 'bool', 'value': False}
+ {'name': 'width', 'title': translate("Exporter", 'width'), 'type': 'int', 'value': int(tr.width()),
+ 'limits': (0, None)},
+ {'name': 'height', 'title': translate("Exporter", 'height'), 'type': 'int', 'value': int(tr.height()),
+ 'limits': (0, None)},
+ {'name': 'antialias', 'title': translate("Exporter", 'antialias'), 'type': 'bool', 'value': True},
+ {'name': 'background', 'title': translate("Exporter", 'background'), 'type': 'color', 'value': bg},
+ {'name': 'invertValue', 'title': translate("Exporter", 'invertValue'), 'type': 'bool', 'value': False}
])
self.params.param('width').sigValueChanged.connect(self.widthChanged)
self.params.param('height').sigValueChanged.connect(self.heightChanged)
@@ -89,7 +92,11 @@ class ImageExporter(Exporter):
painter = QtGui.QPainter(self.png)
#dtr = painter.deviceTransform()
try:
- self.setExportMode(True, {'antialias': self.params['antialias'], 'background': self.params['background'], 'painter': painter, 'resolutionScale': resolutionScale})
+ self.setExportMode(True, {
+ 'antialias': self.params['antialias'],
+ 'background': self.params['background'],
+ 'painter': painter,
+ 'resolutionScale': resolutionScale})
painter.setRenderHint(QtGui.QPainter.Antialiasing, self.params['antialias'])
self.getScene().render(painter, QtCore.QRectF(targetRect), QtCore.QRectF(sourceRect))
finally:
@@ -109,5 +116,4 @@ class ImageExporter(Exporter):
else:
return self.png.save(fileName)
-ImageExporter.register()
-
+ImageExporter.register()
diff --git a/pyqtgraph/exporters/PrintExporter.py b/pyqtgraph/exporters/PrintExporter.py
index 530a1800..1b9860bd 100644
--- a/pyqtgraph/exporters/PrintExporter.py
+++ b/pyqtgraph/exporters/PrintExporter.py
@@ -3,6 +3,8 @@ from ..parametertree import Parameter
from ..Qt import QtGui, QtCore, QtSvg
import re
+translate = QtCore.QCoreApplication.translate
+
__all__ = ['PrintExporter']
#__all__ = [] ## Printer is disabled for now--does not work very well.
@@ -12,8 +14,10 @@ class PrintExporter(Exporter):
Exporter.__init__(self, item)
tr = self.getTargetRect()
self.params = Parameter(name='params', type='group', children=[
- {'name': 'width', 'type': 'float', 'value': 0.1, 'limits': (0, None), 'suffix': 'm', 'siPrefix': True},
- {'name': 'height', 'type': 'float', 'value': (0.1 * tr.height()) / tr.width(), 'limits': (0, None), 'suffix': 'm', 'siPrefix': True},
+ {'name': 'width', 'title': translate("Exporter", 'width'), 'type': 'float', 'value': 0.1,
+ 'limits': (0, None), 'suffix': 'm', 'siPrefix': True},
+ {'name': 'height', 'title': translate("Exporter", 'height'), 'type': 'float',
+ 'value': (0.1 * tr.height()) / tr.width(), 'limits': (0, None), 'suffix': 'm', 'siPrefix': True},
])
self.params.param('width').sigValueChanged.connect(self.widthChanged)
self.params.param('height').sigValueChanged.connect(self.heightChanged)
@@ -22,19 +26,19 @@ class PrintExporter(Exporter):
sr = self.getSourceRect()
ar = sr.height() / sr.width()
self.params.param('height').setValue(self.params['width'] * ar, blockSignal=self.heightChanged)
-
+
def heightChanged(self):
sr = self.getSourceRect()
ar = sr.width() / sr.height()
self.params.param('width').setValue(self.params['height'] * ar, blockSignal=self.widthChanged)
-
+
def parameters(self):
return self.params
def export(self, fileName=None):
printer = QtGui.QPrinter(QtGui.QPrinter.HighResolution)
dialog = QtGui.QPrintDialog(printer)
- dialog.setWindowTitle("Print Document")
+ dialog.setWindowTitle(translate('Exporter', "Print Document"))
if dialog.exec_() != QtGui.QDialog.Accepted:
return
@@ -45,7 +49,7 @@ class PrintExporter(Exporter):
#res = printer.resolution()
sr = self.getSourceRect()
#res = sr.width() * .4 / (self.params['width'] * 100 / 2.54)
- res = QtGui.QDesktopWidget().physicalDpiX()
+ res = QtGui.QGuiApplication.primaryScreen().physicalDotsPerInchX()
printer.setResolution(res)
rect = printer.pageRect()
center = rect.center()
diff --git a/pyqtgraph/exporters/SVGExporter.py b/pyqtgraph/exporters/SVGExporter.py
index ac51732f..ac02990a 100644
--- a/pyqtgraph/exporters/SVGExporter.py
+++ b/pyqtgraph/exporters/SVGExporter.py
@@ -8,6 +8,7 @@ import re
import xml.dom.minidom as xml
import numpy as np
+translate = QtCore.QCoreApplication.translate
__all__ = ['SVGExporter']
@@ -29,12 +30,14 @@ class SVGExporter(Exporter):
bg.setAlpha(0)
self.params = Parameter(name='params', type='group', children=[
- {'name': 'background', 'type': 'color', 'value': bg},
- {'name': 'width', 'type': 'float', 'value': tr.width(), 'limits': (0, None)},
- {'name': 'height', 'type': 'float', 'value': tr.height(), 'limits': (0, None)},
+ {'name': 'background', 'title': translate("Exporter", 'background'), 'type': 'color', 'value': bg},
+ {'name': 'width', 'title': translate("Exporter", 'width'), 'type': 'float', 'value': tr.width(),
+ 'limits': (0, None)},
+ {'name': 'height', 'title': translate("Exporter", 'height'), 'type': 'float', 'value': tr.height(),
+ 'limits': (0, None)},
#{'name': 'viewbox clipping', 'type': 'bool', 'value': True},
#{'name': 'normalize coordinates', 'type': 'bool', 'value': True},
- {'name': 'scaling stroke', 'type': 'bool', 'value': False, 'tip': "If False, strokes are non-scaling, "
+ {'name': 'scaling stroke', 'title': translate("Exporter", 'scaling stroke'), 'type': 'bool', 'value': False, 'tip': "If False, strokes are non-scaling, "
"which means that they appear the same width on screen regardless of how they are scaled or how the view is zoomed."},
])
self.params.param('width').sigValueChanged.connect(self.widthChanged)
@@ -55,7 +58,7 @@ class SVGExporter(Exporter):
def export(self, fileName=None, toBytes=False, copy=False):
if toBytes is False and copy is False and fileName is None:
- self.fileSaveDialog(filter="Scalable Vector Graphics (*.svg)")
+ self.fileSaveDialog(filter=f"{translate('Exporter', 'Scalable Vector Graphics')} (*.svg)")
return
## Qt's SVG generator is not complete. (notably, it lacks clipping)
@@ -126,9 +129,9 @@ def _generateItemSvg(item, nodes=None, root=None, options={}):
## 1) Qt SVG does not implement clipping paths. This is absurd.
## The solution is to let Qt generate SVG for each item independently,
## then glue them together manually with clipping.
- ##
+ ##
## The format Qt generates for all items looks like this:
- ##
+ ##
##
##
## one or more of: or or
@@ -138,21 +141,21 @@ def _generateItemSvg(item, nodes=None, root=None, options={}):
##
## . . .
##
- ##
+ ##
## 2) There seems to be wide disagreement over whether path strokes
- ## should be scaled anisotropically.
+ ## should be scaled anisotropically.
## see: http://web.mit.edu/jonas/www/anisotropy/
## Given that both inkscape and illustrator seem to prefer isotropic
- ## scaling, we will optimize for those cases.
- ##
- ## 3) Qt generates paths using non-scaling-stroke from SVG 1.2, but
- ## inkscape only supports 1.1.
- ##
+ ## scaling, we will optimize for those cases.
+ ##
+ ## 3) Qt generates paths using non-scaling-stroke from SVG 1.2, but
+ ## inkscape only supports 1.1.
+ ##
## Both 2 and 3 can be addressed by drawing all items in world coordinates.
profiler = debug.Profiler()
- if nodes is None: ## nodes maps all node IDs to their XML element.
+ if nodes is None: ## nodes maps all node IDs to their XML element.
## this allows us to ensure all elements receive unique names.
nodes = {}
@@ -195,7 +198,7 @@ def _generateItemSvg(item, nodes=None, root=None, options={}):
buf = QtCore.QBuffer(arr)
svg = QtSvg.QSvgGenerator()
svg.setOutputDevice(buf)
- dpi = QtGui.QDesktopWidget().logicalDpiX()
+ dpi = QtGui.QGuiApplication.primaryScreen().logicalDotsPerInchX()
svg.setResolution(dpi)
p = QtGui.QPainter()
@@ -251,7 +254,7 @@ def _generateItemSvg(item, nodes=None, root=None, options={}):
childGroup = g1 ## add children directly to this node unless we are clipping
if not isinstance(item, QtGui.QGraphicsScene):
## See if this item clips its children
- if int(item.flags() & item.ItemClipsChildrenToShape) > 0:
+ if item.flags() & item.ItemClipsChildrenToShape:
## Generate svg for just the path
path = QtGui.QGraphicsPathItem(item.mapToScene(item.shape()))
item.scene().addItem(path)
@@ -377,11 +380,11 @@ def correctCoordinates(node, defs, item, options):
families = ch.getAttribute('font-family').split(',')
if len(families) == 1:
font = QtGui.QFont(families[0].strip('" '))
- if font.style() == font.SansSerif:
+ if font.styleHint() == font.StyleHint.SansSerif:
families.append('sans-serif')
- elif font.style() == font.Serif:
+ elif font.styleHint() == font.StyleHint.Serif:
families.append('serif')
- elif font.style() == font.Courier:
+ elif font.styleHint() == font.StyleHint.Courier:
families.append('monospace')
ch.setAttribute('font-family', ', '.join([f if ' ' not in f else '"%s"'%f for f in families]))
@@ -414,7 +417,7 @@ def itemTransform(item, root):
return tr
- if int(item.flags() & item.ItemIgnoresTransformations) > 0:
+ if item.flags() & item.ItemIgnoresTransformations:
pos = item.pos()
parent = item.parentItem()
if parent is not None:
@@ -423,7 +426,7 @@ def itemTransform(item, root):
tr.translate(pos.x(), pos.y())
tr = item.transform() * tr
else:
- ## find next parent that is either the root item or
+ ## find next parent that is either the root item or
## an item that ignores its transformation
nextRoot = item
while True:
@@ -431,7 +434,7 @@ def itemTransform(item, root):
if nextRoot is None:
nextRoot = root
break
- if nextRoot is root or int(nextRoot.flags() & nextRoot.ItemIgnoresTransformations) > 0:
+ if nextRoot is root or (nextRoot.flags() & nextRoot.ItemIgnoresTransformations):
break
if isinstance(nextRoot, QtGui.QGraphicsScene):
diff --git a/pyqtgraph/exporters/tests/test_matplotlib.py b/pyqtgraph/exporters/tests/test_matplotlib.py
index 172394c4..3e3e98dd 100644
--- a/pyqtgraph/exporters/tests/test_matplotlib.py
+++ b/pyqtgraph/exporters/tests/test_matplotlib.py
@@ -6,7 +6,16 @@ pytest.importorskip("matplotlib")
app = pg.mkQApp()
+skip_qt6 = pytest.mark.skipif(
+ pg.QT_LIB in ["PySide6", "PyQt6"],
+ reason= (
+ "Matplotlib has no Qt6 support yet, "
+ "see https://github.com/matplotlib/matplotlib/pull/19255"
+ )
+)
+
+@skip_qt6
def test_MatplotlibExporter():
plt = pg.plot()
@@ -20,7 +29,7 @@ def test_MatplotlibExporter():
exp = MatplotlibExporter(plt.getPlotItem())
exp.export()
-
+@skip_qt6
def test_MatplotlibExporter_nonplotitem():
# attempting to export something other than a PlotItem raises an exception
plt = pg.plot()
@@ -29,7 +38,7 @@ def test_MatplotlibExporter_nonplotitem():
with pytest.raises(Exception):
exp.export()
-
+@skip_qt6
@pytest.mark.parametrize('scale', [1e10, 1e-9])
def test_MatplotlibExporter_siscale(scale):
# coarse test to verify that plot data is scaled before export when
diff --git a/pyqtgraph/flowchart/Flowchart.py b/pyqtgraph/flowchart/Flowchart.py
index 9e85296b..c904e710 100644
--- a/pyqtgraph/flowchart/Flowchart.py
+++ b/pyqtgraph/flowchart/Flowchart.py
@@ -5,19 +5,9 @@ from ..pgcollections import OrderedDict
from ..widgets.TreeWidget import *
from .. import FileDialog, DataTreeWidget
-## pyside and pyqt use incompatible ui files.
-if QT_LIB == 'PySide':
- from . import FlowchartTemplate_pyside as FlowchartTemplate
- from . import FlowchartCtrlTemplate_pyside as FlowchartCtrlTemplate
-elif QT_LIB == 'PySide2':
- from . import FlowchartTemplate_pyside2 as FlowchartTemplate
- from . import FlowchartCtrlTemplate_pyside2 as FlowchartCtrlTemplate
-elif QT_LIB == 'PyQt5':
- from . import FlowchartTemplate_pyqt5 as FlowchartTemplate
- from . import FlowchartCtrlTemplate_pyqt5 as FlowchartCtrlTemplate
-else:
- from . import FlowchartTemplate_pyqt as FlowchartTemplate
- from . import FlowchartCtrlTemplate_pyqt as FlowchartCtrlTemplate
+import importlib
+FlowchartCtrlTemplate = importlib.import_module(
+ f'.FlowchartCtrlTemplate_{QT_LIB.lower()}', package=__package__)
from .Terminal import Terminal
from numpy import ndarray
diff --git a/pyqtgraph/flowchart/FlowchartCtrlTemplate.ui b/pyqtgraph/flowchart/FlowchartCtrlTemplate.ui
index 6a9a203a..5198f920 100644
--- a/pyqtgraph/flowchart/FlowchartCtrlTemplate.ui
+++ b/pyqtgraph/flowchart/FlowchartCtrlTemplate.ui
@@ -89,7 +89,6 @@
- 75
true
diff --git a/pyqtgraph/flowchart/FlowchartCtrlTemplate_pyqt.py b/pyqtgraph/flowchart/FlowchartCtrlTemplate_pyqt.py
deleted file mode 100644
index 3d8bcf56..00000000
--- a/pyqtgraph/flowchart/FlowchartCtrlTemplate_pyqt.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file './pyqtgraph/flowchart/FlowchartCtrlTemplate.ui'
-#
-# Created: Mon Dec 23 10:10:50 2013
-# by: PyQt4 UI code generator 4.10
-#
-# WARNING! All changes made in this file will be lost!
-
-from PyQt4 import QtCore, QtGui
-
-try:
- _fromUtf8 = QtCore.QString.fromUtf8
-except AttributeError:
- def _fromUtf8(s):
- return s
-
-try:
- _encoding = QtGui.QApplication.UnicodeUTF8
- def _translate(context, text, disambig):
- return QtGui.QApplication.translate(context, text, disambig, _encoding)
-except AttributeError:
- def _translate(context, text, disambig):
- return QtGui.QApplication.translate(context, text, disambig)
-
-class Ui_Form(object):
- def setupUi(self, Form):
- Form.setObjectName(_fromUtf8("Form"))
- Form.resize(217, 499)
- self.gridLayout = QtGui.QGridLayout(Form)
- self.gridLayout.setMargin(0)
- self.gridLayout.setVerticalSpacing(0)
- self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
- self.loadBtn = QtGui.QPushButton(Form)
- self.loadBtn.setObjectName(_fromUtf8("loadBtn"))
- self.gridLayout.addWidget(self.loadBtn, 1, 0, 1, 1)
- self.saveBtn = FeedbackButton(Form)
- self.saveBtn.setObjectName(_fromUtf8("saveBtn"))
- self.gridLayout.addWidget(self.saveBtn, 1, 1, 1, 2)
- self.saveAsBtn = FeedbackButton(Form)
- self.saveAsBtn.setObjectName(_fromUtf8("saveAsBtn"))
- self.gridLayout.addWidget(self.saveAsBtn, 1, 3, 1, 1)
- self.reloadBtn = FeedbackButton(Form)
- self.reloadBtn.setCheckable(False)
- self.reloadBtn.setFlat(False)
- self.reloadBtn.setObjectName(_fromUtf8("reloadBtn"))
- self.gridLayout.addWidget(self.reloadBtn, 4, 0, 1, 2)
- self.showChartBtn = QtGui.QPushButton(Form)
- self.showChartBtn.setCheckable(True)
- self.showChartBtn.setObjectName(_fromUtf8("showChartBtn"))
- self.gridLayout.addWidget(self.showChartBtn, 4, 2, 1, 2)
- self.ctrlList = TreeWidget(Form)
- self.ctrlList.setObjectName(_fromUtf8("ctrlList"))
- self.ctrlList.headerItem().setText(0, _fromUtf8("1"))
- self.ctrlList.header().setVisible(False)
- self.ctrlList.header().setStretchLastSection(False)
- self.gridLayout.addWidget(self.ctrlList, 3, 0, 1, 4)
- self.fileNameLabel = QtGui.QLabel(Form)
- font = QtGui.QFont()
- font.setBold(True)
- font.setWeight(75)
- self.fileNameLabel.setFont(font)
- self.fileNameLabel.setText(_fromUtf8(""))
- self.fileNameLabel.setAlignment(QtCore.Qt.AlignCenter)
- self.fileNameLabel.setObjectName(_fromUtf8("fileNameLabel"))
- self.gridLayout.addWidget(self.fileNameLabel, 0, 1, 1, 1)
-
- self.retranslateUi(Form)
- QtCore.QMetaObject.connectSlotsByName(Form)
-
- def retranslateUi(self, Form):
- Form.setWindowTitle(_translate("Form", "PyQtGraph", None))
- self.loadBtn.setText(_translate("Form", "Load..", None))
- self.saveBtn.setText(_translate("Form", "Save", None))
- self.saveAsBtn.setText(_translate("Form", "As..", None))
- self.reloadBtn.setText(_translate("Form", "Reload Libs", None))
- self.showChartBtn.setText(_translate("Form", "Flowchart", None))
-
-from ..widgets.TreeWidget import TreeWidget
-from ..widgets.FeedbackButton import FeedbackButton
diff --git a/pyqtgraph/flowchart/FlowchartCtrlTemplate_pyside.py b/pyqtgraph/flowchart/FlowchartCtrlTemplate_pyqt6.py
similarity index 59%
rename from pyqtgraph/flowchart/FlowchartCtrlTemplate_pyside.py
rename to pyqtgraph/flowchart/FlowchartCtrlTemplate_pyqt6.py
index 2db10f6a..5cb9199b 100644
--- a/pyqtgraph/flowchart/FlowchartCtrlTemplate_pyside.py
+++ b/pyqtgraph/flowchart/FlowchartCtrlTemplate_pyqt6.py
@@ -1,23 +1,23 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file './pyqtgraph/flowchart/FlowchartCtrlTemplate.ui'
+# Form implementation generated from reading ui file 'pyqtgraph\flowchart\FlowchartCtrlTemplate.ui'
#
-# Created: Mon Dec 23 10:10:51 2013
-# by: pyside-uic 0.2.14 running on PySide 1.1.2
+# Created by: PyQt6 UI code generator 6.0.0
#
-# WARNING! All changes made in this file will be lost!
+# 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
-from PySide import QtCore, QtGui
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(217, 499)
- self.gridLayout = QtGui.QGridLayout(Form)
+ self.gridLayout = QtWidgets.QGridLayout(Form)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setVerticalSpacing(0)
self.gridLayout.setObjectName("gridLayout")
- self.loadBtn = QtGui.QPushButton(Form)
+ self.loadBtn = QtWidgets.QPushButton(Form)
self.loadBtn.setObjectName("loadBtn")
self.gridLayout.addWidget(self.loadBtn, 1, 0, 1, 1)
self.saveBtn = FeedbackButton(Form)
@@ -31,7 +31,7 @@ class Ui_Form(object):
self.reloadBtn.setFlat(False)
self.reloadBtn.setObjectName("reloadBtn")
self.gridLayout.addWidget(self.reloadBtn, 4, 0, 1, 2)
- self.showChartBtn = QtGui.QPushButton(Form)
+ self.showChartBtn = QtWidgets.QPushButton(Form)
self.showChartBtn.setCheckable(True)
self.showChartBtn.setObjectName("showChartBtn")
self.gridLayout.addWidget(self.showChartBtn, 4, 2, 1, 2)
@@ -41,13 +41,12 @@ class Ui_Form(object):
self.ctrlList.header().setVisible(False)
self.ctrlList.header().setStretchLastSection(False)
self.gridLayout.addWidget(self.ctrlList, 3, 0, 1, 4)
- self.fileNameLabel = QtGui.QLabel(Form)
+ self.fileNameLabel = QtWidgets.QLabel(Form)
font = QtGui.QFont()
- font.setWeight(75)
font.setBold(True)
self.fileNameLabel.setFont(font)
self.fileNameLabel.setText("")
- self.fileNameLabel.setAlignment(QtCore.Qt.AlignCenter)
+ self.fileNameLabel.setAlignment(QtCore.Qt.Alignment.AlignCenter)
self.fileNameLabel.setObjectName("fileNameLabel")
self.gridLayout.addWidget(self.fileNameLabel, 0, 1, 1, 1)
@@ -55,12 +54,12 @@ class Ui_Form(object):
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
- Form.setWindowTitle(QtGui.QApplication.translate("Form", "PyQtGraph", None, QtGui.QApplication.UnicodeUTF8))
- self.loadBtn.setText(QtGui.QApplication.translate("Form", "Load..", None, QtGui.QApplication.UnicodeUTF8))
- self.saveBtn.setText(QtGui.QApplication.translate("Form", "Save", None, QtGui.QApplication.UnicodeUTF8))
- self.saveAsBtn.setText(QtGui.QApplication.translate("Form", "As..", None, QtGui.QApplication.UnicodeUTF8))
- self.reloadBtn.setText(QtGui.QApplication.translate("Form", "Reload Libs", None, QtGui.QApplication.UnicodeUTF8))
- self.showChartBtn.setText(QtGui.QApplication.translate("Form", "Flowchart", None, QtGui.QApplication.UnicodeUTF8))
-
-from ..widgets.TreeWidget import TreeWidget
+ _translate = QtCore.QCoreApplication.translate
+ Form.setWindowTitle(_translate("Form", "PyQtGraph"))
+ self.loadBtn.setText(_translate("Form", "Load.."))
+ self.saveBtn.setText(_translate("Form", "Save"))
+ self.saveAsBtn.setText(_translate("Form", "As.."))
+ self.reloadBtn.setText(_translate("Form", "Reload Libs"))
+ self.showChartBtn.setText(_translate("Form", "Flowchart"))
from ..widgets.FeedbackButton import FeedbackButton
+from ..widgets.TreeWidget import TreeWidget
diff --git a/pyqtgraph/flowchart/FlowchartCtrlTemplate_pyside6.py b/pyqtgraph/flowchart/FlowchartCtrlTemplate_pyside6.py
new file mode 100644
index 00000000..9a1e521c
--- /dev/null
+++ b/pyqtgraph/flowchart/FlowchartCtrlTemplate_pyside6.py
@@ -0,0 +1,90 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'FlowchartCtrlTemplate.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 ..widgets.TreeWidget import TreeWidget
+from ..widgets.FeedbackButton import FeedbackButton
+
+
+class Ui_Form(object):
+ def setupUi(self, Form):
+ if not Form.objectName():
+ Form.setObjectName(u"Form")
+ Form.resize(217, 499)
+ self.gridLayout = QGridLayout(Form)
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout.setObjectName(u"gridLayout")
+ self.gridLayout.setVerticalSpacing(0)
+ self.loadBtn = QPushButton(Form)
+ self.loadBtn.setObjectName(u"loadBtn")
+
+ self.gridLayout.addWidget(self.loadBtn, 1, 0, 1, 1)
+
+ self.saveBtn = FeedbackButton(Form)
+ self.saveBtn.setObjectName(u"saveBtn")
+
+ self.gridLayout.addWidget(self.saveBtn, 1, 1, 1, 2)
+
+ self.saveAsBtn = FeedbackButton(Form)
+ self.saveAsBtn.setObjectName(u"saveAsBtn")
+
+ self.gridLayout.addWidget(self.saveAsBtn, 1, 3, 1, 1)
+
+ self.reloadBtn = FeedbackButton(Form)
+ self.reloadBtn.setObjectName(u"reloadBtn")
+ self.reloadBtn.setCheckable(False)
+ self.reloadBtn.setFlat(False)
+
+ self.gridLayout.addWidget(self.reloadBtn, 4, 0, 1, 2)
+
+ self.showChartBtn = QPushButton(Form)
+ self.showChartBtn.setObjectName(u"showChartBtn")
+ self.showChartBtn.setCheckable(True)
+
+ self.gridLayout.addWidget(self.showChartBtn, 4, 2, 1, 2)
+
+ self.ctrlList = TreeWidget(Form)
+ __qtreewidgetitem = QTreeWidgetItem()
+ __qtreewidgetitem.setText(0, u"1");
+ self.ctrlList.setHeaderItem(__qtreewidgetitem)
+ self.ctrlList.setObjectName(u"ctrlList")
+ self.ctrlList.header().setVisible(False)
+ self.ctrlList.header().setStretchLastSection(False)
+
+ self.gridLayout.addWidget(self.ctrlList, 3, 0, 1, 4)
+
+ self.fileNameLabel = QLabel(Form)
+ self.fileNameLabel.setObjectName(u"fileNameLabel")
+ font = QFont()
+ font.setBold(True)
+ self.fileNameLabel.setFont(font)
+ self.fileNameLabel.setAlignment(Qt.AlignCenter)
+
+ self.gridLayout.addWidget(self.fileNameLabel, 0, 1, 1, 1)
+
+
+ self.retranslateUi(Form)
+
+ QMetaObject.connectSlotsByName(Form)
+ # setupUi
+
+ def retranslateUi(self, Form):
+ Form.setWindowTitle(QCoreApplication.translate("Form", u"PyQtGraph", None))
+ self.loadBtn.setText(QCoreApplication.translate("Form", u"Load..", None))
+ self.saveBtn.setText(QCoreApplication.translate("Form", u"Save", None))
+ self.saveAsBtn.setText(QCoreApplication.translate("Form", u"As..", None))
+ self.reloadBtn.setText(QCoreApplication.translate("Form", u"Reload Libs", None))
+ self.showChartBtn.setText(QCoreApplication.translate("Form", u"Flowchart", None))
+ self.fileNameLabel.setText("")
+ # retranslateUi
+
diff --git a/pyqtgraph/flowchart/FlowchartGraphicsView.py b/pyqtgraph/flowchart/FlowchartGraphicsView.py
index 93011218..2efd313c 100644
--- a/pyqtgraph/flowchart/FlowchartGraphicsView.py
+++ b/pyqtgraph/flowchart/FlowchartGraphicsView.py
@@ -4,6 +4,7 @@ from ..widgets.GraphicsView import GraphicsView
from ..GraphicsScene import GraphicsScene
from ..graphicsItems.ViewBox import ViewBox
+translate = QtCore.QCoreApplication.translate
class FlowchartGraphicsView(GraphicsView):
@@ -37,5 +38,5 @@ class FlowchartViewBox(ViewBox):
def getContextMenus(self, ev):
## called by scene to add menus on to someone else's context menu
menu = self.widget.buildMenu(ev.scenePos())
- menu.setTitle("Add node")
+ menu.setTitle(translate("Context Menu", "Add node"))
return [menu, ViewBox.getMenu(self, ev)]
diff --git a/pyqtgraph/flowchart/FlowchartTemplate.ui b/pyqtgraph/flowchart/FlowchartTemplate.ui
index 22934b91..8b4ef814 100644
--- a/pyqtgraph/flowchart/FlowchartTemplate.ui
+++ b/pyqtgraph/flowchart/FlowchartTemplate.ui
@@ -40,7 +40,6 @@
- 75
true
diff --git a/pyqtgraph/flowchart/FlowchartTemplate_pyqt.py b/pyqtgraph/flowchart/FlowchartTemplate_pyqt.py
deleted file mode 100644
index e6084eee..00000000
--- a/pyqtgraph/flowchart/FlowchartTemplate_pyqt.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file './pyqtgraph/flowchart/FlowchartTemplate.ui'
-#
-# Created: Mon Dec 23 10:10:51 2013
-# by: PyQt4 UI code generator 4.10
-#
-# WARNING! All changes made in this file will be lost!
-
-from PyQt4 import QtCore, QtGui
-
-try:
- _fromUtf8 = QtCore.QString.fromUtf8
-except AttributeError:
- def _fromUtf8(s):
- return s
-
-try:
- _encoding = QtGui.QApplication.UnicodeUTF8
- def _translate(context, text, disambig):
- return QtGui.QApplication.translate(context, text, disambig, _encoding)
-except AttributeError:
- def _translate(context, text, disambig):
- return QtGui.QApplication.translate(context, text, disambig)
-
-class Ui_Form(object):
- def setupUi(self, Form):
- Form.setObjectName(_fromUtf8("Form"))
- Form.resize(529, 329)
- self.selInfoWidget = QtGui.QWidget(Form)
- self.selInfoWidget.setGeometry(QtCore.QRect(260, 10, 264, 222))
- self.selInfoWidget.setObjectName(_fromUtf8("selInfoWidget"))
- self.gridLayout = QtGui.QGridLayout(self.selInfoWidget)
- self.gridLayout.setMargin(0)
- self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
- self.selDescLabel = QtGui.QLabel(self.selInfoWidget)
- self.selDescLabel.setText(_fromUtf8(""))
- self.selDescLabel.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
- self.selDescLabel.setWordWrap(True)
- self.selDescLabel.setObjectName(_fromUtf8("selDescLabel"))
- self.gridLayout.addWidget(self.selDescLabel, 0, 0, 1, 1)
- self.selNameLabel = QtGui.QLabel(self.selInfoWidget)
- font = QtGui.QFont()
- font.setBold(True)
- font.setWeight(75)
- self.selNameLabel.setFont(font)
- self.selNameLabel.setText(_fromUtf8(""))
- self.selNameLabel.setObjectName(_fromUtf8("selNameLabel"))
- self.gridLayout.addWidget(self.selNameLabel, 0, 1, 1, 1)
- self.selectedTree = DataTreeWidget(self.selInfoWidget)
- self.selectedTree.setObjectName(_fromUtf8("selectedTree"))
- self.selectedTree.headerItem().setText(0, _fromUtf8("1"))
- self.gridLayout.addWidget(self.selectedTree, 1, 0, 1, 2)
- self.hoverText = QtGui.QTextEdit(Form)
- self.hoverText.setGeometry(QtCore.QRect(0, 240, 521, 81))
- self.hoverText.setObjectName(_fromUtf8("hoverText"))
- self.view = FlowchartGraphicsView(Form)
- self.view.setGeometry(QtCore.QRect(0, 0, 256, 192))
- self.view.setObjectName(_fromUtf8("view"))
-
- self.retranslateUi(Form)
- QtCore.QMetaObject.connectSlotsByName(Form)
-
- def retranslateUi(self, Form):
- Form.setWindowTitle(_translate("Form", "PyQtGraph", None))
-
-from ..flowchart.FlowchartGraphicsView import FlowchartGraphicsView
-from ..widgets.DataTreeWidget import DataTreeWidget
diff --git a/pyqtgraph/flowchart/FlowchartTemplate_pyside.py b/pyqtgraph/flowchart/FlowchartTemplate_pyqt6.py
similarity index 63%
rename from pyqtgraph/flowchart/FlowchartTemplate_pyside.py
rename to pyqtgraph/flowchart/FlowchartTemplate_pyqt6.py
index 47f97f85..7296a8da 100644
--- a/pyqtgraph/flowchart/FlowchartTemplate_pyside.py
+++ b/pyqtgraph/flowchart/FlowchartTemplate_pyqt6.py
@@ -1,33 +1,32 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file './pyqtgraph/flowchart/FlowchartTemplate.ui'
+# Form implementation generated from reading ui file 'pyqtgraph\flowchart\FlowchartTemplate.ui'
#
-# Created: Mon Dec 23 10:10:51 2013
-# by: pyside-uic 0.2.14 running on PySide 1.1.2
+# Created by: PyQt6 UI code generator 6.0.0
#
-# WARNING! All changes made in this file will be lost!
+# 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
-from PySide import QtCore, QtGui
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(529, 329)
- self.selInfoWidget = QtGui.QWidget(Form)
+ self.selInfoWidget = QtWidgets.QWidget(Form)
self.selInfoWidget.setGeometry(QtCore.QRect(260, 10, 264, 222))
self.selInfoWidget.setObjectName("selInfoWidget")
- self.gridLayout = QtGui.QGridLayout(self.selInfoWidget)
+ self.gridLayout = QtWidgets.QGridLayout(self.selInfoWidget)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
- self.selDescLabel = QtGui.QLabel(self.selInfoWidget)
+ self.selDescLabel = QtWidgets.QLabel(self.selInfoWidget)
self.selDescLabel.setText("")
- self.selDescLabel.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
+ self.selDescLabel.setAlignment(QtCore.Qt.Alignment.AlignLeading|QtCore.Qt.Alignment.AlignLeft|QtCore.Qt.Alignment.AlignTop)
self.selDescLabel.setWordWrap(True)
self.selDescLabel.setObjectName("selDescLabel")
self.gridLayout.addWidget(self.selDescLabel, 0, 0, 1, 1)
- self.selNameLabel = QtGui.QLabel(self.selInfoWidget)
+ self.selNameLabel = QtWidgets.QLabel(self.selInfoWidget)
font = QtGui.QFont()
- font.setWeight(75)
font.setBold(True)
self.selNameLabel.setFont(font)
self.selNameLabel.setText("")
@@ -37,7 +36,7 @@ class Ui_Form(object):
self.selectedTree.setObjectName("selectedTree")
self.selectedTree.headerItem().setText(0, "1")
self.gridLayout.addWidget(self.selectedTree, 1, 0, 1, 2)
- self.hoverText = QtGui.QTextEdit(Form)
+ self.hoverText = QtWidgets.QTextEdit(Form)
self.hoverText.setGeometry(QtCore.QRect(0, 240, 521, 81))
self.hoverText.setObjectName("hoverText")
self.view = FlowchartGraphicsView(Form)
@@ -48,7 +47,7 @@ class Ui_Form(object):
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
- Form.setWindowTitle(QtGui.QApplication.translate("Form", "PyQtGraph", None, QtGui.QApplication.UnicodeUTF8))
-
+ _translate = QtCore.QCoreApplication.translate
+ Form.setWindowTitle(_translate("Form", "PyQtGraph"))
from ..flowchart.FlowchartGraphicsView import FlowchartGraphicsView
from ..widgets.DataTreeWidget import DataTreeWidget
diff --git a/pyqtgraph/flowchart/FlowchartTemplate_pyside6.py b/pyqtgraph/flowchart/FlowchartTemplate_pyside6.py
new file mode 100644
index 00000000..a45b6e09
--- /dev/null
+++ b/pyqtgraph/flowchart/FlowchartTemplate_pyside6.py
@@ -0,0 +1,69 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'FlowchartTemplate.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 ..widgets.DataTreeWidget import DataTreeWidget
+from ..flowchart.FlowchartGraphicsView import FlowchartGraphicsView
+
+
+class Ui_Form(object):
+ def setupUi(self, Form):
+ if not Form.objectName():
+ Form.setObjectName(u"Form")
+ Form.resize(529, 329)
+ self.selInfoWidget = QWidget(Form)
+ self.selInfoWidget.setObjectName(u"selInfoWidget")
+ self.selInfoWidget.setGeometry(QRect(260, 10, 264, 222))
+ self.gridLayout = QGridLayout(self.selInfoWidget)
+ self.gridLayout.setObjectName(u"gridLayout")
+ self.selDescLabel = QLabel(self.selInfoWidget)
+ self.selDescLabel.setObjectName(u"selDescLabel")
+ self.selDescLabel.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignTop)
+ self.selDescLabel.setWordWrap(True)
+
+ self.gridLayout.addWidget(self.selDescLabel, 0, 0, 1, 1)
+
+ self.selNameLabel = QLabel(self.selInfoWidget)
+ self.selNameLabel.setObjectName(u"selNameLabel")
+ font = QFont()
+ font.setBold(True)
+ self.selNameLabel.setFont(font)
+
+ self.gridLayout.addWidget(self.selNameLabel, 0, 1, 1, 1)
+
+ self.selectedTree = DataTreeWidget(self.selInfoWidget)
+ __qtreewidgetitem = QTreeWidgetItem()
+ __qtreewidgetitem.setText(0, u"1");
+ self.selectedTree.setHeaderItem(__qtreewidgetitem)
+ self.selectedTree.setObjectName(u"selectedTree")
+
+ self.gridLayout.addWidget(self.selectedTree, 1, 0, 1, 2)
+
+ self.hoverText = QTextEdit(Form)
+ self.hoverText.setObjectName(u"hoverText")
+ self.hoverText.setGeometry(QRect(0, 240, 521, 81))
+ self.view = FlowchartGraphicsView(Form)
+ self.view.setObjectName(u"view")
+ self.view.setGeometry(QRect(0, 0, 256, 192))
+
+ self.retranslateUi(Form)
+
+ QMetaObject.connectSlotsByName(Form)
+ # setupUi
+
+ def retranslateUi(self, Form):
+ Form.setWindowTitle(QCoreApplication.translate("Form", u"PyQtGraph", None))
+ self.selDescLabel.setText("")
+ self.selNameLabel.setText("")
+ # retranslateUi
+
diff --git a/pyqtgraph/flowchart/Node.py b/pyqtgraph/flowchart/Node.py
index dcda62d7..102fb2f7 100644
--- a/pyqtgraph/flowchart/Node.py
+++ b/pyqtgraph/flowchart/Node.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-from ..Qt import QtCore, QtGui
+from ..Qt import QtCore, QtGui, QtWidgets
from ..graphicsItems.GraphicsObject import GraphicsObject
from .. import functions as fn
from .Terminal import *
@@ -8,6 +8,8 @@ from ..debug import *
import numpy as np
+translate = QtCore.QCoreApplication.translate
+
def strDict(d):
return dict([(str(k), v) for k, v in d.items()])
@@ -436,6 +438,24 @@ class Node(QtCore.QObject):
t.disconnectAll()
+class TextItem(QtWidgets.QGraphicsTextItem):
+ def __init__(self, text, parent, on_update):
+ super().__init__(text, parent)
+ self.on_update = on_update
+
+ def focusOutEvent(self, ev):
+ super().focusOutEvent(ev)
+ if self.on_update is not None:
+ self.on_update()
+
+ def keyPressEvent(self, ev):
+ if ev.key() == QtCore.Qt.Key_Enter or ev.key() == QtCore.Qt.Key_Return:
+ if self.on_update is not None:
+ self.on_update()
+ return
+ super().keyPressEvent(ev)
+
+
#class NodeGraphicsItem(QtGui.QGraphicsItem):
class NodeGraphicsItem(GraphicsObject):
def __init__(self, node):
@@ -461,16 +481,13 @@ class NodeGraphicsItem(GraphicsObject):
self.setFlags(flags)
self.bounds = QtCore.QRectF(0, 0, 100, 100)
- self.nameItem = QtGui.QGraphicsTextItem(self.node.name(), self)
+ self.nameItem = TextItem(self.node.name(), self, self.labelChanged)
self.nameItem.setDefaultTextColor(QtGui.QColor(50, 50, 50))
self.nameItem.moveBy(self.bounds.width()/2. - self.nameItem.boundingRect().width()/2., 0)
self.nameItem.setTextInteractionFlags(QtCore.Qt.TextEditorInteraction)
self.updateTerminals()
#self.setZValue(10)
- self.nameItem.focusOutEvent = self.labelFocusOut
- self.nameItem.keyPressEvent = self.labelKeyPress
-
self.menu = None
self.buildMenu()
@@ -481,16 +498,6 @@ class NodeGraphicsItem(GraphicsObject):
#item.setZValue(z+1)
#GraphicsObject.setZValue(self, z)
- def labelFocusOut(self, ev):
- QtGui.QGraphicsTextItem.focusOutEvent(self.nameItem, ev)
- self.labelChanged()
-
- def labelKeyPress(self, ev):
- if ev.key() == QtCore.Qt.Key_Enter or ev.key() == QtCore.Qt.Key_Return:
- self.labelChanged()
- else:
- QtGui.QGraphicsTextItem.keyPressEvent(self.nameItem, ev)
-
def labelChanged(self):
newName = str(self.nameItem.toPlainText())
if newName != self.node.name():
@@ -574,7 +581,7 @@ class NodeGraphicsItem(GraphicsObject):
def mouseClickEvent(self, ev):
#print "Node.mouseClickEvent called."
- if int(ev.button()) == int(QtCore.Qt.LeftButton):
+ if ev.button() == QtCore.Qt.LeftButton:
ev.accept()
#print " ev.button: left"
sel = self.isSelected()
@@ -587,7 +594,7 @@ class NodeGraphicsItem(GraphicsObject):
self.update()
#return ret
- elif int(ev.button()) == int(QtCore.Qt.RightButton):
+ elif ev.button() == QtCore.Qt.RightButton:
#print " ev.button: right"
ev.accept()
#pos = ev.screenPos()
@@ -634,14 +641,14 @@ class NodeGraphicsItem(GraphicsObject):
def buildMenu(self):
self.menu = QtGui.QMenu()
- self.menu.setTitle("Node")
- a = self.menu.addAction("Add input", self.addInputFromMenu)
+ self.menu.setTitle(translate("Context Menu", "Node"))
+ a = self.menu.addAction(translate("Context Menu","Add input"), self.addInputFromMenu)
if not self.node._allowAddInput:
a.setEnabled(False)
- a = self.menu.addAction("Add output", self.addOutputFromMenu)
+ a = self.menu.addAction(translate("Context Menu", "Add output"), self.addOutputFromMenu)
if not self.node._allowAddOutput:
a.setEnabled(False)
- a = self.menu.addAction("Remove node", self.node.close)
+ a = self.menu.addAction(translate("Context Menu", "Remove node"), self.node.close)
if not self.node._allowRemove:
a.setEnabled(False)
diff --git a/pyqtgraph/flowchart/Terminal.py b/pyqtgraph/flowchart/Terminal.py
index 7c512dda..0333618d 100644
--- a/pyqtgraph/flowchart/Terminal.py
+++ b/pyqtgraph/flowchart/Terminal.py
@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
-from ..Qt import QtCore, QtGui
+from ..Qt import QtCore, QtGui, QtWidgets
import weakref
from ..graphicsItems.GraphicsObject import GraphicsObject
from .. import functions as fn
from ..Point import Point
+translate = QtCore.QCoreApplication.translate
class Terminal(object):
def __init__(self, node, name, io, optional=False, multi=False, pos=None, renamable=False, removable=False, multiable=False, bypass=None):
@@ -273,6 +274,25 @@ class Terminal(object):
"""
return self._name < other._name
+
+class TextItem(QtWidgets.QGraphicsTextItem):
+ def __init__(self, text, parent, on_update):
+ super().__init__(text, parent)
+ self.on_update = on_update
+
+ def focusOutEvent(self, ev):
+ super().focusOutEvent(ev)
+ if self.on_update is not None:
+ self.on_update()
+
+ def keyPressEvent(self, ev):
+ if ev.key() == QtCore.Qt.Key_Enter or ev.key() == QtCore.Qt.Key_Return:
+ if self.on_update is not None:
+ self.on_update()
+ return
+ super().keyPressEvent(ev)
+
+
class TerminalGraphicsItem(GraphicsObject):
def __init__(self, term, parent=None):
@@ -280,27 +300,16 @@ class TerminalGraphicsItem(GraphicsObject):
GraphicsObject.__init__(self, parent)
self.brush = fn.mkBrush(0,0,0)
self.box = QtGui.QGraphicsRectItem(0, 0, 10, 10, self)
- self.label = QtGui.QGraphicsTextItem(self.term.name(), self)
+ on_update = self.labelChanged if self.term.isRenamable() else None
+ self.label = TextItem(self.term.name(), self, on_update)
self.label.scale(0.7, 0.7)
self.newConnection = None
self.setFiltersChildEvents(True) ## to pick up mouse events on the rectitem
if self.term.isRenamable():
self.label.setTextInteractionFlags(QtCore.Qt.TextEditorInteraction)
- self.label.focusOutEvent = self.labelFocusOut
- self.label.keyPressEvent = self.labelKeyPress
self.setZValue(1)
self.menu = None
- def labelFocusOut(self, ev):
- QtGui.QGraphicsTextItem.focusOutEvent(self.label, ev)
- self.labelChanged()
-
- def labelKeyPress(self, ev):
- if ev.key() == QtCore.Qt.Key_Enter or ev.key() == QtCore.Qt.Key_Return:
- self.labelChanged()
- else:
- QtGui.QGraphicsTextItem.keyPressEvent(self.label, ev)
-
def labelChanged(self):
newName = str(self.label.toPlainText())
if newName != self.term.name():
@@ -365,14 +374,14 @@ class TerminalGraphicsItem(GraphicsObject):
def getMenu(self):
if self.menu is None:
self.menu = QtGui.QMenu()
- self.menu.setTitle("Terminal")
- remAct = QtGui.QAction("Remove terminal", self.menu)
+ self.menu.setTitle(translate("Context Menu", "Terminal"))
+ remAct = QtGui.QAction(translate("Context Menu", "Remove terminal"), self.menu)
remAct.triggered.connect(self.removeSelf)
self.menu.addAction(remAct)
self.menu.remAct = remAct
if not self.term.isRemovable():
remAct.setEnabled(False)
- multiAct = QtGui.QAction("Multi-value", self.menu)
+ multiAct = QtGui.QAction(translate("Context Menu", "Multi-value"), self.menu)
multiAct.setCheckable(True)
multiAct.setChecked(self.term.isMultiValue())
multiAct.setEnabled(self.term.isMultiable())
diff --git a/pyqtgraph/flowchart/library/Data.py b/pyqtgraph/flowchart/library/Data.py
index b133b159..6edd3a80 100644
--- a/pyqtgraph/flowchart/library/Data.py
+++ b/pyqtgraph/flowchart/library/Data.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
from ..Node import Node
-from ...Qt import QtGui, QtCore
+from ...Qt import QtGui, QtCore, QtWidgets
import numpy as np
import sys
from .common import *
@@ -173,6 +173,20 @@ class RegionSelectNode(CtrlNode):
self.update()
+class TextEdit(QtWidgets.QTextEdit):
+ def __init__(self, on_update):
+ super().__init__()
+ self.on_update = on_update
+ self.lastText = None
+
+ def focusOutEvent(self, ev):
+ text = str(self.toPlainText())
+ if text != self.lastText:
+ self.lastText = text
+ self.on_update()
+ super().focusOutEvent(ev)
+
+
class EvalNode(Node):
"""Return the output of a string evaluated/executed by the python interpreter.
The string may be either an expression or a python script, and inputs are accessed as the name of the terminal.
@@ -190,15 +204,12 @@ class EvalNode(Node):
self.ui = QtGui.QWidget()
self.layout = QtGui.QGridLayout()
- self.text = QtGui.QTextEdit()
+ self.text = TextEdit(self.update)
self.text.setTabStopWidth(30)
self.text.setPlainText("# Access inputs as args['input_name']\nreturn {'output': None} ## one key per output terminal")
self.layout.addWidget(self.text, 1, 0, 1, 2)
self.ui.setLayout(self.layout)
- self.text.focusOutEvent = self.focusOutEvent
- self.lastText = None
-
def ctrlWidget(self):
return self.ui
@@ -221,13 +232,6 @@ class EvalNode(Node):
def code(self):
return self.text.toPlainText()
- def focusOutEvent(self, ev):
- text = str(self.text.toPlainText())
- if text != self.lastText:
- self.lastText = text
- self.update()
- return QtGui.QTextEdit.focusOutEvent(self.text, ev)
-
def process(self, display=True, **args):
l = locals()
l.update(args)
diff --git a/pyqtgraph/functions.py b/pyqtgraph/functions.py
index 478525dc..037f0f51 100644
--- a/pyqtgraph/functions.py
+++ b/pyqtgraph/functions.py
@@ -6,18 +6,23 @@ Distributed under MIT/X11 license. See license.txt for more information.
"""
from __future__ import division
-import warnings
-import numpy as np
-import decimal, re
+
import ctypes
-import sys, struct
+import decimal
+import re
+import struct
+import sys
+import warnings
+
+import numpy as np
+from pyqtgraph.util.cupy_helper import getCupy
+
+from . import debug, reload
+from .Qt import QtGui, QtCore, QT_LIB, QtVersion
+from . import Qt
+from .metaarray import MetaArray
from .pgcollections import OrderedDict
from .python2_3 import asUnicode, basestring
-from .Qt import QtGui, QtCore, QT_LIB, QtVersion
-from . import getConfigOption, setConfigOptions
-from . import debug, reload
-from .metaarray import MetaArray
-
Colors = {
'b': QtGui.QColor(0,0,255,255),
@@ -38,7 +43,7 @@ SI_PREFIXES_ASCII = 'yzafpnum kMGTPEZY'
SI_PREFIX_EXPONENTS = dict([(SI_PREFIXES[i], (i-8)*3) for i in range(len(SI_PREFIXES))])
SI_PREFIX_EXPONENTS['u'] = -6
-FLOAT_REGEX = re.compile(r'(?P[+-]?((((\d+(\.\d*)?)|(\d*\.\d+))([eE][+-]?\d+)?)|((?i)(nan)|(inf))))\s*((?P[u' + SI_PREFIXES + r']?)(?P\w.*))?$')
+FLOAT_REGEX = re.compile(r'(?P[+-]?((((\d+(\.\d*)?)|(\d*\.\d+))([eE][+-]?\d+)?)|((?i:nan)|(inf))))\s*((?P[u' + SI_PREFIXES + r']?)(?P\w.*))?$')
INT_REGEX = re.compile(r'(?P[+-]?\d+)\s*(?P[u' + SI_PREFIXES + r']?)(?P.*)$')
@@ -947,80 +952,59 @@ def rescaleData(data, scale, offset, dtype=None, clip=None):
The scaling operation is::
data => (data-offset) * scale
-
"""
if dtype is None:
dtype = data.dtype
else:
dtype = np.dtype(dtype)
- try:
- if not getConfigOption('useWeave'):
- raise Exception('Weave is disabled; falling back to slower version.')
- try:
- import scipy.weave
- except ImportError:
- raise Exception('scipy.weave is not importable; falling back to slower version.')
-
- ## require native dtype when using weave
- if not data.dtype.isnative:
- data = data.astype(data.dtype.newbyteorder('='))
- if not dtype.isnative:
- weaveDtype = dtype.newbyteorder('=')
+ if np.can_cast(data, np.float32):
+ work_dtype = np.float32
+ else:
+ work_dtype = np.float64
+ d2 = data.astype(work_dtype, copy=True)
+ d2 -= offset
+ d2 *= scale
+
+ # Clip before converting dtype to avoid overflow
+ if dtype.kind in 'ui':
+ lim = np.iinfo(dtype)
+ if clip is None:
+ # don't let rescale cause integer overflow
+ np.clip(d2, lim.min, lim.max, out=d2)
else:
- weaveDtype = dtype
-
- newData = np.empty((data.size,), dtype=weaveDtype)
- flat = np.ascontiguousarray(data).reshape(data.size)
- size = data.size
-
- code = """
- double sc = (double)scale;
- double off = (double)offset;
- for( int i=0; i= 11.1.
"""
if data.dtype.kind not in ('i', 'u'):
data = data.astype(int)
-
- return np.take(lut, data, axis=0, mode='clip')
+
+ cp = getCupy()
+ if cp and cp.get_array_module(data) == cp:
+ # cupy.take only supports "wrap" mode
+ return cp.take(lut, cp.clip(data, 0, lut.shape[0] - 1), axis=0)
+ else:
+ return np.take(lut, data, axis=0, mode='clip')
def makeRGBA(*args, **kwds):
@@ -1029,8 +1013,8 @@ def makeRGBA(*args, **kwds):
return makeARGB(*args, **kwds)
-def makeARGB(data, lut=None, levels=None, scale=None, useRGBA=False):
- """
+def makeARGB(data, lut=None, levels=None, scale=None, useRGBA=False, output=None):
+ """
Convert an array of values into an ARGB array suitable for building QImages,
OpenGL textures, etc.
@@ -1069,29 +1053,31 @@ def makeARGB(data, lut=None, levels=None, scale=None, useRGBA=False):
is BGRA).
============== ==================================================================================
"""
+ cp = getCupy()
+ xp = cp.get_array_module(data) if cp else np
profile = debug.Profiler()
if data.ndim not in (2, 3):
raise TypeError("data must be 2D or 3D")
if data.ndim == 3 and data.shape[2] > 4:
raise TypeError("data.shape[2] must be <= 4")
- if lut is not None and not isinstance(lut, np.ndarray):
- lut = np.array(lut)
+ if lut is not None and not isinstance(lut, xp.ndarray):
+ lut = xp.array(lut)
if levels is None:
# automatically decide levels based on data dtype
if data.dtype.kind == 'u':
- levels = np.array([0, 2**(data.itemsize*8)-1])
+ levels = xp.array([0, 2**(data.itemsize*8)-1])
elif data.dtype.kind == 'i':
s = 2**(data.itemsize*8 - 1)
- levels = np.array([-s, s-1])
+ levels = xp.array([-s, s-1])
elif data.dtype.kind == 'b':
- levels = np.array([0,1])
+ levels = xp.array([0,1])
else:
raise Exception('levels argument is required for float input types')
- if not isinstance(levels, np.ndarray):
- levels = np.array(levels)
- levels = levels.astype(np.float)
+ if not isinstance(levels, xp.ndarray):
+ levels = xp.array(levels)
+ levels = levels.astype(xp.float)
if levels.ndim == 1:
if levels.shape[0] != 2:
raise Exception('levels argument must have length 2')
@@ -1103,7 +1089,7 @@ def makeARGB(data, lut=None, levels=None, scale=None, useRGBA=False):
else:
raise Exception("levels argument must be 1D or 2D (got shape=%s)." % repr(levels.shape))
- profile()
+ profile('check inputs')
# Decide on maximum scaled value
if scale is None:
@@ -1114,28 +1100,27 @@ def makeARGB(data, lut=None, levels=None, scale=None, useRGBA=False):
# Decide on the dtype we want after scaling
if lut is None:
- dtype = np.ubyte
+ dtype = xp.ubyte
else:
- dtype = np.min_scalar_type(lut.shape[0]-1)
+ dtype = xp.min_scalar_type(lut.shape[0]-1)
# awkward, but fastest numpy native nan evaluation
- #
nanMask = None
- if data.dtype.kind == 'f' and np.isnan(data.min()):
- nanMask = np.isnan(data)
+ if data.dtype.kind == 'f' and xp.isnan(data.min()):
+ nanMask = xp.isnan(data)
if data.ndim > 2:
- nanMask = np.any(nanMask, axis=-1)
+ nanMask = xp.any(nanMask, axis=-1)
# Apply levels if given
if levels is not None:
- if isinstance(levels, np.ndarray) and levels.ndim == 2:
+ if isinstance(levels, xp.ndarray) and levels.ndim == 2:
# we are going to rescale each channel independently
if levels.shape[0] != data.shape[-1]:
raise Exception("When rescaling multi-channel data, there must be the same number of levels as channels (data.shape[-1] == levels.shape[0])")
- newData = np.empty(data.shape, dtype=int)
+ newData = xp.empty(data.shape, dtype=int)
for i in range(data.shape[-1]):
minVal, maxVal = levels[i]
if minVal == maxVal:
- maxVal = np.nextafter(maxVal, 2*maxVal)
+ maxVal = xp.nextafter(maxVal, 2*maxVal)
rng = maxVal-minVal
rng = 1 if rng == 0 else rng
newData[...,i] = rescaleData(data[...,i], scale / rng, minVal, dtype=dtype)
@@ -1145,25 +1130,29 @@ def makeARGB(data, lut=None, levels=None, scale=None, useRGBA=False):
minVal, maxVal = levels
if minVal != 0 or maxVal != scale:
if minVal == maxVal:
- maxVal = np.nextafter(maxVal, 2*maxVal)
+ maxVal = xp.nextafter(maxVal, 2*maxVal)
rng = maxVal-minVal
rng = 1 if rng == 0 else rng
data = rescaleData(data, scale/rng, minVal, dtype=dtype)
- profile()
+ profile('apply levels')
+
# apply LUT if given
if lut is not None:
data = applyLookupTable(data, lut)
else:
- if data.dtype is not np.ubyte:
- data = np.clip(data, 0, 255).astype(np.ubyte)
+ if data.dtype != xp.ubyte:
+ data = xp.clip(data, 0, 255).astype(xp.ubyte)
- profile()
+ profile('apply lut')
# this will be the final image array
- imgData = np.empty(data.shape[:2]+(4,), dtype=np.ubyte)
+ if output is None:
+ imgData = xp.empty(data.shape[:2]+(4,), dtype=xp.ubyte)
+ else:
+ imgData = output
- profile()
+ profile('allocate')
# decide channel order
if useRGBA:
@@ -1174,7 +1163,7 @@ def makeARGB(data, lut=None, levels=None, scale=None, useRGBA=False):
# copy data into image array
if data.ndim == 2:
# This is tempting:
- # imgData[..., :3] = data[..., np.newaxis]
+ # imgData[..., :3] = data[..., xp.newaxis]
# ..but it turns out this is faster:
for i in range(3):
imgData[..., i] = data
@@ -1185,7 +1174,7 @@ def makeARGB(data, lut=None, levels=None, scale=None, useRGBA=False):
for i in range(0, data.shape[2]):
imgData[..., i] = data[..., order[i]]
- profile()
+ profile('reorder channels')
# add opaque alpha channel if needed
if data.ndim == 2 or data.shape[2] == 3:
@@ -1199,7 +1188,7 @@ def makeARGB(data, lut=None, levels=None, scale=None, useRGBA=False):
alpha = True
imgData[nanMask, 3] = 0
- profile()
+ profile('alpha channel')
return imgData, alpha
@@ -1213,10 +1202,14 @@ def makeQImage(imgData, alpha=None, copy=True, transpose=True):
============== ===================================================================
**Arguments:**
- imgData Array of data to convert. Must have shape (width, height, 3 or 4)
- and dtype=ubyte. The order of values in the 3rd axis must be
- (b, g, r, a).
- alpha If True, the QImage returned will have format ARGB32. If False,
+ imgData Array of data to convert. Must have shape (height, width),
+ (height, width, 3), or (height, width, 4). If transpose is
+ True, then the first two axes are swapped. The array dtype
+ must be ubyte. For 2D arrays, the value is interpreted as
+ greyscale. For 3D arrays, the order of values in the 3rd
+ axis must be (b, g, r, a).
+ alpha If the input array is 3D and *alpha* is True, the QImage
+ returned will have format ARGB32. If False,
the format will be RGB32. By default, _alpha_ is True if
array.shape[2] == 4.
copy If True, the data is copied before converting to QImage.
@@ -1232,30 +1225,35 @@ def makeQImage(imgData, alpha=None, copy=True, transpose=True):
## create QImage from buffer
profile = debug.Profiler()
- ## If we didn't explicitly specify alpha, check the array shape.
- if alpha is None:
- alpha = (imgData.shape[2] == 4)
-
copied = False
- if imgData.shape[2] == 3: ## need to make alpha channel (even if alpha==False; QImage requires 32 bpp)
- if copy is True:
- d2 = np.empty(imgData.shape[:2] + (4,), dtype=imgData.dtype)
- d2[:,:,:3] = imgData
- d2[:,:,3] = 255
- imgData = d2
- copied = True
+ if imgData.ndim == 2:
+ imgFormat = QtGui.QImage.Format_Grayscale8
+ elif imgData.ndim == 3:
+ # If we didn't explicitly specify alpha, check the array shape.
+ if alpha is None:
+ alpha = (imgData.shape[2] == 4)
+
+ if imgData.shape[2] == 3: # need to make alpha channel (even if alpha==False; QImage requires 32 bpp)
+ if copy is True:
+ d2 = np.empty(imgData.shape[:2] + (4,), dtype=imgData.dtype)
+ d2[:,:,:3] = imgData
+ d2[:,:,3] = 255
+ imgData = d2
+ copied = True
+ else:
+ raise Exception('Array has only 3 channels; cannot make QImage without copying.')
+
+ profile("add alpha channel")
+
+ if alpha:
+ imgFormat = QtGui.QImage.Format_ARGB32
else:
- raise Exception('Array has only 3 channels; cannot make QImage without copying.')
-
- if alpha:
- imgFormat = QtGui.QImage.Format_ARGB32
+ imgFormat = QtGui.QImage.Format_RGB32
else:
- imgFormat = QtGui.QImage.Format_RGB32
+ raise TypeError("Image array must have ndim = 2 or 3.")
if transpose:
- imgData = imgData.transpose((1, 0, 2)) ## QImage expects the row/column order to be opposite
-
- profile()
+ imgData = imgData.transpose((1, 0, 2)) # QImage expects row-major order
if not imgData.flags['C_CONTIGUOUS']:
if copy is False:
@@ -1264,24 +1262,34 @@ def makeQImage(imgData, alpha=None, copy=True, transpose=True):
imgData = np.ascontiguousarray(imgData)
copied = True
+ profile("ascontiguousarray")
+
if copy is True and copied is False:
imgData = imgData.copy()
- if QT_LIB in ['PySide', 'PySide2']:
- ch = ctypes.c_char.from_buffer(imgData, 0)
- img = QtGui.QImage(ch, imgData.shape[1], imgData.shape[0], imgFormat)
+ profile("copy")
+
+ # C++ QImage has two kind of constructors
+ # - QImage(const uchar*, ...)
+ # - QImage(uchar*, ...)
+ # If the const constructor is used, subsequently calling any non-const method
+ # will trigger the COW mechanism, i.e. a copy is made under the hood.
+
+ if QT_LIB == 'PyQt5':
+ # PyQt5 -> non-const constructor
+ img_ptr = imgData.ctypes.data
+ elif QT_LIB == 'PyQt6':
+ # PyQt5 -> const constructor
+ # PyQt6 -> non-const constructor
+ img_ptr = Qt.sip.voidptr(imgData)
else:
- ## PyQt API for QImage changed between 4.9.3 and 4.9.6 (I don't know exactly which version it was)
- ## So we first attempt the 4.9.6 API, then fall back to 4.9.3
- try:
- img = QtGui.QImage(imgData.ctypes.data, imgData.shape[1], imgData.shape[0], imgFormat)
- except:
- if copy:
- # does not leak memory, is not mutable
- img = QtGui.QImage(buffer(imgData), imgData.shape[1], imgData.shape[0], imgFormat)
- else:
- # mutable, but leaks memory
- img = QtGui.QImage(memoryview(imgData), imgData.shape[1], imgData.shape[0], imgFormat)
+ # bindings that support ndarray
+ # PyQt5 -> const constructor
+ # PySide2 -> non-const constructor
+ # PySide6 -> non-const constructor
+ img_ptr = imgData
+
+ img = QtGui.QImage(img_ptr, imgData.shape[1], imgData.shape[0], imgFormat)
img.data = imgData
return img
@@ -1295,15 +1303,19 @@ def imageToArray(img, copy=False, transpose=True):
"""
fmt = img.format()
ptr = img.bits()
- if QT_LIB in ['PySide', 'PySide2']:
+ if QT_LIB in ['PySide', 'PySide2', 'PySide6']:
arr = np.frombuffer(ptr, dtype=np.ubyte)
else:
- ptr.setsize(img.byteCount())
+ try:
+ # removed in Qt6
+ nbytes = img.byteCount()
+ except AttributeError:
+ # introduced in Qt 5.10
+ # however Python 3.7 + PyQt5-5.12 in the CI fails with
+ # "TypeError: QImage.sizeInBytes() is a private method"
+ nbytes = img.sizeInBytes()
+ ptr.setsize(nbytes)
arr = np.asarray(ptr)
- if img.byteCount() != arr.size * arr.itemsize:
- # Required for Python 2.6, PyQt 4.10
- # If this works on all platforms, then there is no need to use np.asarray..
- arr = np.frombuffer(ptr, np.ubyte, img.byteCount())
arr = arr.reshape(img.height(), img.width(), 4)
if fmt == img.Format_RGB32:
@@ -1369,7 +1381,9 @@ def gaussianFilter(data, sigma):
(note: results are only approximately equal to the output of
gaussian_filter)
"""
- if np.isscalar(sigma):
+ cp = getCupy()
+ xp = cp.get_array_module(data) if cp else np
+ if xp.isscalar(sigma):
sigma = (sigma,) * data.ndim
baseline = data.mean()
@@ -1381,17 +1395,17 @@ def gaussianFilter(data, sigma):
# generate 1D gaussian kernel
ksize = int(s * 6)
- x = np.arange(-ksize, ksize)
- kernel = np.exp(-x**2 / (2*s**2))
+ x = xp.arange(-ksize, ksize)
+ kernel = xp.exp(-x**2 / (2*s**2))
kshape = [1,] * data.ndim
kshape[ax] = len(kernel)
kernel = kernel.reshape(kshape)
# convolve as product of FFTs
shape = data.shape[ax] + ksize
- scale = 1.0 / (abs(s) * (2*np.pi)**0.5)
- filtered = scale * np.fft.irfft(np.fft.rfft(filtered, shape, axis=ax) *
- np.fft.rfft(kernel, shape, axis=ax),
+ scale = 1.0 / (abs(s) * (2*xp.pi)**0.5)
+ filtered = scale * xp.fft.irfft(xp.fft.rfft(filtered, shape, axis=ax) *
+ xp.fft.rfft(kernel, shape, axis=ax),
axis=ax)
# clip off extra data
@@ -1555,6 +1569,9 @@ def arrayToQPath(x, y, connect='all'):
buf = QtCore.QByteArray.fromRawData(path.strn)
except TypeError:
buf = QtCore.QByteArray(bytes(path.strn))
+ except AttributeError:
+ # PyQt6 raises AttributeError
+ buf = QtCore.QByteArray(path.strn, path.strn.nbytes)
ds = QtCore.QDataStream(buf)
ds >> path
@@ -2331,26 +2348,32 @@ def isosurface(data, level):
return vertexes, faces
-
+def _pinv_fallback(tr):
+ arr = np.array([tr.m11(), tr.m12(), tr.m13(),
+ tr.m21(), tr.m22(), tr.m23(),
+ tr.m31(), tr.m32(), tr.m33()])
+ arr.shape = (3, 3)
+ pinv = np.linalg.pinv(arr)
+ return QtGui.QTransform(*pinv.ravel().tolist())
+
+
def invertQTransform(tr):
"""Return a QTransform that is the inverse of *tr*.
- Rasises an exception if tr is not invertible.
+ A pseudo-inverse is returned if tr is not invertible.
Note that this function is preferred over QTransform.inverted() due to
bugs in that method. (specifically, Qt has floating-point precision issues
when determining whether a matrix is invertible)
"""
try:
- import numpy.linalg
- arr = np.array([[tr.m11(), tr.m12(), tr.m13()], [tr.m21(), tr.m22(), tr.m23()], [tr.m31(), tr.m32(), tr.m33()]])
- inv = numpy.linalg.inv(arr)
- return QtGui.QTransform(inv[0,0], inv[0,1], inv[0,2], inv[1,0], inv[1,1], inv[1,2], inv[2,0], inv[2,1])
- except ImportError:
- inv = tr.inverted()
- if inv[1] is False:
- raise Exception("Transform is not invertible.")
- return inv[0]
+ det = tr.determinant()
+ detr = 1.0 / det # let singular matrices raise ZeroDivisionError
+ inv = tr.adjoint()
+ inv *= detr
+ return inv
+ except ZeroDivisionError:
+ return _pinv_fallback(tr)
def pseudoScatter(data, spacing=None, shuffle=True, bidir=False, method='exact'):
diff --git a/pyqtgraph/graphicsItems/ArrowItem.py b/pyqtgraph/graphicsItems/ArrowItem.py
index a7cc831c..77b6c44c 100644
--- a/pyqtgraph/graphicsItems/ArrowItem.py
+++ b/pyqtgraph/graphicsItems/ArrowItem.py
@@ -104,7 +104,7 @@ class ArrowItem(QtGui.QGraphicsPathItem):
def paint(self, p, *args):
p.setRenderHint(QtGui.QPainter.Antialiasing)
- QtGui.QGraphicsPathItem.paint(self, p, *args)
+ super().paint(p, *args)
#p.setPen(fn.mkPen('r'))
#p.setBrush(fn.mkBrush(None))
diff --git a/pyqtgraph/graphicsItems/AxisItem.py b/pyqtgraph/graphicsItems/AxisItem.py
index ed36a676..92cd84f2 100644
--- a/pyqtgraph/graphicsItems/AxisItem.py
+++ b/pyqtgraph/graphicsItems/AxisItem.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-from ..Qt import QtGui, QtCore
+from ..Qt import QtGui, QtCore, QT_LIB
from ..python2_3 import asUnicode
import numpy as np
from ..Point import Point
@@ -1103,19 +1103,28 @@ class AxisItem(GraphicsWidget):
width = textRect.width()
#self.textHeight = height
offset = max(0,self.style['tickLength']) + textOffset
+
if self.orientation == 'left':
- textFlags = QtCore.Qt.TextDontClip|QtCore.Qt.AlignRight|QtCore.Qt.AlignVCenter
+ alignFlags = QtCore.Qt.AlignRight|QtCore.Qt.AlignVCenter
rect = QtCore.QRectF(tickStop-offset-width, x-(height/2), width, height)
elif self.orientation == 'right':
- textFlags = QtCore.Qt.TextDontClip|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter
+ alignFlags = QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter
rect = QtCore.QRectF(tickStop+offset, x-(height/2), width, height)
elif self.orientation == 'top':
- textFlags = QtCore.Qt.TextDontClip|QtCore.Qt.AlignCenter|QtCore.Qt.AlignBottom
+ alignFlags = QtCore.Qt.AlignHCenter|QtCore.Qt.AlignBottom
rect = QtCore.QRectF(x-width/2., tickStop-offset-height, width, height)
elif self.orientation == 'bottom':
- textFlags = QtCore.Qt.TextDontClip|QtCore.Qt.AlignCenter|QtCore.Qt.AlignTop
+ alignFlags = QtCore.Qt.AlignHCenter|QtCore.Qt.AlignTop
rect = QtCore.QRectF(x-width/2., tickStop+offset, width, height)
+ if QT_LIB == 'PyQt6':
+ # PyQt6 doesn't allow or-ing of different enum types
+ # so we need to take its value property
+ textFlags = alignFlags.value | QtCore.Qt.TextDontClip.value
+ else:
+ # for PyQt5, the following expression is not commutative!
+ textFlags = alignFlags | QtCore.Qt.TextDontClip
+
#p.setPen(self.pen())
#p.drawText(rect, textFlags, vstr)
textSpecs.append((rect, textFlags, vstr))
diff --git a/pyqtgraph/graphicsItems/DateAxisItem.py b/pyqtgraph/graphicsItems/DateAxisItem.py
index 3d705e9e..406c28d4 100644
--- a/pyqtgraph/graphicsItems/DateAxisItem.py
+++ b/pyqtgraph/graphicsItems/DateAxisItem.py
@@ -269,10 +269,10 @@ class DateAxisItem(AxisItem):
# Size in pixels a specific tick label will take
if self.orientation in ['bottom', 'top']:
def sizeOf(text):
- return self.fontMetrics.boundingRect(text).width() + padding*self.fontScaleFactor
+ return self.fontMetrics.boundingRect(text).width() + padding
else:
def sizeOf(text):
- return self.fontMetrics.boundingRect(text).height() + padding*self.fontScaleFactor
+ return self.fontMetrics.boundingRect(text).height() + padding
# Fallback zoom level: Years/Months
self.zoomLevel = YEAR_MONTH_ZOOM_LEVEL
@@ -314,6 +314,5 @@ class DateAxisItem(AxisItem):
self.fontMetrics = p.fontMetrics()
# Get font scale factor by current window resolution
- self.fontScaleFactor = p.device().logicalDpiX() / 96
return super(DateAxisItem, self).generateDrawSpecs(p)
diff --git a/pyqtgraph/graphicsItems/GradientEditorItem.py b/pyqtgraph/graphicsItems/GradientEditorItem.py
index 6f5d9132..70918e82 100644
--- a/pyqtgraph/graphicsItems/GradientEditorItem.py
+++ b/pyqtgraph/graphicsItems/GradientEditorItem.py
@@ -10,6 +10,7 @@ from ..widgets.SpinBox import SpinBox
from ..pgcollections import OrderedDict
from ..colormap import ColorMap
+translate = QtCore.QCoreApplication.translate
__all__ = ['TickSliderItem', 'GradientEditorItem']
@@ -442,10 +443,10 @@ class GradientEditorItem(TickSliderItem):
self.setMaxDim(self.rectSize + self.tickSize)
- self.rgbAction = QtGui.QAction('RGB', self)
+ self.rgbAction = QtGui.QAction(translate("GradiantEditorItem", 'RGB'), self)
self.rgbAction.setCheckable(True)
self.rgbAction.triggered.connect(lambda: self.setColorMode('rgb'))
- self.hsvAction = QtGui.QAction('HSV', self)
+ self.hsvAction = QtGui.QAction(translate("GradiantEditorItem", 'HSV'), self)
self.hsvAction.setCheckable(True)
self.hsvAction.triggered.connect(lambda: self.setColorMode('hsv'))
@@ -949,11 +950,11 @@ class TickMenu(QtGui.QMenu):
self.tick = weakref.ref(tick)
self.sliderItem = weakref.ref(sliderItem)
- self.removeAct = self.addAction("Remove Tick", lambda: self.sliderItem().removeTick(tick))
+ self.removeAct = self.addAction(translate("GradientEditorItem", "Remove Tick"), lambda: self.sliderItem().removeTick(tick))
if (not self.tick().removeAllowed) or len(self.sliderItem().ticks) < 3:
self.removeAct.setEnabled(False)
- positionMenu = self.addMenu("Set Position")
+ positionMenu = self.addMenu(translate("GradientEditorItem", "Set Position"))
w = QtGui.QWidget()
l = QtGui.QGridLayout()
w.setLayout(l)
@@ -964,7 +965,7 @@ class TickMenu(QtGui.QMenu):
#self.dataPosSpin = SpinBox(value=dataVal)
#self.dataPosSpin.setOpts(decimals=3, siPrefix=True)
- l.addWidget(QtGui.QLabel("Position:"), 0,0)
+ l.addWidget(QtGui.QLabel(f"{translate('GradiantEditorItem', 'Position')}:"), 0,0)
l.addWidget(self.fracPosSpin, 0, 1)
#l.addWidget(QtGui.QLabel("Position (data units):"), 1, 0)
#l.addWidget(self.dataPosSpin, 1,1)
@@ -979,7 +980,7 @@ class TickMenu(QtGui.QMenu):
self.fracPosSpin.sigValueChanging.connect(self.fractionalValueChanged)
#self.dataPosSpin.valueChanged.connect(self.dataValueChanged)
- colorAct = self.addAction("Set Color", lambda: self.sliderItem().raiseColorDialog(self.tick()))
+ colorAct = self.addAction(translate("Context Menu", "Set Color"), lambda: self.sliderItem().raiseColorDialog(self.tick()))
if not self.tick().colorChangeAllowed:
colorAct.setEnabled(False)
diff --git a/pyqtgraph/graphicsItems/GraphicsItem.py b/pyqtgraph/graphicsItems/GraphicsItem.py
index c69bb3c3..0955726b 100644
--- a/pyqtgraph/graphicsItems/GraphicsItem.py
+++ b/pyqtgraph/graphicsItems/GraphicsItem.py
@@ -21,7 +21,6 @@ class GraphicsItem(object):
The GraphicsView system places a lot of emphasis on the notion that the graphics within the scene should be device independent--you should be able to take the same graphics and display them on screens of different resolutions, printers, export to SVG, etc. This is nice in principle, but causes me a lot of headache in practice. It means that I have to circumvent all the device-independent expectations any time I want to operate in pixel coordinates rather than arbitrary scene coordinates. A lot of the code in GraphicsItem is devoted to this task--keeping track of view widgets and device transforms, computing the size and shape of a pixel in local item coordinates, etc. Note that in item coordinates, a pixel does not have to be square or even rectangular, so just asking how to increase a bounding rect by 2px can be a rather complex task.
"""
_pixelVectorGlobalCache = LRUCache(100, 70)
- _mapRectFromViewGlobalCache = LRUCache(100, 70)
def __init__(self, register=None):
if not hasattr(self, '_qtBaseClass'):
@@ -373,21 +372,8 @@ class GraphicsItem(object):
vt = self.viewTransform()
if vt is None:
return None
-
- cache = self._mapRectFromViewGlobalCache
- k = (
- vt.m11(), vt.m12(), vt.m13(),
- vt.m21(), vt.m22(), vt.m23(),
- vt.m31(), vt.m32(), vt.m33(),
- )
-
- try:
- inv_vt = cache[k]
- except KeyError:
- inv_vt = fn.invertQTransform(vt)
- cache[k] = inv_vt
-
- return inv_vt.mapRect(obj)
+ vt = fn.invertQTransform(vt)
+ return vt.mapRect(obj)
def pos(self):
return Point(self._qtBaseClass.pos(self))
diff --git a/pyqtgraph/graphicsItems/GraphicsObject.py b/pyqtgraph/graphicsItems/GraphicsObject.py
index fac8e819..2e63b531 100644
--- a/pyqtgraph/graphicsItems/GraphicsObject.py
+++ b/pyqtgraph/graphicsItems/GraphicsObject.py
@@ -1,9 +1,6 @@
from ..Qt import QtGui, QtCore, QT_LIB
-if QT_LIB in ['PyQt4', 'PyQt5']:
- try:
- from PyQt5 import sip
- except ImportError:
- import sip
+if QT_LIB.startswith('PyQt'):
+ from ..Qt import sip
from .GraphicsItem import GraphicsItem
__all__ = ['GraphicsObject']
@@ -21,7 +18,7 @@ class GraphicsObject(GraphicsItem, QtGui.QGraphicsObject):
GraphicsItem.__init__(self)
def itemChange(self, change, value):
- ret = QtGui.QGraphicsObject.itemChange(self, change, value)
+ ret = super().itemChange(change, value)
if change in [self.ItemParentHasChanged, self.ItemSceneHasChanged]:
self.parentChanged()
try:
diff --git a/pyqtgraph/graphicsItems/ImageItem.py b/pyqtgraph/graphicsItems/ImageItem.py
index 50cef315..79b8a3b3 100644
--- a/pyqtgraph/graphicsItems/ImageItem.py
+++ b/pyqtgraph/graphicsItems/ImageItem.py
@@ -1,13 +1,15 @@
# -*- coding: utf-8 -*-
from __future__ import division
-from ..Qt import QtGui, QtCore
-import numpy as np
-from .. import functions as fn
-from .. import debug as debug
+import numpy
+
from .GraphicsObject import GraphicsObject
-from ..Point import Point
+from .. import debug as debug
+from .. import functions as fn
from .. import getConfigOption
+from ..Point import Point
+from ..Qt import QtGui, QtCore
+from ..util.cupy_helper import getCupy
try:
from collections.abc import Callable
@@ -15,6 +17,8 @@ except ImportError:
# fallback for python < 3.3
from collections import Callable
+translate = QtCore.QCoreApplication.translate
+
__all__ = ['ImageItem']
@@ -48,11 +52,17 @@ class ImageItem(GraphicsObject):
self.qimage = None ## rendered image for display
self.paintMode = None
-
self.levels = None ## [min, max] or [[redMin, redMax], ...]
self.lut = None
self.autoDownsample = False
self._lastDownsample = (1, 1)
+ self._processingBuffer = None
+ self._displayBuffer = None
+ self._renderRequired = True
+ self._unrenderable = False
+ self._cupy = getCupy()
+ self._xp = None # either numpy or cupy, to match the image data
+ self._defferedLevels = None
self.axisOrder = getConfigOption('imageAxisOrder')
@@ -124,13 +134,16 @@ class ImageItem(GraphicsObject):
Only the first format is compatible with lookup tables. See :func:`makeARGB `
for more details on how levels are applied.
"""
- if levels is not None:
- levels = np.asarray(levels)
- if not fn.eq(levels, self.levels):
+ if self._xp is None:
self.levels = levels
- self._effectiveLut = None
- if update:
- self.updateImage()
+ self._defferedLevels = levels
+ return
+ if levels is not None:
+ levels = self._xp.asarray(levels)
+ self.levels = levels
+ self._effectiveLut = None
+ if update:
+ self.updateImage()
def getLevels(self):
return self.levels
@@ -159,7 +172,7 @@ class ImageItem(GraphicsObject):
Added in version 0.9.9
"""
self.autoDownsample = ads
- self.qimage = None
+ self._renderRequired = True
self.update()
def setOpts(self, update=True, **kargs):
@@ -200,6 +213,14 @@ class ImageItem(GraphicsObject):
self.informViewBoundsChanged()
self.update()
+ def _buildQImageBuffer(self, shape):
+ self._displayBuffer = numpy.empty(shape[:2] + (4,), dtype=numpy.ubyte)
+ if self._xp == self._cupy:
+ self._processingBuffer = self._xp.empty(shape[:2] + (4,), dtype=self._xp.ubyte)
+ else:
+ self._processingBuffer = self._displayBuffer
+ self.qimage = fn.makeQImage(self._displayBuffer, transpose=False, copy=False)
+
def setImage(self, image=None, autoLevels=None, **kargs):
"""
Update the image displayed by this item. For more information on how the image
@@ -250,9 +271,14 @@ class ImageItem(GraphicsObject):
if self.image is None:
return
else:
+ old_xp = self._xp
+ self._xp = self._cupy.get_array_module(image) if self._cupy else numpy
gotNewData = True
- shapeChanged = (self.image is None or image.shape != self.image.shape)
- image = image.view(np.ndarray)
+ processingSubstrateChanged = old_xp != self._xp
+ if processingSubstrateChanged:
+ self._processingBuffer = None
+ shapeChanged = (processingSubstrateChanged or self.image is None or image.shape != self.image.shape)
+ image = image.view()
if self.image is None or image.dtype != self.image.dtype:
self._effectiveLut = None
self.image = image
@@ -274,9 +300,9 @@ class ImageItem(GraphicsObject):
img = self.image
while img.size > 2**16:
img = img[::2, ::2]
- mn, mx = np.nanmin(img), np.nanmax(img)
+ mn, mx = self._xp.nanmin(img), self._xp.nanmax(img)
# mn and mx can still be NaN if the data is all-NaN
- if mn == mx or np.isnan(mn) or np.isnan(mx):
+ if mn == mx or self._xp.isnan(mn) or self._xp.isnan(mx):
mn = 0
mx = 255
kargs['levels'] = [mn,mx]
@@ -287,13 +313,17 @@ class ImageItem(GraphicsObject):
profile()
- self.qimage = None
+ self._renderRequired = True
self.update()
profile()
if gotNewData:
self.sigImageChanged.emit()
+ if self._defferedLevels is not None:
+ levels = self._defferedLevels
+ self._defferedLevels = None
+ self.setLevels((levels))
def dataTransform(self):
"""Return the transform that maps from this image's input array to its
@@ -337,11 +367,11 @@ class ImageItem(GraphicsObject):
"""
data = self.image
while data.size > targetSize:
- ax = np.argmax(data.shape)
+ ax = self._xp.argmax(data.shape)
sl = [slice(None)] * data.ndim
sl[ax] = slice(None, None, 2)
data = data[sl]
- return np.nanmin(data), np.nanmax(data)
+ return self._xp.nanmin(data), self._xp.nanmax(data)
def updateImage(self, *args, **kargs):
## used for re-rendering qimage from self.image.
@@ -356,8 +386,7 @@ class ImageItem(GraphicsObject):
def render(self):
# Convert data to QImage for display.
-
- profile = debug.Profiler()
+ self._unrenderable = True
if self.image is None or self.image.size == 0:
return
@@ -373,7 +402,6 @@ class ImageItem(GraphicsObject):
if self.autoDownsample:
xds, yds = self._computeDownsampleFactors()
if xds is None:
- self.qimage = None
return
axes = [1, 0] if self.axisOrder == 'row-major' else [0, 1]
@@ -390,18 +418,18 @@ class ImageItem(GraphicsObject):
# if the image data is a small int, then we can combine levels + lut
# into a single lut for better performance
levels = self.levels
- if levels is not None and levels.ndim == 1 and image.dtype in (np.ubyte, np.uint16):
+ if levels is not None and levels.ndim == 1 and image.dtype in (self._xp.ubyte, self._xp.uint16):
if self._effectiveLut is None:
eflsize = 2**(image.itemsize*8)
- ind = np.arange(eflsize)
+ ind = self._xp.arange(eflsize)
minlev, maxlev = levels
levdiff = maxlev - minlev
levdiff = 1 if levdiff == 0 else levdiff # don't allow division by 0
if lut is None:
efflut = fn.rescaleData(ind, scale=255./levdiff,
- offset=minlev, dtype=np.ubyte)
+ offset=minlev, dtype=self._xp.ubyte)
else:
- lutdtype = np.min_scalar_type(lut.shape[0]-1)
+ lutdtype = self._xp.min_scalar_type(lut.shape[0] - 1)
efflut = fn.rescaleData(ind, scale=(lut.shape[0]-1)/levdiff,
offset=minlev, dtype=lutdtype, clip=(0, lut.shape[0]-1))
efflut = lut[efflut]
@@ -419,16 +447,22 @@ class ImageItem(GraphicsObject):
if self.axisOrder == 'col-major':
image = image.transpose((1, 0, 2)[:image.ndim])
- argb, alpha = fn.makeARGB(image, lut=lut, levels=levels)
- self.qimage = fn.makeQImage(argb, alpha, transpose=False)
+ if self._processingBuffer is None or self._processingBuffer.shape[:2] != image.shape[:2]:
+ self._buildQImageBuffer(image.shape)
+
+ fn.makeARGB(image, lut=lut, levels=levels, output=self._processingBuffer)
+ if self._xp == self._cupy:
+ self._processingBuffer.get(out=self._displayBuffer)
+ self._renderRequired = False
+ self._unrenderable = False
def paint(self, p, *args):
profile = debug.Profiler()
if self.image is None:
return
- if self.qimage is None:
+ if self._renderRequired:
self.render()
- if self.qimage is None:
+ if self._unrenderable:
return
profile('render QImage')
if self.paintMode is not None:
@@ -444,7 +478,7 @@ class ImageItem(GraphicsObject):
def save(self, fileName, *args):
"""Save this image to file. Note that this saves the visible image (after scale/color changes), not the original data."""
- if self.qimage is None:
+ if self._renderRequired:
self.render()
self.qimage.save(fileName, *args)
@@ -458,7 +492,7 @@ class ImageItem(GraphicsObject):
dimensions roughly *targetImageSize* for each axis.
The *bins* argument and any extra keyword arguments are passed to
- np.histogram(). If *bins* is 'auto', then a bin number is automatically
+ self.xp.histogram(). If *bins* is 'auto', then a bin number is automatically
chosen based on the image characteristics:
* Integer images will have approximately *targetHistogramSize* bins,
@@ -473,31 +507,33 @@ class ImageItem(GraphicsObject):
if self.image is None or self.image.size == 0:
return None, None
if step == 'auto':
- step = (max(1, int(np.ceil(self.image.shape[0] / targetImageSize))),
- max(1, int(np.ceil(self.image.shape[1] / targetImageSize))))
- if np.isscalar(step):
+ step = (max(1, int(self._xp.ceil(self.image.shape[0] / targetImageSize))),
+ max(1, int(self._xp.ceil(self.image.shape[1] / targetImageSize))))
+ if self._xp.isscalar(step):
step = (step, step)
stepData = self.image[::step[0], ::step[1]]
if isinstance(bins, str) and bins == 'auto':
- mn = np.nanmin(stepData)
- mx = np.nanmax(stepData)
+ mn = self._xp.nanmin(stepData).item()
+ mx = self._xp.nanmax(stepData).item()
if mx == mn:
# degenerate image, arange will fail
mx += 1
- if np.isnan(mn) or np.isnan(mx):
+ if self._xp.isnan(mn) or self._xp.isnan(mx):
# the data are all-nan
return None, None
if stepData.dtype.kind in "ui":
# For integer data, we select the bins carefully to avoid aliasing
- step = np.ceil((mx-mn) / 500.)
- bins = np.arange(mn, mx+1.01*step, step, dtype=np.int)
+ step = int(self._xp.ceil((mx - mn) / 500.))
+ bins = []
+ if step > 0.0:
+ bins = self._xp.arange(mn, mx + 1.01 * step, step, dtype=self._xp.int)
else:
# for float data, let numpy select the bins.
- bins = np.linspace(mn, mx, 500)
+ bins = self._xp.linspace(mn, mx, 500)
if len(bins) == 0:
- bins = [mn, mx]
+ bins = self._xp.asarray((mn, mx))
kwds['bins'] = bins
@@ -505,14 +541,20 @@ class ImageItem(GraphicsObject):
hist = []
for i in range(stepData.shape[-1]):
stepChan = stepData[..., i]
- stepChan = stepChan[np.isfinite(stepChan)]
- h = np.histogram(stepChan, **kwds)
- hist.append((h[1][:-1], h[0]))
+ stepChan = stepChan[self._xp.isfinite(stepChan)]
+ h = self._xp.histogram(stepChan, **kwds)
+ if self._cupy:
+ hist.append((self._cupy.asnumpy(h[1][:-1]), self._cupy.asnumpy(h[0])))
+ else:
+ hist.append((h[1][:-1], h[0]))
return hist
else:
- stepData = stepData[np.isfinite(stepData)]
- hist = np.histogram(stepData, **kwds)
- return hist[1][:-1], hist[0]
+ stepData = stepData[self._xp.isfinite(stepData)]
+ hist = self._xp.histogram(stepData, **kwds)
+ if self._cupy:
+ return self._cupy.asnumpy(hist[1][:-1]), self._cupy.asnumpy(hist[0])
+ else:
+ return hist[1][:-1], hist[0]
def setPxMode(self, b):
"""
@@ -527,9 +569,9 @@ class ImageItem(GraphicsObject):
self.setPxMode(False)
def getPixmap(self):
- if self.qimage is None:
+ if self._renderRequired:
self.render()
- if self.qimage is None:
+ if self._unrenderable:
return None
return QtGui.QPixmap.fromImage(self.qimage)
@@ -544,10 +586,11 @@ class ImageItem(GraphicsObject):
if self.autoDownsample:
xds, yds = self._computeDownsampleFactors()
if xds is None:
- self.qimage = None
+ self._renderRequired = True
+ self._unrenderable = True
return
if (xds, yds) != self._lastDownsample:
- self.qimage = None
+ self._renderRequired = True
self.update()
def _computeDownsampleFactors(self):
@@ -593,8 +636,8 @@ class ImageItem(GraphicsObject):
if not self.removable:
return None
self.menu = QtGui.QMenu()
- self.menu.setTitle("Image")
- remAct = QtGui.QAction("Remove image", self.menu)
+ self.menu.setTitle(translate("ImageItem", "Image"))
+ remAct = QtGui.QAction(translate("ImageItem", "Remove image"), self.menu)
remAct.triggered.connect(self.removeClicked)
self.menu.addAction(remAct)
self.menu.remAct = remAct
diff --git a/pyqtgraph/graphicsItems/InfiniteLine.py b/pyqtgraph/graphicsItems/InfiniteLine.py
index c5726031..0b23e569 100644
--- a/pyqtgraph/graphicsItems/InfiniteLine.py
+++ b/pyqtgraph/graphicsItems/InfiniteLine.py
@@ -25,12 +25,14 @@ class InfiniteLine(GraphicsObject):
sigDragged(self)
sigPositionChangeFinished(self)
sigPositionChanged(self)
+ sigclicked(self, ev)
=============================== ===================================================
"""
sigDragged = QtCore.Signal(object)
sigPositionChangeFinished = QtCore.Signal(object)
sigPositionChanged = QtCore.Signal(object)
+ sigClicked = QtCore.Signal(object, object)
def __init__(self, pos=None, angle=90, pen=None, movable=False, bounds=None,
hoverPen=None, label=None, labelOpts=None, span=(0, 1), markers=None,
@@ -400,6 +402,7 @@ class InfiniteLine(GraphicsObject):
self.sigPositionChangeFinished.emit(self)
def mouseClickEvent(self, ev):
+ self.sigClicked.emit(self, ev)
if self.moving and ev.button() == QtCore.Qt.RightButton:
ev.accept()
self.setPos(self.startPosition)
@@ -550,8 +553,7 @@ class InfLineLabel(TextItem):
def setVisible(self, v):
TextItem.setVisible(self, v)
if v:
- self.updateText()
- self.updatePosition()
+ self.valueChanged()
def setMovable(self, m):
"""Set whether this label is movable by dragging along the line.
diff --git a/pyqtgraph/graphicsItems/LegendItem.py b/pyqtgraph/graphicsItems/LegendItem.py
index 6509f979..f5c5a559 100644
--- a/pyqtgraph/graphicsItems/LegendItem.py
+++ b/pyqtgraph/graphicsItems/LegendItem.py
@@ -3,13 +3,14 @@ from .GraphicsWidget import GraphicsWidget
from .LabelItem import LabelItem
from ..Qt import QtGui, QtCore
from .. import functions as fn
+from ..icons import invisibleEye
from ..Point import Point
from .ScatterPlotItem import ScatterPlotItem, drawSymbol
from .PlotDataItem import PlotDataItem
from .GraphicsWidgetAnchor import GraphicsWidgetAnchor
from .BarGraphItem import BarGraphItem
-__all__ = ['LegendItem']
+__all__ = ['LegendItem', 'ItemSample']
class LegendItem(GraphicsWidget, GraphicsWidgetAnchor):
@@ -29,7 +30,8 @@ class LegendItem(GraphicsWidget, GraphicsWidgetAnchor):
def __init__(self, size=None, offset=None, horSpacing=25, verSpacing=0,
pen=None, brush=None, labelTextColor=None, frame=True,
- labelTextSize='9pt', rowCount=1, colCount=1, **kwargs):
+ labelTextSize='9pt', rowCount=1, colCount=1,
+ sampleType=None, **kwargs):
"""
============== ===============================================================
**Arguments:**
@@ -52,6 +54,7 @@ class LegendItem(GraphicsWidget, GraphicsWidgetAnchor):
accepted by :func:`mkPen ` is allowed.
labelTextSize Size to use when drawing legend text. Accepts CSS style
string arguments, e.g. '9pt'.
+ sampleType Customizes the item sample class of the `LegendItem`.
============== ===============================================================
"""
@@ -73,6 +76,14 @@ class LegendItem(GraphicsWidget, GraphicsWidgetAnchor):
if size is not None:
self.setGeometry(QtCore.QRectF(0, 0, self.size[0], self.size[1]))
+ if sampleType is not None:
+ if not issubclass(sampleType, GraphicsWidget):
+ raise RuntimeError("Only classes of type `GraphicsWidgets` "
+ "are allowed as `sampleType`")
+ self.sampleType = sampleType
+ else:
+ self.sampleType = ItemSample
+
self.opts = {
'pen': fn.mkPen(pen),
'brush': fn.mkBrush(brush),
@@ -80,9 +91,26 @@ class LegendItem(GraphicsWidget, GraphicsWidgetAnchor):
'labelTextSize': labelTextSize,
'offset': offset,
}
-
self.opts.update(kwargs)
+ def setSampleType(self, sample):
+ """Set the new sample item claspes"""
+ if sample is self.sampleType:
+ return
+
+ # Clear the legend, but before create a list of items
+ items = list(self.items)
+ self.sampleType = sample
+ self.clear()
+
+ # Refill the legend with the item list and new sample item
+ for sample, label in items:
+ plot_item = sample.item
+ plot_name = label.text
+ self.addItem(plot_item, plot_name)
+
+ self.updateSize()
+
def offset(self):
"""Get the offset position relative to the parent."""
return self.opts['offset']
@@ -183,10 +211,10 @@ class LegendItem(GraphicsWidget, GraphicsWidgetAnchor):
"""
label = LabelItem(name, color=self.opts['labelTextColor'],
justify='left', size=self.opts['labelTextSize'])
- if isinstance(item, ItemSample):
+ if isinstance(item, self.sampleType):
sample = item
else:
- sample = ItemSample(item)
+ sample = self.sampleType(item)
self.items.append((sample, label))
self._addItemToLayout(sample, label)
self.updateSize()
@@ -301,11 +329,8 @@ class LegendItem(GraphicsWidget, GraphicsWidgetAnchor):
class ItemSample(GraphicsWidget):
"""Class responsible for drawing a single item in a LegendItem (sans label)
-
- This may be subclassed to draw custom graphics in a Legend.
"""
- # TODO: make this more generic; let items decide how it should be look.
def __init__(self, item):
GraphicsWidget.__init__(self)
self.item = item
@@ -315,10 +340,15 @@ class ItemSample(GraphicsWidget):
def paint(self, p, *args):
opts = self.item.opts
-
if opts.get('antialias'):
p.setRenderHint(p.Antialiasing)
+ visible = self.item.isVisible()
+ if not visible:
+ icon = invisibleEye.qicon
+ p.drawPixmap(QtCore.QPoint(1, 1), icon.pixmap(18, 18))
+ return
+
if not isinstance(self.item, ScatterPlotItem):
p.setPen(fn.mkPen(opts['pen']))
p.drawLine(0, 11, 20, 11)
@@ -342,3 +372,13 @@ class ItemSample(GraphicsWidget):
if isinstance(self.item, BarGraphItem):
p.setBrush(fn.mkBrush(opts['brush']))
p.drawRect(QtCore.QRectF(2, 2, 18, 18))
+
+ def mouseClickEvent(self, event):
+ """Use the mouseClick event to toggle the visibility of the plotItem
+ """
+ if event.button() == QtCore.Qt.LeftButton:
+ visible = self.item.isVisible()
+ self.item.setVisible(not visible)
+
+ event.accept()
+ self.update()
diff --git a/pyqtgraph/graphicsItems/LinearRegionItem.py b/pyqtgraph/graphicsItems/LinearRegionItem.py
index 56ff5748..93527d14 100644
--- a/pyqtgraph/graphicsItems/LinearRegionItem.py
+++ b/pyqtgraph/graphicsItems/LinearRegionItem.py
@@ -191,8 +191,8 @@ class LinearRegionItem(GraphicsObject):
self.update()
def boundingRect(self):
- br = self.viewRect() # bounds of containing ViewBox mapped to local coords.
-
+ br = QtCore.QRectF(self.viewRect()) # bounds of containing ViewBox mapped to local coords.
+
rng = self.getRegion()
if self.orientation in ('vertical', LinearRegionItem.Vertical):
br.setLeft(rng[0])
@@ -245,7 +245,7 @@ class LinearRegionItem(GraphicsObject):
self.sigRegionChangeFinished.emit(self)
def mouseDragEvent(self, ev):
- if not self.movable or int(ev.button() & QtCore.Qt.LeftButton) == 0:
+ if not self.movable or ev.button() != QtCore.Qt.LeftButton:
return
ev.accept()
diff --git a/pyqtgraph/graphicsItems/NonUniformImage.py b/pyqtgraph/graphicsItems/NonUniformImage.py
new file mode 100644
index 00000000..2b697767
--- /dev/null
+++ b/pyqtgraph/graphicsItems/NonUniformImage.py
@@ -0,0 +1,130 @@
+from ..Qt import QtGui, QtCore
+import numpy as np
+from ..colormap import ColorMap
+from .GraphicsObject import GraphicsObject
+from .. import mkBrush, mkPen
+from .. import functions as fn
+
+
+class NonUniformImage(GraphicsObject):
+ """
+ **Bases:** :class:`GraphicsObject `
+
+ GraphicsObject displaying an image with non-uniform sample points. It's
+ commonly used to display 2-d or slices of higher dimensional data that
+ have a regular but non-uniform grid e.g. measurements or simulation results.
+ """
+
+ def __init__(self, x, y, z, border=None):
+
+ GraphicsObject.__init__(self)
+
+ # convert to numpy arrays
+ x = np.asarray(x, dtype=np.float64)
+ y = np.asarray(y, dtype=np.float64)
+ z = np.asarray(z, dtype=np.float64)
+
+ if x.ndim != 1 or y.ndim != 1:
+ raise Exception("x and y must be 1-d arrays.")
+
+ if np.any(np.diff(x) < 0) or np.any(np.diff(y) < 0):
+ raise Exception("The values in x and y must be monotonically increasing.")
+
+ if len(z.shape) != 2 or z.shape != (x.size, y.size):
+ raise Exception("The length of x and y must match the shape of z.")
+
+ # default colormap (black - white)
+ self.cmap = ColorMap(pos=[0.0, 1.0], color=[(0.0, 0.0, 0.0, 1.0), (1.0, 1.0, 1.0, 1.0)])
+
+ self.data = (x, y, z)
+ self.lut = None
+ self.border = border
+ self.generatePicture()
+
+ def setLookupTable(self, lut, autoLevel=False):
+ lut.sigLevelsChanged.connect(self.generatePicture)
+ lut.gradient.sigGradientChanged.connect(self.generatePicture)
+ self.lut = lut
+
+ if autoLevel:
+ _, _, z = self.data
+ f = z[np.isfinite(z)]
+ lut.setLevels(f.min(), f.max())
+
+ self.generatePicture()
+
+ def setColorMap(self, cmap):
+ self.cmap = cmap
+ self.generatePicture()
+
+ def getHistogram(self, **kwds):
+ """Returns x and y arrays containing the histogram values for the current image.
+ For an explanation of the return format, see numpy.histogram().
+ """
+
+ z = self.data[2]
+ z = z[np.isfinite(z)]
+ hist = np.histogram(z, **kwds)
+
+ return hist[1][:-1], hist[0]
+
+ def generatePicture(self):
+
+ x, y, z = self.data
+
+ self.picture = QtGui.QPicture()
+ p = QtGui.QPainter(self.picture)
+ p.setPen(mkPen(None))
+
+ # normalize
+ if self.lut is not None:
+ mn, mx = self.lut.getLevels()
+ else:
+ f = z[np.isfinite(z)]
+ mn = f.min()
+ mx = f.max()
+
+ # draw the tiles
+ for i in range(x.size):
+ for j in range(y.size):
+
+ value = z[i, j]
+
+ if np.isneginf(value):
+ value = 0.0
+ elif np.isposinf(value):
+ value = 1.0
+ elif np.isnan(value):
+ continue # ignore NaN
+ else:
+ value = (value - mn) / (mx - mn) # normalize
+
+ if self.lut:
+ color = self.lut.gradient.getColor(value)
+ else:
+ color = self.cmap.mapToQColor(value)
+
+ p.setBrush(mkBrush(color))
+
+ # left, right, bottom, top
+ l = x[0] if i == 0 else (x[i - 1] + x[i]) / 2
+ r = (x[i] + x[i + 1]) / 2 if i < x.size - 1 else x[-1]
+ b = y[0] if j == 0 else (y[j - 1] + y[j]) / 2
+ t = (y[j] + y[j + 1]) / 2 if j < y.size - 1 else y[-1]
+
+ p.drawRect(QtCore.QRectF(l, t, r - l, b - t))
+
+ if self.border is not None:
+ p.setPen(self.border)
+ p.setBrush(fn.mkBrush(None))
+ p.drawRect(self.boundingRect())
+
+ p.end()
+
+ self.update()
+
+ def paint(self, p, *args):
+ p.drawPicture(0, 0, self.picture)
+
+ def boundingRect(self):
+ return QtCore.QRectF(self.picture.boundingRect())
diff --git a/pyqtgraph/graphicsItems/PlotCurveItem.py b/pyqtgraph/graphicsItems/PlotCurveItem.py
index b56d3d4d..39003813 100644
--- a/pyqtgraph/graphicsItems/PlotCurveItem.py
+++ b/pyqtgraph/graphicsItems/PlotCurveItem.py
@@ -1,10 +1,6 @@
# -*- coding: utf-8 -*-
-from ..Qt import QtGui, QtCore
-try:
- from ..Qt import QtOpenGL
- HAVE_OPENGL = True
-except:
- HAVE_OPENGL = False
+from ..Qt import QtCore, QtGui, QtWidgets
+HAVE_OPENGL = hasattr(QtWidgets, 'QOpenGLWidget')
import warnings
import numpy as np
@@ -483,9 +479,10 @@ class PlotCurveItem(GraphicsObject):
if self.xData is None or len(self.xData) == 0:
return
- if HAVE_OPENGL and getConfigOption('enableExperimental') and isinstance(widget, QtOpenGL.QGLWidget):
- self.paintGL(p, opt, widget)
- return
+ if getConfigOption('enableExperimental'):
+ if HAVE_OPENGL and isinstance(widget, QtWidgets.QOpenGLWidget):
+ self.paintGL(p, opt, widget)
+ return
x = None
y = None
diff --git a/pyqtgraph/graphicsItems/PlotDataItem.py b/pyqtgraph/graphicsItems/PlotDataItem.py
index ed73dcea..a4d9a067 100644
--- a/pyqtgraph/graphicsItems/PlotDataItem.py
+++ b/pyqtgraph/graphicsItems/PlotDataItem.py
@@ -217,6 +217,13 @@ class PlotDataItem(GraphicsObject):
def boundingRect(self):
return QtCore.QRectF() ## let child items handle this
+ def setPos(self, x, y):
+ GraphicsObject.setPos(self, x, y)
+ # to update viewRect:
+ self.viewTransformChanged()
+ # to update displayed point sets, e.g. when clipping (which uses viewRect):
+ self.viewRangeChanged()
+
def setAlpha(self, alpha, auto):
if self.opts['alphaHint'] == alpha and self.opts['alphaMode'] == auto:
return
@@ -234,6 +241,16 @@ class PlotDataItem(GraphicsObject):
self.informViewBoundsChanged()
def setLogMode(self, xMode, yMode):
+ """
+ To enable log scaling for y<0 and y>0, the following formula is used:
+
+ scaled = sign(y) * log10(abs(y) + eps)
+
+ where eps is the smallest unit of y.dtype.
+ This allows for handling of 0. values, scaling of large values,
+ as well as the typical log scaling of values in the range -1 < x < 1.
+ Note that for values within this range, the signs are inverted.
+ """
if self.opts['logMode'] == [xMode, yMode]:
return
self.opts['logMode'] = [xMode, yMode]
@@ -542,7 +559,6 @@ class PlotDataItem(GraphicsObject):
profiler('emit')
def updateItems(self):
-
curveArgs = {}
for k,v in [('pen','pen'), ('shadowPen','shadowPen'), ('fillLevel','fillLevel'), ('fillOutline', 'fillOutline'), ('fillBrush', 'brush'), ('antialias', 'antialias'), ('connect', 'connect'), ('stepMode', 'stepMode')]:
curveArgs[v] = self.opts[k]
@@ -598,7 +614,11 @@ class PlotDataItem(GraphicsObject):
if self.opts['logMode'][0]:
x = np.log10(x)
if self.opts['logMode'][1]:
- y = np.log10(y)
+ if np.issubdtype(y.dtype, np.floating):
+ eps = np.finfo(y.dtype).eps
+ else:
+ eps = 1
+ y = np.sign(y) * np.log10(np.abs(y)+eps)
ds = self.opts['downsample']
if not isinstance(ds, int):
diff --git a/pyqtgraph/graphicsItems/PlotItem/PlotItem.py b/pyqtgraph/graphicsItems/PlotItem/PlotItem.py
index e6084b22..a6bc3e4e 100644
--- a/pyqtgraph/graphicsItems/PlotItem/PlotItem.py
+++ b/pyqtgraph/graphicsItems/PlotItem/PlotItem.py
@@ -19,14 +19,11 @@ from .. InfiniteLine import InfiniteLine
from ...WidgetGroup import WidgetGroup
from ...python2_3 import basestring
-if QT_LIB == 'PyQt4':
- from .plotConfigTemplate_pyqt import *
-elif QT_LIB == 'PySide':
- from .plotConfigTemplate_pyside import *
-elif QT_LIB == 'PyQt5':
- from .plotConfigTemplate_pyqt5 import *
-elif QT_LIB == 'PySide2':
- from .plotConfigTemplate_pyside2 import *
+translate = QtCore.QCoreApplication.translate
+
+import importlib
+ui_template = importlib.import_module(
+ f'.plotConfigTemplate_{QT_LIB.lower()}', package=__package__)
__all__ = ['PlotItem']
@@ -134,12 +131,14 @@ class PlotItem(GraphicsWidget):
self.setLayout(self.layout)
self.layout.setHorizontalSpacing(0)
self.layout.setVerticalSpacing(0)
-
+
if viewBox is None:
- viewBox = ViewBox(parent=self)
+ viewBox = ViewBox(parent=self, enableMenu=enableMenu)
self.vb = viewBox
self.vb.sigStateChanged.connect(self.viewStateChanged)
- self.setMenuEnabled(enableMenu, enableMenu) ## en/disable plotitem and viewbox menus
+
+ # Enable or disable plotItem menu
+ self.setMenuEnabled(enableMenu, None)
if name is not None:
self.vb.register(name)
@@ -187,23 +186,23 @@ class PlotItem(GraphicsWidget):
### Set up context menu
w = QtGui.QWidget()
- self.ctrl = c = Ui_Form()
+ self.ctrl = c = ui_template.Ui_Form()
c.setupUi(w)
dv = QtGui.QDoubleValidator(self)
menuItems = [
- ('Transforms', c.transformGroup),
- ('Downsample', c.decimateGroup),
- ('Average', c.averageGroup),
- ('Alpha', c.alphaGroup),
- ('Grid', c.gridGroup),
- ('Points', c.pointsGroup),
+ (translate("PlotItem", 'Transforms'), c.transformGroup),
+ (translate("PlotItem", 'Downsample'), c.decimateGroup),
+ (translate("PlotItem", 'Average'), c.averageGroup),
+ (translate("PlotItem", 'Alpha'), c.alphaGroup),
+ (translate("PlotItem", 'Grid'), c.gridGroup),
+ (translate("PlotItem", 'Points'), c.pointsGroup),
]
self.ctrlMenu = QtGui.QMenu()
- self.ctrlMenu.setTitle('Plot Options')
+ self.ctrlMenu.setTitle(translate("PlotItem", 'Plot Options'))
self.subMenus = []
for name, grp in menuItems:
sm = QtGui.QMenu(name)
diff --git a/pyqtgraph/graphicsItems/PlotItem/plotConfigTemplate_pyqt.py b/pyqtgraph/graphicsItems/PlotItem/plotConfigTemplate_pyqt.py
deleted file mode 100644
index 2b752c4d..00000000
--- a/pyqtgraph/graphicsItems/PlotItem/plotConfigTemplate_pyqt.py
+++ /dev/null
@@ -1,192 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file 'pyqtgraph/graphicsItems/PlotItem/plotConfigTemplate.ui'
-#
-# Created: Fri Mar 31 10:35:34 2017
-# by: PyQt4 UI code generator 4.11.3
-#
-# WARNING! All changes made in this file will be lost!
-
-from PyQt4 import QtCore, QtGui
-
-try:
- _fromUtf8 = QtCore.QString.fromUtf8
-except AttributeError:
- def _fromUtf8(s):
- return s
-
-try:
- _encoding = QtGui.QApplication.UnicodeUTF8
- def _translate(context, text, disambig):
- return QtGui.QApplication.translate(context, text, disambig, _encoding)
-except AttributeError:
- def _translate(context, text, disambig):
- return QtGui.QApplication.translate(context, text, disambig)
-
-class Ui_Form(object):
- def setupUi(self, Form):
- Form.setObjectName(_fromUtf8("Form"))
- Form.resize(481, 840)
- self.averageGroup = QtGui.QGroupBox(Form)
- self.averageGroup.setGeometry(QtCore.QRect(0, 640, 242, 182))
- self.averageGroup.setCheckable(True)
- self.averageGroup.setChecked(False)
- self.averageGroup.setObjectName(_fromUtf8("averageGroup"))
- self.gridLayout_5 = QtGui.QGridLayout(self.averageGroup)
- self.gridLayout_5.setMargin(0)
- self.gridLayout_5.setSpacing(0)
- self.gridLayout_5.setObjectName(_fromUtf8("gridLayout_5"))
- self.avgParamList = QtGui.QListWidget(self.averageGroup)
- self.avgParamList.setObjectName(_fromUtf8("avgParamList"))
- self.gridLayout_5.addWidget(self.avgParamList, 0, 0, 1, 1)
- self.decimateGroup = QtGui.QFrame(Form)
- self.decimateGroup.setGeometry(QtCore.QRect(10, 140, 191, 171))
- self.decimateGroup.setObjectName(_fromUtf8("decimateGroup"))
- self.gridLayout_4 = QtGui.QGridLayout(self.decimateGroup)
- self.gridLayout_4.setMargin(0)
- self.gridLayout_4.setSpacing(0)
- self.gridLayout_4.setObjectName(_fromUtf8("gridLayout_4"))
- self.clipToViewCheck = QtGui.QCheckBox(self.decimateGroup)
- self.clipToViewCheck.setObjectName(_fromUtf8("clipToViewCheck"))
- self.gridLayout_4.addWidget(self.clipToViewCheck, 7, 0, 1, 3)
- self.maxTracesCheck = QtGui.QCheckBox(self.decimateGroup)
- self.maxTracesCheck.setObjectName(_fromUtf8("maxTracesCheck"))
- self.gridLayout_4.addWidget(self.maxTracesCheck, 8, 0, 1, 2)
- self.downsampleCheck = QtGui.QCheckBox(self.decimateGroup)
- self.downsampleCheck.setObjectName(_fromUtf8("downsampleCheck"))
- self.gridLayout_4.addWidget(self.downsampleCheck, 0, 0, 1, 3)
- self.peakRadio = QtGui.QRadioButton(self.decimateGroup)
- self.peakRadio.setChecked(True)
- self.peakRadio.setObjectName(_fromUtf8("peakRadio"))
- self.gridLayout_4.addWidget(self.peakRadio, 6, 1, 1, 2)
- self.maxTracesSpin = QtGui.QSpinBox(self.decimateGroup)
- self.maxTracesSpin.setObjectName(_fromUtf8("maxTracesSpin"))
- self.gridLayout_4.addWidget(self.maxTracesSpin, 8, 2, 1, 1)
- self.forgetTracesCheck = QtGui.QCheckBox(self.decimateGroup)
- self.forgetTracesCheck.setObjectName(_fromUtf8("forgetTracesCheck"))
- self.gridLayout_4.addWidget(self.forgetTracesCheck, 9, 0, 1, 3)
- self.meanRadio = QtGui.QRadioButton(self.decimateGroup)
- self.meanRadio.setObjectName(_fromUtf8("meanRadio"))
- self.gridLayout_4.addWidget(self.meanRadio, 3, 1, 1, 2)
- self.subsampleRadio = QtGui.QRadioButton(self.decimateGroup)
- self.subsampleRadio.setObjectName(_fromUtf8("subsampleRadio"))
- self.gridLayout_4.addWidget(self.subsampleRadio, 2, 1, 1, 2)
- self.autoDownsampleCheck = QtGui.QCheckBox(self.decimateGroup)
- self.autoDownsampleCheck.setChecked(True)
- self.autoDownsampleCheck.setObjectName(_fromUtf8("autoDownsampleCheck"))
- self.gridLayout_4.addWidget(self.autoDownsampleCheck, 1, 2, 1, 1)
- spacerItem = QtGui.QSpacerItem(30, 20, QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Minimum)
- self.gridLayout_4.addItem(spacerItem, 2, 0, 1, 1)
- self.downsampleSpin = QtGui.QSpinBox(self.decimateGroup)
- self.downsampleSpin.setMinimum(1)
- self.downsampleSpin.setMaximum(100000)
- self.downsampleSpin.setProperty("value", 1)
- self.downsampleSpin.setObjectName(_fromUtf8("downsampleSpin"))
- self.gridLayout_4.addWidget(self.downsampleSpin, 1, 1, 1, 1)
- self.transformGroup = QtGui.QFrame(Form)
- self.transformGroup.setGeometry(QtCore.QRect(10, 10, 171, 101))
- self.transformGroup.setObjectName(_fromUtf8("transformGroup"))
- self.gridLayout = QtGui.QGridLayout(self.transformGroup)
- self.gridLayout.setMargin(0)
- self.gridLayout.setSpacing(0)
- self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
- self.logYCheck = QtGui.QCheckBox(self.transformGroup)
- self.logYCheck.setObjectName(_fromUtf8("logYCheck"))
- self.gridLayout.addWidget(self.logYCheck, 2, 0, 1, 1)
- self.logXCheck = QtGui.QCheckBox(self.transformGroup)
- self.logXCheck.setObjectName(_fromUtf8("logXCheck"))
- self.gridLayout.addWidget(self.logXCheck, 1, 0, 1, 1)
- self.fftCheck = QtGui.QCheckBox(self.transformGroup)
- self.fftCheck.setObjectName(_fromUtf8("fftCheck"))
- self.gridLayout.addWidget(self.fftCheck, 0, 0, 1, 1)
- self.derivativeCheck = QtGui.QCheckBox(self.transformGroup)
- self.derivativeCheck.setObjectName(_fromUtf8("derivativeCheck"))
- self.gridLayout.addWidget(self.derivativeCheck, 3, 0, 1, 1)
- self.phasemapCheck = QtGui.QCheckBox(self.transformGroup)
- self.phasemapCheck.setObjectName(_fromUtf8("phasemapCheck"))
- self.gridLayout.addWidget(self.phasemapCheck, 4, 0, 1, 1)
- self.pointsGroup = QtGui.QGroupBox(Form)
- self.pointsGroup.setGeometry(QtCore.QRect(10, 550, 234, 58))
- self.pointsGroup.setCheckable(True)
- self.pointsGroup.setObjectName(_fromUtf8("pointsGroup"))
- self.verticalLayout_5 = QtGui.QVBoxLayout(self.pointsGroup)
- self.verticalLayout_5.setObjectName(_fromUtf8("verticalLayout_5"))
- self.autoPointsCheck = QtGui.QCheckBox(self.pointsGroup)
- self.autoPointsCheck.setChecked(True)
- self.autoPointsCheck.setObjectName(_fromUtf8("autoPointsCheck"))
- self.verticalLayout_5.addWidget(self.autoPointsCheck)
- self.gridGroup = QtGui.QFrame(Form)
- self.gridGroup.setGeometry(QtCore.QRect(10, 460, 221, 81))
- self.gridGroup.setObjectName(_fromUtf8("gridGroup"))
- self.gridLayout_2 = QtGui.QGridLayout(self.gridGroup)
- self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2"))
- self.xGridCheck = QtGui.QCheckBox(self.gridGroup)
- self.xGridCheck.setObjectName(_fromUtf8("xGridCheck"))
- self.gridLayout_2.addWidget(self.xGridCheck, 0, 0, 1, 2)
- self.yGridCheck = QtGui.QCheckBox(self.gridGroup)
- self.yGridCheck.setObjectName(_fromUtf8("yGridCheck"))
- self.gridLayout_2.addWidget(self.yGridCheck, 1, 0, 1, 2)
- self.gridAlphaSlider = QtGui.QSlider(self.gridGroup)
- self.gridAlphaSlider.setMaximum(255)
- self.gridAlphaSlider.setProperty("value", 128)
- self.gridAlphaSlider.setOrientation(QtCore.Qt.Horizontal)
- self.gridAlphaSlider.setObjectName(_fromUtf8("gridAlphaSlider"))
- self.gridLayout_2.addWidget(self.gridAlphaSlider, 2, 1, 1, 1)
- self.label = QtGui.QLabel(self.gridGroup)
- self.label.setObjectName(_fromUtf8("label"))
- self.gridLayout_2.addWidget(self.label, 2, 0, 1, 1)
- self.alphaGroup = QtGui.QGroupBox(Form)
- self.alphaGroup.setGeometry(QtCore.QRect(10, 390, 234, 60))
- self.alphaGroup.setCheckable(True)
- self.alphaGroup.setObjectName(_fromUtf8("alphaGroup"))
- self.horizontalLayout = QtGui.QHBoxLayout(self.alphaGroup)
- self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
- self.autoAlphaCheck = QtGui.QCheckBox(self.alphaGroup)
- self.autoAlphaCheck.setChecked(False)
- self.autoAlphaCheck.setObjectName(_fromUtf8("autoAlphaCheck"))
- self.horizontalLayout.addWidget(self.autoAlphaCheck)
- self.alphaSlider = QtGui.QSlider(self.alphaGroup)
- self.alphaSlider.setMaximum(1000)
- self.alphaSlider.setProperty("value", 1000)
- self.alphaSlider.setOrientation(QtCore.Qt.Horizontal)
- self.alphaSlider.setObjectName(_fromUtf8("alphaSlider"))
- self.horizontalLayout.addWidget(self.alphaSlider)
-
- self.retranslateUi(Form)
- QtCore.QMetaObject.connectSlotsByName(Form)
-
- def retranslateUi(self, Form):
- Form.setWindowTitle(_translate("Form", "PyQtGraph", None))
- self.averageGroup.setToolTip(_translate("Form", "Display averages of the curves displayed in this plot. The parameter list allows you to choose parameters to average over (if any are available).", None))
- self.averageGroup.setTitle(_translate("Form", "Average", None))
- self.clipToViewCheck.setToolTip(_translate("Form", "Plot only the portion of each curve that is visible. This assumes X values are uniformly spaced.", None))
- self.clipToViewCheck.setText(_translate("Form", "Clip to View", None))
- self.maxTracesCheck.setToolTip(_translate("Form", "If multiple curves are displayed in this plot, check this box to limit the number of traces that are displayed.", None))
- self.maxTracesCheck.setText(_translate("Form", "Max Traces:", None))
- self.downsampleCheck.setText(_translate("Form", "Downsample", None))
- self.peakRadio.setToolTip(_translate("Form", "Downsample by drawing a saw wave that follows the min and max of the original data. This method produces the best visual representation of the data but is slower.", None))
- self.peakRadio.setText(_translate("Form", "Peak", None))
- self.maxTracesSpin.setToolTip(_translate("Form", "If multiple curves are displayed in this plot, check \"Max Traces\" and set this value to limit the number of traces that are displayed.", None))
- self.forgetTracesCheck.setToolTip(_translate("Form", "If MaxTraces is checked, remove curves from memory after they are hidden (saves memory, but traces can not be un-hidden).", None))
- self.forgetTracesCheck.setText(_translate("Form", "Forget hidden traces", None))
- self.meanRadio.setToolTip(_translate("Form", "Downsample by taking the mean of N samples.", None))
- self.meanRadio.setText(_translate("Form", "Mean", None))
- self.subsampleRadio.setToolTip(_translate("Form", "Downsample by taking the first of N samples. This method is fastest and least accurate.", None))
- self.subsampleRadio.setText(_translate("Form", "Subsample", None))
- self.autoDownsampleCheck.setToolTip(_translate("Form", "Automatically downsample data based on the visible range. This assumes X values are uniformly spaced.", None))
- self.autoDownsampleCheck.setText(_translate("Form", "Auto", None))
- self.downsampleSpin.setToolTip(_translate("Form", "Downsample data before plotting. (plot every Nth sample)", None))
- self.downsampleSpin.setSuffix(_translate("Form", "x", None))
- self.logYCheck.setText(_translate("Form", "Log Y", None))
- self.logXCheck.setText(_translate("Form", "Log X", None))
- self.fftCheck.setText(_translate("Form", "Power Spectrum (FFT)", None))
- self.derivativeCheck.setText(_translate("Form", "dy/dx", None))
- self.phasemapCheck.setText(_translate("Form", "Y vs. Y\'", None))
- self.pointsGroup.setTitle(_translate("Form", "Points", None))
- self.autoPointsCheck.setText(_translate("Form", "Auto", None))
- self.xGridCheck.setText(_translate("Form", "Show X Grid", None))
- self.yGridCheck.setText(_translate("Form", "Show Y Grid", None))
- self.label.setText(_translate("Form", "Opacity", None))
- self.alphaGroup.setTitle(_translate("Form", "Alpha", None))
- self.autoAlphaCheck.setText(_translate("Form", "Auto", None))
-
diff --git a/pyqtgraph/graphicsItems/PlotItem/plotConfigTemplate_pyqt6.py b/pyqtgraph/graphicsItems/PlotItem/plotConfigTemplate_pyqt6.py
new file mode 100644
index 00000000..213f4db5
--- /dev/null
+++ b/pyqtgraph/graphicsItems/PlotItem/plotConfigTemplate_pyqt6.py
@@ -0,0 +1,178 @@
+# Form implementation generated from reading ui file 'pyqtgraph\graphicsItems\PlotItem\plotConfigTemplate.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(481, 840)
+ self.averageGroup = QtWidgets.QGroupBox(Form)
+ self.averageGroup.setGeometry(QtCore.QRect(0, 640, 242, 182))
+ self.averageGroup.setCheckable(True)
+ self.averageGroup.setChecked(False)
+ self.averageGroup.setObjectName("averageGroup")
+ self.gridLayout_5 = QtWidgets.QGridLayout(self.averageGroup)
+ self.gridLayout_5.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_5.setSpacing(0)
+ self.gridLayout_5.setObjectName("gridLayout_5")
+ self.avgParamList = QtWidgets.QListWidget(self.averageGroup)
+ self.avgParamList.setObjectName("avgParamList")
+ self.gridLayout_5.addWidget(self.avgParamList, 0, 0, 1, 1)
+ self.decimateGroup = QtWidgets.QFrame(Form)
+ self.decimateGroup.setGeometry(QtCore.QRect(10, 140, 191, 171))
+ self.decimateGroup.setObjectName("decimateGroup")
+ self.gridLayout_4 = QtWidgets.QGridLayout(self.decimateGroup)
+ self.gridLayout_4.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_4.setSpacing(0)
+ self.gridLayout_4.setObjectName("gridLayout_4")
+ self.clipToViewCheck = QtWidgets.QCheckBox(self.decimateGroup)
+ self.clipToViewCheck.setObjectName("clipToViewCheck")
+ self.gridLayout_4.addWidget(self.clipToViewCheck, 7, 0, 1, 3)
+ self.maxTracesCheck = QtWidgets.QCheckBox(self.decimateGroup)
+ self.maxTracesCheck.setObjectName("maxTracesCheck")
+ self.gridLayout_4.addWidget(self.maxTracesCheck, 8, 0, 1, 2)
+ self.downsampleCheck = QtWidgets.QCheckBox(self.decimateGroup)
+ self.downsampleCheck.setObjectName("downsampleCheck")
+ self.gridLayout_4.addWidget(self.downsampleCheck, 0, 0, 1, 3)
+ self.peakRadio = QtWidgets.QRadioButton(self.decimateGroup)
+ self.peakRadio.setChecked(True)
+ self.peakRadio.setObjectName("peakRadio")
+ self.gridLayout_4.addWidget(self.peakRadio, 6, 1, 1, 2)
+ self.maxTracesSpin = QtWidgets.QSpinBox(self.decimateGroup)
+ self.maxTracesSpin.setObjectName("maxTracesSpin")
+ self.gridLayout_4.addWidget(self.maxTracesSpin, 8, 2, 1, 1)
+ self.forgetTracesCheck = QtWidgets.QCheckBox(self.decimateGroup)
+ self.forgetTracesCheck.setObjectName("forgetTracesCheck")
+ self.gridLayout_4.addWidget(self.forgetTracesCheck, 9, 0, 1, 3)
+ self.meanRadio = QtWidgets.QRadioButton(self.decimateGroup)
+ self.meanRadio.setObjectName("meanRadio")
+ self.gridLayout_4.addWidget(self.meanRadio, 3, 1, 1, 2)
+ self.subsampleRadio = QtWidgets.QRadioButton(self.decimateGroup)
+ self.subsampleRadio.setObjectName("subsampleRadio")
+ self.gridLayout_4.addWidget(self.subsampleRadio, 2, 1, 1, 2)
+ self.autoDownsampleCheck = QtWidgets.QCheckBox(self.decimateGroup)
+ self.autoDownsampleCheck.setChecked(True)
+ self.autoDownsampleCheck.setObjectName("autoDownsampleCheck")
+ self.gridLayout_4.addWidget(self.autoDownsampleCheck, 1, 2, 1, 1)
+ spacerItem = QtWidgets.QSpacerItem(30, 20, QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Policy.Minimum)
+ self.gridLayout_4.addItem(spacerItem, 2, 0, 1, 1)
+ self.downsampleSpin = QtWidgets.QSpinBox(self.decimateGroup)
+ self.downsampleSpin.setMinimum(1)
+ self.downsampleSpin.setMaximum(100000)
+ self.downsampleSpin.setProperty("value", 1)
+ self.downsampleSpin.setObjectName("downsampleSpin")
+ self.gridLayout_4.addWidget(self.downsampleSpin, 1, 1, 1, 1)
+ self.transformGroup = QtWidgets.QFrame(Form)
+ self.transformGroup.setGeometry(QtCore.QRect(10, 10, 171, 101))
+ self.transformGroup.setObjectName("transformGroup")
+ self.gridLayout = QtWidgets.QGridLayout(self.transformGroup)
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout.setSpacing(0)
+ self.gridLayout.setObjectName("gridLayout")
+ self.logYCheck = QtWidgets.QCheckBox(self.transformGroup)
+ self.logYCheck.setObjectName("logYCheck")
+ self.gridLayout.addWidget(self.logYCheck, 2, 0, 1, 1)
+ self.logXCheck = QtWidgets.QCheckBox(self.transformGroup)
+ self.logXCheck.setObjectName("logXCheck")
+ self.gridLayout.addWidget(self.logXCheck, 1, 0, 1, 1)
+ self.fftCheck = QtWidgets.QCheckBox(self.transformGroup)
+ self.fftCheck.setObjectName("fftCheck")
+ self.gridLayout.addWidget(self.fftCheck, 0, 0, 1, 1)
+ self.derivativeCheck = QtWidgets.QCheckBox(self.transformGroup)
+ self.derivativeCheck.setObjectName("derivativeCheck")
+ self.gridLayout.addWidget(self.derivativeCheck, 3, 0, 1, 1)
+ self.phasemapCheck = QtWidgets.QCheckBox(self.transformGroup)
+ self.phasemapCheck.setObjectName("phasemapCheck")
+ self.gridLayout.addWidget(self.phasemapCheck, 4, 0, 1, 1)
+ self.pointsGroup = QtWidgets.QGroupBox(Form)
+ self.pointsGroup.setGeometry(QtCore.QRect(10, 550, 234, 58))
+ self.pointsGroup.setCheckable(True)
+ self.pointsGroup.setObjectName("pointsGroup")
+ self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.pointsGroup)
+ self.verticalLayout_5.setObjectName("verticalLayout_5")
+ self.autoPointsCheck = QtWidgets.QCheckBox(self.pointsGroup)
+ self.autoPointsCheck.setChecked(True)
+ self.autoPointsCheck.setObjectName("autoPointsCheck")
+ self.verticalLayout_5.addWidget(self.autoPointsCheck)
+ self.gridGroup = QtWidgets.QFrame(Form)
+ self.gridGroup.setGeometry(QtCore.QRect(10, 460, 221, 81))
+ self.gridGroup.setObjectName("gridGroup")
+ self.gridLayout_2 = QtWidgets.QGridLayout(self.gridGroup)
+ self.gridLayout_2.setObjectName("gridLayout_2")
+ self.xGridCheck = QtWidgets.QCheckBox(self.gridGroup)
+ self.xGridCheck.setObjectName("xGridCheck")
+ self.gridLayout_2.addWidget(self.xGridCheck, 0, 0, 1, 2)
+ self.yGridCheck = QtWidgets.QCheckBox(self.gridGroup)
+ self.yGridCheck.setObjectName("yGridCheck")
+ self.gridLayout_2.addWidget(self.yGridCheck, 1, 0, 1, 2)
+ self.gridAlphaSlider = QtWidgets.QSlider(self.gridGroup)
+ self.gridAlphaSlider.setMaximum(255)
+ self.gridAlphaSlider.setProperty("value", 128)
+ self.gridAlphaSlider.setOrientation(QtCore.Qt.Orientations.Horizontal)
+ self.gridAlphaSlider.setObjectName("gridAlphaSlider")
+ self.gridLayout_2.addWidget(self.gridAlphaSlider, 2, 1, 1, 1)
+ self.label = QtWidgets.QLabel(self.gridGroup)
+ self.label.setObjectName("label")
+ self.gridLayout_2.addWidget(self.label, 2, 0, 1, 1)
+ self.alphaGroup = QtWidgets.QGroupBox(Form)
+ self.alphaGroup.setGeometry(QtCore.QRect(10, 390, 234, 60))
+ self.alphaGroup.setCheckable(True)
+ self.alphaGroup.setObjectName("alphaGroup")
+ self.horizontalLayout = QtWidgets.QHBoxLayout(self.alphaGroup)
+ self.horizontalLayout.setObjectName("horizontalLayout")
+ self.autoAlphaCheck = QtWidgets.QCheckBox(self.alphaGroup)
+ self.autoAlphaCheck.setChecked(False)
+ self.autoAlphaCheck.setObjectName("autoAlphaCheck")
+ self.horizontalLayout.addWidget(self.autoAlphaCheck)
+ self.alphaSlider = QtWidgets.QSlider(self.alphaGroup)
+ self.alphaSlider.setMaximum(1000)
+ self.alphaSlider.setProperty("value", 1000)
+ self.alphaSlider.setOrientation(QtCore.Qt.Orientations.Horizontal)
+ self.alphaSlider.setObjectName("alphaSlider")
+ self.horizontalLayout.addWidget(self.alphaSlider)
+
+ self.retranslateUi(Form)
+ QtCore.QMetaObject.connectSlotsByName(Form)
+
+ def retranslateUi(self, Form):
+ _translate = QtCore.QCoreApplication.translate
+ Form.setWindowTitle(_translate("Form", "PyQtGraph"))
+ self.averageGroup.setToolTip(_translate("Form", "Display averages of the curves displayed in this plot. The parameter list allows you to choose parameters to average over (if any are available)."))
+ self.averageGroup.setTitle(_translate("Form", "Average"))
+ self.clipToViewCheck.setToolTip(_translate("Form", "Plot only the portion of each curve that is visible. This assumes X values are uniformly spaced."))
+ self.clipToViewCheck.setText(_translate("Form", "Clip to View"))
+ self.maxTracesCheck.setToolTip(_translate("Form", "If multiple curves are displayed in this plot, check this box to limit the number of traces that are displayed."))
+ self.maxTracesCheck.setText(_translate("Form", "Max Traces:"))
+ self.downsampleCheck.setText(_translate("Form", "Downsample"))
+ self.peakRadio.setToolTip(_translate("Form", "Downsample by drawing a saw wave that follows the min and max of the original data. This method produces the best visual representation of the data but is slower."))
+ self.peakRadio.setText(_translate("Form", "Peak"))
+ self.maxTracesSpin.setToolTip(_translate("Form", "If multiple curves are displayed in this plot, check \"Max Traces\" and set this value to limit the number of traces that are displayed."))
+ self.forgetTracesCheck.setToolTip(_translate("Form", "If MaxTraces is checked, remove curves from memory after they are hidden (saves memory, but traces can not be un-hidden)."))
+ self.forgetTracesCheck.setText(_translate("Form", "Forget hidden traces"))
+ self.meanRadio.setToolTip(_translate("Form", "Downsample by taking the mean of N samples."))
+ self.meanRadio.setText(_translate("Form", "Mean"))
+ self.subsampleRadio.setToolTip(_translate("Form", "Downsample by taking the first of N samples. This method is fastest and least accurate."))
+ self.subsampleRadio.setText(_translate("Form", "Subsample"))
+ self.autoDownsampleCheck.setToolTip(_translate("Form", "Automatically downsample data based on the visible range. This assumes X values are uniformly spaced."))
+ self.autoDownsampleCheck.setText(_translate("Form", "Auto"))
+ self.downsampleSpin.setToolTip(_translate("Form", "Downsample data before plotting. (plot every Nth sample)"))
+ self.downsampleSpin.setSuffix(_translate("Form", "x"))
+ self.logYCheck.setText(_translate("Form", "Log Y"))
+ self.logXCheck.setText(_translate("Form", "Log X"))
+ self.fftCheck.setText(_translate("Form", "Power Spectrum (FFT)"))
+ self.derivativeCheck.setText(_translate("Form", "dy/dx"))
+ self.phasemapCheck.setText(_translate("Form", "Y vs. Y\'"))
+ self.pointsGroup.setTitle(_translate("Form", "Points"))
+ self.autoPointsCheck.setText(_translate("Form", "Auto"))
+ self.xGridCheck.setText(_translate("Form", "Show X Grid"))
+ self.yGridCheck.setText(_translate("Form", "Show Y Grid"))
+ self.label.setText(_translate("Form", "Opacity"))
+ self.alphaGroup.setTitle(_translate("Form", "Alpha"))
+ self.autoAlphaCheck.setText(_translate("Form", "Auto"))
diff --git a/pyqtgraph/graphicsItems/PlotItem/plotConfigTemplate_pyside.py b/pyqtgraph/graphicsItems/PlotItem/plotConfigTemplate_pyside.py
deleted file mode 100644
index 9c999b89..00000000
--- a/pyqtgraph/graphicsItems/PlotItem/plotConfigTemplate_pyside.py
+++ /dev/null
@@ -1,178 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file 'plotConfigTemplate.ui'
-#
-# Created: Fri Jun 26 23:50:06 2020
-# by: pyside-uic 0.2.15 running on PySide 1.2.4
-#
-# WARNING! All changes made in this file will be lost!
-
-from PySide import QtCore, QtGui
-
-class Ui_Form(object):
- def setupUi(self, Form):
- Form.setObjectName("Form")
- Form.resize(481, 840)
- self.averageGroup = QtGui.QGroupBox(Form)
- self.averageGroup.setGeometry(QtCore.QRect(0, 640, 242, 182))
- self.averageGroup.setCheckable(True)
- self.averageGroup.setChecked(False)
- self.averageGroup.setObjectName("averageGroup")
- self.gridLayout_5 = QtGui.QGridLayout(self.averageGroup)
- self.gridLayout_5.setContentsMargins(0, 0, 0, 0)
- self.gridLayout_5.setSpacing(0)
- self.gridLayout_5.setObjectName("gridLayout_5")
- self.avgParamList = QtGui.QListWidget(self.averageGroup)
- self.avgParamList.setObjectName("avgParamList")
- self.gridLayout_5.addWidget(self.avgParamList, 0, 0, 1, 1)
- self.decimateGroup = QtGui.QFrame(Form)
- self.decimateGroup.setGeometry(QtCore.QRect(10, 140, 191, 171))
- self.decimateGroup.setObjectName("decimateGroup")
- self.gridLayout_4 = QtGui.QGridLayout(self.decimateGroup)
- self.gridLayout_4.setContentsMargins(0, 0, 0, 0)
- self.gridLayout_4.setSpacing(0)
- self.gridLayout_4.setObjectName("gridLayout_4")
- self.clipToViewCheck = QtGui.QCheckBox(self.decimateGroup)
- self.clipToViewCheck.setObjectName("clipToViewCheck")
- self.gridLayout_4.addWidget(self.clipToViewCheck, 7, 0, 1, 3)
- self.maxTracesCheck = QtGui.QCheckBox(self.decimateGroup)
- self.maxTracesCheck.setObjectName("maxTracesCheck")
- self.gridLayout_4.addWidget(self.maxTracesCheck, 8, 0, 1, 2)
- self.downsampleCheck = QtGui.QCheckBox(self.decimateGroup)
- self.downsampleCheck.setObjectName("downsampleCheck")
- self.gridLayout_4.addWidget(self.downsampleCheck, 0, 0, 1, 3)
- self.peakRadio = QtGui.QRadioButton(self.decimateGroup)
- self.peakRadio.setChecked(True)
- self.peakRadio.setObjectName("peakRadio")
- self.gridLayout_4.addWidget(self.peakRadio, 6, 1, 1, 2)
- self.maxTracesSpin = QtGui.QSpinBox(self.decimateGroup)
- self.maxTracesSpin.setObjectName("maxTracesSpin")
- self.gridLayout_4.addWidget(self.maxTracesSpin, 8, 2, 1, 1)
- self.forgetTracesCheck = QtGui.QCheckBox(self.decimateGroup)
- self.forgetTracesCheck.setObjectName("forgetTracesCheck")
- self.gridLayout_4.addWidget(self.forgetTracesCheck, 9, 0, 1, 3)
- self.meanRadio = QtGui.QRadioButton(self.decimateGroup)
- self.meanRadio.setObjectName("meanRadio")
- self.gridLayout_4.addWidget(self.meanRadio, 3, 1, 1, 2)
- self.subsampleRadio = QtGui.QRadioButton(self.decimateGroup)
- self.subsampleRadio.setObjectName("subsampleRadio")
- self.gridLayout_4.addWidget(self.subsampleRadio, 2, 1, 1, 2)
- self.autoDownsampleCheck = QtGui.QCheckBox(self.decimateGroup)
- self.autoDownsampleCheck.setChecked(True)
- self.autoDownsampleCheck.setObjectName("autoDownsampleCheck")
- self.gridLayout_4.addWidget(self.autoDownsampleCheck, 1, 2, 1, 1)
- spacerItem = QtGui.QSpacerItem(30, 20, QtGui.QSizePolicy.Maximum, QtGui.QSizePolicy.Minimum)
- self.gridLayout_4.addItem(spacerItem, 2, 0, 1, 1)
- self.downsampleSpin = QtGui.QSpinBox(self.decimateGroup)
- self.downsampleSpin.setMinimum(1)
- self.downsampleSpin.setMaximum(100000)
- self.downsampleSpin.setProperty("value", 1)
- self.downsampleSpin.setObjectName("downsampleSpin")
- self.gridLayout_4.addWidget(self.downsampleSpin, 1, 1, 1, 1)
- self.transformGroup = QtGui.QFrame(Form)
- self.transformGroup.setGeometry(QtCore.QRect(10, 10, 171, 101))
- self.transformGroup.setObjectName("transformGroup")
- self.gridLayout = QtGui.QGridLayout(self.transformGroup)
- self.gridLayout.setContentsMargins(0, 0, 0, 0)
- self.gridLayout.setSpacing(0)
- self.gridLayout.setObjectName("gridLayout")
- self.logYCheck = QtGui.QCheckBox(self.transformGroup)
- self.logYCheck.setObjectName("logYCheck")
- self.gridLayout.addWidget(self.logYCheck, 2, 0, 1, 1)
- self.logXCheck = QtGui.QCheckBox(self.transformGroup)
- self.logXCheck.setObjectName("logXCheck")
- self.gridLayout.addWidget(self.logXCheck, 1, 0, 1, 1)
- self.fftCheck = QtGui.QCheckBox(self.transformGroup)
- self.fftCheck.setObjectName("fftCheck")
- self.gridLayout.addWidget(self.fftCheck, 0, 0, 1, 1)
- self.derivativeCheck = QtGui.QCheckBox(self.transformGroup)
- self.derivativeCheck.setObjectName("derivativeCheck")
- self.gridLayout.addWidget(self.derivativeCheck, 3, 0, 1, 1)
- self.phasemapCheck = QtGui.QCheckBox(self.transformGroup)
- self.phasemapCheck.setObjectName("phasemapCheck")
- self.gridLayout.addWidget(self.phasemapCheck, 4, 0, 1, 1)
- self.pointsGroup = QtGui.QGroupBox(Form)
- self.pointsGroup.setGeometry(QtCore.QRect(10, 550, 234, 58))
- self.pointsGroup.setCheckable(True)
- self.pointsGroup.setObjectName("pointsGroup")
- self.verticalLayout_5 = QtGui.QVBoxLayout(self.pointsGroup)
- self.verticalLayout_5.setObjectName("verticalLayout_5")
- self.autoPointsCheck = QtGui.QCheckBox(self.pointsGroup)
- self.autoPointsCheck.setChecked(True)
- self.autoPointsCheck.setObjectName("autoPointsCheck")
- self.verticalLayout_5.addWidget(self.autoPointsCheck)
- self.gridGroup = QtGui.QFrame(Form)
- self.gridGroup.setGeometry(QtCore.QRect(10, 460, 221, 81))
- self.gridGroup.setObjectName("gridGroup")
- self.gridLayout_2 = QtGui.QGridLayout(self.gridGroup)
- self.gridLayout_2.setObjectName("gridLayout_2")
- self.xGridCheck = QtGui.QCheckBox(self.gridGroup)
- self.xGridCheck.setObjectName("xGridCheck")
- self.gridLayout_2.addWidget(self.xGridCheck, 0, 0, 1, 2)
- self.yGridCheck = QtGui.QCheckBox(self.gridGroup)
- self.yGridCheck.setObjectName("yGridCheck")
- self.gridLayout_2.addWidget(self.yGridCheck, 1, 0, 1, 2)
- self.gridAlphaSlider = QtGui.QSlider(self.gridGroup)
- self.gridAlphaSlider.setMaximum(255)
- self.gridAlphaSlider.setProperty("value", 128)
- self.gridAlphaSlider.setOrientation(QtCore.Qt.Horizontal)
- self.gridAlphaSlider.setObjectName("gridAlphaSlider")
- self.gridLayout_2.addWidget(self.gridAlphaSlider, 2, 1, 1, 1)
- self.label = QtGui.QLabel(self.gridGroup)
- self.label.setObjectName("label")
- self.gridLayout_2.addWidget(self.label, 2, 0, 1, 1)
- self.alphaGroup = QtGui.QGroupBox(Form)
- self.alphaGroup.setGeometry(QtCore.QRect(10, 390, 234, 60))
- self.alphaGroup.setCheckable(True)
- self.alphaGroup.setObjectName("alphaGroup")
- self.horizontalLayout = QtGui.QHBoxLayout(self.alphaGroup)
- self.horizontalLayout.setObjectName("horizontalLayout")
- self.autoAlphaCheck = QtGui.QCheckBox(self.alphaGroup)
- self.autoAlphaCheck.setChecked(False)
- self.autoAlphaCheck.setObjectName("autoAlphaCheck")
- self.horizontalLayout.addWidget(self.autoAlphaCheck)
- self.alphaSlider = QtGui.QSlider(self.alphaGroup)
- self.alphaSlider.setMaximum(1000)
- self.alphaSlider.setProperty("value", 1000)
- self.alphaSlider.setOrientation(QtCore.Qt.Horizontal)
- self.alphaSlider.setObjectName("alphaSlider")
- self.horizontalLayout.addWidget(self.alphaSlider)
-
- self.retranslateUi(Form)
- QtCore.QMetaObject.connectSlotsByName(Form)
-
- def retranslateUi(self, Form):
- Form.setWindowTitle(QtGui.QApplication.translate("Form", "PyQtGraph", None, QtGui.QApplication.UnicodeUTF8))
- self.averageGroup.setToolTip(QtGui.QApplication.translate("Form", "Display averages of the curves displayed in this plot. The parameter list allows you to choose parameters to average over (if any are available).", None, QtGui.QApplication.UnicodeUTF8))
- self.averageGroup.setTitle(QtGui.QApplication.translate("Form", "Average", None, QtGui.QApplication.UnicodeUTF8))
- self.clipToViewCheck.setToolTip(QtGui.QApplication.translate("Form", "Plot only the portion of each curve that is visible. This assumes X values are uniformly spaced.", None, QtGui.QApplication.UnicodeUTF8))
- self.clipToViewCheck.setText(QtGui.QApplication.translate("Form", "Clip to View", None, QtGui.QApplication.UnicodeUTF8))
- self.maxTracesCheck.setToolTip(QtGui.QApplication.translate("Form", "If multiple curves are displayed in this plot, check this box to limit the number of traces that are displayed.", None, QtGui.QApplication.UnicodeUTF8))
- self.maxTracesCheck.setText(QtGui.QApplication.translate("Form", "Max Traces:", None, QtGui.QApplication.UnicodeUTF8))
- self.downsampleCheck.setText(QtGui.QApplication.translate("Form", "Downsample", None, QtGui.QApplication.UnicodeUTF8))
- self.peakRadio.setToolTip(QtGui.QApplication.translate("Form", "Downsample by drawing a saw wave that follows the min and max of the original data. This method produces the best visual representation of the data but is slower.", None, QtGui.QApplication.UnicodeUTF8))
- self.peakRadio.setText(QtGui.QApplication.translate("Form", "Peak", None, QtGui.QApplication.UnicodeUTF8))
- self.maxTracesSpin.setToolTip(QtGui.QApplication.translate("Form", "If multiple curves are displayed in this plot, check \"Max Traces\" and set this value to limit the number of traces that are displayed.", None, QtGui.QApplication.UnicodeUTF8))
- self.forgetTracesCheck.setToolTip(QtGui.QApplication.translate("Form", "If MaxTraces is checked, remove curves from memory after they are hidden (saves memory, but traces can not be un-hidden).", None, QtGui.QApplication.UnicodeUTF8))
- self.forgetTracesCheck.setText(QtGui.QApplication.translate("Form", "Forget hidden traces", None, QtGui.QApplication.UnicodeUTF8))
- self.meanRadio.setToolTip(QtGui.QApplication.translate("Form", "Downsample by taking the mean of N samples.", None, QtGui.QApplication.UnicodeUTF8))
- self.meanRadio.setText(QtGui.QApplication.translate("Form", "Mean", None, QtGui.QApplication.UnicodeUTF8))
- self.subsampleRadio.setToolTip(QtGui.QApplication.translate("Form", "Downsample by taking the first of N samples. This method is fastest and least accurate.", None, QtGui.QApplication.UnicodeUTF8))
- self.subsampleRadio.setText(QtGui.QApplication.translate("Form", "Subsample", None, QtGui.QApplication.UnicodeUTF8))
- self.autoDownsampleCheck.setToolTip(QtGui.QApplication.translate("Form", "Automatically downsample data based on the visible range. This assumes X values are uniformly spaced.", None, QtGui.QApplication.UnicodeUTF8))
- self.autoDownsampleCheck.setText(QtGui.QApplication.translate("Form", "Auto", None, QtGui.QApplication.UnicodeUTF8))
- self.downsampleSpin.setToolTip(QtGui.QApplication.translate("Form", "Downsample data before plotting. (plot every Nth sample)", None, QtGui.QApplication.UnicodeUTF8))
- self.downsampleSpin.setSuffix(QtGui.QApplication.translate("Form", "x", None, QtGui.QApplication.UnicodeUTF8))
- self.logYCheck.setText(QtGui.QApplication.translate("Form", "Log Y", None, QtGui.QApplication.UnicodeUTF8))
- self.logXCheck.setText(QtGui.QApplication.translate("Form", "Log X", None, QtGui.QApplication.UnicodeUTF8))
- self.fftCheck.setText(QtGui.QApplication.translate("Form", "Power Spectrum (FFT)", None, QtGui.QApplication.UnicodeUTF8))
- self.derivativeCheck.setText(QtGui.QApplication.translate("Form", "dy/dx", None, QtGui.QApplication.UnicodeUTF8))
- self.phasemapCheck.setText(QtGui.QApplication.translate("Form", "Y vs. Y\'", None, QtGui.QApplication.UnicodeUTF8))
- self.pointsGroup.setTitle(QtGui.QApplication.translate("Form", "Points", None, QtGui.QApplication.UnicodeUTF8))
- self.autoPointsCheck.setText(QtGui.QApplication.translate("Form", "Auto", None, QtGui.QApplication.UnicodeUTF8))
- self.xGridCheck.setText(QtGui.QApplication.translate("Form", "Show X Grid", None, QtGui.QApplication.UnicodeUTF8))
- self.yGridCheck.setText(QtGui.QApplication.translate("Form", "Show Y Grid", None, QtGui.QApplication.UnicodeUTF8))
- self.label.setText(QtGui.QApplication.translate("Form", "Opacity", None, QtGui.QApplication.UnicodeUTF8))
- self.alphaGroup.setTitle(QtGui.QApplication.translate("Form", "Alpha", None, QtGui.QApplication.UnicodeUTF8))
- self.autoAlphaCheck.setText(QtGui.QApplication.translate("Form", "Auto", None, QtGui.QApplication.UnicodeUTF8))
-
diff --git a/pyqtgraph/graphicsItems/PlotItem/plotConfigTemplate_pyside6.py b/pyqtgraph/graphicsItems/PlotItem/plotConfigTemplate_pyside6.py
new file mode 100644
index 00000000..84abbdb5
--- /dev/null
+++ b/pyqtgraph/graphicsItems/PlotItem/plotConfigTemplate_pyside6.py
@@ -0,0 +1,254 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'plotConfigTemplate.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 *
+
+
+class Ui_Form(object):
+ def setupUi(self, Form):
+ if not Form.objectName():
+ Form.setObjectName(u"Form")
+ Form.resize(481, 840)
+ self.averageGroup = QGroupBox(Form)
+ self.averageGroup.setObjectName(u"averageGroup")
+ self.averageGroup.setGeometry(QRect(0, 640, 242, 182))
+ self.averageGroup.setCheckable(True)
+ self.averageGroup.setChecked(False)
+ self.gridLayout_5 = QGridLayout(self.averageGroup)
+ self.gridLayout_5.setSpacing(0)
+ self.gridLayout_5.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_5.setObjectName(u"gridLayout_5")
+ self.avgParamList = QListWidget(self.averageGroup)
+ self.avgParamList.setObjectName(u"avgParamList")
+
+ self.gridLayout_5.addWidget(self.avgParamList, 0, 0, 1, 1)
+
+ self.decimateGroup = QFrame(Form)
+ self.decimateGroup.setObjectName(u"decimateGroup")
+ self.decimateGroup.setGeometry(QRect(10, 140, 191, 171))
+ self.gridLayout_4 = QGridLayout(self.decimateGroup)
+ self.gridLayout_4.setSpacing(0)
+ self.gridLayout_4.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_4.setObjectName(u"gridLayout_4")
+ self.clipToViewCheck = QCheckBox(self.decimateGroup)
+ self.clipToViewCheck.setObjectName(u"clipToViewCheck")
+
+ self.gridLayout_4.addWidget(self.clipToViewCheck, 7, 0, 1, 3)
+
+ self.maxTracesCheck = QCheckBox(self.decimateGroup)
+ self.maxTracesCheck.setObjectName(u"maxTracesCheck")
+
+ self.gridLayout_4.addWidget(self.maxTracesCheck, 8, 0, 1, 2)
+
+ self.downsampleCheck = QCheckBox(self.decimateGroup)
+ self.downsampleCheck.setObjectName(u"downsampleCheck")
+
+ self.gridLayout_4.addWidget(self.downsampleCheck, 0, 0, 1, 3)
+
+ self.peakRadio = QRadioButton(self.decimateGroup)
+ self.peakRadio.setObjectName(u"peakRadio")
+ self.peakRadio.setChecked(True)
+
+ self.gridLayout_4.addWidget(self.peakRadio, 6, 1, 1, 2)
+
+ self.maxTracesSpin = QSpinBox(self.decimateGroup)
+ self.maxTracesSpin.setObjectName(u"maxTracesSpin")
+
+ self.gridLayout_4.addWidget(self.maxTracesSpin, 8, 2, 1, 1)
+
+ self.forgetTracesCheck = QCheckBox(self.decimateGroup)
+ self.forgetTracesCheck.setObjectName(u"forgetTracesCheck")
+
+ self.gridLayout_4.addWidget(self.forgetTracesCheck, 9, 0, 1, 3)
+
+ self.meanRadio = QRadioButton(self.decimateGroup)
+ self.meanRadio.setObjectName(u"meanRadio")
+
+ self.gridLayout_4.addWidget(self.meanRadio, 3, 1, 1, 2)
+
+ self.subsampleRadio = QRadioButton(self.decimateGroup)
+ self.subsampleRadio.setObjectName(u"subsampleRadio")
+
+ self.gridLayout_4.addWidget(self.subsampleRadio, 2, 1, 1, 2)
+
+ self.autoDownsampleCheck = QCheckBox(self.decimateGroup)
+ self.autoDownsampleCheck.setObjectName(u"autoDownsampleCheck")
+ self.autoDownsampleCheck.setChecked(True)
+
+ self.gridLayout_4.addWidget(self.autoDownsampleCheck, 1, 2, 1, 1)
+
+ self.horizontalSpacer = QSpacerItem(30, 20, QSizePolicy.Maximum, QSizePolicy.Minimum)
+
+ self.gridLayout_4.addItem(self.horizontalSpacer, 2, 0, 1, 1)
+
+ self.downsampleSpin = QSpinBox(self.decimateGroup)
+ self.downsampleSpin.setObjectName(u"downsampleSpin")
+ self.downsampleSpin.setMinimum(1)
+ self.downsampleSpin.setMaximum(100000)
+ self.downsampleSpin.setValue(1)
+
+ self.gridLayout_4.addWidget(self.downsampleSpin, 1, 1, 1, 1)
+
+ self.transformGroup = QFrame(Form)
+ self.transformGroup.setObjectName(u"transformGroup")
+ self.transformGroup.setGeometry(QRect(10, 10, 171, 101))
+ self.gridLayout = QGridLayout(self.transformGroup)
+ self.gridLayout.setSpacing(0)
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout.setObjectName(u"gridLayout")
+ self.logYCheck = QCheckBox(self.transformGroup)
+ self.logYCheck.setObjectName(u"logYCheck")
+
+ self.gridLayout.addWidget(self.logYCheck, 2, 0, 1, 1)
+
+ self.logXCheck = QCheckBox(self.transformGroup)
+ self.logXCheck.setObjectName(u"logXCheck")
+
+ self.gridLayout.addWidget(self.logXCheck, 1, 0, 1, 1)
+
+ self.fftCheck = QCheckBox(self.transformGroup)
+ self.fftCheck.setObjectName(u"fftCheck")
+
+ self.gridLayout.addWidget(self.fftCheck, 0, 0, 1, 1)
+
+ self.derivativeCheck = QCheckBox(self.transformGroup)
+ self.derivativeCheck.setObjectName(u"derivativeCheck")
+
+ self.gridLayout.addWidget(self.derivativeCheck, 3, 0, 1, 1)
+
+ self.phasemapCheck = QCheckBox(self.transformGroup)
+ self.phasemapCheck.setObjectName(u"phasemapCheck")
+
+ self.gridLayout.addWidget(self.phasemapCheck, 4, 0, 1, 1)
+
+ self.pointsGroup = QGroupBox(Form)
+ self.pointsGroup.setObjectName(u"pointsGroup")
+ self.pointsGroup.setGeometry(QRect(10, 550, 234, 58))
+ self.pointsGroup.setCheckable(True)
+ self.verticalLayout_5 = QVBoxLayout(self.pointsGroup)
+ self.verticalLayout_5.setObjectName(u"verticalLayout_5")
+ self.autoPointsCheck = QCheckBox(self.pointsGroup)
+ self.autoPointsCheck.setObjectName(u"autoPointsCheck")
+ self.autoPointsCheck.setChecked(True)
+
+ self.verticalLayout_5.addWidget(self.autoPointsCheck)
+
+ self.gridGroup = QFrame(Form)
+ self.gridGroup.setObjectName(u"gridGroup")
+ self.gridGroup.setGeometry(QRect(10, 460, 221, 81))
+ self.gridLayout_2 = QGridLayout(self.gridGroup)
+ self.gridLayout_2.setObjectName(u"gridLayout_2")
+ self.xGridCheck = QCheckBox(self.gridGroup)
+ self.xGridCheck.setObjectName(u"xGridCheck")
+
+ self.gridLayout_2.addWidget(self.xGridCheck, 0, 0, 1, 2)
+
+ self.yGridCheck = QCheckBox(self.gridGroup)
+ self.yGridCheck.setObjectName(u"yGridCheck")
+
+ self.gridLayout_2.addWidget(self.yGridCheck, 1, 0, 1, 2)
+
+ self.gridAlphaSlider = QSlider(self.gridGroup)
+ self.gridAlphaSlider.setObjectName(u"gridAlphaSlider")
+ self.gridAlphaSlider.setMaximum(255)
+ self.gridAlphaSlider.setValue(128)
+ self.gridAlphaSlider.setOrientation(Qt.Horizontal)
+
+ self.gridLayout_2.addWidget(self.gridAlphaSlider, 2, 1, 1, 1)
+
+ self.label = QLabel(self.gridGroup)
+ self.label.setObjectName(u"label")
+
+ self.gridLayout_2.addWidget(self.label, 2, 0, 1, 1)
+
+ self.alphaGroup = QGroupBox(Form)
+ self.alphaGroup.setObjectName(u"alphaGroup")
+ self.alphaGroup.setGeometry(QRect(10, 390, 234, 60))
+ self.alphaGroup.setCheckable(True)
+ self.horizontalLayout = QHBoxLayout(self.alphaGroup)
+ self.horizontalLayout.setObjectName(u"horizontalLayout")
+ self.autoAlphaCheck = QCheckBox(self.alphaGroup)
+ self.autoAlphaCheck.setObjectName(u"autoAlphaCheck")
+ self.autoAlphaCheck.setChecked(False)
+
+ self.horizontalLayout.addWidget(self.autoAlphaCheck)
+
+ self.alphaSlider = QSlider(self.alphaGroup)
+ self.alphaSlider.setObjectName(u"alphaSlider")
+ self.alphaSlider.setMaximum(1000)
+ self.alphaSlider.setValue(1000)
+ self.alphaSlider.setOrientation(Qt.Horizontal)
+
+ self.horizontalLayout.addWidget(self.alphaSlider)
+
+
+ self.retranslateUi(Form)
+
+ QMetaObject.connectSlotsByName(Form)
+ # setupUi
+
+ def retranslateUi(self, Form):
+ Form.setWindowTitle(QCoreApplication.translate("Form", u"PyQtGraph", None))
+#if QT_CONFIG(tooltip)
+ self.averageGroup.setToolTip(QCoreApplication.translate("Form", u"Display averages of the curves displayed in this plot. The parameter list allows you to choose parameters to average over (if any are available).", None))
+#endif // QT_CONFIG(tooltip)
+ self.averageGroup.setTitle(QCoreApplication.translate("Form", u"Average", None))
+#if QT_CONFIG(tooltip)
+ self.clipToViewCheck.setToolTip(QCoreApplication.translate("Form", u"Plot only the portion of each curve that is visible. This assumes X values are uniformly spaced.", None))
+#endif // QT_CONFIG(tooltip)
+ self.clipToViewCheck.setText(QCoreApplication.translate("Form", u"Clip to View", None))
+#if QT_CONFIG(tooltip)
+ self.maxTracesCheck.setToolTip(QCoreApplication.translate("Form", u"If multiple curves are displayed in this plot, check this box to limit the number of traces that are displayed.", None))
+#endif // QT_CONFIG(tooltip)
+ self.maxTracesCheck.setText(QCoreApplication.translate("Form", u"Max Traces:", None))
+ self.downsampleCheck.setText(QCoreApplication.translate("Form", u"Downsample", None))
+#if QT_CONFIG(tooltip)
+ self.peakRadio.setToolTip(QCoreApplication.translate("Form", u"Downsample by drawing a saw wave that follows the min and max of the original data. This method produces the best visual representation of the data but is slower.", None))
+#endif // QT_CONFIG(tooltip)
+ self.peakRadio.setText(QCoreApplication.translate("Form", u"Peak", None))
+#if QT_CONFIG(tooltip)
+ self.maxTracesSpin.setToolTip(QCoreApplication.translate("Form", u"If multiple curves are displayed in this plot, check \"Max Traces\" and set this value to limit the number of traces that are displayed.", None))
+#endif // QT_CONFIG(tooltip)
+#if QT_CONFIG(tooltip)
+ self.forgetTracesCheck.setToolTip(QCoreApplication.translate("Form", u"If MaxTraces is checked, remove curves from memory after they are hidden (saves memory, but traces can not be un-hidden).", None))
+#endif // QT_CONFIG(tooltip)
+ self.forgetTracesCheck.setText(QCoreApplication.translate("Form", u"Forget hidden traces", None))
+#if QT_CONFIG(tooltip)
+ self.meanRadio.setToolTip(QCoreApplication.translate("Form", u"Downsample by taking the mean of N samples.", None))
+#endif // QT_CONFIG(tooltip)
+ self.meanRadio.setText(QCoreApplication.translate("Form", u"Mean", None))
+#if QT_CONFIG(tooltip)
+ self.subsampleRadio.setToolTip(QCoreApplication.translate("Form", u"Downsample by taking the first of N samples. This method is fastest and least accurate.", None))
+#endif // QT_CONFIG(tooltip)
+ self.subsampleRadio.setText(QCoreApplication.translate("Form", u"Subsample", None))
+#if QT_CONFIG(tooltip)
+ self.autoDownsampleCheck.setToolTip(QCoreApplication.translate("Form", u"Automatically downsample data based on the visible range. This assumes X values are uniformly spaced.", None))
+#endif // QT_CONFIG(tooltip)
+ self.autoDownsampleCheck.setText(QCoreApplication.translate("Form", u"Auto", None))
+#if QT_CONFIG(tooltip)
+ self.downsampleSpin.setToolTip(QCoreApplication.translate("Form", u"Downsample data before plotting. (plot every Nth sample)", None))
+#endif // QT_CONFIG(tooltip)
+ self.downsampleSpin.setSuffix(QCoreApplication.translate("Form", u"x", None))
+ self.logYCheck.setText(QCoreApplication.translate("Form", u"Log Y", None))
+ self.logXCheck.setText(QCoreApplication.translate("Form", u"Log X", None))
+ self.fftCheck.setText(QCoreApplication.translate("Form", u"Power Spectrum (FFT)", None))
+ self.derivativeCheck.setText(QCoreApplication.translate("Form", u"dy/dx", None))
+ self.phasemapCheck.setText(QCoreApplication.translate("Form", u"Y vs. Y'", None))
+ self.pointsGroup.setTitle(QCoreApplication.translate("Form", u"Points", None))
+ self.autoPointsCheck.setText(QCoreApplication.translate("Form", u"Auto", None))
+ self.xGridCheck.setText(QCoreApplication.translate("Form", u"Show X Grid", None))
+ self.yGridCheck.setText(QCoreApplication.translate("Form", u"Show Y Grid", None))
+ self.label.setText(QCoreApplication.translate("Form", u"Opacity", None))
+ self.alphaGroup.setTitle(QCoreApplication.translate("Form", u"Alpha", None))
+ self.autoAlphaCheck.setText(QCoreApplication.translate("Form", u"Auto", None))
+ # retranslateUi
+
diff --git a/pyqtgraph/graphicsItems/PlotItem/tests/test_PlotItem.py b/pyqtgraph/graphicsItems/PlotItem/tests/test_PlotItem.py
index bad3555b..83d2531d 100644
--- a/pyqtgraph/graphicsItems/PlotItem/tests/test_PlotItem.py
+++ b/pyqtgraph/graphicsItems/PlotItem/tests/test_PlotItem.py
@@ -21,3 +21,36 @@ def test_PlotItem_shared_axis_items(orientation):
with pytest.raises(RuntimeError):
pi2.setAxisItems({orientation: ax1})
+
+
+def test_plotitem_menu_initialize():
+ """Test the menu initialization of the plotitem"""
+ item = pg.PlotItem()
+ assert item.menuEnabled() is True
+ viewbox = item.vb
+ assert viewbox is not None
+ assert viewbox.menu is not None
+ assert viewbox.menuEnabled() is True
+
+ item = pg.PlotItem(enableMenu=False)
+ assert item.menuEnabled() is False
+ viewbox = item.vb
+ assert viewbox is not None
+ assert viewbox.menu is None
+ assert viewbox.menuEnabled() is False
+
+ viewbox = pg.ViewBox()
+ item = pg.PlotItem(viewBox=viewbox, enableMenu=False)
+ assert item.menuEnabled() is False
+ viewbox = item.vb
+ assert viewbox is not None
+ assert viewbox.menu is not None
+ assert viewbox.menuEnabled() is True
+
+ viewbox = pg.ViewBox(enableMenu=False)
+ item = pg.PlotItem(viewBox=viewbox)
+ assert item.menuEnabled() is True
+ viewbox = item.vb
+ assert viewbox is not None
+ assert viewbox.menu is None
+ assert viewbox.menuEnabled() is False
diff --git a/pyqtgraph/graphicsItems/ROI.py b/pyqtgraph/graphicsItems/ROI.py
index 4f23ccd1..c3ef3112 100644
--- a/pyqtgraph/graphicsItems/ROI.py
+++ b/pyqtgraph/graphicsItems/ROI.py
@@ -23,6 +23,8 @@ from .GraphicsObject import GraphicsObject
from .UIGraphicsItem import UIGraphicsItem
from .. import getConfigOption
+translate = QtCore.QCoreApplication.translate
+
__all__ = [
'ROI',
'TestROI', 'RectROI', 'EllipseROI', 'CircleROI', 'PolygonROI',
@@ -721,8 +723,8 @@ class ROI(GraphicsObject):
if self.translatable and ev.acceptDrags(QtCore.Qt.LeftButton):
hover=True
- for btn in [QtCore.Qt.LeftButton, QtCore.Qt.RightButton, QtCore.Qt.MidButton]:
- if int(self.acceptedMouseButtons() & btn) > 0 and ev.acceptClicks(btn):
+ for btn in [QtCore.Qt.LeftButton, QtCore.Qt.RightButton, QtCore.Qt.MiddleButton]:
+ if (self.acceptedMouseButtons() & btn) and ev.acceptClicks(btn):
hover=True
if self.contextMenuEnabled():
ev.acceptClicks(QtCore.Qt.RightButton)
@@ -731,7 +733,7 @@ class ROI(GraphicsObject):
self.setMouseHover(True)
ev.acceptClicks(QtCore.Qt.LeftButton) ## If the ROI is hilighted, we should accept all clicks to avoid confusion.
ev.acceptClicks(QtCore.Qt.RightButton)
- ev.acceptClicks(QtCore.Qt.MidButton)
+ ev.acceptClicks(QtCore.Qt.MiddleButton)
self.sigHoverEvent.emit(self)
else:
self.setMouseHover(False)
@@ -770,8 +772,8 @@ class ROI(GraphicsObject):
def getMenu(self):
if self.menu is None:
self.menu = QtGui.QMenu()
- self.menu.setTitle("ROI")
- remAct = QtGui.QAction("Remove ROI", self.menu)
+ self.menu.setTitle(translate("ROI", "ROI"))
+ remAct = QtGui.QAction(translate("ROI", "Remove ROI"), self.menu)
remAct.triggered.connect(self.removeClicked)
self.menu.addAction(remAct)
self.menu.remAct = remAct
@@ -794,7 +796,7 @@ class ROI(GraphicsObject):
if ev.button() == QtCore.Qt.RightButton and self.contextMenuEnabled():
self.raiseContextMenu(ev)
ev.accept()
- elif int(ev.button() & self.acceptedMouseButtons()) > 0:
+ elif ev.button() & self.acceptedMouseButtons():
ev.accept()
self.sigClicked.emit(self, ev)
else:
@@ -820,7 +822,7 @@ class ROI(GraphicsObject):
"""
return True
- def movePoint(self, handle, pos, modifiers=QtCore.Qt.KeyboardModifier(), finish=True, coords='parent'):
+ def movePoint(self, handle, pos, modifiers=QtCore.Qt.KeyboardModifiers(0), finish=True, coords='parent'):
## called by Handles when they are moved.
## pos is the new position of the handle in scene coords, as requested by the handle.
@@ -1342,8 +1344,8 @@ class Handle(UIGraphicsItem):
if not ev.isExit():
if ev.acceptDrags(QtCore.Qt.LeftButton):
hover=True
- for btn in [QtCore.Qt.LeftButton, QtCore.Qt.RightButton, QtCore.Qt.MidButton]:
- if int(self.acceptedMouseButtons() & btn) > 0 and ev.acceptClicks(btn):
+ for btn in [QtCore.Qt.LeftButton, QtCore.Qt.RightButton, QtCore.Qt.MiddleButton]:
+ if (self.acceptedMouseButtons() & btn) and ev.acceptClicks(btn):
hover=True
if hover:
@@ -1358,7 +1360,7 @@ class Handle(UIGraphicsItem):
self.isMoving = False ## prevents any further motion
self.movePoint(self.startPos, finish=True)
ev.accept()
- elif int(ev.button() & self.acceptedMouseButtons()) > 0:
+ elif ev.button() & self.acceptedMouseButtons():
ev.accept()
if ev.button() == QtCore.Qt.RightButton and self.deletable:
self.raiseContextMenu(ev)
@@ -1368,8 +1370,8 @@ class Handle(UIGraphicsItem):
def buildMenu(self):
menu = QtGui.QMenu()
- menu.setTitle("Handle")
- self.removeAction = menu.addAction("Remove handle", self.removeClicked)
+ menu.setTitle(translate("ROI", "Handle"))
+ self.removeAction = menu.addAction(translate("ROI", "Remove handle"), self.removeClicked)
return menu
def getMenu(self):
@@ -1415,7 +1417,7 @@ class Handle(UIGraphicsItem):
self.currentPen = self.hoverPen
self.movePoint(pos, ev.modifiers(), finish=False)
- def movePoint(self, pos, modifiers=QtCore.Qt.KeyboardModifier(), finish=True):
+ def movePoint(self, pos, modifiers=QtCore.Qt.KeyboardModifiers(0), finish=True):
for r in self.rois:
if not r.checkPointMove(self, pos, modifiers):
return
@@ -2330,7 +2332,7 @@ class RulerROI(LineSegmentROI):
p.resetTransform()
txt = fn.siFormat(length, suffix='m') + '\n%0.1f deg' % angle
- p.drawText(QtCore.QRectF(pos.x()-50, pos.y()-50, 100, 100), QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter, txt)
+ p.drawText(QtCore.QRectF(pos.x()-50, pos.y()-50, 100, 100), QtCore.Qt.AlignCenter, txt)
def boundingRect(self):
r = LineSegmentROI.boundingRect(self)
diff --git a/pyqtgraph/graphicsItems/ScatterPlotItem.py b/pyqtgraph/graphicsItems/ScatterPlotItem.py
index 5c776f52..84424c64 100644
--- a/pyqtgraph/graphicsItems/ScatterPlotItem.py
+++ b/pyqtgraph/graphicsItems/ScatterPlotItem.py
@@ -34,7 +34,7 @@ __all__ = ['ScatterPlotItem', 'SpotItem']
# as the separate calls to this method are the current bottleneck.
# See: https://bugreports.qt.io/browse/PYSIDE-163
-_USE_QRECT = QT_LIB != 'PySide2'
+_USE_QRECT = QT_LIB not in ['PySide2', 'PySide6']
## Build all symbol paths
name_list = ['o', 's', 't', 't1', 't2', 't3', 'd', '+', 'x', 'p', 'h', 'star',
diff --git a/pyqtgraph/graphicsItems/UIGraphicsItem.py b/pyqtgraph/graphicsItems/UIGraphicsItem.py
index 07d32944..2f9a3bfe 100644
--- a/pyqtgraph/graphicsItems/UIGraphicsItem.py
+++ b/pyqtgraph/graphicsItems/UIGraphicsItem.py
@@ -1,11 +1,8 @@
from ..Qt import QtGui, QtCore, QT_LIB
import weakref
from .GraphicsObject import GraphicsObject
-if QT_LIB in ['PyQt4', 'PyQt5']:
- try:
- from PyQt5 import sip
- except ImportError:
- import sip
+if QT_LIB.startswith('PyQt'):
+ from ..Qt import sip
__all__ = ['UIGraphicsItem']
class UIGraphicsItem(GraphicsObject):
diff --git a/pyqtgraph/graphicsItems/ViewBox/ViewBox.py b/pyqtgraph/graphicsItems/ViewBox/ViewBox.py
index ac23fae4..2fd6ea61 100644
--- a/pyqtgraph/graphicsItems/ViewBox/ViewBox.py
+++ b/pyqtgraph/graphicsItems/ViewBox/ViewBox.py
@@ -1243,7 +1243,7 @@ class ViewBox(GraphicsWidget):
mask[1-axis] = 0.0
## Scale or translate based on mouse button
- if ev.button() & (QtCore.Qt.LeftButton | QtCore.Qt.MidButton):
+ if ev.button() & (QtCore.Qt.LeftButton | QtCore.Qt.MiddleButton):
if self.state['mouseMode'] == ViewBox.RectMode and axis is None:
if ev.isFinish(): ## This is the final move in the drag; change the view scale now
#print "finish"
@@ -1397,7 +1397,7 @@ class ViewBox(GraphicsWidget):
itemBounds.append((bounds, useX, useY, pxPad))
else:
- if int(item.flags() & item.ItemHasNoContents) > 0:
+ if item.flags() & item.ItemHasNoContents:
continue
bounds = self.mapFromItemToView(item, item.boundingRect()).boundingRect()
itemBounds.append((bounds, True, True, 0))
diff --git a/pyqtgraph/graphicsItems/ViewBox/ViewBoxMenu.py b/pyqtgraph/graphicsItems/ViewBox/ViewBoxMenu.py
index 1f44bdd6..51138129 100644
--- a/pyqtgraph/graphicsItems/ViewBox/ViewBoxMenu.py
+++ b/pyqtgraph/graphicsItems/ViewBox/ViewBoxMenu.py
@@ -3,17 +3,13 @@ from ...Qt import QtCore, QtGui, QT_LIB
from ...python2_3 import asUnicode
from ...WidgetGroup import WidgetGroup
-if QT_LIB == 'PyQt4':
- from .axisCtrlTemplate_pyqt import Ui_Form as AxisCtrlTemplate
-elif QT_LIB == 'PySide':
- from .axisCtrlTemplate_pyside import Ui_Form as AxisCtrlTemplate
-elif QT_LIB == 'PyQt5':
- from .axisCtrlTemplate_pyqt5 import Ui_Form as AxisCtrlTemplate
-elif QT_LIB == 'PySide2':
- from .axisCtrlTemplate_pyside2 import Ui_Form as AxisCtrlTemplate
+import importlib
+ui_template = importlib.import_module(
+ f'.axisCtrlTemplate_{QT_LIB.lower()}', package=__package__)
import weakref
+translate = QtCore.QCoreApplication.translate
class ViewBoxMenu(QtGui.QMenu):
def __init__(self, view):
QtGui.QMenu.__init__(self)
@@ -22,8 +18,8 @@ class ViewBoxMenu(QtGui.QMenu):
self.valid = False ## tells us whether the ui needs to be updated
self.viewMap = weakref.WeakValueDictionary() ## weakrefs to all views listed in the link combos
- self.setTitle("ViewBox options")
- self.viewAll = QtGui.QAction("View All", self)
+ self.setTitle(translate("ViewBox", "ViewBox options"))
+ self.viewAll = QtGui.QAction(translate("ViewBox", "View All"), self)
self.viewAll.triggered.connect(self.autoRange)
self.addAction(self.viewAll)
@@ -33,9 +29,9 @@ class ViewBoxMenu(QtGui.QMenu):
self.dv = QtGui.QDoubleValidator(self)
for axis in 'XY':
m = QtGui.QMenu()
- m.setTitle("%s Axis" % axis)
+ m.setTitle(f"{axis} {translate('ViewBox', 'axis')}")
w = QtGui.QWidget()
- ui = AxisCtrlTemplate()
+ ui = ui_template.Ui_Form()
ui.setupUi(w)
a = QtGui.QWidgetAction(self)
a.setDefaultWidget(w)
@@ -68,15 +64,15 @@ class ViewBoxMenu(QtGui.QMenu):
#self.setExportMethods(view.exportMethods)
#self.addMenu(self.export)
- self.leftMenu = QtGui.QMenu("Mouse Mode")
+ self.leftMenu = QtGui.QMenu(translate("ViewBox", "Mouse Mode"))
group = QtGui.QActionGroup(self)
# This does not work! QAction _must_ be initialized with a permanent
# object as the parent or else it may be collected prematurely.
#pan = self.leftMenu.addAction("3 button", self.set3ButtonMode)
#zoom = self.leftMenu.addAction("1 button", self.set1ButtonMode)
- pan = QtGui.QAction("3 button", self.leftMenu)
- zoom = QtGui.QAction("1 button", self.leftMenu)
+ pan = QtGui.QAction(translate("ViewBox", "3 button"), self.leftMenu)
+ zoom = QtGui.QAction(translate("ViewBox", "1 button"), self.leftMenu)
self.leftMenu.addAction(pan)
self.leftMenu.addAction(zoom)
pan.triggered.connect(self.set3ButtonMode)
diff --git a/pyqtgraph/graphicsItems/ViewBox/axisCtrlTemplate_pyqt.py b/pyqtgraph/graphicsItems/ViewBox/axisCtrlTemplate_pyqt.py
deleted file mode 100644
index b54153fc..00000000
--- a/pyqtgraph/graphicsItems/ViewBox/axisCtrlTemplate_pyqt.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file './pyqtgraph/graphicsItems/ViewBox/axisCtrlTemplate.ui'
-#
-# Created: Mon Dec 23 10:10:51 2013
-# by: PyQt4 UI code generator 4.10
-#
-# WARNING! All changes made in this file will be lost!
-
-from ...Qt import QtCore, QtGui
-
-try:
- _fromUtf8 = QtCore.QString.fromUtf8
-except AttributeError:
- def _fromUtf8(s):
- return s
-
-try:
- _encoding = QtGui.QApplication.UnicodeUTF8
- def _translate(context, text, disambig):
- return QtGui.QApplication.translate(context, text, disambig, _encoding)
-except AttributeError:
- def _translate(context, text, disambig):
- return QtGui.QApplication.translate(context, text, disambig)
-
-class Ui_Form(object):
- def setupUi(self, Form):
- Form.setObjectName(_fromUtf8("Form"))
- Form.resize(186, 154)
- Form.setMaximumSize(QtCore.QSize(200, 16777215))
- self.gridLayout = QtGui.QGridLayout(Form)
- self.gridLayout.setMargin(0)
- self.gridLayout.setSpacing(0)
- self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
- self.label = QtGui.QLabel(Form)
- self.label.setObjectName(_fromUtf8("label"))
- self.gridLayout.addWidget(self.label, 7, 0, 1, 2)
- self.linkCombo = QtGui.QComboBox(Form)
- self.linkCombo.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents)
- self.linkCombo.setObjectName(_fromUtf8("linkCombo"))
- self.gridLayout.addWidget(self.linkCombo, 7, 2, 1, 2)
- self.autoPercentSpin = QtGui.QSpinBox(Form)
- self.autoPercentSpin.setEnabled(True)
- self.autoPercentSpin.setMinimum(1)
- self.autoPercentSpin.setMaximum(100)
- self.autoPercentSpin.setSingleStep(1)
- self.autoPercentSpin.setProperty("value", 100)
- self.autoPercentSpin.setObjectName(_fromUtf8("autoPercentSpin"))
- self.gridLayout.addWidget(self.autoPercentSpin, 2, 2, 1, 2)
- self.autoRadio = QtGui.QRadioButton(Form)
- self.autoRadio.setChecked(True)
- self.autoRadio.setObjectName(_fromUtf8("autoRadio"))
- self.gridLayout.addWidget(self.autoRadio, 2, 0, 1, 2)
- self.manualRadio = QtGui.QRadioButton(Form)
- self.manualRadio.setObjectName(_fromUtf8("manualRadio"))
- self.gridLayout.addWidget(self.manualRadio, 1, 0, 1, 2)
- self.minText = QtGui.QLineEdit(Form)
- self.minText.setObjectName(_fromUtf8("minText"))
- self.gridLayout.addWidget(self.minText, 1, 2, 1, 1)
- self.maxText = QtGui.QLineEdit(Form)
- self.maxText.setObjectName(_fromUtf8("maxText"))
- self.gridLayout.addWidget(self.maxText, 1, 3, 1, 1)
- self.invertCheck = QtGui.QCheckBox(Form)
- self.invertCheck.setObjectName(_fromUtf8("invertCheck"))
- self.gridLayout.addWidget(self.invertCheck, 5, 0, 1, 4)
- self.mouseCheck = QtGui.QCheckBox(Form)
- self.mouseCheck.setChecked(True)
- self.mouseCheck.setObjectName(_fromUtf8("mouseCheck"))
- self.gridLayout.addWidget(self.mouseCheck, 6, 0, 1, 4)
- self.visibleOnlyCheck = QtGui.QCheckBox(Form)
- self.visibleOnlyCheck.setObjectName(_fromUtf8("visibleOnlyCheck"))
- self.gridLayout.addWidget(self.visibleOnlyCheck, 3, 2, 1, 2)
- self.autoPanCheck = QtGui.QCheckBox(Form)
- self.autoPanCheck.setObjectName(_fromUtf8("autoPanCheck"))
- self.gridLayout.addWidget(self.autoPanCheck, 4, 2, 1, 2)
-
- self.retranslateUi(Form)
- QtCore.QMetaObject.connectSlotsByName(Form)
-
- def retranslateUi(self, Form):
- Form.setWindowTitle(_translate("Form", "PyQtGraph", None))
- self.label.setText(_translate("Form", "Link Axis:", None))
- self.linkCombo.setToolTip(_translate("Form", "
Links this axis with another view. When linked, both views will display the same data range.
", None))
- self.autoPercentSpin.setToolTip(_translate("Form", "Percent of data to be visible when auto-scaling. It may be useful to decrease this value for data with spiky noise.
", None))
- self.autoPercentSpin.setSuffix(_translate("Form", "%", None))
- self.autoRadio.setToolTip(_translate("Form", "Automatically resize this axis whenever the displayed data is changed.
", None))
- self.autoRadio.setText(_translate("Form", "Auto", None))
- self.manualRadio.setToolTip(_translate("Form", "Set the range for this axis manually. This disables automatic scaling.
", None))
- self.manualRadio.setText(_translate("Form", "Manual", None))
- self.minText.setToolTip(_translate("Form", "Minimum value to display for this axis.
", None))
- self.minText.setText(_translate("Form", "0", None))
- self.maxText.setToolTip(_translate("Form", "Maximum value to display for this axis.
", None))
- self.maxText.setText(_translate("Form", "0", None))
- self.invertCheck.setToolTip(_translate("Form", "Inverts the display of this axis. (+y points downward instead of upward)
", None))
- self.invertCheck.setText(_translate("Form", "Invert Axis", None))
- self.mouseCheck.setToolTip(_translate("Form", "Enables mouse interaction (panning, scaling) for this axis.
", None))
- self.mouseCheck.setText(_translate("Form", "Mouse Enabled", None))
- self.visibleOnlyCheck.setToolTip(_translate("Form", "When checked, the axis will only auto-scale to data that is visible along the orthogonal axis.
", None))
- self.visibleOnlyCheck.setText(_translate("Form", "Visible Data Only", None))
- self.autoPanCheck.setToolTip(_translate("Form", "When checked, the axis will automatically pan to center on the current data, but the scale along this axis will not change.
", None))
- self.autoPanCheck.setText(_translate("Form", "Auto Pan Only", None))
-
diff --git a/pyqtgraph/graphicsItems/ViewBox/axisCtrlTemplate_pyqt6.py b/pyqtgraph/graphicsItems/ViewBox/axisCtrlTemplate_pyqt6.py
new file mode 100644
index 00000000..6c883610
--- /dev/null
+++ b/pyqtgraph/graphicsItems/ViewBox/axisCtrlTemplate_pyqt6.py
@@ -0,0 +1,88 @@
+# Form implementation generated from reading ui file 'pyqtgraph\graphicsItems\ViewBox\axisCtrlTemplate.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(186, 154)
+ Form.setMaximumSize(QtCore.QSize(200, 16777215))
+ self.gridLayout = QtWidgets.QGridLayout(Form)
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout.setSpacing(0)
+ self.gridLayout.setObjectName("gridLayout")
+ self.label = QtWidgets.QLabel(Form)
+ self.label.setObjectName("label")
+ self.gridLayout.addWidget(self.label, 7, 0, 1, 2)
+ self.linkCombo = QtWidgets.QComboBox(Form)
+ self.linkCombo.setSizeAdjustPolicy(QtWidgets.QComboBox.SizeAdjustPolicy.AdjustToContents)
+ self.linkCombo.setObjectName("linkCombo")
+ self.gridLayout.addWidget(self.linkCombo, 7, 2, 1, 2)
+ self.autoPercentSpin = QtWidgets.QSpinBox(Form)
+ self.autoPercentSpin.setEnabled(True)
+ self.autoPercentSpin.setMinimum(1)
+ self.autoPercentSpin.setMaximum(100)
+ self.autoPercentSpin.setSingleStep(1)
+ self.autoPercentSpin.setProperty("value", 100)
+ self.autoPercentSpin.setObjectName("autoPercentSpin")
+ self.gridLayout.addWidget(self.autoPercentSpin, 2, 2, 1, 2)
+ self.autoRadio = QtWidgets.QRadioButton(Form)
+ self.autoRadio.setChecked(True)
+ self.autoRadio.setObjectName("autoRadio")
+ self.gridLayout.addWidget(self.autoRadio, 2, 0, 1, 2)
+ self.manualRadio = QtWidgets.QRadioButton(Form)
+ self.manualRadio.setObjectName("manualRadio")
+ self.gridLayout.addWidget(self.manualRadio, 1, 0, 1, 2)
+ self.minText = QtWidgets.QLineEdit(Form)
+ self.minText.setObjectName("minText")
+ self.gridLayout.addWidget(self.minText, 1, 2, 1, 1)
+ self.maxText = QtWidgets.QLineEdit(Form)
+ self.maxText.setObjectName("maxText")
+ self.gridLayout.addWidget(self.maxText, 1, 3, 1, 1)
+ self.invertCheck = QtWidgets.QCheckBox(Form)
+ self.invertCheck.setObjectName("invertCheck")
+ self.gridLayout.addWidget(self.invertCheck, 5, 0, 1, 4)
+ self.mouseCheck = QtWidgets.QCheckBox(Form)
+ self.mouseCheck.setChecked(True)
+ self.mouseCheck.setObjectName("mouseCheck")
+ self.gridLayout.addWidget(self.mouseCheck, 6, 0, 1, 4)
+ self.visibleOnlyCheck = QtWidgets.QCheckBox(Form)
+ self.visibleOnlyCheck.setObjectName("visibleOnlyCheck")
+ self.gridLayout.addWidget(self.visibleOnlyCheck, 3, 2, 1, 2)
+ self.autoPanCheck = QtWidgets.QCheckBox(Form)
+ self.autoPanCheck.setObjectName("autoPanCheck")
+ self.gridLayout.addWidget(self.autoPanCheck, 4, 2, 1, 2)
+
+ self.retranslateUi(Form)
+ QtCore.QMetaObject.connectSlotsByName(Form)
+
+ def retranslateUi(self, Form):
+ _translate = QtCore.QCoreApplication.translate
+ Form.setWindowTitle(_translate("Form", "PyQtGraph"))
+ self.label.setText(_translate("Form", "Link Axis:"))
+ self.linkCombo.setToolTip(_translate("Form", "Links this axis with another view. When linked, both views will display the same data range.
"))
+ self.autoPercentSpin.setToolTip(_translate("Form", "Percent of data to be visible when auto-scaling. It may be useful to decrease this value for data with spiky noise.
"))
+ self.autoPercentSpin.setSuffix(_translate("Form", "%"))
+ self.autoRadio.setToolTip(_translate("Form", "Automatically resize this axis whenever the displayed data is changed.
"))
+ self.autoRadio.setText(_translate("Form", "Auto"))
+ self.manualRadio.setToolTip(_translate("Form", "Set the range for this axis manually. This disables automatic scaling.
"))
+ self.manualRadio.setText(_translate("Form", "Manual"))
+ self.minText.setToolTip(_translate("Form", "Minimum value to display for this axis.
"))
+ self.minText.setText(_translate("Form", "0"))
+ self.maxText.setToolTip(_translate("Form", "Maximum value to display for this axis.
"))
+ self.maxText.setText(_translate("Form", "0"))
+ self.invertCheck.setToolTip(_translate("Form", "Inverts the display of this axis. (+y points downward instead of upward)
"))
+ self.invertCheck.setText(_translate("Form", "Invert Axis"))
+ self.mouseCheck.setToolTip(_translate("Form", "Enables mouse interaction (panning, scaling) for this axis.
"))
+ self.mouseCheck.setText(_translate("Form", "Mouse Enabled"))
+ self.visibleOnlyCheck.setToolTip(_translate("Form", "When checked, the axis will only auto-scale to data that is visible along the orthogonal axis.
"))
+ self.visibleOnlyCheck.setText(_translate("Form", "Visible Data Only"))
+ self.autoPanCheck.setToolTip(_translate("Form", "When checked, the axis will automatically pan to center on the current data, but the scale along this axis will not change.
"))
+ self.autoPanCheck.setText(_translate("Form", "Auto Pan Only"))
diff --git a/pyqtgraph/graphicsItems/ViewBox/axisCtrlTemplate_pyside.py b/pyqtgraph/graphicsItems/ViewBox/axisCtrlTemplate_pyside.py
deleted file mode 100644
index c90206b5..00000000
--- a/pyqtgraph/graphicsItems/ViewBox/axisCtrlTemplate_pyside.py
+++ /dev/null
@@ -1,88 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file './pyqtgraph/graphicsItems/ViewBox/axisCtrlTemplate.ui'
-#
-# Created: Mon Dec 23 10:10:51 2013
-# by: pyside-uic 0.2.14 running on PySide 1.1.2
-#
-# WARNING! All changes made in this file will be lost!
-
-from PySide import QtCore, QtGui
-
-class Ui_Form(object):
- def setupUi(self, Form):
- Form.setObjectName("Form")
- Form.resize(186, 154)
- Form.setMaximumSize(QtCore.QSize(200, 16777215))
- self.gridLayout = QtGui.QGridLayout(Form)
- self.gridLayout.setContentsMargins(0, 0, 0, 0)
- self.gridLayout.setSpacing(0)
- self.gridLayout.setObjectName("gridLayout")
- self.label = QtGui.QLabel(Form)
- self.label.setObjectName("label")
- self.gridLayout.addWidget(self.label, 7, 0, 1, 2)
- self.linkCombo = QtGui.QComboBox(Form)
- self.linkCombo.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents)
- self.linkCombo.setObjectName("linkCombo")
- self.gridLayout.addWidget(self.linkCombo, 7, 2, 1, 2)
- self.autoPercentSpin = QtGui.QSpinBox(Form)
- self.autoPercentSpin.setEnabled(True)
- self.autoPercentSpin.setMinimum(1)
- self.autoPercentSpin.setMaximum(100)
- self.autoPercentSpin.setSingleStep(1)
- self.autoPercentSpin.setProperty("value", 100)
- self.autoPercentSpin.setObjectName("autoPercentSpin")
- self.gridLayout.addWidget(self.autoPercentSpin, 2, 2, 1, 2)
- self.autoRadio = QtGui.QRadioButton(Form)
- self.autoRadio.setChecked(True)
- self.autoRadio.setObjectName("autoRadio")
- self.gridLayout.addWidget(self.autoRadio, 2, 0, 1, 2)
- self.manualRadio = QtGui.QRadioButton(Form)
- self.manualRadio.setObjectName("manualRadio")
- self.gridLayout.addWidget(self.manualRadio, 1, 0, 1, 2)
- self.minText = QtGui.QLineEdit(Form)
- self.minText.setObjectName("minText")
- self.gridLayout.addWidget(self.minText, 1, 2, 1, 1)
- self.maxText = QtGui.QLineEdit(Form)
- self.maxText.setObjectName("maxText")
- self.gridLayout.addWidget(self.maxText, 1, 3, 1, 1)
- self.invertCheck = QtGui.QCheckBox(Form)
- self.invertCheck.setObjectName("invertCheck")
- self.gridLayout.addWidget(self.invertCheck, 5, 0, 1, 4)
- self.mouseCheck = QtGui.QCheckBox(Form)
- self.mouseCheck.setChecked(True)
- self.mouseCheck.setObjectName("mouseCheck")
- self.gridLayout.addWidget(self.mouseCheck, 6, 0, 1, 4)
- self.visibleOnlyCheck = QtGui.QCheckBox(Form)
- self.visibleOnlyCheck.setObjectName("visibleOnlyCheck")
- self.gridLayout.addWidget(self.visibleOnlyCheck, 3, 2, 1, 2)
- self.autoPanCheck = QtGui.QCheckBox(Form)
- self.autoPanCheck.setObjectName("autoPanCheck")
- self.gridLayout.addWidget(self.autoPanCheck, 4, 2, 1, 2)
-
- self.retranslateUi(Form)
- QtCore.QMetaObject.connectSlotsByName(Form)
-
- def retranslateUi(self, Form):
- Form.setWindowTitle(QtGui.QApplication.translate("Form", "PyQtGraph", None, QtGui.QApplication.UnicodeUTF8))
- self.label.setText(QtGui.QApplication.translate("Form", "Link Axis:", None, QtGui.QApplication.UnicodeUTF8))
- self.linkCombo.setToolTip(QtGui.QApplication.translate("Form", "Links this axis with another view. When linked, both views will display the same data range.
", None, QtGui.QApplication.UnicodeUTF8))
- self.autoPercentSpin.setToolTip(QtGui.QApplication.translate("Form", "Percent of data to be visible when auto-scaling. It may be useful to decrease this value for data with spiky noise.
", None, QtGui.QApplication.UnicodeUTF8))
- self.autoPercentSpin.setSuffix(QtGui.QApplication.translate("Form", "%", None, QtGui.QApplication.UnicodeUTF8))
- self.autoRadio.setToolTip(QtGui.QApplication.translate("Form", "Automatically resize this axis whenever the displayed data is changed.
", None, QtGui.QApplication.UnicodeUTF8))
- self.autoRadio.setText(QtGui.QApplication.translate("Form", "Auto", None, QtGui.QApplication.UnicodeUTF8))
- self.manualRadio.setToolTip(QtGui.QApplication.translate("Form", "Set the range for this axis manually. This disables automatic scaling.
", None, QtGui.QApplication.UnicodeUTF8))
- self.manualRadio.setText(QtGui.QApplication.translate("Form", "Manual", None, QtGui.QApplication.UnicodeUTF8))
- self.minText.setToolTip(QtGui.QApplication.translate("Form", "Minimum value to display for this axis.
", None, QtGui.QApplication.UnicodeUTF8))
- self.minText.setText(QtGui.QApplication.translate("Form", "0", None, QtGui.QApplication.UnicodeUTF8))
- self.maxText.setToolTip(QtGui.QApplication.translate("Form", "Maximum value to display for this axis.
", None, QtGui.QApplication.UnicodeUTF8))
- self.maxText.setText(QtGui.QApplication.translate("Form", "0", None, QtGui.QApplication.UnicodeUTF8))
- self.invertCheck.setToolTip(QtGui.QApplication.translate("Form", "Inverts the display of this axis. (+y points downward instead of upward)
", None, QtGui.QApplication.UnicodeUTF8))
- self.invertCheck.setText(QtGui.QApplication.translate("Form", "Invert Axis", None, QtGui.QApplication.UnicodeUTF8))
- self.mouseCheck.setToolTip(QtGui.QApplication.translate("Form", " Enables mouse interaction (panning, scaling) for this axis.
", None, QtGui.QApplication.UnicodeUTF8))
- self.mouseCheck.setText(QtGui.QApplication.translate("Form", "Mouse Enabled", None, QtGui.QApplication.UnicodeUTF8))
- self.visibleOnlyCheck.setToolTip(QtGui.QApplication.translate("Form", "
When checked, the axis will only auto-scale to data that is visible along the orthogonal axis.
", None, QtGui.QApplication.UnicodeUTF8))
- self.visibleOnlyCheck.setText(QtGui.QApplication.translate("Form", "Visible Data Only", None, QtGui.QApplication.UnicodeUTF8))
- self.autoPanCheck.setToolTip(QtGui.QApplication.translate("Form", "When checked, the axis will automatically pan to center on the current data, but the scale along this axis will not change.
", None, QtGui.QApplication.UnicodeUTF8))
- self.autoPanCheck.setText(QtGui.QApplication.translate("Form", "Auto Pan Only", None, QtGui.QApplication.UnicodeUTF8))
-
diff --git a/pyqtgraph/graphicsItems/ViewBox/axisCtrlTemplate_pyside6.py b/pyqtgraph/graphicsItems/ViewBox/axisCtrlTemplate_pyside6.py
new file mode 100644
index 00000000..f52ddf16
--- /dev/null
+++ b/pyqtgraph/graphicsItems/ViewBox/axisCtrlTemplate_pyside6.py
@@ -0,0 +1,138 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'axisCtrlTemplate.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 *
+
+
+class Ui_Form(object):
+ def setupUi(self, Form):
+ if not Form.objectName():
+ Form.setObjectName(u"Form")
+ Form.resize(186, 154)
+ Form.setMaximumSize(QSize(200, 16777215))
+ self.gridLayout = QGridLayout(Form)
+ self.gridLayout.setSpacing(0)
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout.setObjectName(u"gridLayout")
+ self.label = QLabel(Form)
+ self.label.setObjectName(u"label")
+
+ self.gridLayout.addWidget(self.label, 7, 0, 1, 2)
+
+ self.linkCombo = QComboBox(Form)
+ self.linkCombo.setObjectName(u"linkCombo")
+ self.linkCombo.setSizeAdjustPolicy(QComboBox.AdjustToContents)
+
+ self.gridLayout.addWidget(self.linkCombo, 7, 2, 1, 2)
+
+ self.autoPercentSpin = QSpinBox(Form)
+ self.autoPercentSpin.setObjectName(u"autoPercentSpin")
+ self.autoPercentSpin.setEnabled(True)
+ self.autoPercentSpin.setMinimum(1)
+ self.autoPercentSpin.setMaximum(100)
+ self.autoPercentSpin.setSingleStep(1)
+ self.autoPercentSpin.setValue(100)
+
+ self.gridLayout.addWidget(self.autoPercentSpin, 2, 2, 1, 2)
+
+ self.autoRadio = QRadioButton(Form)
+ self.autoRadio.setObjectName(u"autoRadio")
+ self.autoRadio.setChecked(True)
+
+ self.gridLayout.addWidget(self.autoRadio, 2, 0, 1, 2)
+
+ self.manualRadio = QRadioButton(Form)
+ self.manualRadio.setObjectName(u"manualRadio")
+
+ self.gridLayout.addWidget(self.manualRadio, 1, 0, 1, 2)
+
+ self.minText = QLineEdit(Form)
+ self.minText.setObjectName(u"minText")
+
+ self.gridLayout.addWidget(self.minText, 1, 2, 1, 1)
+
+ self.maxText = QLineEdit(Form)
+ self.maxText.setObjectName(u"maxText")
+
+ self.gridLayout.addWidget(self.maxText, 1, 3, 1, 1)
+
+ self.invertCheck = QCheckBox(Form)
+ self.invertCheck.setObjectName(u"invertCheck")
+
+ self.gridLayout.addWidget(self.invertCheck, 5, 0, 1, 4)
+
+ self.mouseCheck = QCheckBox(Form)
+ self.mouseCheck.setObjectName(u"mouseCheck")
+ self.mouseCheck.setChecked(True)
+
+ self.gridLayout.addWidget(self.mouseCheck, 6, 0, 1, 4)
+
+ self.visibleOnlyCheck = QCheckBox(Form)
+ self.visibleOnlyCheck.setObjectName(u"visibleOnlyCheck")
+
+ self.gridLayout.addWidget(self.visibleOnlyCheck, 3, 2, 1, 2)
+
+ self.autoPanCheck = QCheckBox(Form)
+ self.autoPanCheck.setObjectName(u"autoPanCheck")
+
+ self.gridLayout.addWidget(self.autoPanCheck, 4, 2, 1, 2)
+
+
+ self.retranslateUi(Form)
+
+ QMetaObject.connectSlotsByName(Form)
+ # setupUi
+
+ def retranslateUi(self, Form):
+ Form.setWindowTitle(QCoreApplication.translate("Form", u"PyQtGraph", None))
+ self.label.setText(QCoreApplication.translate("Form", u"Link Axis:", None))
+#if QT_CONFIG(tooltip)
+ self.linkCombo.setToolTip(QCoreApplication.translate("Form", u"Links this axis with another view. When linked, both views will display the same data range.
", None))
+#endif // QT_CONFIG(tooltip)
+#if QT_CONFIG(tooltip)
+ self.autoPercentSpin.setToolTip(QCoreApplication.translate("Form", u"Percent of data to be visible when auto-scaling. It may be useful to decrease this value for data with spiky noise.
", None))
+#endif // QT_CONFIG(tooltip)
+ self.autoPercentSpin.setSuffix(QCoreApplication.translate("Form", u"%", None))
+#if QT_CONFIG(tooltip)
+ self.autoRadio.setToolTip(QCoreApplication.translate("Form", u"Automatically resize this axis whenever the displayed data is changed.
", None))
+#endif // QT_CONFIG(tooltip)
+ self.autoRadio.setText(QCoreApplication.translate("Form", u"Auto", None))
+#if QT_CONFIG(tooltip)
+ self.manualRadio.setToolTip(QCoreApplication.translate("Form", u"Set the range for this axis manually. This disables automatic scaling.
", None))
+#endif // QT_CONFIG(tooltip)
+ self.manualRadio.setText(QCoreApplication.translate("Form", u"Manual", None))
+#if QT_CONFIG(tooltip)
+ self.minText.setToolTip(QCoreApplication.translate("Form", u"Minimum value to display for this axis.
", None))
+#endif // QT_CONFIG(tooltip)
+ self.minText.setText(QCoreApplication.translate("Form", u"0", None))
+#if QT_CONFIG(tooltip)
+ self.maxText.setToolTip(QCoreApplication.translate("Form", u"Maximum value to display for this axis.
", None))
+#endif // QT_CONFIG(tooltip)
+ self.maxText.setText(QCoreApplication.translate("Form", u"0", None))
+#if QT_CONFIG(tooltip)
+ self.invertCheck.setToolTip(QCoreApplication.translate("Form", u"Inverts the display of this axis. (+y points downward instead of upward)
", None))
+#endif // QT_CONFIG(tooltip)
+ self.invertCheck.setText(QCoreApplication.translate("Form", u"Invert Axis", None))
+#if QT_CONFIG(tooltip)
+ self.mouseCheck.setToolTip(QCoreApplication.translate("Form", u"Enables mouse interaction (panning, scaling) for this axis.
", None))
+#endif // QT_CONFIG(tooltip)
+ self.mouseCheck.setText(QCoreApplication.translate("Form", u"Mouse Enabled", None))
+#if QT_CONFIG(tooltip)
+ self.visibleOnlyCheck.setToolTip(QCoreApplication.translate("Form", u"When checked, the axis will only auto-scale to data that is visible along the orthogonal axis.
", None))
+#endif // QT_CONFIG(tooltip)
+ self.visibleOnlyCheck.setText(QCoreApplication.translate("Form", u"Visible Data Only", None))
+#if QT_CONFIG(tooltip)
+ self.autoPanCheck.setToolTip(QCoreApplication.translate("Form", u"When checked, the axis will automatically pan to center on the current data, but the scale along this axis will not change.
", None))
+#endif // QT_CONFIG(tooltip)
+ self.autoPanCheck.setText(QCoreApplication.translate("Form", u"Auto Pan Only", None))
+ # retranslateUi
+
diff --git a/pyqtgraph/graphicsItems/tests/test_InfiniteLine.py b/pyqtgraph/graphicsItems/tests/test_InfiniteLine.py
index 5d9a2184..689e1963 100644
--- a/pyqtgraph/graphicsItems/tests/test_InfiniteLine.py
+++ b/pyqtgraph/graphicsItems/tests/test_InfiniteLine.py
@@ -63,8 +63,8 @@ def test_mouseInteraction():
plt.setYRange(-10, 10)
# test horizontal drag
- pos = plt.plotItem.vb.mapViewToScene(pg.Point(0,5)).toPoint()
- pos2 = pos - QtCore.QPoint(200, 200)
+ pos = plt.plotItem.vb.mapViewToScene(pg.Point(0,5))
+ pos2 = pos - QtCore.QPointF(200, 200)
mouseMove(plt, pos)
assert vline.mouseHovering is True and hline.mouseHovering is False
mouseDrag(plt, pos, pos2, QtCore.Qt.LeftButton)
@@ -72,17 +72,17 @@ def test_mouseInteraction():
assert abs(vline.value() - plt.plotItem.vb.mapSceneToView(pos2).x()) <= px
# test missed drag
- pos = plt.plotItem.vb.mapViewToScene(pg.Point(5,0)).toPoint()
- pos = pos + QtCore.QPoint(0, 6)
- pos2 = pos + QtCore.QPoint(-20, -20)
+ pos = plt.plotItem.vb.mapViewToScene(pg.Point(5,0))
+ pos = pos + QtCore.QPointF(0, 6)
+ pos2 = pos + QtCore.QPointF(-20, -20)
mouseMove(plt, pos)
assert vline.mouseHovering is False and hline.mouseHovering is False
mouseDrag(plt, pos, pos2, QtCore.Qt.LeftButton)
assert hline.value() == 0
# test vertical drag
- pos = plt.plotItem.vb.mapViewToScene(pg.Point(5,0)).toPoint()
- pos2 = pos - QtCore.QPoint(50, 50)
+ pos = plt.plotItem.vb.mapViewToScene(pg.Point(5,0))
+ pos2 = pos - QtCore.QPointF(50, 50)
mouseMove(plt, pos)
assert vline.mouseHovering is False and hline.mouseHovering is True
mouseDrag(plt, pos, pos2, QtCore.Qt.LeftButton)
@@ -90,8 +90,8 @@ def test_mouseInteraction():
assert abs(hline.value() - plt.plotItem.vb.mapSceneToView(pos2).y()) <= px
# test non-interactive line
- pos = plt.plotItem.vb.mapViewToScene(pg.Point(5,-1)).toPoint()
- pos2 = pos - QtCore.QPoint(50, 50)
+ pos = plt.plotItem.vb.mapViewToScene(pg.Point(5,-1))
+ pos2 = pos - QtCore.QPointF(50, 50)
mouseMove(plt, pos)
assert hline2.mouseHovering == False
mouseDrag(plt, pos, pos2, QtCore.Qt.LeftButton)
diff --git a/pyqtgraph/graphicsItems/tests/test_LegendItem.py b/pyqtgraph/graphicsItems/tests/test_LegendItem.py
index f9647024..080651fc 100644
--- a/pyqtgraph/graphicsItems/tests/test_LegendItem.py
+++ b/pyqtgraph/graphicsItems/tests/test_LegendItem.py
@@ -1,9 +1,7 @@
-import pytest
import pyqtgraph as pg
-
def test_legend_item_basics():
- app = pg.mkQApp()
+ pg.mkQApp()
legend = pg.LegendItem()
@@ -21,6 +19,7 @@ def test_legend_item_basics():
assert legend.labelTextSize() == '9pt'
assert legend.brush() == pg.mkBrush(None)
assert legend.pen() == pg.mkPen(None)
+ assert legend.sampleType is pg.ItemSample
# Set brush
# ----------------------------------------------------
diff --git a/pyqtgraph/graphicsItems/tests/test_NonUniformImage.py b/pyqtgraph/graphicsItems/tests/test_NonUniformImage.py
new file mode 100644
index 00000000..fbedef15
--- /dev/null
+++ b/pyqtgraph/graphicsItems/tests/test_NonUniformImage.py
@@ -0,0 +1,104 @@
+import numpy as np
+import pyqtgraph as pg
+from pyqtgraph.Qt import QtTest
+from pyqtgraph.graphicsItems.NonUniformImage import NonUniformImage
+from pyqtgraph.tests import assertImageApproved
+from pyqtgraph.colormap import ColorMap
+import pyqtgraph.functions as fn
+import pytest
+
+app = pg.mkQApp()
+
+
+def test_NonUniformImage_scale_dimensions():
+
+ x = [1.0, 3.0, 10.0]
+ y = [1.0, 2.0, 4.0]
+ X, Y = np.meshgrid(x, y, indexing='ij')
+ Z = X * Y
+
+ for args in [(Z, y, Z), (x, Z, Z)]:
+ with pytest.raises(Exception) as ex:
+ NonUniformImage(*args)
+ assert "x and y must be 1-d arrays." in str(ex)
+
+
+def test_NonUniformImage_scale_monotonicity():
+
+ x = [1.0, 0.0, 10.0]
+ y = [1.0, 2.0, 4.0]
+ X, Y = np.meshgrid(x, y, indexing='ij')
+ Z = X * Y
+
+ for args in [(x, y, Z), (y, x, Z)]:
+ with pytest.raises(Exception) as ex:
+ NonUniformImage(*args)
+ assert "The values in x and y must be monotonically increasing." in str(ex)
+
+
+def test_NonUniformImage_data_dimensions():
+
+ x = [1.0, 3.0, 10.0]
+ y = [1.0, 2.0, 4.0]
+
+ with pytest.raises(Exception) as ex:
+ NonUniformImage(x, y, x)
+ assert "The length of x and y must match the shape of z." in str(ex)
+
+
+def test_NonUniformImage_lut():
+
+ window = pg.GraphicsWindow()
+ viewbox = pg.ViewBox()
+ window.setCentralWidget(viewbox)
+ window.resize(200, 200)
+ window.show()
+
+ x = [1.0, 3.0, 10.0]
+ y = [1.0, 2.0, 4.0]
+ X, Y = np.meshgrid(x, y, indexing='ij')
+ Z = X * Y
+
+ image = NonUniformImage(x, y, Z, border=fn.mkPen('g'))
+ viewbox.addItem(image)
+
+ lut = pg.HistogramLUTItem()
+ window.addItem(lut)
+
+ image.setLookupTable(lut, autoLevel=True)
+
+ h = image.getHistogram()
+ lut.plot.setData(*h)
+
+ QtTest.QTest.qWaitForWindowShown(window)
+ QtTest.QTest.qWait(100)
+
+ assertImageApproved(window, 'nonuniform_image/lut-3x3')
+
+
+def test_NonUniformImage_colormap():
+
+ window = pg.GraphicsWindow()
+ viewbox = pg.ViewBox()
+ window.setCentralWidget(viewbox)
+ window.resize(200, 200)
+ window.show()
+
+ x = [1.0, 3.0, 10.0]
+ y = [1.0, 2.0, 4.0]
+ X, Y = np.meshgrid(x, y, indexing='ij')
+ Z = X * Y
+
+ Z[:, 0] = [np.NINF, np.NAN, np.PINF]
+
+ image = NonUniformImage(x, y, Z, border=fn.mkPen('g'))
+
+ cmap = ColorMap(pos=[0.0, 1.0], color=[(0.0, 0.0, 0.0, 1.0), (1.0, 1.0, 1.0, 1.0)], mode='rgb')
+ image.setColorMap(cmap)
+
+ viewbox.addItem(image)
+
+ QtTest.QTest.qWaitForWindowShown(window)
+ QtTest.QTest.qWait(100)
+
+ assertImageApproved(window, 'nonuniform_image/colormap-3x3')
diff --git a/pyqtgraph/icons/__init__.py b/pyqtgraph/icons/__init__.py
new file mode 100644
index 00000000..7842d8a9
--- /dev/null
+++ b/pyqtgraph/icons/__init__.py
@@ -0,0 +1,38 @@
+import os.path as op
+
+from ..Qt import QtGui
+
+__all__ = ['getGraphIcon']
+
+_ICON_REGISTRY = {}
+
+
+class GraphIcon:
+ """An icon place holder for lazy loading of QIcons"""
+
+ def __init__(self, path):
+ self._path = path
+ self._icon = None
+ name = path.split('.')[0]
+ _ICON_REGISTRY[name] = self
+
+ @property
+ def qicon(self):
+ if self._icon is None:
+ self._icon = QtGui.QIcon(op.join(op.dirname(__file__), self._path))
+
+ return self._icon
+
+
+def getGraphIcon(name):
+ """Return a `PyQtGraph` icon from the registry by `name`"""
+ icon = _ICON_REGISTRY[name]
+ if isinstance(icon, GraphIcon):
+ icon = icon.qicon
+ _ICON_REGISTRY[name] = icon
+
+ return icon
+
+
+# Note: List all graph icons here ...
+invisibleEye = GraphIcon("invisibleEye.svg")
diff --git a/pyqtgraph/icons/invisibleEye.svg b/pyqtgraph/icons/invisibleEye.svg
new file mode 100644
index 00000000..5a678328
--- /dev/null
+++ b/pyqtgraph/icons/invisibleEye.svg
@@ -0,0 +1,35 @@
+
+
diff --git a/pyqtgraph/imageview/ImageView.py b/pyqtgraph/imageview/ImageView.py
index c8974fa5..4d438289 100644
--- a/pyqtgraph/imageview/ImageView.py
+++ b/pyqtgraph/imageview/ImageView.py
@@ -16,14 +16,9 @@ import os, sys
import numpy as np
from ..Qt import QtCore, QtGui, QT_LIB
-if QT_LIB == 'PySide':
- from .ImageViewTemplate_pyside import *
-elif QT_LIB == 'PySide2':
- from .ImageViewTemplate_pyside2 import *
-elif QT_LIB == 'PyQt5':
- from .ImageViewTemplate_pyqt5 import *
-else:
- from .ImageViewTemplate_pyqt import *
+import importlib
+ui_template = importlib.import_module(
+ f'.ImageViewTemplate_{QT_LIB.lower()}', package=__package__)
from ..graphicsItems.ImageItem import *
from ..graphicsItems.ROI import *
@@ -42,6 +37,7 @@ try:
except ImportError:
from numpy import nanmin, nanmax
+translate = QtCore.QCoreApplication.translate
class PlotROI(ROI):
def __init__(self, size):
@@ -126,7 +122,7 @@ class ImageView(QtGui.QWidget):
self.image = None
self.axes = {}
self.imageDisp = None
- self.ui = Ui_Form()
+ self.ui = ui_template.Ui_Form()
self.ui.setupUi(self)
self.scene = self.ui.graphicsView.scene()
self.ui.histogram.setLevelMode(levelMode)
@@ -455,7 +451,7 @@ class ImageView(QtGui.QWidget):
self.keysPressed[ev.key()] = 1
self.evalKeyState()
else:
- QtGui.QWidget.keyPressEvent(self, ev)
+ super().keyPressEvent(ev)
def keyReleaseEvent(self, ev):
if ev.key() in [QtCore.Qt.Key_Space, QtCore.Qt.Key_Home, QtCore.Qt.Key_End]:
@@ -470,7 +466,7 @@ class ImageView(QtGui.QWidget):
self.keysPressed = {}
self.evalKeyState()
else:
- QtGui.QWidget.keyReleaseEvent(self, ev)
+ super().keyReleaseEvent(ev)
def evalKeyState(self):
if len(self.keysPressed) == 1:
@@ -822,11 +818,11 @@ class ImageView(QtGui.QWidget):
def buildMenu(self):
self.menu = QtGui.QMenu()
- self.normAction = QtGui.QAction("Normalization", self.menu)
+ self.normAction = QtGui.QAction(translate("ImageView", "Normalization"), self.menu)
self.normAction.setCheckable(True)
self.normAction.toggled.connect(self.normToggled)
self.menu.addAction(self.normAction)
- self.exportAction = QtGui.QAction("Export", self.menu)
+ self.exportAction = QtGui.QAction(translate("ImageView", "Export"), self.menu)
self.exportAction.triggered.connect(self.exportClicked)
self.menu.addAction(self.exportAction)
diff --git a/pyqtgraph/imageview/ImageViewTemplate.ui b/pyqtgraph/imageview/ImageViewTemplate.ui
index ece77864..9c2bd9c5 100644
--- a/pyqtgraph/imageview/ImageViewTemplate.ui
+++ b/pyqtgraph/imageview/ImageViewTemplate.ui
@@ -116,7 +116,6 @@
- 75
true
@@ -129,7 +128,6 @@
- 75
true
@@ -142,7 +140,6 @@
- 75
true
diff --git a/pyqtgraph/imageview/ImageViewTemplate_pyqt.py b/pyqtgraph/imageview/ImageViewTemplate_pyqt.py
deleted file mode 100644
index 8a34c1d8..00000000
--- a/pyqtgraph/imageview/ImageViewTemplate_pyqt.py
+++ /dev/null
@@ -1,168 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file 'ImageViewTemplate.ui'
-#
-# Created: Thu May 1 15:20:40 2014
-# by: PyQt4 UI code generator 4.10.4
-#
-# WARNING! All changes made in this file will be lost!
-
-from ..Qt import QtCore, QtGui
-
-try:
- _fromUtf8 = QtCore.QString.fromUtf8
-except AttributeError:
- def _fromUtf8(s):
- return s
-
-try:
- _encoding = QtGui.QApplication.UnicodeUTF8
- def _translate(context, text, disambig):
- return QtGui.QApplication.translate(context, text, disambig, _encoding)
-except AttributeError:
- def _translate(context, text, disambig):
- return QtGui.QApplication.translate(context, text, disambig)
-
-class Ui_Form(object):
- def setupUi(self, Form):
- Form.setObjectName(_fromUtf8("Form"))
- Form.resize(726, 588)
- self.gridLayout_3 = QtGui.QGridLayout(Form)
- self.gridLayout_3.setMargin(0)
- self.gridLayout_3.setSpacing(0)
- self.gridLayout_3.setObjectName(_fromUtf8("gridLayout_3"))
- self.splitter = QtGui.QSplitter(Form)
- self.splitter.setOrientation(QtCore.Qt.Vertical)
- self.splitter.setObjectName(_fromUtf8("splitter"))
- self.layoutWidget = QtGui.QWidget(self.splitter)
- self.layoutWidget.setObjectName(_fromUtf8("layoutWidget"))
- self.gridLayout = QtGui.QGridLayout(self.layoutWidget)
- self.gridLayout.setSpacing(0)
- self.gridLayout.setMargin(0)
- self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
- self.graphicsView = GraphicsView(self.layoutWidget)
- self.graphicsView.setObjectName(_fromUtf8("graphicsView"))
- self.gridLayout.addWidget(self.graphicsView, 0, 0, 2, 1)
- self.histogram = HistogramLUTWidget(self.layoutWidget)
- self.histogram.setObjectName(_fromUtf8("histogram"))
- self.gridLayout.addWidget(self.histogram, 0, 1, 1, 2)
- self.roiBtn = QtGui.QPushButton(self.layoutWidget)
- sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(1)
- sizePolicy.setHeightForWidth(self.roiBtn.sizePolicy().hasHeightForWidth())
- self.roiBtn.setSizePolicy(sizePolicy)
- self.roiBtn.setCheckable(True)
- self.roiBtn.setObjectName(_fromUtf8("roiBtn"))
- self.gridLayout.addWidget(self.roiBtn, 1, 1, 1, 1)
- self.menuBtn = QtGui.QPushButton(self.layoutWidget)
- sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(1)
- sizePolicy.setHeightForWidth(self.menuBtn.sizePolicy().hasHeightForWidth())
- self.menuBtn.setSizePolicy(sizePolicy)
- self.menuBtn.setObjectName(_fromUtf8("menuBtn"))
- self.gridLayout.addWidget(self.menuBtn, 1, 2, 1, 1)
- self.roiPlot = PlotWidget(self.splitter)
- sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.roiPlot.sizePolicy().hasHeightForWidth())
- self.roiPlot.setSizePolicy(sizePolicy)
- self.roiPlot.setMinimumSize(QtCore.QSize(0, 40))
- self.roiPlot.setObjectName(_fromUtf8("roiPlot"))
- self.gridLayout_3.addWidget(self.splitter, 0, 0, 1, 1)
- self.normGroup = QtGui.QGroupBox(Form)
- self.normGroup.setObjectName(_fromUtf8("normGroup"))
- self.gridLayout_2 = QtGui.QGridLayout(self.normGroup)
- self.gridLayout_2.setMargin(0)
- self.gridLayout_2.setSpacing(0)
- self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2"))
- self.normSubtractRadio = QtGui.QRadioButton(self.normGroup)
- self.normSubtractRadio.setObjectName(_fromUtf8("normSubtractRadio"))
- self.gridLayout_2.addWidget(self.normSubtractRadio, 0, 2, 1, 1)
- self.normDivideRadio = QtGui.QRadioButton(self.normGroup)
- self.normDivideRadio.setChecked(False)
- self.normDivideRadio.setObjectName(_fromUtf8("normDivideRadio"))
- self.gridLayout_2.addWidget(self.normDivideRadio, 0, 1, 1, 1)
- self.label_5 = QtGui.QLabel(self.normGroup)
- font = QtGui.QFont()
- font.setBold(True)
- font.setWeight(75)
- self.label_5.setFont(font)
- self.label_5.setObjectName(_fromUtf8("label_5"))
- self.gridLayout_2.addWidget(self.label_5, 0, 0, 1, 1)
- self.label_3 = QtGui.QLabel(self.normGroup)
- font = QtGui.QFont()
- font.setBold(True)
- font.setWeight(75)
- self.label_3.setFont(font)
- self.label_3.setObjectName(_fromUtf8("label_3"))
- self.gridLayout_2.addWidget(self.label_3, 1, 0, 1, 1)
- self.label_4 = QtGui.QLabel(self.normGroup)
- font = QtGui.QFont()
- font.setBold(True)
- font.setWeight(75)
- self.label_4.setFont(font)
- self.label_4.setObjectName(_fromUtf8("label_4"))
- self.gridLayout_2.addWidget(self.label_4, 2, 0, 1, 1)
- self.normROICheck = QtGui.QCheckBox(self.normGroup)
- self.normROICheck.setObjectName(_fromUtf8("normROICheck"))
- self.gridLayout_2.addWidget(self.normROICheck, 1, 1, 1, 1)
- self.normXBlurSpin = QtGui.QDoubleSpinBox(self.normGroup)
- self.normXBlurSpin.setObjectName(_fromUtf8("normXBlurSpin"))
- self.gridLayout_2.addWidget(self.normXBlurSpin, 2, 2, 1, 1)
- self.label_8 = QtGui.QLabel(self.normGroup)
- self.label_8.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
- self.label_8.setObjectName(_fromUtf8("label_8"))
- self.gridLayout_2.addWidget(self.label_8, 2, 1, 1, 1)
- self.label_9 = QtGui.QLabel(self.normGroup)
- self.label_9.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
- self.label_9.setObjectName(_fromUtf8("label_9"))
- self.gridLayout_2.addWidget(self.label_9, 2, 3, 1, 1)
- self.normYBlurSpin = QtGui.QDoubleSpinBox(self.normGroup)
- self.normYBlurSpin.setObjectName(_fromUtf8("normYBlurSpin"))
- self.gridLayout_2.addWidget(self.normYBlurSpin, 2, 4, 1, 1)
- self.label_10 = QtGui.QLabel(self.normGroup)
- self.label_10.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
- self.label_10.setObjectName(_fromUtf8("label_10"))
- self.gridLayout_2.addWidget(self.label_10, 2, 5, 1, 1)
- self.normOffRadio = QtGui.QRadioButton(self.normGroup)
- self.normOffRadio.setChecked(True)
- self.normOffRadio.setObjectName(_fromUtf8("normOffRadio"))
- self.gridLayout_2.addWidget(self.normOffRadio, 0, 3, 1, 1)
- self.normTimeRangeCheck = QtGui.QCheckBox(self.normGroup)
- self.normTimeRangeCheck.setObjectName(_fromUtf8("normTimeRangeCheck"))
- self.gridLayout_2.addWidget(self.normTimeRangeCheck, 1, 3, 1, 1)
- self.normFrameCheck = QtGui.QCheckBox(self.normGroup)
- self.normFrameCheck.setObjectName(_fromUtf8("normFrameCheck"))
- self.gridLayout_2.addWidget(self.normFrameCheck, 1, 2, 1, 1)
- self.normTBlurSpin = QtGui.QDoubleSpinBox(self.normGroup)
- self.normTBlurSpin.setObjectName(_fromUtf8("normTBlurSpin"))
- self.gridLayout_2.addWidget(self.normTBlurSpin, 2, 6, 1, 1)
- self.gridLayout_3.addWidget(self.normGroup, 1, 0, 1, 1)
-
- self.retranslateUi(Form)
- QtCore.QMetaObject.connectSlotsByName(Form)
-
- def retranslateUi(self, Form):
- Form.setWindowTitle(_translate("Form", "PyQtGraph", None))
- self.roiBtn.setText(_translate("Form", "ROI", None))
- self.menuBtn.setText(_translate("Form", "Menu", None))
- self.normGroup.setTitle(_translate("Form", "Normalization", None))
- self.normSubtractRadio.setText(_translate("Form", "Subtract", None))
- self.normDivideRadio.setText(_translate("Form", "Divide", None))
- self.label_5.setText(_translate("Form", "Operation:", None))
- self.label_3.setText(_translate("Form", "Mean:", None))
- self.label_4.setText(_translate("Form", "Blur:", None))
- self.normROICheck.setText(_translate("Form", "ROI", None))
- self.label_8.setText(_translate("Form", "X", None))
- self.label_9.setText(_translate("Form", "Y", None))
- self.label_10.setText(_translate("Form", "T", None))
- self.normOffRadio.setText(_translate("Form", "Off", None))
- self.normTimeRangeCheck.setText(_translate("Form", "Time range", None))
- self.normFrameCheck.setText(_translate("Form", "Frame", None))
-
-from ..widgets.HistogramLUTWidget import HistogramLUTWidget
-from ..widgets.GraphicsView import GraphicsView
-from ..widgets.PlotWidget import PlotWidget
diff --git a/pyqtgraph/imageview/ImageViewTemplate_pyside.py b/pyqtgraph/imageview/ImageViewTemplate_pyqt6.py
similarity index 52%
rename from pyqtgraph/imageview/ImageViewTemplate_pyside.py
rename to pyqtgraph/imageview/ImageViewTemplate_pyqt6.py
index 9980e2ba..c27aa232 100644
--- a/pyqtgraph/imageview/ImageViewTemplate_pyside.py
+++ b/pyqtgraph/imageview/ImageViewTemplate_pyqt6.py
@@ -1,30 +1,30 @@
-# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file 'ImageViewTemplate.ui'
+# Form implementation generated from reading ui file 'pyqtgraph\imageview\ImageViewTemplate.ui'
#
-# Created: Thu May 1 15:20:42 2014
-# by: pyside-uic 0.2.15 running on PySide 1.2.1
+# Created by: PyQt6 UI code generator 6.0.0
#
-# WARNING! All changes made in this file will be lost!
+# 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
-from PySide import QtCore, QtGui
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(726, 588)
- self.gridLayout_3 = QtGui.QGridLayout(Form)
+ self.gridLayout_3 = QtWidgets.QGridLayout(Form)
self.gridLayout_3.setContentsMargins(0, 0, 0, 0)
self.gridLayout_3.setSpacing(0)
self.gridLayout_3.setObjectName("gridLayout_3")
- self.splitter = QtGui.QSplitter(Form)
- self.splitter.setOrientation(QtCore.Qt.Vertical)
+ self.splitter = QtWidgets.QSplitter(Form)
+ self.splitter.setOrientation(QtCore.Qt.Orientations.Vertical)
self.splitter.setObjectName("splitter")
- self.layoutWidget = QtGui.QWidget(self.splitter)
+ self.layoutWidget = QtWidgets.QWidget(self.splitter)
self.layoutWidget.setObjectName("layoutWidget")
- self.gridLayout = QtGui.QGridLayout(self.layoutWidget)
- self.gridLayout.setSpacing(0)
+ self.gridLayout = QtWidgets.QGridLayout(self.layoutWidget)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout.setSpacing(0)
self.gridLayout.setObjectName("gridLayout")
self.graphicsView = GraphicsView(self.layoutWidget)
self.graphicsView.setObjectName("graphicsView")
@@ -32,8 +32,8 @@ class Ui_Form(object):
self.histogram = HistogramLUTWidget(self.layoutWidget)
self.histogram.setObjectName("histogram")
self.gridLayout.addWidget(self.histogram, 0, 1, 1, 2)
- self.roiBtn = QtGui.QPushButton(self.layoutWidget)
- sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
+ self.roiBtn = QtWidgets.QPushButton(self.layoutWidget)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(1)
sizePolicy.setHeightForWidth(self.roiBtn.sizePolicy().hasHeightForWidth())
@@ -41,8 +41,8 @@ class Ui_Form(object):
self.roiBtn.setCheckable(True)
self.roiBtn.setObjectName("roiBtn")
self.gridLayout.addWidget(self.roiBtn, 1, 1, 1, 1)
- self.menuBtn = QtGui.QPushButton(self.layoutWidget)
- sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
+ self.menuBtn = QtWidgets.QPushButton(self.layoutWidget)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(1)
sizePolicy.setHeightForWidth(self.menuBtn.sizePolicy().hasHeightForWidth())
@@ -50,7 +50,7 @@ class Ui_Form(object):
self.menuBtn.setObjectName("menuBtn")
self.gridLayout.addWidget(self.menuBtn, 1, 2, 1, 1)
self.roiPlot = PlotWidget(self.splitter)
- sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
+ sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.roiPlot.sizePolicy().hasHeightForWidth())
@@ -58,72 +58,69 @@ class Ui_Form(object):
self.roiPlot.setMinimumSize(QtCore.QSize(0, 40))
self.roiPlot.setObjectName("roiPlot")
self.gridLayout_3.addWidget(self.splitter, 0, 0, 1, 1)
- self.normGroup = QtGui.QGroupBox(Form)
+ self.normGroup = QtWidgets.QGroupBox(Form)
self.normGroup.setObjectName("normGroup")
- self.gridLayout_2 = QtGui.QGridLayout(self.normGroup)
+ self.gridLayout_2 = QtWidgets.QGridLayout(self.normGroup)
self.gridLayout_2.setContentsMargins(0, 0, 0, 0)
self.gridLayout_2.setSpacing(0)
self.gridLayout_2.setObjectName("gridLayout_2")
- self.normSubtractRadio = QtGui.QRadioButton(self.normGroup)
+ self.normSubtractRadio = QtWidgets.QRadioButton(self.normGroup)
self.normSubtractRadio.setObjectName("normSubtractRadio")
self.gridLayout_2.addWidget(self.normSubtractRadio, 0, 2, 1, 1)
- self.normDivideRadio = QtGui.QRadioButton(self.normGroup)
+ self.normDivideRadio = QtWidgets.QRadioButton(self.normGroup)
self.normDivideRadio.setChecked(False)
self.normDivideRadio.setObjectName("normDivideRadio")
self.gridLayout_2.addWidget(self.normDivideRadio, 0, 1, 1, 1)
- self.label_5 = QtGui.QLabel(self.normGroup)
+ self.label_5 = QtWidgets.QLabel(self.normGroup)
font = QtGui.QFont()
- font.setWeight(75)
font.setBold(True)
self.label_5.setFont(font)
self.label_5.setObjectName("label_5")
self.gridLayout_2.addWidget(self.label_5, 0, 0, 1, 1)
- self.label_3 = QtGui.QLabel(self.normGroup)
+ self.label_3 = QtWidgets.QLabel(self.normGroup)
font = QtGui.QFont()
- font.setWeight(75)
font.setBold(True)
self.label_3.setFont(font)
self.label_3.setObjectName("label_3")
self.gridLayout_2.addWidget(self.label_3, 1, 0, 1, 1)
- self.label_4 = QtGui.QLabel(self.normGroup)
+ self.label_4 = QtWidgets.QLabel(self.normGroup)
font = QtGui.QFont()
- font.setWeight(75)
font.setBold(True)
self.label_4.setFont(font)
self.label_4.setObjectName("label_4")
self.gridLayout_2.addWidget(self.label_4, 2, 0, 1, 1)
- self.normROICheck = QtGui.QCheckBox(self.normGroup)
+ self.normROICheck = QtWidgets.QCheckBox(self.normGroup)
self.normROICheck.setObjectName("normROICheck")
self.gridLayout_2.addWidget(self.normROICheck, 1, 1, 1, 1)
- self.normXBlurSpin = QtGui.QDoubleSpinBox(self.normGroup)
+ self.normXBlurSpin = QtWidgets.QDoubleSpinBox(self.normGroup)
self.normXBlurSpin.setObjectName("normXBlurSpin")
self.gridLayout_2.addWidget(self.normXBlurSpin, 2, 2, 1, 1)
- self.label_8 = QtGui.QLabel(self.normGroup)
- self.label_8.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
+ self.label_8 = QtWidgets.QLabel(self.normGroup)
+ self.label_8.setAlignment(QtCore.Qt.Alignment.AlignRight|QtCore.Qt.Alignment.AlignTrailing|QtCore.Qt.Alignment.AlignVCenter)
self.label_8.setObjectName("label_8")
self.gridLayout_2.addWidget(self.label_8, 2, 1, 1, 1)
- self.label_9 = QtGui.QLabel(self.normGroup)
- self.label_9.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
+ self.label_9 = QtWidgets.QLabel(self.normGroup)
+ self.label_9.setAlignment(QtCore.Qt.Alignment.AlignRight|QtCore.Qt.Alignment.AlignTrailing|QtCore.Qt.Alignment.AlignVCenter)
self.label_9.setObjectName("label_9")
self.gridLayout_2.addWidget(self.label_9, 2, 3, 1, 1)
- self.normYBlurSpin = QtGui.QDoubleSpinBox(self.normGroup)
+ self.normYBlurSpin = QtWidgets.QDoubleSpinBox(self.normGroup)
self.normYBlurSpin.setObjectName("normYBlurSpin")
self.gridLayout_2.addWidget(self.normYBlurSpin, 2, 4, 1, 1)
- self.label_10 = QtGui.QLabel(self.normGroup)
- self.label_10.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
+ self.label_10 = QtWidgets.QLabel(self.normGroup)
+ self.label_10.setAlignment(QtCore.Qt.Alignment.AlignRight|QtCore.Qt.Alignment.AlignTrailing|QtCore.Qt.Alignment.AlignVCenter)
self.label_10.setObjectName("label_10")
self.gridLayout_2.addWidget(self.label_10, 2, 5, 1, 1)
- self.normOffRadio = QtGui.QRadioButton(self.normGroup)
+ self.normOffRadio = QtWidgets.QRadioButton(self.normGroup)
self.normOffRadio.setChecked(True)
self.normOffRadio.setObjectName("normOffRadio")
self.gridLayout_2.addWidget(self.normOffRadio, 0, 3, 1, 1)
- self.normTimeRangeCheck = QtGui.QCheckBox(self.normGroup)
+ self.normTimeRangeCheck = QtWidgets.QCheckBox(self.normGroup)
self.normTimeRangeCheck.setObjectName("normTimeRangeCheck")
self.gridLayout_2.addWidget(self.normTimeRangeCheck, 1, 3, 1, 1)
- self.normFrameCheck = QtGui.QCheckBox(self.normGroup)
+ self.normFrameCheck = QtWidgets.QCheckBox(self.normGroup)
self.normFrameCheck.setObjectName("normFrameCheck")
self.gridLayout_2.addWidget(self.normFrameCheck, 1, 2, 1, 1)
- self.normTBlurSpin = QtGui.QDoubleSpinBox(self.normGroup)
+ self.normTBlurSpin = QtWidgets.QDoubleSpinBox(self.normGroup)
self.normTBlurSpin.setObjectName("normTBlurSpin")
self.gridLayout_2.addWidget(self.normTBlurSpin, 2, 6, 1, 1)
self.gridLayout_3.addWidget(self.normGroup, 1, 0, 1, 1)
@@ -132,23 +129,23 @@ class Ui_Form(object):
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
- Form.setWindowTitle(QtGui.QApplication.translate("Form", "PyQtGraph", None, QtGui.QApplication.UnicodeUTF8))
- self.roiBtn.setText(QtGui.QApplication.translate("Form", "ROI", None, QtGui.QApplication.UnicodeUTF8))
- self.menuBtn.setText(QtGui.QApplication.translate("Form", "Menu", None, QtGui.QApplication.UnicodeUTF8))
- self.normGroup.setTitle(QtGui.QApplication.translate("Form", "Normalization", None, QtGui.QApplication.UnicodeUTF8))
- self.normSubtractRadio.setText(QtGui.QApplication.translate("Form", "Subtract", None, QtGui.QApplication.UnicodeUTF8))
- self.normDivideRadio.setText(QtGui.QApplication.translate("Form", "Divide", None, QtGui.QApplication.UnicodeUTF8))
- self.label_5.setText(QtGui.QApplication.translate("Form", "Operation:", None, QtGui.QApplication.UnicodeUTF8))
- self.label_3.setText(QtGui.QApplication.translate("Form", "Mean:", None, QtGui.QApplication.UnicodeUTF8))
- self.label_4.setText(QtGui.QApplication.translate("Form", "Blur:", None, QtGui.QApplication.UnicodeUTF8))
- self.normROICheck.setText(QtGui.QApplication.translate("Form", "ROI", None, QtGui.QApplication.UnicodeUTF8))
- self.label_8.setText(QtGui.QApplication.translate("Form", "X", None, QtGui.QApplication.UnicodeUTF8))
- self.label_9.setText(QtGui.QApplication.translate("Form", "Y", None, QtGui.QApplication.UnicodeUTF8))
- self.label_10.setText(QtGui.QApplication.translate("Form", "T", None, QtGui.QApplication.UnicodeUTF8))
- self.normOffRadio.setText(QtGui.QApplication.translate("Form", "Off", None, QtGui.QApplication.UnicodeUTF8))
- self.normTimeRangeCheck.setText(QtGui.QApplication.translate("Form", "Time range", None, QtGui.QApplication.UnicodeUTF8))
- self.normFrameCheck.setText(QtGui.QApplication.translate("Form", "Frame", None, QtGui.QApplication.UnicodeUTF8))
-
-from ..widgets.HistogramLUTWidget import HistogramLUTWidget
+ _translate = QtCore.QCoreApplication.translate
+ Form.setWindowTitle(_translate("Form", "PyQtGraph"))
+ self.roiBtn.setText(_translate("Form", "ROI"))
+ self.menuBtn.setText(_translate("Form", "Menu"))
+ self.normGroup.setTitle(_translate("Form", "Normalization"))
+ self.normSubtractRadio.setText(_translate("Form", "Subtract"))
+ self.normDivideRadio.setText(_translate("Form", "Divide"))
+ self.label_5.setText(_translate("Form", "Operation:"))
+ self.label_3.setText(_translate("Form", "Mean:"))
+ self.label_4.setText(_translate("Form", "Blur:"))
+ self.normROICheck.setText(_translate("Form", "ROI"))
+ self.label_8.setText(_translate("Form", "X"))
+ self.label_9.setText(_translate("Form", "Y"))
+ self.label_10.setText(_translate("Form", "T"))
+ self.normOffRadio.setText(_translate("Form", "Off"))
+ self.normTimeRangeCheck.setText(_translate("Form", "Time range"))
+ self.normFrameCheck.setText(_translate("Form", "Frame"))
from ..widgets.GraphicsView import GraphicsView
+from ..widgets.HistogramLUTWidget import HistogramLUTWidget
from ..widgets.PlotWidget import PlotWidget
diff --git a/pyqtgraph/imageview/ImageViewTemplate_pyside6.py b/pyqtgraph/imageview/ImageViewTemplate_pyside6.py
new file mode 100644
index 00000000..e26e6024
--- /dev/null
+++ b/pyqtgraph/imageview/ImageViewTemplate_pyside6.py
@@ -0,0 +1,197 @@
+# -*- coding: utf-8 -*-
+
+################################################################################
+## Form generated from reading UI file 'ImageViewTemplate.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 ..widgets.PlotWidget import PlotWidget
+from ..widgets.GraphicsView import GraphicsView
+from ..widgets.HistogramLUTWidget import HistogramLUTWidget
+
+
+class Ui_Form(object):
+ def setupUi(self, Form):
+ if not Form.objectName():
+ Form.setObjectName(u"Form")
+ Form.resize(726, 588)
+ self.gridLayout_3 = QGridLayout(Form)
+ self.gridLayout_3.setSpacing(0)
+ self.gridLayout_3.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_3.setObjectName(u"gridLayout_3")
+ self.splitter = QSplitter(Form)
+ self.splitter.setObjectName(u"splitter")
+ self.splitter.setOrientation(Qt.Vertical)
+ self.layoutWidget = QWidget(self.splitter)
+ self.layoutWidget.setObjectName(u"layoutWidget")
+ self.gridLayout = QGridLayout(self.layoutWidget)
+ self.gridLayout.setSpacing(0)
+ self.gridLayout.setObjectName(u"gridLayout")
+ self.gridLayout.setContentsMargins(0, 0, 0, 0)
+ self.graphicsView = GraphicsView(self.layoutWidget)
+ self.graphicsView.setObjectName(u"graphicsView")
+
+ self.gridLayout.addWidget(self.graphicsView, 0, 0, 2, 1)
+
+ self.histogram = HistogramLUTWidget(self.layoutWidget)
+ self.histogram.setObjectName(u"histogram")
+
+ self.gridLayout.addWidget(self.histogram, 0, 1, 1, 2)
+
+ self.roiBtn = QPushButton(self.layoutWidget)
+ self.roiBtn.setObjectName(u"roiBtn")
+ sizePolicy = QSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
+ sizePolicy.setHorizontalStretch(0)
+ sizePolicy.setVerticalStretch(1)
+ sizePolicy.setHeightForWidth(self.roiBtn.sizePolicy().hasHeightForWidth())
+ self.roiBtn.setSizePolicy(sizePolicy)
+ self.roiBtn.setCheckable(True)
+
+ self.gridLayout.addWidget(self.roiBtn, 1, 1, 1, 1)
+
+ self.menuBtn = QPushButton(self.layoutWidget)
+ self.menuBtn.setObjectName(u"menuBtn")
+ sizePolicy.setHeightForWidth(self.menuBtn.sizePolicy().hasHeightForWidth())
+ self.menuBtn.setSizePolicy(sizePolicy)
+
+ self.gridLayout.addWidget(self.menuBtn, 1, 2, 1, 1)
+
+ self.splitter.addWidget(self.layoutWidget)
+ self.roiPlot = PlotWidget(self.splitter)
+ self.roiPlot.setObjectName(u"roiPlot")
+ sizePolicy1 = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
+ sizePolicy1.setHorizontalStretch(0)
+ sizePolicy1.setVerticalStretch(0)
+ sizePolicy1.setHeightForWidth(self.roiPlot.sizePolicy().hasHeightForWidth())
+ self.roiPlot.setSizePolicy(sizePolicy1)
+ self.roiPlot.setMinimumSize(QSize(0, 40))
+ self.splitter.addWidget(self.roiPlot)
+
+ self.gridLayout_3.addWidget(self.splitter, 0, 0, 1, 1)
+
+ self.normGroup = QGroupBox(Form)
+ self.normGroup.setObjectName(u"normGroup")
+ self.gridLayout_2 = QGridLayout(self.normGroup)
+ self.gridLayout_2.setSpacing(0)
+ self.gridLayout_2.setContentsMargins(0, 0, 0, 0)
+ self.gridLayout_2.setObjectName(u"gridLayout_2")
+ self.normSubtractRadio = QRadioButton(self.normGroup)
+ self.normSubtractRadio.setObjectName(u"normSubtractRadio")
+
+ self.gridLayout_2.addWidget(self.normSubtractRadio, 0, 2, 1, 1)
+
+ self.normDivideRadio = QRadioButton(self.normGroup)
+ self.normDivideRadio.setObjectName(u"normDivideRadio")
+ self.normDivideRadio.setChecked(False)
+
+ self.gridLayout_2.addWidget(self.normDivideRadio, 0, 1, 1, 1)
+
+ self.label_5 = QLabel(self.normGroup)
+ self.label_5.setObjectName(u"label_5")
+ font = QFont()
+ font.setBold(True)
+ self.label_5.setFont(font)
+
+ self.gridLayout_2.addWidget(self.label_5, 0, 0, 1, 1)
+
+ self.label_3 = QLabel(self.normGroup)
+ self.label_3.setObjectName(u"label_3")
+ self.label_3.setFont(font)
+
+ self.gridLayout_2.addWidget(self.label_3, 1, 0, 1, 1)
+
+ self.label_4 = QLabel(self.normGroup)
+ self.label_4.setObjectName(u"label_4")
+ self.label_4.setFont(font)
+
+ self.gridLayout_2.addWidget(self.label_4, 2, 0, 1, 1)
+
+ self.normROICheck = QCheckBox(self.normGroup)
+ self.normROICheck.setObjectName(u"normROICheck")
+
+ self.gridLayout_2.addWidget(self.normROICheck, 1, 1, 1, 1)
+
+ self.normXBlurSpin = QDoubleSpinBox(self.normGroup)
+ self.normXBlurSpin.setObjectName(u"normXBlurSpin")
+
+ self.gridLayout_2.addWidget(self.normXBlurSpin, 2, 2, 1, 1)
+
+ self.label_8 = QLabel(self.normGroup)
+ self.label_8.setObjectName(u"label_8")
+ self.label_8.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
+
+ self.gridLayout_2.addWidget(self.label_8, 2, 1, 1, 1)
+
+ self.label_9 = QLabel(self.normGroup)
+ self.label_9.setObjectName(u"label_9")
+ self.label_9.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
+
+ self.gridLayout_2.addWidget(self.label_9, 2, 3, 1, 1)
+
+ self.normYBlurSpin = QDoubleSpinBox(self.normGroup)
+ self.normYBlurSpin.setObjectName(u"normYBlurSpin")
+
+ self.gridLayout_2.addWidget(self.normYBlurSpin, 2, 4, 1, 1)
+
+ self.label_10 = QLabel(self.normGroup)
+ self.label_10.setObjectName(u"label_10")
+ self.label_10.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
+
+ self.gridLayout_2.addWidget(self.label_10, 2, 5, 1, 1)
+
+ self.normOffRadio = QRadioButton(self.normGroup)
+ self.normOffRadio.setObjectName(u"normOffRadio")
+ self.normOffRadio.setChecked(True)
+
+ self.gridLayout_2.addWidget(self.normOffRadio, 0, 3, 1, 1)
+
+ self.normTimeRangeCheck = QCheckBox(self.normGroup)
+ self.normTimeRangeCheck.setObjectName(u"normTimeRangeCheck")
+
+ self.gridLayout_2.addWidget(self.normTimeRangeCheck, 1, 3, 1, 1)
+
+ self.normFrameCheck = QCheckBox(self.normGroup)
+ self.normFrameCheck.setObjectName(u"normFrameCheck")
+
+ self.gridLayout_2.addWidget(self.normFrameCheck, 1, 2, 1, 1)
+
+ self.normTBlurSpin = QDoubleSpinBox(self.normGroup)
+ self.normTBlurSpin.setObjectName(u"normTBlurSpin")
+
+ self.gridLayout_2.addWidget(self.normTBlurSpin, 2, 6, 1, 1)
+
+
+ self.gridLayout_3.addWidget(self.normGroup, 1, 0, 1, 1)
+
+
+ self.retranslateUi(Form)
+
+ QMetaObject.connectSlotsByName(Form)
+ # setupUi
+
+ def retranslateUi(self, Form):
+ Form.setWindowTitle(QCoreApplication.translate("Form", u"PyQtGraph", None))
+ self.roiBtn.setText(QCoreApplication.translate("Form", u"ROI", None))
+ self.menuBtn.setText(QCoreApplication.translate("Form", u"Menu", None))
+ self.normGroup.setTitle(QCoreApplication.translate("Form", u"Normalization", None))
+ self.normSubtractRadio.setText(QCoreApplication.translate("Form", u"Subtract", None))
+ self.normDivideRadio.setText(QCoreApplication.translate("Form", u"Divide", None))
+ self.label_5.setText(QCoreApplication.translate("Form", u"Operation:", None))
+ self.label_3.setText(QCoreApplication.translate("Form", u"Mean:", None))
+ self.label_4.setText(QCoreApplication.translate("Form", u"Blur:", None))
+ self.normROICheck.setText(QCoreApplication.translate("Form", u"ROI", None))
+ self.label_8.setText(QCoreApplication.translate("Form", u"X", None))
+ self.label_9.setText(QCoreApplication.translate("Form", u"Y", None))
+ self.label_10.setText(QCoreApplication.translate("Form", u"T", None))
+ self.normOffRadio.setText(QCoreApplication.translate("Form", u"Off", None))
+ self.normTimeRangeCheck.setText(QCoreApplication.translate("Form", u"Time range", None))
+ self.normFrameCheck.setText(QCoreApplication.translate("Form", u"Frame", None))
+ # retranslateUi
+
diff --git a/pyqtgraph/multiprocess/bootstrap.py b/pyqtgraph/multiprocess/bootstrap.py
index d31a1ca6..a20c3e20 100644
--- a/pyqtgraph/multiprocess/bootstrap.py
+++ b/pyqtgraph/multiprocess/bootstrap.py
@@ -1,5 +1,6 @@
"""For starting up remote processes"""
import sys, pickle, os
+import importlib
if __name__ == '__main__':
if hasattr(os, 'setpgrp'):
@@ -33,12 +34,8 @@ if __name__ == '__main__':
sip.setapi(k, v)
qt_lib = opts.pop('qt_lib', None)
- if qt_lib == 'PySide':
- import PySide
- elif qt_lib == 'PySide2':
- import PySide2
- elif qt_lib == 'PyQt5':
- import PyQt5
+ if qt_lib is not None:
+ globals()[qt_lib] = importlib.import_module(qt_lib)
targetStr = opts.pop('targetStr')
try:
diff --git a/pyqtgraph/multiprocess/processes.py b/pyqtgraph/multiprocess/processes.py
index 7f40be2c..24fdebf2 100644
--- a/pyqtgraph/multiprocess/processes.py
+++ b/pyqtgraph/multiprocess/processes.py
@@ -6,7 +6,7 @@ except ImportError:
import pickle
from .remoteproxy import RemoteEventHandler, ClosedError, NoResultError, LocalObjectProxy, ObjectProxy
-from ..Qt import QT_LIB
+from ..Qt import QT_LIB, mkQApp
from ..util import cprint # color printing for debugging
@@ -451,7 +451,7 @@ def startQtEventLoop(name, port, authkey, ppid, debug=False):
app = QtGui.QApplication.instance()
#print app
if app is None:
- app = QtGui.QApplication([])
+ app = mkQApp()
app.setQuitOnLastWindowClosed(False) ## generally we want the event loop to stay open
## until it is explicitly closed by the parent process.
diff --git a/pyqtgraph/opengl/GLViewWidget.py b/pyqtgraph/opengl/GLViewWidget.py
index 8dca4ed0..d0761d57 100644
--- a/pyqtgraph/opengl/GLViewWidget.py
+++ b/pyqtgraph/opengl/GLViewWidget.py
@@ -1,4 +1,4 @@
-from ..Qt import QtCore, QtGui, QtOpenGL, QT_LIB
+from ..Qt import QtCore, QtGui, QtWidgets, QT_LIB
from OpenGL.GL import *
import OpenGL.GL.framebufferobjects as glfbo
import numpy as np
@@ -9,30 +9,45 @@ from .. import functions as fn
ShareWidget = None
-class GLViewWidget(QtOpenGL.QGLWidget):
- """
- Basic widget for displaying 3D data
+class GLViewWidget(QtWidgets.QOpenGLWidget):
+
+ def __init__(self, parent=None, devicePixelRatio=None, rotationMethod='euler'):
+ """
+ Basic widget for displaying 3D data
- Rotation/scale controls
- Axis/grid display
- Export options
- High-DPI displays: Qt5 should automatically detect the correct resolution.
- For Qt4, specify the ``devicePixelRatio`` argument when initializing the
- widget (usually this value is 1-2).
- """
-
- def __init__(self, parent=None, devicePixelRatio=None):
- global ShareWidget
+ ================ ==============================================================
+ **Arguments:**
+ parent (QObject, optional): Parent QObject. Defaults to None.
+ devicePixelRatio (float, optional): High-DPI displays Qt5 should automatically
+ detect the correct resolution. For Qt4, specify the
+ ``devicePixelRatio`` argument when initializing the widget
+ (usually this value is 1-2). Defaults to None.
+ rotationMethod (str): Mechanimsm to drive the rotation method, options are
+ 'euler' and 'quaternion'. Defaults to 'euler'.
+ ================ ==============================================================
+ """
- if ShareWidget is None:
- ## create a dummy widget to allow sharing objects (textures, shaders, etc) between views
- ShareWidget = QtOpenGL.QGLWidget()
-
- QtOpenGL.QGLWidget.__init__(self, parent, ShareWidget)
+ QtWidgets.QOpenGLWidget.__init__(self, parent)
self.setFocusPolicy(QtCore.Qt.ClickFocus)
+
+ if rotationMethod not in {"euler", "quaternion"}:
+ raise RuntimeError("Rotation method should be either 'euler' or 'quaternion'")
+
self.opts = {
- 'devicePixelRatio': devicePixelRatio
+ 'center': Vector(0,0,0), ## will always appear at the center of the widget
+ 'rotation' : QtGui.QQuaternion(1,0,0,0), ## camera rotation (quaternion:wxyz)
+ 'distance': 10.0, ## distance of camera from center
+ 'fov': 60, ## horizontal field of view in degrees
+ 'elevation': 30, ## camera's angle of elevation in degrees
+ 'azimuth': 45, ## camera's azimuthal angle in degrees
+ ## (rotation around z-axis 0 points along x-axis)
+ 'viewport': None, ## glViewport params; None == whole widget
+ 'devicePixelRatio': devicePixelRatio,
+ 'rotationMethod': rotationMethod
}
self.reset()
self.items = []
@@ -41,9 +56,41 @@ class GLViewWidget(QtOpenGL.QGLWidget):
self.keysPressed = {}
self.keyTimer = QtCore.QTimer()
self.keyTimer.timeout.connect(self.evalKeyState)
-
self.makeCurrent()
+
+
+ @property
+ def _dpiRatio(self):
+ return self.devicePixelRatioF() or 1
+
+ def _updateScreen(self, screen):
+ self._updatePixelRatio()
+ if screen is not None:
+ screen.physicalDotsPerInchChanged.connect(self._updatePixelRatio)
+ screen.logicalDotsPerInchChanged.connect(self._updatePixelRatio)
+
+ def _updatePixelRatio(self):
+ event = QtGui.QResizeEvent(self.size(), self.size())
+ self.resizeEvent(event)
+
+ def showEvent(self, event):
+ window = self.window().windowHandle()
+ window.screenChanged.connect(self._updateScreen)
+ self._updateScreen(window.screen())
+ def width(self):
+ if self._dpiRatio.is_integer():
+ return super().width()
+ else:
+ return int(super().width() * self._dpiRatio)
+
+ def height(self):
+ if self._dpiRatio.is_integer():
+ return super().height()
+ else:
+ return int(super().height() * self._dpiRatio)
+
+
def reset(self):
"""
Initialize the widget state or reset the current state to the original state.
@@ -111,10 +158,7 @@ class GLViewWidget(QtOpenGL.QGLWidget):
if dpr is not None:
return dpr
- if hasattr(QtOpenGL.QGLWidget, 'devicePixelRatio'):
- return QtOpenGL.QGLWidget.devicePixelRatio(self)
- else:
- return 1.0
+ return QtWidgets.QOpenGLWidget.devicePixelRatio(self)
def resizeGL(self, w, h):
pass
@@ -162,8 +206,12 @@ class GLViewWidget(QtOpenGL.QGLWidget):
def viewMatrix(self):
tr = QtGui.QMatrix4x4()
tr.translate( 0.0, 0.0, -self.opts['distance'])
- tr.rotate(self.opts['elevation']-90, 1, 0, 0)
- tr.rotate(self.opts['azimuth']+90, 0, 0, -1)
+ if self.opts['rotationMethod'] == 'quaternion':
+ tr.rotate(self.opts['rotation'])
+ else:
+ # default rotation method
+ tr.rotate(self.opts['elevation']-90, 1, 0, 0)
+ tr.rotate(self.opts['azimuth']+90, 0, 0, -1)
center = self.opts['center']
tr.translate(-center.x(), -center.y(), -center.z())
return tr
@@ -251,36 +299,52 @@ class GLViewWidget(QtOpenGL.QGLWidget):
glMatrixMode(GL_MODELVIEW)
glPopMatrix()
- def setCameraPosition(self, pos=None, distance=None, elevation=None, azimuth=None):
+ def setCameraPosition(self, pos=None, distance=None, elevation=None, azimuth=None, rotation=None):
if pos is not None:
self.opts['center'] = pos
if distance is not None:
self.opts['distance'] = distance
- if elevation is not None:
- self.opts['elevation'] = elevation
- if azimuth is not None:
- self.opts['azimuth'] = azimuth
+ if rotation is not None:
+ # set with quaternion
+ self.opts['rotation'] = rotation
+ else:
+ # set with elevation-azimuth, restored for compatibility
+ eu = self.opts['rotation'].toEulerAngles()
+ if azimuth is not None:
+ eu.setZ(-azimuth-90)
+ if elevation is not None:
+ eu.setX(elevation-90)
+ self.opts['rotation'] = QtGui.QQuaternion.fromEulerAngles(eu)
self.update()
def cameraPosition(self):
"""Return current position of camera based on center, dist, elevation, and azimuth"""
center = self.opts['center']
dist = self.opts['distance']
- elev = self.opts['elevation'] * np.pi/180.
- azim = self.opts['azimuth'] * np.pi/180.
-
- pos = Vector(
- center.x() + dist * np.cos(elev) * np.cos(azim),
- center.y() + dist * np.cos(elev) * np.sin(azim),
- center.z() + dist * np.sin(elev)
- )
-
+ if self.opts['rotationMethod'] == "quaternion":
+ pos = center - self.opts['rotation'].rotatedVector( Vector(0,0,dist) )
+ else:
+ # using 'euler' rotation method
+ elev = self.opts['elevation'] * np.pi / 180
+ azim = self.opts['azimuth'] * np.pi / 180
+ pos = Vector(
+ center.x() + dist * np.cos(elev) * np.cos(azim),
+ center.y() + dist * np.cos(elev) * np.sin(azim),
+ center.z() + dist * np.sin(elev)
+ )
return pos
def orbit(self, azim, elev):
"""Orbits the camera around the center position. *azim* and *elev* are given in degrees."""
- self.opts['azimuth'] += azim
- self.opts['elevation'] = np.clip(self.opts['elevation'] + elev, -90, 90)
+ if self.opts['rotationMethod'] == 'quaternion':
+ q = QtGui.QQuaternion.fromEulerAngles(
+ elev, -azim, 0
+ ) # rx-ry-rz
+ q *= self.opts['rotation']
+ self.opts['rotation'] = q
+ else: # default euler rotation method
+ self.opts['azimuth'] += azim
+ self.opts['elevation'] = np.clip(self.opts['elevation'] + elev, -90, 90)
self.update()
def pan(self, dx, dy, dz, relative='global'):
@@ -326,16 +390,29 @@ class GLViewWidget(QtOpenGL.QGLWidget):
self.opts['center'] = self.opts['center'] + xVec * xScale * dx + yVec * xScale * dy + zVec * xScale * dz
elif relative == 'view':
# pan in plane of camera
- elev = np.radians(self.opts['elevation'])
- azim = np.radians(self.opts['azimuth'])
- fov = np.radians(self.opts['fov'])
- dist = (self.opts['center'] - self.cameraPosition()).length()
- fov_factor = np.tan(fov / 2) * 2
- scale_factor = dist * fov_factor / self.width()
- z = scale_factor * np.cos(elev) * dy
- x = scale_factor * (np.sin(azim) * dx - np.sin(elev) * np.cos(azim) * dy)
- y = scale_factor * (np.cos(azim) * dx + np.sin(elev) * np.sin(azim) * dy)
- self.opts['center'] += QtGui.QVector3D(x, -y, z)
+
+ if self.opts['rotationMethod'] == 'quaternion':
+ # obtain basis vectors
+ qc = self.opts['rotation'].conjugated()
+ xv = qc.rotatedVector( Vector(1,0,0) )
+ yv = qc.rotatedVector( Vector(0,1,0) )
+ zv = qc.rotatedVector( Vector(0,0,1) )
+
+ scale_factor = self.pixelSize( self.opts['center'] )
+
+ # apply translation
+ self.opts['center'] += scale_factor * (xv*-dx + yv*dy + zv*dz)
+ else: # use default euler rotation method
+ elev = np.radians(self.opts['elevation'])
+ azim = np.radians(self.opts['azimuth'])
+ fov = np.radians(self.opts['fov'])
+ dist = (self.opts['center'] - self.cameraPosition()).length()
+ fov_factor = np.tan(fov / 2) * 2
+ scale_factor = dist * fov_factor / self.width()
+ z = scale_factor * np.cos(elev) * dy
+ x = scale_factor * (np.sin(azim) * dx - np.sin(elev) * np.cos(azim) * dy)
+ y = scale_factor * (np.cos(azim) * dx + np.sin(elev) * np.sin(azim) * dy)
+ self.opts['center'] += QtGui.QVector3D(x, -y, z)
else:
raise ValueError("relative argument must be global, view, or view-upright")
@@ -356,18 +433,19 @@ class GLViewWidget(QtOpenGL.QGLWidget):
return xDist / self.width()
def mousePressEvent(self, ev):
- self.mousePos = ev.pos()
+ self.mousePos = ev.localPos()
def mouseMoveEvent(self, ev):
- diff = ev.pos() - self.mousePos
- self.mousePos = ev.pos()
+ lpos = ev.localPos()
+ diff = lpos - self.mousePos
+ self.mousePos = lpos
if ev.buttons() == QtCore.Qt.LeftButton:
if (ev.modifiers() & QtCore.Qt.ControlModifier):
self.pan(diff.x(), diff.y(), 0, relative='view')
else:
self.orbit(-diff.x(), diff.y())
- elif ev.buttons() == QtCore.Qt.MidButton:
+ elif ev.buttons() == QtCore.Qt.MiddleButton:
if (ev.modifiers() & QtCore.Qt.ControlModifier):
self.pan(diff.x(), 0, diff.y(), relative='view-upright')
else:
diff --git a/pyqtgraph/opengl/glInfo.py b/pyqtgraph/opengl/glInfo.py
index 0c3e758a..4120e93e 100644
--- a/pyqtgraph/opengl/glInfo.py
+++ b/pyqtgraph/opengl/glInfo.py
@@ -1,16 +1,12 @@
-from ..Qt import QtCore, QtGui, QtOpenGL
+from ..Qt import QtWidgets
from OpenGL.GL import *
-app = QtGui.QApplication([])
-class GLTest(QtOpenGL.QGLWidget):
- def __init__(self):
- QtOpenGL.QGLWidget.__init__(self)
- self.makeCurrent()
+class GLTest(QtWidgets.QOpenGLWidget):
+ def initializeGL(self):
print("GL version:" + glGetString(GL_VERSION).decode("utf-8"))
print("MAX_TEXTURE_SIZE: %d" % glGetIntegerv(GL_MAX_TEXTURE_SIZE))
print("MAX_3D_TEXTURE_SIZE: %d" % glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE))
print("Extensions: " + glGetString(GL_EXTENSIONS).decode("utf-8").replace(" ", "\n"))
-GLTest()
-
-
+app = QtWidgets.QApplication([])
+GLTest().show()
diff --git a/pyqtgraph/parametertree/Parameter.py b/pyqtgraph/parametertree/Parameter.py
index b44280bb..f573fcd7 100644
--- a/pyqtgraph/parametertree/Parameter.py
+++ b/pyqtgraph/parametertree/Parameter.py
@@ -10,6 +10,11 @@ PARAM_TYPES = {}
PARAM_NAMES = {}
def registerParameterType(name, cls, override=False):
+ """Register a parameter type in the parametertree system.
+
+ This enables construction of custom Parameter classes by name in
+ :meth:`~pyqtgraph.parametertree.Parameter.create`.
+ """
global PARAM_TYPES
if name in PARAM_TYPES and not override:
raise Exception("Parameter type '%s' already exists (use override=True to replace)" % name)
diff --git a/pyqtgraph/parametertree/ParameterItem.py b/pyqtgraph/parametertree/ParameterItem.py
index 4cdbfaff..7629a933 100644
--- a/pyqtgraph/parametertree/ParameterItem.py
+++ b/pyqtgraph/parametertree/ParameterItem.py
@@ -2,6 +2,8 @@ from ..Qt import QtGui, QtCore
from ..python2_3 import asUnicode
import os, weakref, re
+translate = QtCore.QCoreApplication.translate
+
class ParameterItem(QtGui.QTreeWidgetItem):
"""
Abstract ParameterTree item.
@@ -111,9 +113,9 @@ class ParameterItem(QtGui.QTreeWidgetItem):
self.contextMenu = QtGui.QMenu() # Put in global name space to prevent garbage collection
self.contextMenu.addSeparator()
if opts.get('renamable', False):
- self.contextMenu.addAction('Rename').triggered.connect(self.editName)
+ self.contextMenu.addAction(translate("ParameterItem", 'Rename')).triggered.connect(self.editName)
if opts.get('removable', False):
- self.contextMenu.addAction("Remove").triggered.connect(self.requestRemove)
+ self.contextMenu.addAction(translate("ParameterItem", "Remove")).triggered.connect(self.requestRemove)
# context menu
context = opts.get('context', None)
diff --git a/pyqtgraph/parametertree/ParameterTree.py b/pyqtgraph/parametertree/ParameterTree.py
index 145c448c..155682c5 100644
--- a/pyqtgraph/parametertree/ParameterTree.py
+++ b/pyqtgraph/parametertree/ParameterTree.py
@@ -157,11 +157,12 @@ class ParameterTree(TreeWidget):
self.lastSel = sel[0]
if hasattr(sel[0], 'selected'):
sel[0].selected(True)
- return TreeWidget.selectionChanged(self, *args)
+ return super().selectionChanged(*args)
+ # commented out due to being unreliable
# def wheelEvent(self, ev):
# self.clearSelection()
- # return TreeWidget.wheelEvent(self, ev)
+ # return super().wheelEvent(ev)
def sizeHint(self):
w, h = 0, 0
diff --git a/pyqtgraph/parametertree/parameterTypes.py b/pyqtgraph/parametertree/parameterTypes.py
index 656c69cb..d01dd272 100644
--- a/pyqtgraph/parametertree/parameterTypes.py
+++ b/pyqtgraph/parametertree/parameterTypes.py
@@ -1,5 +1,4 @@
import os
-
from ..Qt import QtCore, QtGui
from ..python2_3 import asUnicode
from .Parameter import Parameter, registerParameterType
@@ -341,9 +340,27 @@ class EventProxy(QtCore.QObject):
class SimpleParameter(Parameter):
+ """Parameter representing a single value.
+
+ This parameter is backed by :class:`WidgetParameterItem` to represent the
+ following parameter names:
+
+ - 'int'
+ - 'float'
+ - 'bool'
+ - 'str'
+ - 'color'
+ - 'colormap'
+ """
itemClass = WidgetParameterItem
-
+
def __init__(self, *args, **kargs):
+ """Initialize the parameter.
+
+ This is normally called implicitly through :meth:`Parameter.create`.
+ The keyword arguments avaialble to :meth:`Parameter.__init__` are
+ applicable.
+ """
Parameter.__init__(self, *args, **kargs)
## override a few methods for color parameters
@@ -465,11 +482,11 @@ class GroupParameterItem(ParameterItem):
tw = self.treeWidget()
if tw is None:
return
- tw.setFirstItemColumnSpanned(self, True)
+ self.setFirstColumnSpanned(True)
if self.addItem is not None:
tw.setItemWidget(self.addItem, 0, self.addWidgetBox)
- tw.setFirstItemColumnSpanned(self.addItem, True)
-
+ self.addItem.setFirstColumnSpanned(True)
+
def addChild(self, child): ## make sure added childs are actually inserted before add btn
if self.addItem is not None:
ParameterItem.insertChild(self, self.childCount()-1, child)
@@ -590,6 +607,21 @@ class ListParameterItem(WidgetParameterItem):
class ListParameter(Parameter):
+ """Parameter with a list of acceptable values.
+
+ By default, this parameter is represtented by a :class:`ListParameterItem`,
+ displaying a combo box to select a value from the list.
+
+ In addition to the generic :class:`~pyqtgraph.parametertree.Parameter`
+ options, this parameter type accepts a ``limits`` argument specifying the
+ list of allowed values. ``values`` is an alias and may be used instead.
+
+ The values may generally be of any data type, as long as they can be
+ represented as a string. If the string representation provided is
+ undesirable, the values may be given as a dictionary mapping the desired
+ string representation to the value.
+ """
+
itemClass = ListParameterItem
def __init__(self, **opts):
@@ -605,6 +637,7 @@ class ListParameter(Parameter):
self.setLimits(opts['limits'])
def setLimits(self, limits):
+ """Change the list of allowed values."""
self.forward, self.reverse = self.mapping(limits)
Parameter.setLimits(self, limits)
@@ -634,6 +667,7 @@ registerParameterType('list', ListParameter, override=True)
class ActionParameterItem(ParameterItem):
+ """ParameterItem displaying a clickable button."""
def __init__(self, param, depth):
ParameterItem.__init__(self, param, depth)
self.layoutWidget = QtGui.QWidget()
@@ -654,7 +688,7 @@ class ActionParameterItem(ParameterItem):
if tree is None:
return
- tree.setFirstItemColumnSpanned(self, True)
+ self.setFirstColumnSpanned(True)
tree.setItemWidget(self, 0, self.layoutWidget)
def titleChanged(self):
@@ -674,7 +708,10 @@ class ActionParameterItem(ParameterItem):
self.param.activate()
class ActionParameter(Parameter):
- """Used for displaying a button within the tree."""
+ """Used for displaying a button within the tree.
+
+ ``sigActivated(self)`` is emitted when the button is clicked.
+ """
itemClass = ActionParameterItem
sigActivated = QtCore.Signal(object)
@@ -686,6 +723,8 @@ registerParameterType('action', ActionParameter, override=True)
class TextParameterItem(WidgetParameterItem):
+ """ParameterItem displaying a QTextEdit widget."""
+
def makeWidget(self):
self.hideWidget = False
self.asSubItem = True
@@ -698,7 +737,7 @@ class TextParameterItem(WidgetParameterItem):
class TextParameter(Parameter):
- """Editable string; displayed as large text box in the tree."""
+ """Editable string, displayed as large text box in the tree."""
itemClass = TextParameterItem
diff --git a/pyqtgraph/tests/image_testing.py b/pyqtgraph/tests/image_testing.py
index cfb62bb9..1245bb02 100644
--- a/pyqtgraph/tests/image_testing.py
+++ b/pyqtgraph/tests/image_testing.py
@@ -44,7 +44,7 @@ Procedure for unit-testing with images:
# pyqtgraph should be tested against. When adding or changing test images,
# create and push a new tag and update this variable. To test locally, begin
# by creating the tag in your ~/.pyqtgraph/test-data repository.
-testDataTag = 'test-data-7'
+testDataTag = 'test-data-8'
import time
@@ -212,7 +212,7 @@ def assertImageApproved(image, standardFile, message=None, **kwargs):
else:
if os.getenv('TRAVIS') is not None:
saveFailedTest(image, stdImage, standardFile, upload=True)
- elif os.getenv('AZURE') is not None:
+ elif os.getenv('CI') is not None:
standardFile = os.path.join(os.getenv("SCREENSHOT_DIR", "screenshots"), standardFile)
saveFailedTest(image, stdImage, standardFile)
print(graphstate)
@@ -257,7 +257,7 @@ def assertImageMatch(im1, im2, minCorr=None, pxThreshold=50.,
assert im1.dtype == im2.dtype
if pxCount == -1:
- if QT_LIB in {'PyQt5', 'PySide2'}:
+ if QT_LIB in {'PyQt5', 'PySide2', 'PySide6', 'PyQt6'}:
# Qt5 generates slightly different results; relax the tolerance
# until test images are updated.
pxCount = int(im1.shape[0] * im1.shape[1] * 0.01)
@@ -469,7 +469,10 @@ def getTestDataRepo():
"""
global testDataTag
- dataPath = os.path.join(os.path.expanduser('~'), '.pyqtgraph', 'test-data')
+ if os.getenv("CI"):
+ dataPath = os.path.join(os.environ["GITHUB_WORKSPACE"], '.pyqtgraph', 'test-data')
+ else:
+ dataPath = os.path.join(os.path.expanduser('~'), '.pyqtgraph', 'test-data')
gitPath = 'https://github.com/pyqtgraph/test-data'
gitbase = gitCmdBase(dataPath)
@@ -509,7 +512,7 @@ def getTestDataRepo():
if not os.path.isdir(parentPath):
os.makedirs(parentPath)
- if os.getenv('TRAVIS') is not None or os.getenv('AZURE') is not None:
+ if os.getenv('TRAVIS') is not None or os.getenv('CI') is not None:
# Create a shallow clone of the test-data repository (to avoid
# downloading more data than is necessary)
os.makedirs(dataPath)
diff --git a/pyqtgraph/tests/test_exit_crash.py b/pyqtgraph/tests/test_exit_crash.py
index 41703ce6..e5661386 100644
--- a/pyqtgraph/tests/test_exit_crash.py
+++ b/pyqtgraph/tests/test_exit_crash.py
@@ -4,7 +4,6 @@ import sys
import subprocess
import tempfile
import pyqtgraph as pg
-import six
import pytest
import textwrap
import time
diff --git a/pyqtgraph/tests/test_ref_cycles.py b/pyqtgraph/tests/test_ref_cycles.py
index 121a09e4..905173c9 100644
--- a/pyqtgraph/tests/test_ref_cycles.py
+++ b/pyqtgraph/tests/test_ref_cycles.py
@@ -6,7 +6,6 @@ Test for unwanted reference cycles
import pyqtgraph as pg
import numpy as np
import gc, weakref
-import six
import pytest
app = pg.mkQApp()
@@ -38,7 +37,7 @@ def mkrefs(*objs):
return [weakref.ref(obj) for obj in allObjs.values()]
-@pytest.mark.skipif(pg.Qt.QT_LIB in {'PySide', 'PySide2'}, reason=skipreason)
+@pytest.mark.skipif(pg.Qt.QT_LIB in {'PySide'}, reason=skipreason)
def test_PlotWidget():
def mkobjs(*args, **kwds):
w = pg.PlotWidget(*args, **kwds)
@@ -56,7 +55,7 @@ def test_PlotWidget():
for i in range(5):
assert_alldead(mkobjs())
-@pytest.mark.skipif(pg.Qt.QT_LIB in {'PySide', 'PySide2'}, reason=skipreason)
+@pytest.mark.skipif(pg.Qt.QT_LIB in {'PySide', 'PySide2', 'PySide6'}, reason=skipreason)
def test_ImageView():
def mkobjs():
iv = pg.ImageView()
@@ -69,7 +68,7 @@ def test_ImageView():
assert_alldead(mkobjs())
-@pytest.mark.skipif(pg.Qt.QT_LIB in {'PySide', 'PySide2'}, reason=skipreason)
+@pytest.mark.skipif(pg.Qt.QT_LIB in {'PySide'}, reason=skipreason)
def test_GraphicsWindow():
def mkobjs():
w = pg.GraphicsWindow()
diff --git a/pyqtgraph/tests/test_reload.py b/pyqtgraph/tests/test_reload.py
index 934d2ed2..e806100f 100644
--- a/pyqtgraph/tests/test_reload.py
+++ b/pyqtgraph/tests/test_reload.py
@@ -1,6 +1,7 @@
import tempfile, os, sys, shutil, time
import pyqtgraph as pg
import pyqtgraph.reload
+import pytest
pgpath = os.path.join(os.path.dirname(pg.__file__), '..')
@@ -41,7 +42,11 @@ def remove_cache(mod):
if os.path.isdir(cachedir):
shutil.rmtree(cachedir)
-
+@pytest.mark.skipif(
+ ((pg.Qt.QT_LIB == "PySide2" and pg.Qt.PySide2.__version__.startswith("5.15"))
+ or (pg.Qt.QT_LIB == "PySide6"))
+ and sys.version_info > (3, 9),
+ reason="Unknown Issue")
def test_reload():
py3 = sys.version_info >= (3,)
diff --git a/pyqtgraph/tests/ui_testing.py b/pyqtgraph/tests/ui_testing.py
index 4bcb7606..747aadf9 100644
--- a/pyqtgraph/tests/ui_testing.py
+++ b/pyqtgraph/tests/ui_testing.py
@@ -1,5 +1,5 @@
import time
-from ..Qt import QtCore, QtGui, QtTest, QT_LIB
+from ..Qt import QtCore, QtGui, QtTest
def resizeWindow(win, w, h, timeout=2.0):
@@ -32,8 +32,6 @@ def mousePress(widget, pos, button, modifier=None):
widget = widget.viewport()
if modifier is None:
modifier = QtCore.Qt.NoModifier
- if QT_LIB != 'PyQt5' and isinstance(pos, QtCore.QPointF):
- pos = pos.toPoint()
event = QtGui.QMouseEvent(QtCore.QEvent.MouseButtonPress, pos, button, QtCore.Qt.NoButton, modifier)
QtGui.QApplication.sendEvent(widget, event)
@@ -43,8 +41,6 @@ def mouseRelease(widget, pos, button, modifier=None):
widget = widget.viewport()
if modifier is None:
modifier = QtCore.Qt.NoModifier
- if QT_LIB != 'PyQt5' and isinstance(pos, QtCore.QPointF):
- pos = pos.toPoint()
event = QtGui.QMouseEvent(QtCore.QEvent.MouseButtonRelease, pos, button, QtCore.Qt.NoButton, modifier)
QtGui.QApplication.sendEvent(widget, event)
@@ -56,8 +52,6 @@ def mouseMove(widget, pos, buttons=None, modifier=None):
modifier = QtCore.Qt.NoModifier
if buttons is None:
buttons = QtCore.Qt.NoButton
- if QT_LIB != 'PyQt5' and isinstance(pos, QtCore.QPointF):
- pos = pos.toPoint()
event = QtGui.QMouseEvent(QtCore.QEvent.MouseMove, pos, QtCore.Qt.NoButton, buttons, modifier)
QtGui.QApplication.sendEvent(widget, event)
diff --git a/pyqtgraph/units.py b/pyqtgraph/units.py
index adf5dc55..d0f8987c 100644
--- a/pyqtgraph/units.py
+++ b/pyqtgraph/units.py
@@ -1,41 +1,41 @@
# -*- coding: utf-8 -*-
-## Very simple unit support:
-## - creates variable names like 'mV' and 'kHz'
-## - the value assigned to the variable corresponds to the scale prefix
-## (mV = 0.001)
-## - the actual units are purely cosmetic for making code clearer:
-##
-## x = 20*pA is identical to x = 20*1e-12
+# Very simple unit support:
+# - creates variable names like 'mV' and 'kHz'
+# - the value assigned to the variable corresponds to the scale prefix
+# (mV = 0.001)
+# - the actual units are purely cosmetic for making code clearer:
+#
+# x = 20*pA is identical to x = 20*1e-12
+#
+# No unicode variable names (μ,Ω) allowed until python 3, but just assigning
+# them to the globals dict doesn't error in python 2.
+import unicodedata
-## No unicode variable names (μ,Ω) allowed until python 3
-
-SI_PREFIXES = 'yzafpnum kMGTPEZY'
-UNITS = 'm,s,g,W,J,V,A,F,T,Hz,Ohm,S,N,C,px,b,B,Pa'.split(',')
+# All unicode identifiers get normalized automatically
+SI_PREFIXES = unicodedata.normalize("NFKC", u"yzafpnµm kMGTPEZY")
+UNITS = unicodedata.normalize("NFKC", u"m,s,g,W,J,V,A,F,T,Hz,Ohm,Ω,S,N,C,px,b,B,Pa").split(",")
allUnits = {}
-def addUnit(p, n):
+
+def addUnit(prefix, val):
g = globals()
- v = 1000**n
for u in UNITS:
- g[p+u] = v
- allUnits[p+u] = v
-
-for p in SI_PREFIXES:
- if p == ' ':
- p = ''
- n = 0
- elif p == 'u':
- n = -2
- else:
- n = SI_PREFIXES.index(p) - 8
-
- addUnit(p, n)
-
-cm = 0.01
-
+ g[prefix + u] = val
+ allUnits[prefix + u] = val
+for pre in SI_PREFIXES:
+ v = SI_PREFIXES.index(pre) - 8
+ if pre == " ":
+ pre = ""
+ addUnit(pre, 1000 ** v)
+addUnit("c", 0.01)
+addUnit("d", 0.1)
+addUnit("da", 10)
+addUnit("h", 100)
+# py2 compatibility
+addUnit("u", 1e-6)
def evalUnits(unitStr):
@@ -46,19 +46,19 @@ def evalUnits(unitStr):
A*s / V => ([A, s], [V,])
"""
pass
-
+
+
def formatUnits(units):
"""
Format a unit specification ([numerators,...], [denominators,...])
into a string (this is the inverse of evalUnits)
"""
pass
-
+
+
def simplify(units):
"""
Cancel units that appear in both numerator and denominator, then attempt to replace
groups of units with single units where possible (ie, J/s => W)
"""
pass
-
-
\ No newline at end of file
diff --git a/pyqtgraph/util/cupy_helper.py b/pyqtgraph/util/cupy_helper.py
new file mode 100644
index 00000000..5313bb62
--- /dev/null
+++ b/pyqtgraph/util/cupy_helper.py
@@ -0,0 +1,18 @@
+import os
+from warnings import warn
+
+from pyqtgraph import getConfigOption
+
+
+def getCupy():
+ if getConfigOption("useCupy"):
+ try:
+ import cupy
+ except ImportError:
+ warn("cupy library could not be loaded, but 'useCupy' is set.")
+ return None
+ if os.name == "nt" and cupy.cuda.runtime.runtimeGetVersion() < 11000:
+ warn("In Windows, CUDA toolkit should be version 11 or higher, or some functions may misbehave.")
+ return cupy
+ else:
+ return None
diff --git a/pyqtgraph/util/get_resolution.py b/pyqtgraph/util/get_resolution.py
index 79e17170..421afabe 100644
--- a/pyqtgraph/util/get_resolution.py
+++ b/pyqtgraph/util/get_resolution.py
@@ -1,13 +1,16 @@
from .. import mkQApp
+from ..Qt import QtGui
def test_screenInformation():
+ # a qApp is still needed, otherwise screen is None
qApp = mkQApp()
- desktop = qApp.desktop()
- resolution = desktop.screenGeometry()
- availableResolution = desktop.availableGeometry()
+ screen = QtGui.QGuiApplication.primaryScreen()
+ screens = QtGui.QGuiApplication.screens()
+ resolution = screen.size()
+ availableResolution = screen.availableSize()
print("Screen resolution: {}x{}".format(resolution.width(), resolution.height()))
print("Available geometry: {}x{}".format(availableResolution.width(), availableResolution.height()))
- print("Number of Screens: {}".format(desktop.screenCount()))
+ print("Number of Screens: {}".format(len(screens)))
return None
diff --git a/pyqtgraph/widgets/ColorButton.py b/pyqtgraph/widgets/ColorButton.py
index 43dd16f6..11a5ac14 100644
--- a/pyqtgraph/widgets/ColorButton.py
+++ b/pyqtgraph/widgets/ColorButton.py
@@ -35,7 +35,7 @@ class ColorButton(QtGui.QPushButton):
self.setMinimumWidth(15)
def paintEvent(self, ev):
- QtGui.QPushButton.paintEvent(self, ev)
+ super().paintEvent(ev)
p = QtGui.QPainter(self)
rect = self.rect().adjusted(6, 6, -6, -6)
## draw white base, then texture for indicating transparency, then actual color
diff --git a/pyqtgraph/widgets/ComboBox.py b/pyqtgraph/widgets/ComboBox.py
index 6f184c5f..632216ee 100644
--- a/pyqtgraph/widgets/ComboBox.py
+++ b/pyqtgraph/widgets/ComboBox.py
@@ -24,7 +24,7 @@ class ComboBox(QtGui.QComboBox):
#self.value = default
if 'darwin' in sys.platform: ## because MacOSX can show names that are wider than the comboBox
- self.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToMinimumContentsLength)
+ self.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents)
#self.setMinimumContentsLength(10)
self._chosenText = None
self._items = OrderedDict()
diff --git a/pyqtgraph/widgets/DataTreeWidget.py b/pyqtgraph/widgets/DataTreeWidget.py
index edcfd427..ad9bf49a 100644
--- a/pyqtgraph/widgets/DataTreeWidget.py
+++ b/pyqtgraph/widgets/DataTreeWidget.py
@@ -65,7 +65,7 @@ class DataTreeWidget(QtGui.QTreeWidget):
subnode = QtGui.QTreeWidgetItem(["", "", ""])
node.addChild(subnode)
self.setItemWidget(subnode, 0, widget)
- self.setFirstItemColumnSpanned(subnode, True)
+ subnode.setFirstColumnSpanned(True)
# recurse to children
for key, data in childs.items():
diff --git a/pyqtgraph/widgets/GradientWidget.py b/pyqtgraph/widgets/GradientWidget.py
index 77881b30..c5396d75 100644
--- a/pyqtgraph/widgets/GradientWidget.py
+++ b/pyqtgraph/widgets/GradientWidget.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-from ..Qt import QtGui, QtCore
+from ..Qt import QtGui, QtCore, QtWidgets, QT_LIB
from .GraphicsView import GraphicsView
from ..graphicsItems.GradientEditorItem import GradientEditorItem
import weakref
@@ -40,7 +40,18 @@ class GradientWidget(GraphicsView):
self.setOrientation(orientation)
self.setCacheMode(self.CacheNone)
self.setRenderHints(QtGui.QPainter.Antialiasing | QtGui.QPainter.TextAntialiasing)
- self.setFrameStyle(QtGui.QFrame.NoFrame | QtGui.QFrame.Plain)
+
+ if QT_LIB == 'PyQt6':
+ # PyQt6 doesn't allow or-ing of different enum types
+ # so we need to take its value property
+ NoFrame = QtWidgets.QFrame.Shape.NoFrame.value
+ Plain = QtWidgets.QFrame.Shadow.Plain.value
+ else:
+ NoFrame = QtWidgets.QFrame.NoFrame
+ Plain = QtWidgets.QFrame.Plain
+ frame_style = NoFrame | Plain
+
+ self.setFrameStyle(frame_style)
#self.setBackgroundRole(QtGui.QPalette.NoRole)
#self.setBackgroundBrush(QtGui.QBrush(QtCore.Qt.NoBrush))
#self.setAutoFillBackground(False)
diff --git a/pyqtgraph/widgets/GraphicsView.py b/pyqtgraph/widgets/GraphicsView.py
index 2cdec4b8..6e93aa45 100644
--- a/pyqtgraph/widgets/GraphicsView.py
+++ b/pyqtgraph/widgets/GraphicsView.py
@@ -5,14 +5,7 @@ Copyright 2010 Luke Campagnola
Distributed under MIT/X11 license. See license.txt for more information.
"""
-from ..Qt import QtCore, QtGui, QT_LIB
-
-try:
- from ..Qt import QtOpenGL
- HAVE_OPENGL = True
-except ImportError:
- HAVE_OPENGL = False
-
+from ..Qt import QtCore, QtGui, QtWidgets, QT_LIB
from ..Point import Point
import sys, os
import warnings
@@ -25,6 +18,7 @@ from .. import getConfigOption
__all__ = ['GraphicsView']
+
class GraphicsView(QtGui.QGraphicsView):
"""Re-implementation of QGraphicsView that removes scrollbars and allows unambiguous control of the
viewed coordinate range. Also automatically creates a GraphicsScene and a central QGraphicsWidget
@@ -57,7 +51,7 @@ class GraphicsView(QtGui.QGraphicsView):
useOpenGL If True, the GraphicsView will use OpenGL to do all of its
rendering. This can improve performance on some systems,
but may also introduce bugs (the combination of
- QGraphicsView and QGLWidget is still an 'experimental'
+ QGraphicsView and QOpenGLWidget is still an 'experimental'
feature of Qt)
background Set the background color of the GraphicsView. Accepts any
single argument accepted by
@@ -131,10 +125,9 @@ class GraphicsView(QtGui.QGraphicsView):
self.clickAccepted = False
# Set a transparent background QPalette!
- if QT_LIB in ["PySide2", "PyQt5"]:
- palette = self.palette()
- palette.setColor(QtGui.QPalette.Background, QtCore.Qt.transparent)
- self.setPalette(palette)
+ palette = self.palette()
+ palette.setColor(QtGui.QPalette.Window, QtCore.Qt.transparent)
+ self.setPalette(palette)
def setAntialiasing(self, aa):
"""Enable or disable default antialiasing.
@@ -158,11 +151,11 @@ class GraphicsView(QtGui.QGraphicsView):
def paintEvent(self, ev):
self.scene().prepareForPaint()
- return QtGui.QGraphicsView.paintEvent(self, ev)
+ return super().paintEvent(ev)
def render(self, *args, **kwds):
self.scene().prepareForPaint()
- return QtGui.QGraphicsView.render(self, *args, **kwds)
+ return super().render(*args, **kwds)
def close(self):
@@ -176,9 +169,11 @@ class GraphicsView(QtGui.QGraphicsView):
def useOpenGL(self, b=True):
if b:
+ HAVE_OPENGL = hasattr(QtWidgets, 'QOpenGLWidget')
if not HAVE_OPENGL:
- raise Exception("Requested to use OpenGL with QGraphicsView, but QtOpenGL module is not available.")
- v = QtOpenGL.QGLWidget()
+ raise Exception("Requested to use OpenGL with QGraphicsView, but QOpenGLWidget is not available.")
+
+ v = QtWidgets.QOpenGLWidget()
else:
v = QtGui.QWidget()
@@ -329,10 +324,9 @@ class GraphicsView(QtGui.QGraphicsView):
GraphicsView.setRange(self, r1, padding=[0, padding], propagate=False)
def wheelEvent(self, ev):
- QtGui.QGraphicsView.wheelEvent(self, ev)
+ super().wheelEvent(ev)
if not self.mouseEnabled:
return
-
delta = 0
if QT_LIB in ['PyQt4', 'PySide']:
delta = ev.delta()
@@ -353,20 +347,21 @@ class GraphicsView(QtGui.QGraphicsView):
self.scene().leaveEvent(ev) ## inform scene when mouse leaves
def mousePressEvent(self, ev):
- QtGui.QGraphicsView.mousePressEvent(self, ev)
+ super().mousePressEvent(ev)
if not self.mouseEnabled:
return
- self.lastMousePos = Point(ev.pos())
- self.mousePressPos = ev.pos()
+ lpos = ev.localPos()
+ self.lastMousePos = lpos
+ self.mousePressPos = lpos
self.clickAccepted = ev.isAccepted()
if not self.clickAccepted:
self.scene().clearSelection()
return ## Everything below disabled for now..
def mouseReleaseEvent(self, ev):
- QtGui.QGraphicsView.mouseReleaseEvent(self, ev)
+ super().mouseReleaseEvent(ev)
if not self.mouseEnabled:
return
self.sigMouseReleased.emit(ev)
@@ -374,15 +369,16 @@ class GraphicsView(QtGui.QGraphicsView):
return ## Everything below disabled for now..
def mouseMoveEvent(self, ev):
+ lpos = ev.localPos()
if self.lastMousePos is None:
- self.lastMousePos = Point(ev.pos())
- delta = Point(ev.pos() - self.lastMousePos.toQPoint())
- self.lastMousePos = Point(ev.pos())
+ self.lastMousePos = lpos
+ delta = Point(lpos - self.lastMousePos)
+ self.lastMousePos = lpos
- QtGui.QGraphicsView.mouseMoveEvent(self, ev)
+ super().mouseMoveEvent(ev)
if not self.mouseEnabled:
return
- self.sigSceneMouseMoved.emit(self.mapToScene(ev.pos()))
+ self.sigSceneMouseMoved.emit(self.mapToScene(lpos))
if self.clickAccepted: ## Ignore event if an item in the scene has already claimed it.
return
@@ -393,7 +389,7 @@ class GraphicsView(QtGui.QGraphicsView):
self.scale(scale[0], scale[1], center=self.mapToScene(self.mousePressPos))
self.sigDeviceRangeChanged.emit(self, self.range)
- elif ev.buttons() in [QtCore.Qt.MidButton, QtCore.Qt.LeftButton]: ## Allow panning by left or mid button.
+ elif ev.buttons() in [QtCore.Qt.MiddleButton, QtCore.Qt.LeftButton]: ## Allow panning by left or mid button.
px = self.pixelSize()
tr = -delta * px
diff --git a/pyqtgraph/widgets/JoystickButton.py b/pyqtgraph/widgets/JoystickButton.py
index 6f73c8dc..b668d82d 100644
--- a/pyqtgraph/widgets/JoystickButton.py
+++ b/pyqtgraph/widgets/JoystickButton.py
@@ -18,11 +18,11 @@ class JoystickButton(QtGui.QPushButton):
def mousePressEvent(self, ev):
self.setChecked(True)
- self.pressPos = ev.pos()
+ self.pressPos = ev.localPos()
ev.accept()
def mouseMoveEvent(self, ev):
- dif = ev.pos()-self.pressPos
+ dif = ev.localPos()-self.pressPos
self.setState(dif.x(), -dif.y())
def mouseReleaseEvent(self, ev):
@@ -64,14 +64,14 @@ class JoystickButton(QtGui.QPushButton):
self.sigStateChanged.emit(self, self.state)
def paintEvent(self, ev):
- QtGui.QPushButton.paintEvent(self, ev)
+ super().paintEvent(ev)
p = QtGui.QPainter(self)
p.setBrush(QtGui.QBrush(QtGui.QColor(0,0,0)))
p.drawEllipse(self.spotPos.x()-3,self.spotPos.y()-3,6,6)
def resizeEvent(self, ev):
self.setState(*self.state)
- QtGui.QPushButton.resizeEvent(self, ev)
+ super().resizeEvent(ev)
diff --git a/pyqtgraph/widgets/MatplotlibWidget.py b/pyqtgraph/widgets/MatplotlibWidget.py
index c5b6c980..b3868e8f 100644
--- a/pyqtgraph/widgets/MatplotlibWidget.py
+++ b/pyqtgraph/widgets/MatplotlibWidget.py
@@ -1,18 +1,8 @@
from ..Qt import QtGui, QtCore, QT_LIB
import matplotlib
-if QT_LIB != 'PyQt5':
- if QT_LIB == 'PySide':
- matplotlib.rcParams['backend.qt4']='PySide'
-
- from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
- try:
- from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar
- except ImportError:
- from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
-else:
- from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
- from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
+from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
+from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure
diff --git a/pyqtgraph/widgets/PathButton.py b/pyqtgraph/widgets/PathButton.py
index ee2e0bca..06fe131f 100644
--- a/pyqtgraph/widgets/PathButton.py
+++ b/pyqtgraph/widgets/PathButton.py
@@ -32,7 +32,7 @@ class PathButton(QtGui.QPushButton):
self.update()
def paintEvent(self, ev):
- QtGui.QPushButton.paintEvent(self, ev)
+ super().paintEvent(ev)
margin = self.margin
geom = QtCore.QRectF(0, 0, self.width(), self.height()).adjusted(margin, margin, -margin, -margin)
rect = self.path.boundingRect()
diff --git a/pyqtgraph/widgets/ProgressDialog.py b/pyqtgraph/widgets/ProgressDialog.py
index 7d2ef8a4..989a8d61 100644
--- a/pyqtgraph/widgets/ProgressDialog.py
+++ b/pyqtgraph/widgets/ProgressDialog.py
@@ -195,7 +195,7 @@ class ProgressDialog(QtGui.QProgressDialog):
if self._nestingReady:
# don't let progress dialog manage widgets anymore.
return
- return QtGui.QProgressDialog.resizeEvent(self, ev)
+ return super().resizeEvent(ev)
## wrap all other functions to make sure they aren't being called from non-gui threads
diff --git a/pyqtgraph/widgets/RawImageWidget.py b/pyqtgraph/widgets/RawImageWidget.py
index 43eafeb6..98cee889 100644
--- a/pyqtgraph/widgets/RawImageWidget.py
+++ b/pyqtgraph/widgets/RawImageWidget.py
@@ -5,10 +5,11 @@ Copyright 2010-2016 Luke Campagnola
Distributed under MIT/X11 license. See license.txt for more infomation.
"""
+from .. import getConfigOption, functions as fn, getCupy
from ..Qt import QtCore, QtGui
try:
- from ..Qt import QtOpenGL
+ from ..Qt import QtWidgets
from OpenGL.GL import *
HAVE_OPENGL = True
@@ -17,8 +18,6 @@ except (ImportError, AttributeError):
# AttributeError upon import
HAVE_OPENGL = False
-from .. import getConfigOption, functions as fn
-
class RawImageWidget(QtGui.QWidget):
"""
@@ -37,6 +36,7 @@ class RawImageWidget(QtGui.QWidget):
self.scaled = scaled
self.opts = None
self.image = None
+ self._cp = getCupy()
def setImage(self, img, *args, **kargs):
"""
@@ -52,6 +52,8 @@ class RawImageWidget(QtGui.QWidget):
return
if self.image is None:
argb, alpha = fn.makeARGB(self.opts[0], *self.opts[1], **self.opts[2])
+ if self._cp and self._cp.get_array_module(argb) == self._cp:
+ argb = argb.get() # transfer GPU data back to the CPU
self.image = fn.makeQImage(argb, alpha)
self.opts = ()
# if self.pixmap is None:
@@ -74,7 +76,7 @@ class RawImageWidget(QtGui.QWidget):
if HAVE_OPENGL:
- class RawImageGLWidget(QtOpenGL.QGLWidget):
+ class RawImageGLWidget(QtWidgets.QOpenGLWidget):
"""
Similar to RawImageWidget, but uses a GL widget to do all drawing.
Perfomance varies between platforms; see examples/VideoSpeedTest for benchmarking.
@@ -83,7 +85,7 @@ if HAVE_OPENGL:
"""
def __init__(self, parent=None, scaled=False):
- QtOpenGL.QGLWidget.__init__(self, parent)
+ QtWidgets.QOpenGLWidget.__init__(self, parent)
self.scaled = scaled
self.image = None
self.uploaded = False
@@ -142,7 +144,9 @@ if HAVE_OPENGL:
if not self.uploaded:
self.uploadTexture()
- glViewport(0, 0, self.width() * self.devicePixelRatio(), self.height() * self.devicePixelRatio())
+ dpr = self.devicePixelRatio()
+ vp = (0, 0, int(self.width() * dpr), int(self.height() * dpr))
+ glViewport(*vp)
glEnable(GL_TEXTURE_2D)
glBindTexture(GL_TEXTURE_2D, self.texture)
glColor4f(1, 1, 1, 1)
diff --git a/pyqtgraph/widgets/RemoteGraphicsView.py b/pyqtgraph/widgets/RemoteGraphicsView.py
index 2e1d9cc3..68af64f5 100644
--- a/pyqtgraph/widgets/RemoteGraphicsView.py
+++ b/pyqtgraph/widgets/RemoteGraphicsView.py
@@ -1,66 +1,14 @@
from ..Qt import QtGui, QtCore, QT_LIB
-if QT_LIB in ['PyQt4', 'PyQt5']:
- try:
- from PyQt5 import sip
- except ImportError:
- import sip
+if QT_LIB.startswith('PyQt'):
+ from ..Qt import sip
from .. import multiprocess as mp
from .GraphicsView import GraphicsView
from .. import CONFIG_OPTIONS
import numpy as np
-import mmap, tempfile, ctypes, atexit, sys, random
+import mmap, tempfile, os, atexit, sys, random
__all__ = ['RemoteGraphicsView']
-class SerializableWheelEvent:
- """
- Contains all information of a QWheelEvent, is serializable and can generate QWheelEvents.
-
- Methods have the functionality of their QWheelEvent equivalent.
- """
- def __init__(self, _pos, _globalPos, _delta, _buttons, _modifiers, _orientation):
- self._pos = _pos
- self._globalPos = _globalPos
- self._delta = _delta
- self._buttons = _buttons
- self._modifiers = _modifiers
- self._orientation_vertical = _orientation == QtCore.Qt.Vertical
-
- def pos(self):
- return self._pos
-
- def globalPos(self):
- return self._globalPos
-
- def delta(self):
- return self._delta
-
- def orientation(self):
- if self._orientation_vertical:
- return QtCore.Qt.Vertical
- else:
- return QtCore.Qt.Horizontal
-
- def angleDelta(self):
- if self._orientation_vertical:
- return QtCore.QPoint(0, self._delta)
- else:
- return QtCore.QPoint(self._delta, 0)
-
- def buttons(self):
- return QtCore.Qt.MouseButtons(self._buttons)
-
- def modifiers(self):
- return QtCore.Qt.KeyboardModifiers(self._modifiers)
-
- def toQWheelEvent(self):
- """
- Generate QWheelEvent from SerializableWheelEvent.
- """
- if QT_LIB in ['PyQt4', 'PySide']:
- return QtGui.QWheelEvent(self.pos(), self.globalPos(), self.delta(), self.buttons(), self.modifiers(), self.orientation())
- else:
- return QtGui.QWheelEvent(self.pos(), self.globalPos(), QtCore.QPoint(), self.angleDelta(), self.delta(), self.orientation(), self.buttons(), self.modifiers())
class RemoteGraphicsView(QtGui.QWidget):
"""
@@ -114,7 +62,7 @@ class RemoteGraphicsView(QtGui.QWidget):
setattr(self, method, getattr(self._view, method))
def resizeEvent(self, ev):
- ret = QtGui.QWidget.resizeEvent(self, ev)
+ ret = super().resizeEvent(ev)
self._view.resize(self.size(), _callSync='off')
return ret
@@ -130,10 +78,6 @@ class RemoteGraphicsView(QtGui.QWidget):
if sys.platform.startswith('win'):
self.shmtag = newfile ## on windows, we create a new tag for every resize
self.shm = mmap.mmap(-1, size, self.shmtag) ## can't use tmpfile on windows because the file can only be opened once.
- elif sys.platform == 'darwin':
- self.shmFile.close()
- self.shmFile = open(self._view.shmFileName(), 'r')
- self.shm = mmap.mmap(self.shmFile.fileno(), size, mmap.MAP_SHARED, mmap.PROT_READ)
else:
self.shm = mmap.mmap(self.shmFile.fileno(), size, mmap.MAP_SHARED, mmap.PROT_READ)
self.shm.seek(0)
@@ -148,51 +92,62 @@ class RemoteGraphicsView(QtGui.QWidget):
p = QtGui.QPainter(self)
p.drawImage(self.rect(), self._img, QtCore.QRect(0, 0, self._img.width(), self._img.height()))
p.end()
-
+
+ def serialize_mouse_enum(self, *args):
+ # PyQt6 can pickle enums and flags but cannot cast to int
+ # PyQt5 5.12, PyQt5 5.15, PySide2 5.15, PySide6 can pickle enums but not flags
+ # PySide2 5.12 cannot pickle enums nor flags
+ # MouseButtons and KeyboardModifiers are flags
+ if QT_LIB != 'PyQt6':
+ args = [int(x) for x in args]
+ return args
+
+ def serialize_mouse_event(self, ev):
+ lpos, gpos = ev.localPos(), ev.screenPos()
+ typ, btn, btns, mods = self.serialize_mouse_enum(
+ ev.type(), ev.button(), ev.buttons(), ev.modifiers())
+ return (typ, lpos, gpos, btn, btns, mods)
+
+ def serialize_wheel_event(self, ev):
+ # {PyQt6, PySide6} have position()
+ # {PyQt5, PySide2} 5.15 have position()
+ # {PyQt5, PySide2} 5.15 have posF() (contrary to C++ docs)
+ # {PyQt5, PySide2} 5.12 have posF()
+ lpos = ev.position() if hasattr(ev, 'position') else ev.posF()
+ # gpos = ev.globalPosition() if hasattr(ev, 'globalPosition') else ev.globalPosF()
+ gpos = lpos # RemoteGraphicsView Renderer assumes to be at (0, 0)
+ btns, mods, phase = self.serialize_mouse_enum(ev.buttons(), ev.modifiers(), ev.phase())
+ return (lpos, gpos, ev.pixelDelta(), ev.angleDelta(), btns, mods, phase, ev.inverted())
+
def mousePressEvent(self, ev):
- self._view.mousePressEvent(int(ev.type()), ev.pos(), ev.pos(), int(ev.button()), int(ev.buttons()), int(ev.modifiers()), _callSync='off')
+ self._view.mousePressEvent(self.serialize_mouse_event(ev), _callSync='off')
ev.accept()
- return QtGui.QWidget.mousePressEvent(self, ev)
+ return super().mousePressEvent(ev)
def mouseReleaseEvent(self, ev):
- self._view.mouseReleaseEvent(int(ev.type()), ev.pos(), ev.pos(), int(ev.button()), int(ev.buttons()), int(ev.modifiers()), _callSync='off')
+ self._view.mouseReleaseEvent(self.serialize_mouse_event(ev), _callSync='off')
ev.accept()
- return QtGui.QWidget.mouseReleaseEvent(self, ev)
+ return super().mouseReleaseEvent(ev)
def mouseMoveEvent(self, ev):
- self._view.mouseMoveEvent(int(ev.type()), ev.pos(), ev.pos(), int(ev.button()), int(ev.buttons()), int(ev.modifiers()), _callSync='off')
+ self._view.mouseMoveEvent(self.serialize_mouse_event(ev), _callSync='off')
ev.accept()
- return QtGui.QWidget.mouseMoveEvent(self, ev)
+ return super().mouseMoveEvent(ev)
def wheelEvent(self, ev):
- delta = 0
- orientation = QtCore.Qt.Horizontal
- if QT_LIB in ['PyQt4', 'PySide']:
- delta = ev.delta()
- orientation = ev.orientation()
- else:
- delta = ev.angleDelta().x()
- if delta == 0:
- orientation = QtCore.Qt.Vertical
- delta = ev.angleDelta().y()
-
- serializableEvent = SerializableWheelEvent(ev.pos(), ev.pos(), delta, int(ev.buttons()), int(ev.modifiers()), orientation)
- self._view.wheelEvent(serializableEvent, _callSync='off')
+ self._view.wheelEvent(self.serialize_wheel_event(ev), _callSync='off')
ev.accept()
- return QtGui.QWidget.wheelEvent(self, ev)
-
- def keyEvent(self, ev):
- if self._view.keyEvent(int(ev.type()), int(ev.modifiers()), text, autorep, count):
- ev.accept()
- return QtGui.QWidget.keyEvent(self, ev)
-
+ return super().wheelEvent(ev)
+
def enterEvent(self, ev):
- self._view.enterEvent(int(ev.type()), _callSync='off')
- return QtGui.QWidget.enterEvent(self, ev)
+ lws = ev.localPos(), ev.windowPos(), ev.screenPos()
+ self._view.enterEvent(lws, _callSync='off')
+ return super().enterEvent(ev)
def leaveEvent(self, ev):
- self._view.leaveEvent(int(ev.type()), _callSync='off')
- return QtGui.QWidget.leaveEvent(self, ev)
+ typ, = self.serialize_mouse_enum(ev.type())
+ self._view.leaveEvent(typ, _callSync='off')
+ return super().leaveEvent(ev)
def remoteProcess(self):
"""Return the remote process handle. (see multiprocess.remoteproxy.RemoteEventHandler)"""
@@ -200,6 +155,7 @@ class RemoteGraphicsView(QtGui.QWidget):
def close(self):
"""Close the remote process. After this call, the widget will no longer be updated."""
+ self._view.sceneRendered.disconnect()
self._proc.close()
@@ -242,11 +198,11 @@ class Renderer(GraphicsView):
def update(self):
self.img = None
- return GraphicsView.update(self)
+ return super().update()
def resize(self, size):
oldSize = self.size()
- GraphicsView.resize(self, size)
+ super().resize(size)
self.resizeEvent(QtGui.QResizeEvent(size, oldSize))
self.update()
@@ -265,72 +221,67 @@ class Renderer(GraphicsView):
self.shm = mmap.mmap(-1, size, self.shmtag)
elif sys.platform == 'darwin':
self.shm.close()
- self.shmFile.close()
- self.shmFile = tempfile.NamedTemporaryFile(prefix='pyqtgraph_shmem_')
- self.shmFile.write(b'\x00' * (size + 1))
- self.shmFile.flush()
- self.shm = mmap.mmap(self.shmFile.fileno(), size, mmap.MAP_SHARED, mmap.PROT_WRITE)
+ fd = self.shmFile.fileno()
+ os.ftruncate(fd, size + 1)
+ self.shm = mmap.mmap(fd, size, mmap.MAP_SHARED, mmap.PROT_WRITE)
else:
self.shm.resize(size)
## render the scene directly to shared memory
- if QT_LIB in ['PySide', 'PySide2']:
- ch = ctypes.c_char.from_buffer(self.shm, 0)
- #ch = ctypes.c_char_p(address)
- self.img = QtGui.QImage(ch, self.width(), self.height(), QtGui.QImage.Format_ARGB32)
+ if QT_LIB == 'PyQt5':
+ img_ptr = int(sip.voidptr(self.shm))
+ elif QT_LIB == 'PyQt6':
+ img_ptr = sip.voidptr(self.shm)
else:
- address = ctypes.addressof(ctypes.c_char.from_buffer(self.shm, 0))
+ # PySide2, PySide6
+ img_ptr = self.shm
+
+ self.img = QtGui.QImage(img_ptr, self.width(), self.height(), QtGui.QImage.Format_ARGB32)
- # different versions of pyqt have different requirements here..
- try:
- self.img = QtGui.QImage(sip.voidptr(address), self.width(), self.height(), QtGui.QImage.Format_ARGB32)
- except TypeError:
- try:
- self.img = QtGui.QImage(memoryview(buffer(self.shm)), self.width(), self.height(), QtGui.QImage.Format_ARGB32)
- except TypeError:
- # Works on PyQt 4.9.6
- self.img = QtGui.QImage(address, self.width(), self.height(), QtGui.QImage.Format_ARGB32)
self.img.fill(0xffffffff)
p = QtGui.QPainter(self.img)
self.render(p, self.viewRect(), self.rect())
p.end()
self.sceneRendered.emit((self.width(), self.height(), self.shm.size(), self.shmFileName()))
- def mousePressEvent(self, typ, pos, gpos, btn, btns, mods):
- typ = QtCore.QEvent.Type(typ)
- btn = QtCore.Qt.MouseButton(btn)
- btns = QtCore.Qt.MouseButtons(btns)
- mods = QtCore.Qt.KeyboardModifiers(mods)
- return GraphicsView.mousePressEvent(self, QtGui.QMouseEvent(typ, pos, gpos, btn, btns, mods))
+ def deserialize_mouse_event(self, mouse_event):
+ typ, pos, gpos, btn, btns, mods = mouse_event
+ if QT_LIB != 'PyQt6':
+ typ = QtCore.QEvent.Type(typ)
+ btn = QtCore.Qt.MouseButton(btn)
+ btns = QtCore.Qt.MouseButtons(btns)
+ mods = QtCore.Qt.KeyboardModifiers(mods)
+ return QtGui.QMouseEvent(typ, pos, gpos, btn, btns, mods)
- def mouseMoveEvent(self, typ, pos, gpos, btn, btns, mods):
- typ = QtCore.QEvent.Type(typ)
- btn = QtCore.Qt.MouseButton(btn)
+ def deserialize_wheel_event(self, wheel_event):
+ pos, gpos, pixelDelta, angleDelta, btns, mods, phase, inverted = wheel_event
btns = QtCore.Qt.MouseButtons(btns)
mods = QtCore.Qt.KeyboardModifiers(mods)
- return GraphicsView.mouseMoveEvent(self, QtGui.QMouseEvent(typ, pos, gpos, btn, btns, mods))
+ phase = QtCore.Qt.ScrollPhase(phase)
+ return QtGui.QWheelEvent(pos, gpos, pixelDelta, angleDelta, btns, mods, phase, inverted)
- def mouseReleaseEvent(self, typ, pos, gpos, btn, btns, mods):
- typ = QtCore.QEvent.Type(typ)
- btn = QtCore.Qt.MouseButton(btn)
- btns = QtCore.Qt.MouseButtons(btns)
- mods = QtCore.Qt.KeyboardModifiers(mods)
- return GraphicsView.mouseReleaseEvent(self, QtGui.QMouseEvent(typ, pos, gpos, btn, btns, mods))
+ def mousePressEvent(self, mouse_event):
+ ev = self.deserialize_mouse_event(mouse_event)
+ return super().mousePressEvent(ev)
+
+ def mouseMoveEvent(self, mouse_event):
+ ev = self.deserialize_mouse_event(mouse_event)
+ return super().mouseMoveEvent(ev)
+
+ def mouseReleaseEvent(self, mouse_event):
+ ev = self.deserialize_mouse_event(mouse_event)
+ return super().mouseReleaseEvent(ev)
- def wheelEvent(self, ev):
- return GraphicsView.wheelEvent(self, ev.toQWheelEvent())
+ def wheelEvent(self, wheel_event):
+ ev = self.deserialize_wheel_event(wheel_event)
+ return super().wheelEvent(ev)
- def keyEvent(self, typ, mods, text, autorep, count):
- typ = QtCore.QEvent.Type(typ)
- mods = QtCore.Qt.KeyboardModifiers(mods)
- GraphicsView.keyEvent(self, QtGui.QKeyEvent(typ, mods, text, autorep, count))
- return ev.accepted()
-
- def enterEvent(self, typ):
- ev = QtCore.QEvent(QtCore.QEvent.Type(typ))
- return GraphicsView.enterEvent(self, ev)
+ def enterEvent(self, lws):
+ ev = QtGui.QEnterEvent(*lws)
+ return super().enterEvent(ev)
def leaveEvent(self, typ):
- ev = QtCore.QEvent(QtCore.QEvent.Type(typ))
- return GraphicsView.leaveEvent(self, ev)
+ typ = QtCore.QEvent.Type(typ)
+ ev = QtCore.QEvent(typ)
+ return super().leaveEvent(ev)
diff --git a/pyqtgraph/widgets/SpinBox.py b/pyqtgraph/widgets/SpinBox.py
index 2f95a6fa..cbde6fc7 100644
--- a/pyqtgraph/widgets/SpinBox.py
+++ b/pyqtgraph/widgets/SpinBox.py
@@ -114,7 +114,7 @@ class SpinBox(QtGui.QAbstractSpinBox):
self.editingFinished.connect(self.editingFinishedEvent)
def event(self, ev):
- ret = QtGui.QAbstractSpinBox.event(self, ev)
+ ret = super().event(ev)
if ev.type() == QtCore.QEvent.KeyPress and ev.key() == QtCore.Qt.Key_Return:
ret = True ## For some reason, spinbox pretends to ignore return key press
return ret
@@ -595,7 +595,7 @@ class SpinBox(QtGui.QAbstractSpinBox):
def paintEvent(self, ev):
self._updateHeight()
- QtGui.QAbstractSpinBox.paintEvent(self, ev)
+ super().paintEvent(ev)
class ErrorBox(QtGui.QWidget):
diff --git a/pyqtgraph/widgets/TableWidget.py b/pyqtgraph/widgets/TableWidget.py
index c0e6ea90..194b23f9 100644
--- a/pyqtgraph/widgets/TableWidget.py
+++ b/pyqtgraph/widgets/TableWidget.py
@@ -4,6 +4,7 @@ from ..Qt import QtGui, QtCore
from ..python2_3 import asUnicode, basestring
from .. import metaarray
+translate = QtCore.QCoreApplication.translate
__all__ = ['TableWidget']
@@ -74,10 +75,10 @@ class TableWidget(QtGui.QTableWidget):
self.itemChanged.connect(self.handleItemChanged)
self.contextMenu = QtGui.QMenu()
- self.contextMenu.addAction('Copy Selection').triggered.connect(self.copySel)
- self.contextMenu.addAction('Copy All').triggered.connect(self.copyAll)
- self.contextMenu.addAction('Save Selection').triggered.connect(self.saveSel)
- self.contextMenu.addAction('Save All').triggered.connect(self.saveAll)
+ self.contextMenu.addAction(translate("TableWidget", 'Copy Selection')).triggered.connect(self.copySel)
+ self.contextMenu.addAction(translate("TableWidget", 'Copy All')).triggered.connect(self.copyAll)
+ self.contextMenu.addAction(translate("TableWidget", 'Save Selection')).triggered.connect(self.saveSel)
+ self.contextMenu.addAction(translate("TableWidget", 'Save All')).triggered.connect(self.saveAll)
def clear(self):
"""Clear all contents from the table."""
@@ -350,7 +351,12 @@ class TableWidget(QtGui.QTableWidget):
self.save(self.serialize(useSelection=False))
def save(self, data):
- fileName = QtGui.QFileDialog.getSaveFileName(self, "Save As..", "", "Tab-separated values (*.tsv)")
+ fileName = QtGui.QFileDialog.getSaveFileName(
+ self,
+ f"{translate('TableWidget', 'Save As')}...",
+ "",
+ f"{translate('TableWidget', 'Tab-separated values')} (*.tsv)"
+ )
if isinstance(fileName, tuple):
fileName = fileName[0] # Qt4/5 API difference
if fileName == '':
@@ -366,7 +372,7 @@ class TableWidget(QtGui.QTableWidget):
ev.accept()
self.copySel()
else:
- QtGui.QTableWidget.keyPressEvent(self, ev)
+ super().keyPressEvent(ev)
def handleItemChanged(self, item):
item.itemChanged()
diff --git a/pyqtgraph/widgets/TreeWidget.py b/pyqtgraph/widgets/TreeWidget.py
index 4540915f..b3e3f947 100644
--- a/pyqtgraph/widgets/TreeWidget.py
+++ b/pyqtgraph/widgets/TreeWidget.py
@@ -144,7 +144,7 @@ class TreeWidget(QtGui.QTreeWidget):
return items
def dropEvent(self, ev):
- QtGui.QTreeWidget.dropEvent(self, ev)
+ super().dropEvent(ev)
self.updateDropFlags()
def updateDropFlags(self):
diff --git a/pyqtgraph/widgets/ValueLabel.py b/pyqtgraph/widgets/ValueLabel.py
index b24fb16c..0714689f 100644
--- a/pyqtgraph/widgets/ValueLabel.py
+++ b/pyqtgraph/widgets/ValueLabel.py
@@ -58,7 +58,7 @@ class ValueLabel(QtGui.QLabel):
def paintEvent(self, ev):
self.setText(self.generateText())
- return QtGui.QLabel.paintEvent(self, ev)
+ return super().paintEvent(ev)
def generateText(self):
if len(self.values) == 0:
diff --git a/pyqtgraph/widgets/tests/test_graphics_view.py b/pyqtgraph/widgets/tests/test_graphics_view.py
index be042dbd..c2206985 100644
--- a/pyqtgraph/widgets/tests/test_graphics_view.py
+++ b/pyqtgraph/widgets/tests/test_graphics_view.py
@@ -7,13 +7,12 @@ def test_basics_graphics_view():
app = pg.mkQApp()
view = pg.GraphicsView()
background_role = view.backgroundRole()
- assert background_role == QtGui.QPalette.Background
+ assert background_role == QtGui.QPalette.Window
palette = view.palette()
- if pg.Qt.QT_LIB in ["PySide2", "PyQt5"]:
- assert palette.isBrushSet(QtGui.QPalette.Active, QtGui.QPalette.Background)
- assert palette.color(QtGui.QPalette.Background) == QtCore.Qt.transparent
+ 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.focusPolicy() == QtCore.Qt.StrongFocus
@@ -39,10 +38,8 @@ def test_basics_graphics_view():
view.setBackground("w")
assert view._background == "w"
palette = view.palette()
- if pg.Qt.QT_LIB in ["PySide2", "PyQt5"]:
-
- assert palette.isBrushSet(QtGui.QPalette.Active, QtGui.QPalette.Background)
- assert palette.color(QtGui.QPalette.Background) == QtCore.Qt.transparent
+ 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
# Set anti aliasing
diff --git a/pytest.ini b/pytest.ini
index 355e9dfd..cc80f5f7 100644
--- a/pytest.ini
+++ b/pytest.ini
@@ -4,7 +4,7 @@ xvfb_height = 1080
# use this due to some issues with ndarray reshape errors on CI systems
xvfb_colordepth = 24
xvfb_args=-ac +extension GLX +render
-faulthandler_timeout = 15
+faulthandler_timeout = 30
filterwarnings =
# comfortable skipping these warnings runtime warnings
@@ -16,4 +16,6 @@ filterwarnings =
# py36/pyside2_512 specific issue
ignore:split\(\) requires a non-empty pattern match\.:FutureWarning
# pyqtgraph specific warning we want to ignore during testing
- ignore:Visible window deleted. To prevent this, store a reference to the window object.
\ No newline at end of file
+ ignore:Visible window deleted. To prevent this, store a reference to the window object.
+ # xvfb warnings
+ ignore:Unknown config option:pytest.PytestConfigWarning
diff --git a/setup.py b/setup.py
index aa1bb787..8f328f9a 100644
--- a/setup.py
+++ b/setup.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
DESCRIPTION = """\
-PyQtGraph is a pure-python graphics and GUI library built on PyQt4/PyQt5/PySide/PySide2 and
+PyQtGraph is a pure-python graphics and GUI library built on PyQt5/PySide2 and
numpy.
It is intended for use in mathematics / scientific / engineering applications.
@@ -19,8 +19,6 @@ setupOpts = dict(
author_email='luke.campagnola@gmail.com',
classifiers = [
"Programming Language :: Python",
- "Programming Language :: Python :: 2",
- "Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Development Status :: 4 - Beta",
"Environment :: Other Environment",
@@ -138,10 +136,13 @@ setup(
'mergetest': helpers.MergeTestCommand,
'style': helpers.StyleCommand},
packages=allPackages,
+ python_requires=">=3.7",
package_dir={'pyqtgraph.examples': 'examples'}, ## install examples along with the rest of the source
- package_data={'pyqtgraph.examples': ['optics/*.gz', 'relativity/presets/*.cfg']},
+ package_data={'pyqtgraph.examples': ['optics/*.gz', 'relativity/presets/*.cfg'],
+ "pyqtgraph.icons": ["*.svg", "*.png"],
+ },
install_requires = [
- 'numpy>=1.8.0',
+ 'numpy>=1.17.0',
],
**setupOpts
)
diff --git a/test.py b/test.py
index d2aeff5c..ab892457 100644
--- a/test.py
+++ b/test.py
@@ -6,18 +6,18 @@ import sys
import pytest
args = sys.argv[1:]
-if '--pyside' in args:
- args.remove('--pyside')
- import PySide
-elif '--pyqt4' in args:
- args.remove('--pyqt4')
- import PyQt4
-elif '--pyqt5' in args:
+if '--pyqt5' in args:
args.remove('--pyqt5')
import PyQt5
elif '--pyside2' in args:
args.remove('--pyside2')
import PySide2
+elif '--pyside6' in args:
+ args.remove('--pyside6')
+ import PySide6
+elif '--pyqt6' in args:
+ args.remove('--pyqt6')
+ import PyQt6
import pyqtgraph as pg
pg.systemInfo()
diff --git a/tools/rebuildUi.py b/tools/rebuildUi.py
index 18de45d6..8c64c070 100644
--- a/tools/rebuildUi.py
+++ b/tools/rebuildUi.py
@@ -7,10 +7,10 @@ Script for compiling Qt Designer .ui files to .py
"""
import os, sys, subprocess, tempfile
-pyqtuic = 'pyuic4'
-pysideuic = 'pyside-uic'
pyqt5uic = 'pyuic5'
+pyqt6uic = 'pyuic6'
pyside2uic = 'pyside2-uic'
+pyside6uic = 'pyside6-uic'
usage = """Compile .ui files to .py for all supported pyqt/pyside versions.
@@ -50,7 +50,8 @@ for arg in args:
# rebuild all requested ui files
for ui in uifiles:
base, _ = os.path.splitext(ui)
- for compiler, ext in [(pyqtuic, '_pyqt.py'), (pysideuic, '_pyside.py'), (pyqt5uic, '_pyqt5.py'), (pyside2uic, '_pyside2.py')]:
+ for compiler, ext in [(pyqt5uic, '_pyqt5.py'), (pyside2uic, '_pyside2.py'),
+ (pyqt6uic, '_pyqt6.py'), (pyside6uic, '_pyside6.py')]:
py = base + ext
if not force and os.path.exists(py) and os.stat(ui).st_mtime <= os.stat(py).st_mtime:
print("Skipping %s; already compiled." % py)
diff --git a/tools/setupHelpers.py b/tools/setupHelpers.py
index 642c5d77..63b255d3 100644
--- a/tools/setupHelpers.py
+++ b/tools/setupHelpers.py
@@ -379,7 +379,7 @@ def getGitVersion(tagPrefix):
'describe',
'--tags',
'--dirty',
- '--match=%s*'%tagPrefix]).strip().decode('utf-8')
+ '--match="%s*"'%tagPrefix]).strip().decode('utf-8')
# chop off prefix
assert v.startswith(tagPrefix)
diff --git a/tox.ini b/tox.ini
index 130085ba..c05fe689 100644
--- a/tox.ini
+++ b/tox.ini
@@ -9,9 +9,6 @@ envlist =
; qt 5.9.7 (LTS)
py36-{pyqt5,pyside2}_59_conda
- ; qt 4.8.7
- py27-{pyqt4,pyside}_conda
-
[base]
deps =
pytest
@@ -19,7 +16,6 @@ deps =
scipy
pyopengl
flake8
- six
coverage
[testenv]
@@ -37,8 +33,6 @@ deps=
conda_deps=
pyside2_59_conda: pyside2=5.9
pyqt5_59_conda: pyqt=5.9
- pyqt4_conda: pyqt=4
- pyside_conda: pyside
conda_channels=
conda-forge