color registry handles updates now

This commit is contained in:
Nils Nemitz 2021-05-06 02:53:33 +09:00
commit ab51264021
198 changed files with 7634 additions and 2414 deletions

46
.flake8
View File

@ -3,47 +3,5 @@ exclude = .git,.tox,__pycache__,doc,old,build,dist
show_source = True
statistics = True
verbose = 2
select =
E101,
E112,
E122,
E125,
E133,
E223,
E224,
E242,
E273,
E274,
E901,
E902,
W191,
W601,
W602,
W603,
W604,
E124,
E231,
E211,
E261,
E271,
E272,
E304,
F401,
F402,
F403,
F404,
E501,
E502,
E702,
E703,
E711,
E712,
E721,
F811,
F812,
F821,
F822,
F823,
F831,
F841,
W292
max-line-length = 88
extend-ignore = E203, W503

View File

@ -24,19 +24,19 @@ jobs:
- python-version: "3.8"
qt-lib: "pyqt"
qt-version: "PyQt5~=5.15.0"
numpy-version: "~=1.19.0"
numpy-version: "~=1.20.0"
- python-version: "3.8"
qt-lib: "pyside"
qt-version: "PySide2~=5.15.0"
numpy-version: "~=1.19.0"
numpy-version: "~=1.20.0"
- python-version: "3.9"
qt-lib: "pyqt"
qt-version: "PyQt6"
numpy-version: "~=1.19.0"
numpy-version: "~=1.20.0"
- python-version: "3.9"
qt-lib: "pyside"
qt-version: "PySide6"
numpy-version: "~=1.19.0"
numpy-version: "~=1.20.0"
steps:
- name: Checkout
uses: actions/checkout@v2
@ -70,9 +70,9 @@ jobs:
- name: Install Dependencies
run: |
pip install --upgrade pip
pip install ${{ matrix.qt-version }} numpy${{ matrix.numpy-version }} scipy pyopengl h5py matplotlib
pip install ${{ matrix.qt-version }} numpy${{ matrix.numpy-version }} scipy pyopengl h5py matplotlib numba
pip install .
pip install pytest pytest-cov pytest-xdist coverage
pip install pytest
- name: "Install Linux VirtualDisplay"
if: runner.os == 'Linux'
run: |
@ -106,10 +106,8 @@ jobs:
- name: Run Tests
run: |
mkdir $SCREENSHOT_DIR
pytest . -v \
-n auto \
pytest pyqtgraph examples -v \
--junitxml pytest.xml \
--cov pyqtgraph --cov-report=xml --cov-report=html
shell: bash
- name: Upload Screenshots
uses: actions/upload-artifact@v2
@ -120,29 +118,9 @@ jobs:
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

1
.gitignore vendored
View File

@ -108,3 +108,4 @@ rtr.cvs
.tags*
.asv/
asv.conf.json

View File

@ -1,9 +1,102 @@
pyqtgraph-0.12.1
New Features
- #1596 - Add ColorBarItem for simplified image level adjustment
Performance enhancement:
- #1650 Don't use clip_array on scalers in DynamicPlotRange
- #1617 Optimize makeARGB for ubyte images
- #1648 Implement blocked variant of rescaleData
API/Behavior Change:
- #1690 Parameter Item default created from value if not present
Bug Fixes:
- #1665 Don't pass brush to mkPen in LegendItem.paint()
- #1660 Include colormaps in the python wheel
- #1653 Fix accidental disabling of style updates in PlotDataItem
- #1647 Handle empty adjacency array for GraphItem
- #1680 Fix test suite for big-endian architectures
- #1694 DateAxisItem now accounts for Daylight Savings Time
- #1691 Make sure dynamic range limiter runs on PlotDataItem
pyqtgraph-0.12.0
Deprecations:
- Qt < 5.12, Python < 3.7, and NumPy < 1.17 are no longer supported
New Features:
- Qt6 Compatibility (thank you so much @pijyoi !)
- #1466 CuPy/CUDA support for ImageItem! (thanks you so much @outofculture !)
- #1520/#1518 i18n Localization support for dialogs
- #1497 Allow toggling visibility via mouse click on LegendItem
- #1527 Expand parameter tree documentation
- #1563 Fixes to FlowChart documentation
- #1534 Extend pixmaps for GraphIcons
- #1566 Toggle-able options for ScatterPlotSpeedTest.py
- #1572 Arbitrary scale center ROI
- #1581 Equilateral Triangle ROI
Performance enhancement:
- #1493 significant speedup to invertQTransform()
- #1501 various ImageItem performance improvements
- #1509 mkQApp will now have settings for better HiDPI settings
- #1518 Small Optimizations for functions.rescaleData()
- #1556 Reduce reallocation in PlotDataItem dynamic range limiter
- #1560 Cache scatter-plot items by hashable properties
- #1564 Correct id-based keyring of scatter plot pixmap cache
- #1569 Fix ScatterPlotItem performance regression
- #1619 Stop PlotDataItem from always sending full style information to PlotCurveItem/ScatterPlotItem
- #1630 Combine levels and lut only if both are present
- #1632/#1641/#1649 workaround for np.clip regression since numpy 1.17
- #1641 Introduce functions.clip_array as faster replacement for currently slow np.clip
- #1637 PlotDataItem Fix viewRange <-> dynamic range limit
- #1650 Introduce functions.clip_scalar to clip scalar values
API/Behavior Change:
- #1476 Use log modulus transform for y-axis log scaling
- #1522 InfiniteLine emits clicked signal event
- #1525 Use QOpenGLWidget instead of QGLWidget
- #1540 Support siPrefix with no suffix in SpinBox
- #1541 Use qWaitForWindowExposed instead of qWaitForWindowShown
- #1554 Disable paint in GLScatterPlotItem if it has no data
- #1573/1576 Add deprecation warnings to portions of library
- #1587 qApp.property('darkMode') is now a dynamic property
- #1613 Added keys() method to Parameter class
- #1646 Removed unhelpful warnings
- #1645 Make main stanza PyQt6 compatible
- #1644 Deprecate use of hex strings that do not start with "#" in mkColor
Bug Fixes:
- #1487 Fix InfiniteLabel object has no attribute 'updateText'
- #1491 LinearRegionItem would break with setSpan
- #1496 enableMenu setting now preserved when passing ViewBox to PlotItem
- #1498 PlotDataItem now signals on setPos()
- #1500 AlignCenter should have been AlignHCenter
- #1506 Fix "camerPosition" typo in GLViewWidget
- #1510 Fix RemoteGraphicsView mouse interactions on Qt 5.12
- #1517 Fix RemoteSpeedTest Shutdown Errors
- #1528 Support suffix for int parameters in SpinBox
- #1546 ImageView guards against key events when there is no time axis
- #1558 Fix Small Heights in ErrorBarItem
- #1567 Handle 0-d arrays in InfiniteLine.setPos()
- #1583 RawImageWidget fix port to QOpenGLWidget
- #1594 PlotItem removeItem regression fixed
- #1595 Workaround for CuPy Indexing Bug
- #1597 Fix RawImageWidget transpose did not handle luminance only images
- #1598 Remove references to self from lambdas for Signals
- #1618 Install sys.excepthook for PyQt6
- #1639 Fix transformations in GradientLegend
- #1647 Have GraphItem handle empty adjacency array
- #1653 Fix accidentally styled updates in PlotDataItem
- #1651 Use collections.abc for collections metaclasses in colormap.py
pyqtgraph-0.11.1
New Features:
- #800 Legend for bar graphs
- #1244 Arrow scatter symbols
- #161 Allow hiding individulal points in scatter plot
- #161 Allow hiding individual points in scatter plot
- #395 LegendItem display options
- #1310 Added `Pa` to Units
- #1310 `debug.ThreadTrace` add support for thread names
@ -35,14 +128,14 @@ pyqtgraph-0.11.1
- #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
- #1251 Allow explicit 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
- #1264 Added exception to checkOpenGLVersion to highlight OpenGL ES incompatibility
- #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

