Skip to content

Commit 6d6063d

Browse files
committed
Substantially upgrade ImageItem docs
This change is intended to be used as a template for improving the docs elsewhere in the pyqtgraph library. Changes Include * Adding a performance section to ImageItem docs * Use of sphinx's inheritance diagram * Adding spelling dictionaries (although no spelling check is mandated) * Use of numpy docstring style exclusively * numpydoc lint passes but the check does not occur in CI * More type-annotations (although not exhaustive) * More cross-referencing/linking to other parts of the library as well as the Qt and numpy docs where appropriate
1 parent 9cffade commit 6d6063d

18 files changed

Lines changed: 6288 additions & 366 deletions

.readthedocs.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ build:
99
python: "3"
1010
apt_packages:
1111
- libopengl0
12+
- graphviz
1213

1314
sphinx:
1415
fail_on_warning: true

doc/source/_static/custom.css

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ Nat Methods 8, 441 (2011). https://doi.org/10.1038/nmeth.1618
5858
}
5959

6060
/* Main index page overview cards */
61-
6261
.sd-card {
6362
background: #fff;
6463
border-radius: 0;
@@ -134,15 +133,14 @@ types are assumed to be normal images.
134133
*/
135134
html[data-theme=dark] img[src*='.svg']:not(.only-dark):not(.dark-light) {
136135
filter: brightness(0.8) invert(0.82) contrast(1.2);
137-
background: unset
136+
background: unset;
138137
}
139138

140139
html[data-theme=dark] .MathJax_SVG * {
141140
fill: var(--pst-color-text-base);
142141
}
143142

144143
/* Main index page overview cards */
145-
146144
html[data-theme=dark] .sd-card {
147145
background-color:var(--pst-color-background);
148146
border: none
@@ -161,10 +159,23 @@ html[data-theme=dark] .sd-card .sd-card-footer {
161159
background-color:var(--pst-color-background);
162160
}
163161

164-
/*
165-
Hide TypeAlias Classes
166-
*/
167-
162+
/* Hide TypeAlias Classes */
168163
dt#ColorMapSpecifier {
169164
visibility: hidden;
170-
}
165+
}
166+
167+
/* Flip the colours on graphviz graphs on dark mode */
168+
html[data-theme="dark"] div.graphviz > object.inheritance {
169+
filter: brightness(0.8) invert(0.82) contrast(1.2);
170+
color-scheme: normal;
171+
}
172+
173+
/* Make inheritance images have a scroll bar if necessary. */
174+
div.graphviz {
175+
border: 1px solid #7f7f7f00;
176+
max-height: 50em;
177+
overflow: auto;
178+
}
179+
img.graphviz.inheritance {
180+
max-width: none;
181+
}

doc/source/api_reference/functions.rst

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@ Color, Pen, and Brush Functions
1515

1616
Qt uses the classes QColor, QPen, and QBrush to determine how to draw lines and fill shapes. These classes are highly capable but somewhat awkward to use. PyQtGraph offers the functions :func:`~pyqtgraph.mkColor`, :func:`~pyqtgraph.mkPen`, and :func:`~pyqtgraph.mkBrush` to simplify the process of creating these classes. In most cases, however, it will be unnecessary to call these functions directly--any function or method that accepts *pen* or *brush* arguments will make use of these functions for you. For example, the following three lines all have the same effect::
1717
18+
.. code-block:: python
19+
1820
pg.plot(xdata, ydata, pen='r')
1921
pg.plot(xdata, ydata, pen=pg.mkPen('r'))
2022
pg.plot(xdata, ydata, pen=QPen(QColor(255, 0, 0)))
2123
22-
2324
.. autofunction:: pyqtgraph.mkColor
2425

2526
.. autofunction:: pyqtgraph.mkPen
@@ -36,13 +37,11 @@ Qt uses the classes QColor, QPen, and QBrush to determine how to draw lines and
3637

3738
.. autofunction:: pyqtgraph.colorDistance
3839

39-
4040
Data Slicing
4141
------------
4242

4343
.. autofunction:: pyqtgraph.affineSlice
4444

45-
4645
Coordinate Transformation
4746
-------------------------
4847

