Skip to content

Commit 1df24d4

Browse files
committed
Substantially upgrade ImageItem docs
1 parent 9cffade commit 1df24d4

File tree

5 files changed

+491
-268
lines changed

5 files changed

+491
-268
lines changed

doc/source/api_reference/functions.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ Miscellaneous Functions
103103

104104
.. autofunction:: pyqtgraph.exit
105105

106+
.. autofunction:: pyqtgraph.functions.makeARGB
107+
106108

107109
Legacy Color Helper Functions
108110
-------------------------------

doc/source/api_reference/graphicsItems/imageitem.rst

Lines changed: 79 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,91 @@
1+
.. role:: python(code)
2+
:language: python
3+
14
ImageItem
25
=========
36

4-
:class:`~pyqtgraph.ImageItem` displays images inside a :class:`~pyqtgraph.GraphicsView`, or a
5-
:class:`~pyqtgraph.ViewBox`, which may itself be part of a :class:`~pyqtgraph.PlotItem`. It is designed
6-
for rapid updates as needed for a video display. The supplied data is optionally scaled (see
7-
:func:`~pyqtgraph.ImageItem.setLevels`) and/or colored according to a
8-
lookup table (see :func:`~pyqtgraph.ImageItem.setColorMap` and
9-
:func:`~pyqtgraph.ImageItem.setLookupTable`).
7+
:class:`~pyqtgraph.ImageItem` displays images inside a
8+
:class:`~pyqtgraph.GraphicsView`, or a :class:`~pyqtgraph.ViewBox`, which may itself be
9+
part of a :class:`~pyqtgraph.PlotItem`. It is designed for rapid updates as needed for
10+
a video display. The supplied data is optionally scaled (see
11+
:meth:`ImageItem.setLevels <pyqtgraph.ImageItem.setLevels>`) and/or colored according
12+
to a lookup table (see :meth:`ImageItem.setColorMap <pyqtgraph.ImageItem.setColorMap>`
13+
and :meth:`ImageItem.setLookupTable <pyqtgraph.ImageItem.setLookupTable>`).
1014

1115
Data is provided as a NumPy array with an ordering of either
1216

13-
* `col-major`, where the shape of the array represents (width, height) or
14-
* `row-major`, where the shape of the array represents (height, width).
17+
* `col-major`, where the shape of the array represents (width, height) or
18+
* `row-major`, where the shape of the array represents (height, width).
1519

16-
While `col-major` is the default, `row-major` ordering typically has the best performance. In either ordering,
17-
a third dimension can be added to the array to hold individual
18-
``[R,G,B]`` or ``[R,G,B,A]`` components.
20+
While `col-major` is the default, `row-major` ordering typically has the best
21+
performance. In either ordering, a third dimension can be added to the array to hold
22+
individual :python:`[R,G,B]` or :python:`[R,G,B,A]` channels/components.
1923

2024
Notes
2125
-----
2226

23-
Data ordering can be set for each ImageItem, or in the :ref:`global configuration options <apiref_config>` by ::
24-
25-
pyqtgraph.setConfigOption('imageAxisOrder', 'row-major') # best performance
26-
2727
An image can be placed into a plot area of a given extent directly through the
28-
:func:`~pyqtgraph.ImageItem.setRect` method or the ``rect`` keyword. This is internally realized through
29-
assigning a ``QtGui.QTransform``. For other translation, scaling or rotations effects that
30-
persist for all later image data, the user can also directly define and assign such a
31-
transform, as shown in the example below.
32-
33-
ImageItem is frequently used in conjunction with :class:`~pyqtgraph.ColorBarItem` to provide
34-
a color map display and interactive level adjustments, or with
35-
:class:`~pyqtgraph.HistogramLUTItem` or :class:`~pyqtgraph.HistogramLUTWidget` for a full GUI
36-
to control the levels and lookup table used to display the image.
37-
38-
If performance is critial, the following points may be worth investigating:
39-
40-
* Use row-major ordering and C-contiguous image data.
41-
* Manually provide ``level`` information to avoid autoLevels sampling of the image.
42-
* Prefer `float32` to `float64` for floating point data, avoid NaN values.
43-
* Use lookup tables with <= 256 entries for false color images.
44-
* Avoid individual level adjustments RGB components.
45-
* Use the latest version of NumPy. Notably, SIMD code added in version 1.20 significantly improved performance on Linux platforms.
46-
* Enable Numba with ``pyqtgraph.setConfigOption('useNumba', True)``, although the JIT compilation will only accelerate repeated image display.
28+
:meth:`ImageItem.setRect <pyqtgraph.ImageItem.setRect>` method or the ``rect`` keyword.
29+
This is internally realized through assigning a :class:`QTransform`. For other
30+
translation, scaling or rotations effects that persist for all later image data, the
31+
user can also directly define and assign such a transform, as shown in the example
32+
below.
33+
34+
:class:`~pyqtgraph.ImageItem` is frequently used in conjunction with
35+
:class:`~pyqtgraph.ColorBarItem` to provide a color map display and interactive level
36+
adjustments, or with :class:`~pyqtgraph.HistogramLUTItem` or
37+
:class:`~pyqtgraph.HistogramLUTWidget` for a full GUI to control the levels and lookup
38+
table used to display the image.
39+
40+
Performance
41+
-----------
42+
43+
The performance of :class:`~pyqtgraph.ImageItem` can vary *significantly* based on
44+
attributes of the ``image``, ``levels`` and ``lut`` input arguments. It should not be
45+
assumed that the default parameters are the most performant, as the default values are
46+
largely there to preserve backwards compatibility.
47+
48+
The following guidance should be observed if performance is an important factor
49+
50+
* Instantiate :class:`~pyqtgraph.ImageItem` with :python:`axisOrder='row-major'`
51+
52+
* Alternatively, set the global configuration optionally
53+
:python:`pyqtgraph.setConfigOption('imageAxisOrder', 'row-major')`
54+
55+
* Use C-contiguous image data.
56+
* For 1 or 3 channel data, use `uint8`, `uint16`, `float32`, or `float64`
57+
``image`` dtype.
58+
* For 4-channel data, use `uint8` or `uint16` with :python":`levels=None`.
59+
* ``levels`` should be single channel (if 1 or 3 channel data).
60+
61+
* Setting :python:`levels=None` will trigger autoLevels sampling, and thus should
62+
be avoided if possible.
63+
64+
* If using LUTs (lookup tables), ensure they have a dtype of `uint8` and have 256
65+
points or less, and that. That can be accomplished with calling:
66+
67+
* :func:`ImageItem.setColorMap <pyqtgraph.ImageItem.setColorMap>` or
68+
* :func:`ImageItem.setLookupTable <pyqtgraph.ImageItem.setLookupTable>` with
69+
:python:`ColorMap.getLookupTable(nPts=256)` (default is :python:`nPts=512`)
70+
71+
* For floating point ``image`` arrays, prefer `float32` dtype to `float64`
72+
and avoid ``NaN`` values.
73+
* Enable Numba with :python:`pyqtgraph.setConfigOption('useNumba', True)`
74+
75+
* JIT compilation will only accelerate repeated image display.
76+
77+
Internally, pyqtgraph attempts to directly construct a :class:`QImage` using a
78+
combination of :class:`QImage.Format <QImage.Format>` options and
79+
:meth:`QImage.setColorTable <QImage.setColorTable>` if necessary. This does not work in
80+
all cases that pyqtgraph supports. If pyqtgraph is unable to construct the
81+
:class:`QImage` in such a fashion, it will fall back on
82+
:func:`~pyqtgraph.functions.makeARGB` to manipulate the data in a manner that
83+
:class:`QImage` can read it in. There is a *significant* performance penalty when
84+
having to use :func:`~pyqtgraph.functions.makeARGB`.
85+
86+
For applications that are *very* performance sensitive, every effort should be made so
87+
that the arguments passed to :meth:`ImageItem.setImage <pyqtgraph.ImageItem.setImage>`
88+
do not call :func:`~pyqtgraph.functions.makeARGB`.
4789