View File

@ -70,3 +70,14 @@ As PyQtGraph supports a wide array of Qt-bindings, and python versions, we make
### Continous Integration
For our Continuous Integration, we utilize Azure Pipelines. Tested configurations are visible on [README](README.md). More information on coverage and test failures can be found on the respective tabs of the [build results page](https://dev.azure.com/pyqtgraph/pyqtgraph/_build?definitionId=1)
### Benchmarks
( *Still under development* ) To ensure this library is performant, we use [Air Speed Velocity (asv)](https://asv.readthedocs.io/en/stable/) to run benchmarks. For developing on core functions and classes, be aware of any impact your changes have on their speed. To configure and run asv:
```
pip install asv
python setup.py asv_config
asv run
```
( TODO publish results )

View File

@ -55,15 +55,18 @@ The following table represents the python environments we test in our CI system.
| 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: |
| PyQt5-5.12 | :white_check_mark: | | :x: |
| PySide2-5.15 | | :white_check_mark: | |
| PyQt5-5.15 | | :white_check_mark: | |
| PySide6-6.0 | | | :white_check_mark: |
| PyQt6-6.0 | | | :white_check_mark: |
* :x: - Not compatible
* :white_check_mark: - Tested
Support
-------
* Report issues on the [GitHub issue tracker](https://github.com/pyqtgraph/pyqtgraph/issues)
* Post questions to the [mailing list / forum](https://groups.google.com/forum/?fromgroups#!forum/pyqtgraph) or [StackOverflow](https://stackoverflow.com/questions/tagged/pyqtgraph)
@ -94,7 +97,8 @@ Here is a partial listing of some of the applications that make use of PyQtGraph
* [ACQ4](https://github.com/acq4/acq4)
* [Orange3](https://orangedatamining.com/)
* [neurotic](neurotic)
* [neurotic](https://neurotic.readthedocs.io)
* [ephyviewer](https://ephyviewer.readthedocs.io)
* [Joulescope](https://www.joulescope.com/)
* [rapidtide](https://rapidtide.readthedocs.io/en/latest/)
* [argos](https://github.com/titusjan/argos)

View File

@ -1,140 +0,0 @@
{
// 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%
// }
}

View File

@ -1,72 +1,130 @@
import numpy as np
import pyqtgraph as pg
from pyqtgraph.functions import makeARGB
try:
import cupy as cp
class TimeSuite(object):
pg.setConfigOption("useCupy", True)
except ImportError:
cp = None
class _TimeSuite(object):
def __init__(self):
self.c_map = None
super(_TimeSuite, self).__init__()
self.float_data = None
self.uint8_data = None
self.uint8_lut = None
self.uint16_data = None
self.uint16_lut = None
self.output = None
self.cupy_output = 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'],
size = (self.size, self.size)
self.float_data, self.uint16_data, self.uint8_data, self.uint16_lut, self.uint8_lut = self._create_data(
size, np
)
self.output = np.zeros(size + (4,), dtype=np.ubyte)
makeARGB(self.uint16_data["data"]) # prime the cpu
if cp:
self.cupy_output = cp.zeros(size + (4,), dtype=cp.ubyte)
makeARGB(cp.asarray(self.uint16_data["data"])) # prime the gpu
@staticmethod
def _create_data(size, xp):
float_data = {
"data": xp.random.normal(size=size),
"levels": [-4.0, 4.0],
}
uint16_data = {
"data": xp.random.randint(100, 4500, size=size).astype("uint16"),
"levels": [250, 3000],
}
uint8_data = {
"data": xp.random.randint(0, 255, size=size).astype("ubyte"),
"levels": [20, 220],
}
c_map = xp.array([[-500.0, 255.0], [-255.0, 255.0], [0.0, 500.0]])
uint8_lut = xp.zeros((256, 4), dtype="ubyte")
for i in range(3):
uint8_lut[:, i] = xp.clip(xp.linspace(c_map[i][0], c_map[i][1], 256), 0, 255)
uint8_lut[:, 3] = 255
uint16_lut = xp.zeros((2 ** 16, 4), dtype="ubyte")
for i in range(3):
uint16_lut[:, i] = xp.clip(xp.linspace(c_map[i][0], c_map[i][1], 2 ** 16), 0, 255)
uint16_lut[:, 3] = 255
return float_data, uint16_data, uint8_data, uint16_lut, uint8_lut
def make_test(dtype, use_cupy, use_levels, lut_name, func_name):
def time_test(self):
data = getattr(self, dtype + "_data")
levels = data["levels"] if use_levels else None
lut = getattr(self, lut_name + "_lut", None) if lut_name is not None else None
for _ in range(10):
img_data = data["data"]
output = self.output
if use_cupy:
img_data = cp.asarray(img_data)
output = self.cupy_output
makeARGB(
img_data, lut=lut, levels=levels, output=output,
)
if use_cupy:
output.get(out=self.output)
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))
for cupy in [True, False]:
if cupy and cp is None:
continue
for dtype in ["float", "uint16", "uint8"]:
for levels in [True, False]:
if dtype == "float" and not levels:
continue
for lutname in [None, "uint8", "uint16"]:
name = (
f'time_10x_makeARGB_{"cupy" if cupy else ""}{dtype}_{"" if levels else "no"}levels_{lutname or "no"}lut'
)
setattr(_TimeSuite, name, make_test(dtype, cupy, levels, lutname, name))
if __name__ == "__main__":
ts = TimeSuite()
ts.setup()
class Time0256Suite(_TimeSuite):
def __init__(self):
self.size = 256
super(Time0256Suite, self).__init__()
class Time0512Suite(_TimeSuite):
def __init__(self):
self.size = 512
super(Time0512Suite, self).__init__()
class Time1024Suite(_TimeSuite):
def __init__(self):
self.size = 1024
super(Time1024Suite, self).__init__()
class Time2048Suite(_TimeSuite):
def __init__(self):
self.size = 2048
super(Time2048Suite, self).__init__()
class Time3072Suite(_TimeSuite):
def __init__(self):
self.size = 3072
super(Time3072Suite, self).__init__()
class Time4096Suite(_TimeSuite):
def __init__(self):
self.size = 4096
super(Time4096Suite, self).__init__()

View File

@ -26,10 +26,7 @@ imageAxisOrder str 'col-major' For 'row-major', image
change in the future.
editorCommand str or None None Command used to invoke code editor from ConsoleWidget.
exitCleanup bool True Attempt to work around some exit crash bugs in PyQt and PySide.
useWeave bool False Use weave to speed up some operations, if it is available.
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.
useOpenGL bool False Enable OpenGL in GraphicsView.
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).

View File

@ -46,3 +46,4 @@ Contents:
uigraphicsitem
graphicswidgetanchor
dateaxisitem
targetitem

View File

@ -0,0 +1,17 @@
TargetItem
==========
.. autoclass:: pyqtgraph.TargetItem
:members:
.. automethod:: pyqtgraph.TargetItem.__init__
TargetLabel
==================
.. autoclass:: pyqtgraph.TargetLabel
:members:
.. automethod:: pyqtgraph.TargetLabel.__init__

View File

@ -101,11 +101,11 @@ Embedding PyQtGraph as a sub-package of a larger project
When writing applications or python packages that make use of pyqtgraph, it is most common to install pyqtgraph system-wide (or within a virtualenv) and simply call `import pyqtgraph` from within your application. The main benefit to this is that pyqtgraph is configured independently of your application and thus you (or your users) are free to install newer versions of pyqtgraph without changing anything in your application. This is standard practice when developing with python.
However, it is also often the case, especially for scientific applications, that software is written for a very specific purpose and then archived. If we want to ensure that the software will still work ten years later, then it is preferrable to tie the application to a very specific version of pyqtgraph and *avoid* importing the system-installed version of pyqtgraph, which may be much newer (and potentially incompatible). This is especially the case when the application requires site-specific modifications to the pyqtgraph package which may not be present in the main releases.
Occasionally, a specific program needs to be kept in working order for an extended amount of time after development has been completed. This is often the case for single-purpose scientific applications. If we want to ensure that the software will still work ten years later, then it is preferrable to tie it to a very specific version of pyqtgraph and *avoid* importing the system-installed version, which may be much newer and potentially incompatible. This is especially true when the application requires site-specific modifications to the pyqtgraph package.
PyQtGraph facilitates this usage through two mechanisms. First, all internal import statements in pyqtgraph are relative, which allows the package to be renamed or used as a sub-package without any naming conflicts with other versions of pyqtgraph on the system (that is, pyqtgraph never refers to itself internally as 'pyqtgraph'). Second, a git subtree repository is available at https://github.com/pyqtgraph/pyqtgraph-core.git that contains only the 'pyqtgraph/' subtree, allowing the code to be cloned directly as a subtree of the application which uses it.
To support such a separate local installation, all internal import statements in pyqtgraph are relative. That means that pyqtgraph never refers to itself internally as 'pyqtgraph'. This allows the package to be renamed or used as a sub-package without any naming conflicts with other versions of pyqtgraph on the system.
The basic approach is to clone the repository into the appropriate location in your package. When you import pyqtgraph from within your package, be sure to use the full name to avoid importing any system-installed pyqtgraph packages. For example, imagine a simple project has the following structure::
The basic approach is to clone the repository into the appropriate location in your project. When you import pyqtgraph, be sure to use the full name to avoid importing any system-installed pyqtgraph packages. For example, imagine a simple project has the following structure::
my_project/
__init__.py
@ -115,32 +115,32 @@ The basic approach is to clone the repository into the appropriate location in y
def my_plot_function(*data):
pg.plot(*data)
To embed a specific version of pyqtgraph, we would clone the pyqtgraph-core repository inside the project::
To embed a specific version of pyqtgraph, we would clone the pyqtgraph repository inside the project, with a directory name that distinguishes it from a system-wide installation::
my_project$ git clone https://github.com/pyqtgraph/pyqtgraph-core.git
my_project$ git clone https://github.com/pyqtgraph/pyqtgraph.git local_pyqtgraph
Then adjust the import statements accordingly::
my_project/
__init__.py
pyqtgraph/
local_pyqtgraph/
plotting.py
"""Plotting functions used by this package"""
import my_project.pyqtgraph as pg # be sure to use the local subpackage
# rather than any globally-installed
# versions.
import local_pyqtgraph.pyqtgraph as pg # be sure to use the local subpackage
# rather than any globally-installed
# version.
def my_plot_function(*data):
pg.plot(*data)
Use ``git checkout pyqtgraph-core-x.x.x`` to select a specific version of the repository, or use ``git pull`` to pull pyqtgraph updates from upstream (see the git documentation for more information).
Use ``git checkout pyqtgraph-x.x.x`` to select a specific library version from the repository, or use ``git pull`` to pull pyqtgraph updates from upstream (see the git documentation for more information). If you do not plan to make use of git's versioning features, adding the option ``--depth 1`` to the ``git clone`` command retrieves only the latest version.
For projects that already use git for code control, it is also possible to include pyqtgraph as a git subtree within your own repository. The major advantage to this approach is that, in addition to being able to pull pyqtgraph updates from the upstream repository, it is also possible to commit your local pyqtgraph changes into the project repository and push those changes upstream::
my_project$ git remote add pyqtgraph-core https://github.com/pyqtgraph/pyqtgraph-core.git
my_project$ git fetch pyqtgraph-core
my_project$ git merge -s ours --no-commit pyqtgraph-core/core
my_project$ mkdir pyqtgraph
my_project$ git read-tree -u --prefix=pyqtgraph/ pyqtgraph-core/core
my_project$ git remote add pyqtgraph https://github.com/pyqtgraph/pyqtgraph.git
my_project$ git fetch pyqtgraph
my_project$ git merge -s ours --allow-unrelated-histories --no-commit pyqtgraph/master
my_project$ mkdir local_pyqtgraph
my_project$ git read-tree -u --prefix=local_pyqtgraph/ pyqtgraph/master
my_project$ git commit -m "Added pyqtgraph to project repository"
See the ``git subtree`` documentation for more information.

View File

@ -21,6 +21,6 @@ There are a few other methods for displaying images as well:
* Instances of :class:`~pyqtgraph.ImageItem` can be used inside a :class:`ViewBox <pyqtgraph.ViewBox>` or :class:`GraphicsView <pyqtgraph.GraphicsView>`.
* For higher performance, use :class:`~pyqtgraph.RawImageWidget`.
Any of these classes are acceptable for displaying video by calling setImage() to display a new frame. To increase performance, the image processing system uses scipy.weave to produce compiled libraries. If your computer has a compiler available, weave will automatically attempt to build the libraries it needs on demand. If this fails, then the slower pure-python methods will be used instead.
Any of these classes are acceptable for displaying video by calling setImage() to display a new frame.
For more information, see the classes listed above and the 'VideoSpeedTest', 'ImageItem', 'ImageView', and 'HistogramLUT' :ref:`examples`.

View File

@ -50,8 +50,5 @@ p2.addItem(a)
anim = a.makeAnimation(loop=-1)
anim.start()
## 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_()
pg.mkQApp().exec_()

View File

@ -34,8 +34,5 @@ class BarGraph(pg.BarGraphItem):
bg = BarGraph(x=x, y=y1*0.3+2, height=0.4+y1*0.2, width=0.8)
win.addItem(bg)
## 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_()
pg.mkQApp().exec_()

View File

@ -18,9 +18,5 @@ pg.plot(data, title="Simplest possible plotting example")
data = np.random.normal(size=(500,500))
pg.image(data, title="Simplest possible image example")
## 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'):
pg.QtGui.QApplication.exec_()
pg.mkQApp().exec_()

100
examples/ColorBarItem.py Normal file
View File

@ -0,0 +1,100 @@
# -*- coding: utf-8 -*-
"""
This example demonstrates the use of ColorBarItem, which displays a simple interactive color bar.
"""
## Add path to library (just for examples; you do not need this)
import initExample
import numpy as np
from pyqtgraph.Qt import QtWidgets, mkQApp
import pyqtgraph as pg
class MainWindow(QtWidgets.QMainWindow):
""" example application main window """
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
gr_wid = pg.GraphicsLayoutWidget(show=True)
self.setCentralWidget(gr_wid)
self.setWindowTitle('pyqtgraph example: Interactive color bar')
self.resize(800,700)
self.show()
## Create image items
data = np.fromfunction(lambda i, j: (1+0.3*np.sin(i)) * (i)**2 + (j)**2, (100, 100))
noisy_data = data * (1 + 0.2 * np.random.random(data.shape) )
noisy_transposed = noisy_data.transpose()
#--- add non-interactive image with integrated color -----------------
i1 = pg.ImageItem(image=data)
p1 = gr_wid.addPlot(title="non-interactive")
p1.addItem( i1 )
p1.setMouseEnabled( x=False, y=False)
p1.disableAutoRange()
p1.hideButtons()
p1.setRange(xRange=(0,100), yRange=(0,100), padding=0)
for key in ['left','right','top','bottom']:
p1.showAxis(key)
axis = p1.getAxis(key)
axis.setZValue(1)
if key in ['top', 'right']:
p1.getAxis(key).setStyle( showValues=False )
cmap = pg.colormap.get('CET-L9')
bar = pg.ColorBarItem(
interactive=False, values= (0, 30_000), cmap=cmap,
label='vertical fixed color bar'
)
bar.setImageItem( i1, insert_in=p1 )
#--- add interactive image with integrated horizontal color bar --------------
i2 = pg.ImageItem(image=noisy_data)
p2 = gr_wid.addPlot(1,0, 1,1, title="interactive")
p2.addItem( i2, title='' )
# inserted color bar also works with labels on the right.
p2.showAxis('right')
p2.getAxis('left').setStyle( showValues=False )
p2.getAxis('bottom').setLabel('bottom axis label')
p2.getAxis('right').setLabel('right axis label')
cmap = pg.colormap.get('CET-L4')
bar = pg.ColorBarItem(
values = (0, 30_000),
cmap=cmap,
label='horizontal color bar',
limits = (0, None),
rounding=1000,
orientation = 'horizontal',
pen='#8888FF', hoverPen='#EEEEFF', hoverBrush='#EEEEFF80'
)
bar.setImageItem( i2, insert_in=p2 )
#--- multiple images adjusted by a separate color bar ------------------------
i3 = pg.ImageItem(image=noisy_data)
p3 = gr_wid.addPlot(0,1, 1,1, title="shared 1")
p3.addItem( i3 )
i4 = pg.ImageItem(image=noisy_transposed)
p4 = gr_wid.addPlot(1,1, 1,1, title="shared 2")
p4.addItem( i4 )
cmap = pg.colormap.get('CET-L8')
bar = pg.ColorBarItem(
# values = (-15_000, 15_000),
limits = (-30_000, 30_000), # start with full range...
rounding=1000,
width = 10,
cmap=cmap )
bar.setImageItem( [i3, i4] )
bar.setLevels( low=-5_000, high=15_000) # ... then adjust to retro sunset.
# manually adjust reserved space at top and bottom to align with plot
bar.getAxis('bottom').setHeight(21)
bar.getAxis('top').setHeight(31)
gr_wid.addItem(bar, 0,2, 2,1) # large bar spanning both rows
mkQApp("ColorBarItem Example")
main_window = MainWindow()
## Start Qt event loop
if __name__ == '__main__':
mkQApp().exec_()

View File

@ -26,8 +26,5 @@ def done(btn):
btn.sigColorChanging.connect(change)
btn.sigColorChanged.connect(done)
## 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_()
pg.mkQApp().exec_()

View File

@ -29,8 +29,5 @@ c = pyqtgraph.console.ConsoleWidget(namespace=namespace, text=text)
c.show()
c.setWindowTitle('pyqtgraph example: ConsoleWidget')
## 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_()
pg.mkQApp().exec_()

View File

@ -129,8 +129,5 @@ g.setData(pos=pos, adj=adj, pen=lines, size=1, symbol=symbols, pxMode=False, tex
## 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_()
pg.mkQApp().exec_()

View File

@ -57,8 +57,5 @@ imv1.setLevels(-0.003, 0.003)
update()
## 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_()
pg.mkQApp().exec_()

View File

@ -42,8 +42,5 @@ tree.setWindowTitle('pyqtgraph example: DataTreeWidget')
tree.resize(600,600)
## 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_()
pg.mkQApp().exec_()

View File

@ -26,8 +26,5 @@ w.plot(now-(2*np.pi/x)**2*100*np.pi*1e7, np.sin(x), symbol='o')
w.setWindowTitle('pyqtgraph example: DateAxisItem')
w.show()
## 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'):
app.exec_()
app.exec_()

View File

@ -42,8 +42,5 @@ window = ExampleApp()
window.setWindowTitle('pyqtgraph example: DateAxisItem_QtDesigner')
window.show()
## 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'):
app.exec_()
app.exec_()

View File

@ -45,8 +45,5 @@ tree.setWindowTitle('pyqtgraph example: DiffTreeWidget')
tree.resize(1000, 800)
## 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_()
pg.mkQApp().exec_()

View File

@ -42,8 +42,5 @@ kern = np.array([
img.setDrawKernel(kern, mask=kern, center=(1,1), mode='add')
img.setLevels([0, 10])
## 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_()
pg.mkQApp().exec_()

View File

@ -26,8 +26,5 @@ err = pg.ErrorBarItem(x=x, y=y, top=top, bottom=bottom, beam=0.5)
plt.addItem(err)
plt.plot(x, y, symbol='o', pen={'color': 0.8, 'width': 2})
## 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_()
pg.mkQApp().exec_()

View File

@ -360,15 +360,7 @@ class ExampleLoader(QtGui.QMainWindow):
fn = self.currentFile()
if fn is None:
return
if sys.platform.startswith('win'):
args = [os.P_NOWAIT, sys.executable, '"'+sys.executable+'"', '"' + fn + '"']
else:
args = [os.P_NOWAIT, sys.executable, sys.executable, fn]
if env is None:
os.spawnl(*args)
else:
args.append(env)
os.spawnle(*args)
subprocess.Popen([sys.executable, fn], env=env)
def showFile(self):
fn = self.currentFile()
@ -377,7 +369,8 @@ class ExampleLoader(QtGui.QMainWindow):
return
if os.path.isdir(fn):
fn = os.path.join(fn, '__main__.py')
text = open(fn).read()
with open(fn, "r") as currentFile:
text = currentFile.read()
self.ui.codeView.setPlainText(text)
self.ui.loadedFileLabel.setText(fn)
self.codeBtn.hide()
@ -393,7 +386,6 @@ def main():
app = pg.mkQApp()
loader = ExampleLoader()
app.exec_()
# or condition so pytest runs ExampleApp as part of test suite
if __name__ == '__main__':
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
main()
main()

View File

@ -45,8 +45,5 @@ timer.timeout.connect(update)
timer.start(30)
## 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_()
pg.mkQApp().exec_()

View File

@ -75,10 +75,5 @@ fc.connectTerminals(fc['dataIn'], pw1Node['In'])
fc.connectTerminals(fNode['Out'], pw2Node['In'])
fc.connectTerminals(fNode['Out'], fc['dataOut'])
## 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_()
pg.mkQApp().exec_()

View File

@ -150,10 +150,5 @@ fc.connectTerminals(fc['dataIn'], v1Node['data'])
fc.connectTerminals(fNode['dataOut'], v2Node['data'])
fc.connectTerminals(fNode['dataOut'], fc['dataOut'])
## 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_()
pg.mkQApp().exec_()

View File

@ -39,9 +39,5 @@ size[...,2] = np.random.normal(size=(10,10))
bg = gl.GLBarGraphItem(pos, size)
w.addItem(bg)
## 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_()
pg.mkQApp().exec_()

View File

@ -50,8 +50,5 @@ w.addItem(v3)
ax = gl.GLAxisItem()
w.addItem(ax)
## 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_()
pg.mkQApp().exec_()

View File

@ -7,7 +7,7 @@ This example uses the isosurface function to convert a scalar field
## Add path to library (just for examples; you do not need this)
import initExample
from pyqtgraph.Qt import QtCore, QtGui
import numpy as np
import pyqtgraph as pg
import pyqtgraph.opengl as gl
@ -22,23 +22,16 @@ g = gl.GLGridItem()
g.scale(2,2,1)
w.addItem(g)
import numpy as np
## Define a scalar field from which we will generate an isosurface
def psi(i, j, k, offset=(25, 25, 50)):
x = i-offset[0]
y = j-offset[1]
z = k-offset[2]
th = np.arctan2(z, (x**2+y**2)**0.5)
phi = np.arctan2(y, x)
r = (x**2 + y**2 + z **2)**0.5
th = np.arctan2(z, np.hypot(x, y))
r = np.sqrt(x**2 + y**2 + z **2)
a0 = 1
#ps = (1./81.) * (2./np.pi)**0.5 * (1./a0)**(3/2) * (6 - r/a0) * (r/a0) * np.exp(-r/(3*a0)) * np.cos(th)
ps = (1./81.) * 1./(6.*np.pi)**0.5 * (1./a0)**(3/2) * (r/a0)**2 * np.exp(-r/(3*a0)) * (3 * np.cos(th)**2 - 1)
return ps
#return ((1./81.) * (1./np.pi)**0.5 * (1./a0)**(3/2) * (r/a0)**2 * (r/a0) * np.exp(-r/(3*a0)) * np.sin(th) * np.cos(th) * np.exp(2 * 1j * phi))**2
print("Generating scalar field..")
@ -66,10 +59,5 @@ m2.setGLOptions('additive')
w.addItem(m2)
m2.translate(-25, -25, -50)
## 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_()
pg.mkQApp().exec_()

View File

@ -29,24 +29,16 @@ gz = gl.GLGridItem()
gz.translate(0, 0, -10)
w.addItem(gz)
def fn(x, y):
return np.cos((x**2 + y**2)**0.5)
n = 51
y = np.linspace(-10,10,n)
x = np.linspace(-10,10,100)
for i in range(n):
yi = np.array([y[i]]*100)
d = (x**2 + yi**2)**0.5
yi = y[i]
d = np.hypot(x, yi)
z = 10 * np.cos(d) / (d+1)
pts = np.vstack([x,yi,z]).transpose()
pts = np.column_stack([x, np.full_like(x, yi), z])
plt = gl.GLLinePlotItem(pos=pts, color=pg.glColor((i,n*1.3)), width=(i+1)/10., antialias=True)
w.addItem(plt)
## 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_()
pg.mkQApp().exec_()

View File

@ -117,13 +117,5 @@ m6.rotate(0., 0, 1, 1)
w.addItem(m5)
w.addItem(m6)
## 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_()
pg.mkQApp().exec_()

View File

@ -8,6 +8,7 @@ Demonstrates use of GLScatterPlotItem with rapidly-updating plots.
import initExample
import pyqtgraph as pg
from pyqtgraph import functions as fn
from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph.opengl as gl
import numpy as np
@ -84,10 +85,10 @@ def update():
global phase, sp2, d2
s = -np.cos(d2*2+phase)
color = np.empty((len(d2),4), dtype=np.float32)
color[:,3] = np.clip(s * 0.1, 0, 1)
color[:,0] = np.clip(s * 3.0, 0, 1)
color[:,1] = np.clip(s * 1.0, 0, 1)
color[:,2] = np.clip(s ** 3, 0, 1)
color[:,3] = fn.clip_array(s * 0.1, 0., 1.)
color[:,0] = fn.clip_array(s * 3.0, 0., 1.)
color[:,1] = fn.clip_array(s * 1.0, 0., 1.)
color[:,2] = fn.clip_array(s ** 3, 0., 1.)
sp2.setData(color=color)
phase -= 0.1
@ -106,9 +107,5 @@ t = QtCore.QTimer()
t.timeout.connect(update)
t.start(50)
## 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_()
pg.mkQApp().exec_()

View File

@ -92,8 +92,5 @@ timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(30)
## 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_()
pg.mkQApp().exec_()

View File

@ -27,8 +27,5 @@ ax2.setParentItem(b)
b.translate(1,1,1)
## 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_()
pg.mkQApp().exec_()

View File

@ -7,9 +7,10 @@ Demonstrates GLVolumeItem for displaying volumetric data.
## Add path to library (just for examples; you do not need this)
import initExample
import numpy as np
import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph.opengl as gl
from pyqtgraph import functions as fn
app = pg.mkQApp("GLVolumeItem Example")
w = gl.GLViewWidget()
@ -23,27 +24,21 @@ g = gl.GLGridItem()
g.scale(10, 10, 1)
w.addItem(g)
import numpy as np
## Hydrogen electron probability density
def psi(i, j, k, offset=(50,50,100)):
x = i-offset[0]
y = j-offset[1]
z = k-offset[2]
th = np.arctan2(z, (x**2+y**2)**0.5)
phi = np.arctan2(y, x)
r = (x**2 + y**2 + z **2)**0.5
th = np.arctan2(z, np.hypot(x, y))
r = np.sqrt(x**2 + y**2 + z **2)
a0 = 2
#ps = (1./81.) * (2./np.pi)**0.5 * (1./a0)**(3/2) * (6 - r/a0) * (r/a0) * np.exp(-r/(3*a0)) * np.cos(th)
ps = (1./81.) * 1./(6.*np.pi)**0.5 * (1./a0)**(3/2) * (r/a0)**2 * np.exp(-r/(3*a0)) * (3 * np.cos(th)**2 - 1)
return ps
#return ((1./81.) * (1./np.pi)**0.5 * (1./a0)**(3/2) * (r/a0)**2 * (r/a0) * np.exp(-r/(3*a0)) * np.sin(th) * np.cos(th) * np.exp(2 * 1j * phi))**2
data = np.fromfunction(psi, (100,100,200))
positive = np.log(np.clip(data, 0, data.max())**2)
negative = np.log(np.clip(-data, 0, -data.min())**2)
positive = np.log(fn.clip_array(data, np.finfo(data.dtype).eps, data.max())**2)
negative = np.log(fn.clip_array(-data, -np.finfo(data.dtype).eps, -data.min())**2)
d2 = np.empty(data.shape + (4,), dtype=np.ubyte)
d2[..., 0] = positive * (255./positive.max())
@ -63,8 +58,5 @@ w.addItem(v)
ax = gl.GLAxisItem()
w.addItem(ax)
## 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_()
pg.mkQApp().exec_()

View File

@ -9,6 +9,7 @@ used to affect the appearance of a surface.
## 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
import pyqtgraph.opengl as gl
@ -23,9 +24,6 @@ g = gl.GLGridItem()
g.scale(2,2,1)
w.addItem(g)
import numpy as np
md = gl.MeshData.sphere(rows=10, cols=20)
x = np.linspace(-8, 8, 6)
@ -101,10 +99,5 @@ w.addItem(m6)
#w.addItem(m2)
#m2.translate(-25, -25, -50)
## 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_()
pg.mkQApp().exec_()

View File

@ -20,9 +20,5 @@ mw.show()
ge = pg.GradientEditorItem()
mw.setCentralItem(ge)
## 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_()
pg.mkQApp().exec_()

View File

@ -47,12 +47,8 @@ l.addWidget(w3, 2, 1)
l.addWidget(w4, 1, 0)
l.addWidget(label, 1, 1)
## 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_()
pg.mkQApp().exec_()

View File

@ -57,11 +57,5 @@ lines = np.array([
## Update the graph
g.setData(pos=pos, adj=adj, pen=lines, size=1, symbol=symbols, pxMode=False)
## 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_()
pg.mkQApp().exec_()

View File

@ -78,10 +78,5 @@ p2.plot([1,3,2,4,3,5])
p4.plot([1,3,2,4,3,5])
p5.plot([1,3,2,4,3,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_()
pg.mkQApp().exec_()

View File

@ -58,9 +58,5 @@ vb.addItem(prox)
g = pg.GridItem()
vb.addItem(g)
## 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_()
pg.mkQApp().exec_()

View File

@ -3,45 +3,49 @@
Use a HistogramLUTWidget to control the contrast / coloration of an image.
"""
## Add path to library (just for examples; you do not need this)
# Add path to library (just for examples; you do not need this)
import initExample
import numpy as np
from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg
import pyqtgraph as pg
from pyqtgraph.Qt import QtGui
app = pg.mkQApp("Histogram Lookup Table Example")
win = QtGui.QMainWindow()
win.resize(800,600)
win.resize(880, 600)
win.show()
win.setWindowTitle('pyqtgraph example: Histogram LUT')
cw = QtGui.QWidget()
win.setCentralWidget(cw)
l = QtGui.QGridLayout()
cw.setLayout(l)
l.setSpacing(0)
layout = QtGui.QGridLayout()
cw.setLayout(layout)
layout.setSpacing(0)
v = pg.GraphicsView()
view = pg.GraphicsView()
vb = pg.ViewBox()
vb.setAspectLocked()
v.setCentralItem(vb)
l.addWidget(v, 0, 0, 3, 1)
view.setCentralItem(vb)
layout.addWidget(view, 0, 1, 3, 1)
hist = pg.HistogramLUTWidget(gradientPosition="left")
layout.addWidget(hist, 0, 2)
w = pg.HistogramLUTWidget()
l.addWidget(w, 0, 1)
monoRadio = QtGui.QRadioButton('mono')
rgbaRadio = QtGui.QRadioButton('rgba')
l.addWidget(monoRadio, 1, 1)
l.addWidget(rgbaRadio, 2, 1)
layout.addWidget(monoRadio, 1, 2)
layout.addWidget(rgbaRadio, 2, 2)
monoRadio.setChecked(True)
def setLevelMode():
mode = 'mono' if monoRadio.isChecked() else 'rgba'
w.setLevelMode(mode)
hist.setLevelMode(mode)
monoRadio.toggled.connect(setLevelMode)
data = pg.gaussianFilter(np.random.normal(size=(256, 256, 3)), (20, 20, 0))
@ -52,11 +56,7 @@ img = pg.ImageItem(data)
vb.addItem(img)
vb.autoRange()
w.setImageItem(img)
hist.setImageItem(img)
## 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_()
pg.mkQApp().exec_()

View File

@ -58,8 +58,5 @@ def updateData():
timer.timeout.connect(updateData)
updateData()
## 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_()
pg.mkQApp().exec_()

View File

@ -63,8 +63,5 @@ imv.setColorMap(cmap)
imv.ui.roiBtn.setChecked(True)
imv.roiClicked()
## 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_()
pg.mkQApp().exec_()

View File

@ -32,14 +32,54 @@ p1.addItem(inf1)
p1.addItem(inf2)
p1.addItem(inf3)
targetItem1 = pg.TargetItem()
targetItem2 = pg.TargetItem(
pos=(30, 5),
size=20,
symbol="star",
pen="#F4511E",
label="vert={1:0.2f}",
labelOpts={
"offset": QtCore.QPoint(15, 15)
}
)
targetItem2.label().setAngle(45)
targetItem3 = pg.TargetItem(
pos=(10, 10),
size=10,
symbol="x",
pen="#00ACC1",
)
targetItem3.setLabel(
"Third Label",
{
"anchor": QtCore.QPointF(0.5, 0.5),
"offset": QtCore.QPointF(30, 0),
"color": "#558B2F",
"rotateAxis": (0, 1)
}
)
def callableFunction(x, y):
return f"Square Values: ({x**2:.4f}, {y**2:.4f})"
targetItem4 = pg.TargetItem(
pos=(10, -10),
label=callableFunction
)
p1.addItem(targetItem1)
p1.addItem(targetItem2)
p1.addItem(targetItem3)
p1.addItem(targetItem4)
# Add a linear region with a label
lr = pg.LinearRegionItem(values=[70, 80])
p1.addItem(lr)
label = pg.InfLineLabel(lr.lines[1], "region 1", position=0.95, rotateAxis=(1,0), anchor=(1, 1))
## 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_()
pg.mkQApp().exec_()

View File

@ -46,11 +46,5 @@ timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(30)
## 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_()
pg.mkQApp().exec_()

View File

@ -39,8 +39,5 @@ 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
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_()
pg.mkQApp().exec_()

View File

@ -30,8 +30,5 @@ p5.setLabel('bottom', "Y Axis", units='s')
p5.setLogMode(x=True, y=False)
## 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_()
pg.mkQApp().exec_()

View File

@ -30,8 +30,5 @@ for c in curves:
win.addItem(c)
c.sigClicked.connect(plotClicked)
## 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_()
pg.mkQApp().exec_()

View File

@ -62,8 +62,5 @@ timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(0)
## 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_()
pg.mkQApp().exec_()

View File

@ -32,9 +32,6 @@ ma = MetaArray(data, info=[
])
pw.plot(ma, pen='y')
## 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_()
pg.mkQApp().exec_()

View File

@ -60,8 +60,5 @@ p1.plot([1,2,4,8,16,32])
p2.addItem(pg.PlotCurveItem([10,20,40,80,40,20], pen='b'))
p3.addItem(pg.PlotCurveItem([3200,1600,800,400,200,100], pen='r'))
## 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_()
pg.mkQApp().exec_()

View File

@ -78,9 +78,5 @@ p.setLabel(axis='left', text='Torque [Nm]')
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_()
pg.mkQApp().exec_()

View File

@ -83,8 +83,5 @@ def updateData():
timer.timeout.connect(updateData)
updateData()
## 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_()
pg.mkQApp().exec_()

View File

@ -26,7 +26,7 @@ class MainWindow(QtWidgets.QMainWindow):
test_palette = pg.palette.get('system')
pg.palette.get('relaxed-dark').apply()
pg.palette.get('relaxed_dark').apply()
main_layout = QtWidgets.QGridLayout( main_wid )
gr_wid = pg.GraphicsLayoutWidget(show=True)

View File

@ -75,7 +75,7 @@ class MainWindow(QtWidgets.QMainWindow):
ax.setZValue(0.1)
self.curves = []
curve = pg.PlotCurveItem(pen='p0', brush='p0') # ('p0',127))
curve = pg.PlotCurveItem(pen='p0', brush=('p0',127))
curve.setFillLevel(0)
self.curves.append( (1, 1, curve) ) # dataset 1, vertical offset 3
plt.addItem(curve)
@ -101,7 +101,7 @@ class MainWindow(QtWidgets.QMainWindow):
plt.getAxis('left').setLabel('plot color')
plt.getAxis('left').setGrid(0.5) # 63)
pen_list = [('p0',255),'p1','p2','p3','p4','p5','p6','p7'] # add right-side plots for each main color
pen_list = [('p0',2),('p1',2),('p2',2),('p3',2),('p4',2),('p5',2),('p6',2),('p7',2)] # add right-side plots for each main color
for idx, pen in enumerate( pen_list ):
curve = pg.PlotCurveItem(pen=pen)
self.curves.append( (1+idx, idx, curve) ) # datasets 2+, vertical offset by index
@ -231,9 +231,12 @@ class MainWindow(QtWidgets.QMainWindow):
def make_dark_QPalette(self):
# color definitions match QDarkstyle
BLACK = QtGui.QColor('#000000')
BG_LIGHT = QtGui.QColor('#505F69')
BG_NORMAL = QtGui.QColor('#32414B')
BG_DARK = QtGui.QColor('#19232D')
# BG_LIGHT = QtGui.QColor('#505F69')
# BG_NORMAL = QtGui.QColor('#32414B')
# BG_DARK = QtGui.QColor('#19232D')
BG_LIGHT = QtGui.QColor('#32414B')
BG_NORMAL = QtGui.QColor('#212a31')
BG_DARK = QtGui.QColor('#101518')
FG_LIGHT = QtGui.QColor('#F0F0F0')
FG_NORMAL = QtGui.QColor('#AAAAAA')
FG_DARK = QtGui.QColor('#787878')
@ -296,22 +299,27 @@ class MainWindow(QtWidgets.QMainWindow):
l_layout.setContentsMargins(0,0,0,0)
l_layout.setSpacing(1)
row_idx = 0
label = QtWidgets.QLabel('Select a palette:')
label = QtWidgets.QLabel('System style:')
l_layout.addWidget( label, row_idx,0, 1,2 )
label = QtWidgets.QLabel('Select a palette:')
l_layout.addWidget( label, row_idx,2, 1,2 )
row_idx += 1
btn = QtWidgets.QPushButton('dark GUI')
btn.setCheckable(True)
btn.setChecked(False)
btn.clicked.connect(self.handle_dark_button)
box = QtWidgets.QComboBox()
for text, identifier, args in self.palette_options:
del identifier, args # not needed here
box.addItem(text)
box.activated.connect(self.handle_palette_select)
btn = QtWidgets.QPushButton('dark GUI')
btn.setCheckable(True)
btn.setChecked(False)
btn.clicked.connect(self.handle_dark_button)
l_layout.addWidget( box, row_idx,0, 1,2 )
l_layout.addWidget( btn, row_idx,3, 1,1 )
l_layout.addWidget( box, row_idx,2, 1,2 )
l_layout.addWidget( btn, row_idx,0, 1,2 )
ui['dark'] = btn
row_idx += 1

View File

@ -30,8 +30,5 @@ timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(50)
## 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_()
pg.mkQApp().exec_()

View File

@ -40,10 +40,5 @@ timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(50)
## 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_()
pg.mkQApp().exec_()

View File

@ -48,10 +48,5 @@ timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(0)
## 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_()
pg.mkQApp().exec_()

View File

@ -86,8 +86,5 @@ line = pg.InfiniteLine(angle=90, movable=True)
pw3.addItem(line)
line.setBounds([0,200])
## 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_()
pg.mkQApp().exec_()

View File

@ -95,8 +95,5 @@ lr.sigRegionChanged.connect(updatePlot)
p9.sigXRangeChanged.connect(updateRegion)
updatePlot()
## 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_()
pg.mkQApp().exec_()

View File

@ -157,15 +157,5 @@ def remove():
v4.removeItem(r4)
r4.sigRemoveRequested.connect(remove)
## 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_()
pg.mkQApp().exec_()

View File

@ -118,10 +118,5 @@ t = QtCore.QTimer()
t.timeout.connect(updateImage)
t.start(50)
## 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_()
pg.mkQApp().exec_()

View File

@ -26,9 +26,5 @@ plt = v.pg.PlotItem()
v.setCentralItem(plt)
plt.plot([1,4,2,3,6,2,3,4,2,3], pen='g')
## 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_()
pg.mkQApp().exec_()

View File

@ -72,10 +72,5 @@ timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(0)
## 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_()
pg.mkQApp().exec_()

View File

@ -24,8 +24,5 @@ scale = pg.ScaleBar(size=0.1)
scale.setParentItem(vb)
scale.anchor((1, 1), (1, 1), offset=(-20, -20))
## 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_()
pg.mkQApp().exec_()

View File

@ -134,9 +134,5 @@ s4.addPoints(
w4.addItem(s4)
s4.sigClicked.connect(clicked)
## 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_()
pg.mkQApp().exec_()

View File

@ -128,10 +128,5 @@ param.child('paused').sigValueChanged.connect(lambda _, v: timer.stop() if v els
timer.timeout.connect(update)
timer.start(0)
# 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_()
pg.mkQApp().exec_()

View File

@ -62,9 +62,5 @@ spw.setFields([
spw.setData(data)
spw.show()
## 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_()
pg.mkQApp().exec_()

View File

@ -5,8 +5,5 @@ import pyqtgraph.exporters
import numpy as np
plt = pg.plot(np.random.normal(size=100), title="Simplest possible plotting example")
## 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(pg.QtCore, 'PYQT_VERSION'):
pg.QtGui.QApplication.exec_()
pg.mkQApp().exec_()

View File

@ -128,8 +128,5 @@ layout.addWidget(changedLabel, 2, 1)
#s.editingFinished.disconnect()
## 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_()
pg.mkQApp().exec_()

View File

@ -35,8 +35,5 @@ plot.plot([13, 14, 15, 16, 17], pen=(187, 26, 95), symbolBrush=(187, 26, 95), sy
plot.plot([14, 15, 16, 17, 18], pen=(248, 187, 208), symbolBrush=(248, 187, 208), symbolPen='w', symbol='arrow_right', symbolSize=22, name="symbol='arrow_right'")
plot.setXRange(-2, 4)
## 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_()
pg.mkQApp().exec_()

View File

@ -26,9 +26,5 @@ data = np.array([
w.setData(data)
## 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_()
pg.mkQApp().exec_()

View File

@ -48,8 +48,5 @@ i2.addChild(i22)
b1 = QtGui.QPushButton("Button")
w.setItemWidget(i1, 1, b1)
## 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_()
pg.mkQApp().exec_()

View File

@ -18,6 +18,8 @@ import pyqtgraph as pg
import pyqtgraph.ptime as ptime
from pyqtgraph.Qt import QtGui, QtCore, QT_LIB
pg.setConfigOption('imageAxisOrder', 'row-major')
import importlib
ui_template = importlib.import_module(f'VideoTemplate_{QT_LIB.lower()}')
@ -157,7 +159,7 @@ def mkData():
dt = xp.uint16
loc = 4096
scale = 1024
mx = 2**16
mx = 2**16 - 1
elif cacheKey[0] == 'float':
dt = xp.float32
loc = 1.0
@ -165,19 +167,25 @@ def mkData():
mx = 1.0
else:
raise ValueError(f"unable to handle dtype: {cacheKey[0]}")
chan_shape = (height, width)
if ui.rgbCheck.isChecked():
data = xp.random.normal(size=(frames,width,height,3), loc=loc, scale=scale)
data = pg.gaussianFilter(data, (0, 6, 6, 0))
frame_shape = chan_shape + (3,)
else:
data = xp.random.normal(size=(frames,width,height), loc=loc, scale=scale)
data = pg.gaussianFilter(data, (0, 6, 6))
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
frame_shape = chan_shape
data = xp.empty((frames,) + frame_shape, dtype=dt)
view = data.reshape((-1,) + chan_shape)
for idx in range(view.shape[0]):
subdata = xp.random.normal(loc=loc, scale=scale, size=chan_shape)
# note: gaussian filtering has been removed as it slows down array
# creation greatly.
if cacheKey[0] != 'float':
xp.clip(subdata, 0, mx, out=subdata)
view[idx] = subdata
data[:, 10:50, 10] = mx
data[:, 48, 9:12] = mx
data[:, 47, 8:13] = mx
cache = {cacheKey: data} # clear to save memory (but keep one to prevent unnecessary regeneration)
data = cache[cacheKey]
@ -272,10 +280,5 @@ timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(0)
## 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_()
pg.mkQApp().exec_()

View File

@ -93,8 +93,5 @@ t = QtCore.QTimer()
t.timeout.connect(updateData)
t.start(50)
## 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_()
pg.mkQApp().exec_()

View File

@ -81,10 +81,5 @@ v6.setAutoVisible(x=False, y=True)
l6 = pg.PlotDataItem(y)
v6.addItem(l6)
## 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_()
pg.mkQApp().exec_()

View File

@ -7,9 +7,5 @@ import numpy as np
plt = pg.plot(np.random.normal(size=100), title="View limit example")
plt.centralWidget.vb.setLimits(xMin=-20, xMax=120, minXRange=5, maxXRange=100)
## 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'):
pg.QtGui.QApplication.exec_()
pg.mkQApp().exec_()

View File

@ -31,8 +31,5 @@ err = pg.ErrorBarItem(x=np.arange(4), y=data.mean(axis=1), height=data.std(axis=
win.addItem(err)
## 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_()
pg.mkQApp().exec_()

View File

@ -1,14 +1,8 @@
# -*- 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)
This example demonstrates generating ColorMap objects from external data.
It displays the full list of color maps available as local files or by import
from Matplotlib or ColorCET.
"""
## Add path to library (just for examples; you do not need this)
import initExample
@ -111,8 +105,5 @@ for map_name in list_of_maps:
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_()
pg.mkQApp().exec_()

View File

@ -135,8 +135,5 @@ box2.setParentItem(box1)
box2.setPos(5, 5)
box2.setScale(0.2)
## 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_()
pg.mkQApp().exec_()

View File

@ -80,8 +80,5 @@ proxy = pg.SignalProxy(p1.scene().sigMouseMoved, rateLimit=60, slot=mouseMoved)
#p1.scene().sigMouseMoved.connect(mouseMoved)
## 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_()
pg.mkQApp().exec_()

View File

@ -54,8 +54,5 @@ plt = pg.plot()
plt.addItem(item)
plt.setWindowTitle('pyqtgraph example: customGraphicsItem')
## 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_()
pg.mkQApp().exec_()

View File

@ -42,7 +42,7 @@ class CustomTickSliderItem(pg.TickSliderItem):
self.removeTick(tick)
for pos in ticks:
tickItem = self.addTick(pos, movable=False, color="333333")
tickItem = self.addTick(pos, movable=False, color="#333333")
self.all_ticks[pos] = tickItem
self.updateRange(None, self._range)
@ -91,8 +91,5 @@ pw.setWindowTitle('pyqtgraph example: customPlot')
r = pg.PolyLineROI([(0,0), (10, 10)])
pw.addItem(r)
## 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_()
pg.mkQApp().exec_()

View File

@ -38,9 +38,5 @@ class MainWindow(TemplateBaseClass):
win = MainWindow()
## 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_()
pg.mkQApp().exec_()

View File

@ -111,8 +111,5 @@ win.show()
## 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_()
pg.mkQApp().exec_()

View File

@ -56,7 +56,7 @@ def update():
p2 = pts[i+1]
v2 = p2 - p1
t = p1 - pts[0]
r = v2.angle(v1)
r = v1.angle(v2)
s = v2.length() / l1
trs.append(pg.SRTTransform({'pos': t, 'scale': (s, s), 'angle': r}))
@ -106,10 +106,5 @@ depthSpin.valueChanged.connect(update)
# Initialize
update()
## 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_()
pg.mkQApp().exec_()

View File

@ -141,15 +141,5 @@ curve = HDF5Plot()
curve.setHDF5(f['data'])
plt.addItem(curve)
## 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_()
pg.mkQApp().exec_()

View File

@ -29,8 +29,5 @@ y = pg.pseudoScatter(vals, spacing=0.15)
#plt2.plot(vals, y, pen=None, symbol='o', symbolSize=5)
plt2.plot(vals, y, pen=None, symbol='o', symbolSize=5, symbolPen=(255,255,255,200), symbolBrush=(0,0,255,150))
## 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_()
pg.mkQApp().exec_()

View File

@ -113,9 +113,5 @@ def imageHoverEvent(event):
# but it works for a very simple use like this.
img.hoverEvent = imageHoverEvent
## 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_()
pg.mkQApp().exec_()

View File

@ -44,9 +44,5 @@ timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(0)
# 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_()
pg.mkQApp().exec_()

View File

@ -53,8 +53,5 @@ timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(50)
## 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_()
pg.mkQApp().exec_()

View File

@ -40,10 +40,6 @@ p3.setXLink(p1)
p3.setLabel('left', "Label to test offset")
#QtGui.QApplication.processEvents()
## 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_()
pg.mkQApp().exec_()

View File

@ -34,9 +34,5 @@ p3.plot(x, y)
#p.getAxis('bottom').setLogMode(True)
## 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_()
pg.mkQApp().exec_()

View File

@ -86,8 +86,5 @@ else:
plt.autoRange()
## 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_()
pg.mkQApp().exec_()

Some files were not shown because too many files have changed in this diff Show More