@@ -54,8 +53,6 @@ Coordinate Transformation
5453

5554
.. autofunction:: pyqtgraph.solveBilinearTransform
5655

57-
58-
5956
SI Unit Conversion Functions
6057
----------------------------
6158

@@ -67,20 +64,18 @@ SI Unit Conversion Functions
6764

6865
.. autofunction:: pyqtgraph.siParse
6966

70-
7167
Image Preparation Functions
7268
---------------------------
7369

74-
.. autofunction:: pyqtgraph.makeARGB
75-
76-
.. autofunction:: pyqtgraph.makeQImage
70+
.. autofunction:: pyqtgraph.functions.makeARGB
7771

78-
.. autofunction:: pyqtgraph.applyLookupTable
72+
.. autofunction:: pyqtgraph.functions.makeQImage
7973

80-
.. autofunction:: pyqtgraph.rescaleData
74+
.. autofunction:: pyqtgraph.functions.applyLookupTable
8175

82-
.. autofunction:: pyqtgraph.imageToArray
76+
.. autofunction:: pyqtgraph.functions.rescaleData
8377

78+
.. autofunction:: pyqtgraph.functions.imageToArray
8479

8580
Mesh Generation Functions
8681
-------------------------
@@ -89,7 +84,6 @@ Mesh Generation Functions
8984

9085
.. autofunction:: pyqtgraph.isosurface
9186

92-
9387
Miscellaneous Functions
9488
-----------------------
9589

@@ -103,13 +97,11 @@ Miscellaneous Functions
10397

10498
.. autofunction:: pyqtgraph.exit
10599

106-
107100
Legacy Color Helper Functions
108101
-------------------------------
109102

110103
The following helper functions should no longer be used. The functionality that they implement is trivial and it is suggested that the user use the equivalent QColor methods directly.
111104

112-
113105
.. autofunction:: pyqtgraph.colorTuple
114106

115107
.. autofunction:: pyqtgraph.colorStr

doc/source/api_reference/graphicsItems/imageitem.rst

Lines changed: 98 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,128 @@
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+
Overview
8+
--------
9+
10+
:class:`~pyqtgraph.ImageItem` displays images inside a
11+
:class:`~pyqtgraph.GraphicsView`, or a :class:`~pyqtgraph.ViewBox`, which may itself be
12+
part of a :class:`~pyqtgraph.PlotItem`. It is designed for rapid updates as needed for
13+
a video display. The supplied data is optionally scaled (see
14+
:meth:`ImageItem.setLevels <pyqtgraph.ImageItem.setLevels>`) and/or colored according
15+
to a lookup table (see :meth:`ImageItem.setColorMap <pyqtgraph.ImageItem.setColorMap>`
16+
and :meth:`ImageItem.setLookupTable <pyqtgraph.ImageItem.setLookupTable>`).
1017

1118
Data is provided as a NumPy array with an ordering of either
1219

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).
20+
* `col-major`, where the shape of the array represents (width, height) or
21+
* `row-major`, where the shape of the array represents (height, width).
1522

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.
23+
While `col-major` is the default, `row-major` ordering typically has the best
24+
performance. In either ordering, a third dimension can be added to the array to hold
25+
individual :python:`[R,G,B]` or :python:`[R,G,B,A]` channels/components.
1926

2027
Notes
2128
-----
2229

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
30+
:class:`~pyqtgraph.ImageItem` is frequently used in conjunction with
31+
:class:`~pyqtgraph.ColorBarItem` to provide a color map display and interactive level
32+
adjustments, or with :class:`~pyqtgraph.HistogramLUTItem` or
33+
:class:`~pyqtgraph.HistogramLUTWidget` for a full GUI to control the levels and lookup
34+
table used to display the image.
2635