4890
.. _ImageItem_examples:
4991

@@ -53,13 +95,16 @@ Examples
5395
.. literalinclude:: /images/gen_example_imageitem_transform.py
5496
:lines: 19-28
5597
:dedent: 8
98+
:language: python
5699

57100
.. thumbnail::
58101
/images/example_imageitem_transform.png
59102
:width: 49%
60103
:alt: Example of transformed image display
61104
:title: Transformed Image Display
62105

106+
API
107+
---
63108

64109
.. autoclass:: pyqtgraph.ImageItem
65110
:members:

doc/source/conf.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import os
1414
import sys
1515
import time
16-
from datetime import datetime
16+
import datetime
1717

1818
from sphinx.application import Sphinx
1919

@@ -63,9 +63,14 @@
6363
("py:class", r"re\.Pattern"), # doesn't seem to be a good ref in python docs
6464
]
6565

66+
napoleon_use_admonition_for_examples = True
67+
napoleon_use_admonition_for_notes = True
68+
napoleon_use_admonition_for_references = True
69+
napoleon_use_rtype = True
70+
napoleon_custom_sections = [("Signals", "params_style")]
6671
napoleon_preprocess_types = True
6772
napoleon_type_aliases = {
68-
"callable": ":class:`collections.abc.Callable`",
73+
"callable": ":class:`~collections.abc.Callable`",
6974
"np.ndarray": ":class:`numpy.ndarray`",
7075
'array_like': ':term:`array_like`',
7176
'color_like': ':func:`pyqtgraph.mkColor`',
@@ -80,10 +85,12 @@
8085

8186
# General information about the project.
8287
project = 'pyqtgraph'
83-
now = datetime.utcfromtimestamp(
84-
int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))
88+
89+
now = datetime.datetime.fromtimestamp(
90+
int(os.environ.get('SOURCE_DATE_EPOCH', time.time())),
91+
tz=datetime.timezone.utc
8592
)
86-
copyright = '2011 - {}, PyQtGraph developers'.format(now.year)
93+
copyright = f'2011 - {now.year}, PyQtGraph developers'
8794

8895
# The version info for the project you're documenting, acts as replacement for
8996
# |version| and |release|, also used in various other places throughout the

pyqtgraph/functions.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1986,11 +1986,12 @@ def arrayToQPath(x, y, connect='all', finiteCheck=True):
19861986
a ``QDataStream`` object is created and the QDataStream >> QPainterPath
19871987
operator is used to pass the data. The memory format is as follows
19881988
1989-
numVerts(i4)
1990-
0(i4) x(f8) y(f8) <-- 0 means this vertex does not connect
1991-
1(i4) x(f8) y(f8) <-- 1 means this vertex connects to the previous vertex
1992-
...
1993-
cStart(i4) fillRule(i4)
1989+
.. code-block:
1990+
numVerts(i4)
1991+
0(i4) x(f8) y(f8) <-- 0 means this vertex does not connect
1992+
1(i4) x(f8) y(f8) <-- 1 means this vertex connects to the previous vertex
1993+
...
1994+
cStart(i4) fillRule(i4)
19941995
19951996
see: https://github.com/qt/qtbase/blob/dev/src/gui/painting/qpainterpath.cpp
19961997

0 commit comments

Comments
 (0)