2736
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.
37+
:meth:`ImageItem.setRect <pyqtgraph.ImageItem.setRect>` method or the `rect` keyword.
38+
This is internally realized through assigning a :class:`QTransform`. For other
39+
translation, scaling or rotations effects that persist for all later image data, the
40+
user can also directly define and assign such a transform, as shown in the example
41+
below.
42+
43+
.. _ImageItem_performance:
44+
45+
Performance
46+
-----------
47+
48+
The performance of :class:`~pyqtgraph.ImageItem` can vary *significantly* based on
49+
attributes of the `image`, `levels` and `lut` input arguments. It should not be
50+
assumed that the default parameters are the most performant, as the default values are
51+
largely there to preserve backwards compatibility.
52+
53+
The following guidance should be observed if performance is an important factor
54+
55+
* Instantiate :class:`~pyqtgraph.ImageItem` with :python:`axisOrder='row-major'`
56+
57+
* Alternatively, set the global configuration optionally
58+
:python:`pyqtgraph.setConfigOption('imageAxisOrder', 'row-major')`
59+
60+
* Use C-contiguous image data.
61+
* For 1 or 3 channel data, use `uint8`, `uint16`, `float32`, or `float64` `image`
62+
dtype.
63+
* For 4-channel data, use `uint8` or `uint16` with :python:`levels=None`.
64+
* `levels` should be set to either to ``None`` or to single channel ``[min, max]``
65+
66+
* Not setting `levels` will trigger autoLevels sampling
67+
68+
* If using LUTs (lookup tables), ensure they have a dtype of `uint8` and have 256
69+
points or less. That can be accomplished with calling:
70+
71+
* :func:`ImageItem.setColorMap <pyqtgraph.ImageItem.setColorMap>` or
72+
* :func:`ImageItem.setLookupTable <pyqtgraph.ImageItem.setLookupTable>` with
73+
:python:`ColorMap.getLookupTable(nPts=256)` (default is :python:`nPts=512`)
74+
75+
* For floating point `image` arrays, prefer `float32` dtype to `float64` and avoid
76+
``NaN`` values.
77+
* Enable Numba with :python:`pyqtgraph.setConfigOption('useNumba', True)`
78+
79+
* JIT compilation will only accelerate repeated image display.
80+
81+
Internally, pyqtgraph attempts to directly construct a :class:`QImage` using a
82+
combination of :class:`QImage.Format <QImage.Format>` options and
83+
:meth:`QImage.setColorTable <QImage.setColorTable>` if necessary. This does not work in
84+
all cases that pyqtgraph supports. If pyqtgraph is unable to construct the
85+
:class:`QImage` in such a fashion, it will fall back on
86+
:func:`~pyqtgraph.functions.makeARGB` to manipulate the data in a manner that
87+
:class:`QImage` can read it in. There is a *significant* performance penalty when
88+
having to use :func:`~pyqtgraph.functions.makeARGB`.
89+
90+
For applications that are *very* performance sensitive, every effort should be made so
91+
that the arguments passed to :meth:`ImageItem.setImage <pyqtgraph.ImageItem.setImage>`
92+
do not call :func:`~pyqtgraph.functions.makeARGB`.
4793

4894
.. _ImageItem_examples:
4995

5096
Examples
5197
--------
5298

99+
Scale and Position ImageItem
100+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
101+
102+
In the following example, it is demonstrated how a user scale and translate a
103+
:class:`~pyqtgraph.ImageItem` within a :class:`~pyqtgraph.ViewBox` to occupy a specific
104+
position and size.
105+
53106
.. literalinclude:: /images/gen_example_imageitem_transform.py
54-
:lines: 19-28
55-
:dedent: 8
107+
:lines: 4-44
108+
:emphasize-lines: 24-33
109+
:language: python
56110

57111
.. thumbnail::
58112
/images/example_imageitem_transform.png
59113
:width: 49%
60114
:alt: Example of transformed image display
61115
:title: Transformed Image Display
62116

117+
Inheritance
118+
-----------
119+
120+
.. inheritance-diagram:: pyqtgraph.graphicsItems.ImageItem.ImageItem
121+
:top-classes: PyQt6.QtCore.QObject, PyQt6.QtWidgets.QGraphicsItem
122+
:parts: 1
123+
124+
API
125+
---
63126

64127
.. autoclass:: pyqtgraph.ImageItem
65128
:members:
66-
67-
.. automethod:: pyqtgraph.ImageItem.__init__

0 commit comments

Comments
 (0)