8000 Merge pull request #30112 from trygvrad/colorbar-docs-colorizer · matplotlib/matplotlib@b09a0c7 · GitHub
[go: up one dir, main page]

Skip to content

Commit b09a0c7

Browse files
authored
Merge pull request #30112 from trygvrad/colorbar-docs-colorizer
Update to docs with regards to colorbar and colorizer
2 parents 6083ecd + 150165b commit b09a0c7

File tree

4 files changed

+53
-54
lines changed

4 files changed

+53
-54
lines changed

galleries/examples/images_contours_and_fields/multi_image.py

Lines changed: 15 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,17 @@
1111
value *x* in the image).
1212
1313
If we want one colorbar to be representative for multiple images, we have
14-
to explicitly ensure consistent data coloring by using the same data
15-
normalization for all the images. We ensure this by explicitly creating a
16-
``norm`` object that we pass to all the image plotting methods.
14+
to explicitly ensure consistent data coloring by using the same
15+
data-to-color pipeline for all the images. We ensure this by explicitly
16+
creating a `matplotlib.colorizer.Colorizer` object that we pass to all
17+
the image plotting methods.
1718
"""
1819

1920
import matplotlib.pyplot as plt
2021
import numpy as np
2122

22-
from matplotlib import colors
23+
import matplotlib.colorizer as mcolorizer
24+
import matplotlib.colors as mcolors
2325

2426
np.random.seed(19680801)
2527

@@ -31,12 +33,13 @@
3133
fig, axs = plt.subplots(2, 2)
3234
fig.suptitle('Multiple images')
3335

34-
# create a single norm to be shared across all images
35-
norm = colors.Normalize(vmin=np.min(datasets), vmax=np.max(datasets))
36+
# create a colorizer with a predefined norm to be shared across all images
37+
norm = mcolors.Normalize(vmin=np.min(datasets), vmax=np.max(datasets))
38+
colorizer = mcolorizer.Colorizer(norm=norm)
3639

3740
images = []
3841
for ax, data in zip(axs.flat, datasets):
39-
images.append(ax.imshow(data, norm=norm))
42+
images.append(ax.imshow(data, colorizer=colorizer))
4043

4144
fig.colorbar(images[0], ax=axs, orientation='horizontal', fraction=.1)
4245

@@ -45,30 +48,10 @@
4548
# %%
4649
# The colors are now kept consistent across all images when changing the
4750
# scaling, e.g. through zooming in the colorbar or via the "edit axis,
48-
# curves and images parameters" GUI of the Qt backend. This is sufficient
49-
# for most practical use cases.
50-
#
51-
# Advanced: Additionally sync the colormap
52-
# ----------------------------------------
53-
#
54-
# Sharing a common norm object guarantees synchronized scaling because scale
55-
# changes modify the norm object in-place and thus propagate to all images
56-
# that use this norm. This approach does not help with synchronizing colormaps
57-
# because changing the colormap of an image (e.g. through the "edit axis,
58-
# curves and images parameters" GUI of the Qt backend) results in the image
59-
# referencing the new colormap object. Thus, the other images are not updated.
60-
#
61-
# To update the other images, sync the
62-
# colormaps using the following code::
63-
#
64-
# def sync_cmaps(changed_image):
65-
# for im in images:
66-
# if changed_image.get_cmap() != im.get_cmap():
67-
# im.set_cmap(changed_image.get_cmap())
68-
#
69-
# for im in images:
70-
# im.callbacks.connect('changed', sync_cmaps)
71-
#
51+
# curves and images parameters" GUI of the Qt backend. Additionally,
52+
# if the colormap of the colorizer is changed, (e.g. through the "edit
53+
# axis, curves and images parameters" GUI of the Qt backend) this change
54+
# propagates to the other plots and the colorbar.
7255
#
7356
# .. admonition:: References
7457
#
@@ -77,6 +60,5 @@
7760
#
7861
# - `matplotlib.axes.Axes.imshow` / `matplotlib.pyplot.imshow`
7962
# - `matplotlib.figure.Figure.colorbar` / `matplotlib.pyplot.colorbar`
63+
# - `matplotlib.colorizer.Colorizer`
8064
# - `matplotlib.colors.Normalize`
81-
# - `matplotlib.cm.ScalarMappable.set_cmap`
82-
# - `matplotlib.cbook.CallbackRegistry.connect`

galleries/users_explain/colors/colorbar_only.py

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
This tutorial shows how to build and customize standalone colorbars, i.e.
99
without an attached plot.
1010
11-
A `~.Figure.colorbar` needs a "mappable" (`matplotlib.cm.ScalarMappable`)
12-
object (typically, an image) which indicates the colormap and the norm to be
13-
used. In order to create a colorbar without an attached image, one can instead
14-
use a `.ScalarMappable` with no associated data.
11+
A `~.Figure.colorbar` requires a `matplotlib.colorizer.ColorizingArtist` which
12+
contains a `matplotlib.colorizer.Colorizer` that holds the data-to-color pipeline
13+
(norm and colormap). To create a colorbar without an attached plot one can
14+
directly instantiate the base class `.ColorizingArtist`, which has no associated
15+
data.
16+
1517
"""
1618

1719
import matplotlib.pyplot as plt
@@ -23,17 +25,21 @@
2325
# -------------------------
2426
# Here, we create a basic continuous colorbar with ticks and labels.
2527
#
26-
# The arguments to the `~.Figure.colorbar` call are the `.ScalarMappable`
27-
# (constructed using the *norm* and *cmap* arguments), the axes where the
28-
# colorbar should be drawn, and the colorbar's orientation.
28+
# The arguments to the `~.Figure.colorbar` call are a `.ColorizingArtist`,
29+
# the axes where the colorbar should be drawn, and the colorbar's orientation.
30+
# To crate a `.ColorizingArtist` one must first make `.Colorizer` that holds the
31+
# desired *norm* and *cmap*.
32+
#
2933
#
3034
# For more information see the `~matplotlib.colorbar` API.
3135

3236
fig, ax = plt.subplots(figsize=(6, 1), layout='constrained')
3337

3438
norm = mpl.colors.Normalize(vmin=5, vmax=10)
3539

36-
fig.colorbar(mpl.cm.ScalarMappable(norm=norm, cmap="cool"),
40+
colorizer = mpl.colorizer.Colorizer(norm=norm, cmap="cool")
41+
42+
fig.colorbar(mpl.colorizer.ColorizingArtist(colorizer),
3743
cax=ax, orientation='horizontal', label='Some Units')
3844

3945
# %%
@@ -47,7 +53,9 @@
4753

4854
fig, ax = plt.subplots(layout='constrained')
4955

50-
fig.colorbar(mpl.cm.ScalarMappable(norm=mpl.colors.Normalize(0, 1), cmap='magma'),
56+
colorizer = mpl.colorizer.Colorizer(norm=mpl.colors.Normalize(0, 1), cmap='magma')
57+
58+
fig.colorbar(mpl.colorizer.ColorizingArtist(colorizer),
5159
ax=ax, orientation='vertical', label='a colorbar label')
5260

5361
# %%
@@ -65,7 +73,9 @@
6573
bounds = [-1, 2, 5, 7, 12, 15]
6674
norm = mpl.colors.BoundaryNorm(bounds, cmap.N, extend='both')
6775

68-
fig.colorbar(mpl.cm.ScalarMappable(norm=norm, cmap="viridis"),
76+
colorizer = mpl.colorizer.Colorizer(norm=norm, cmap='viridis')
77+
78+
fig.colorbar(mpl.colorizer.ColorizingArtist(colorizer),
6979
cax=ax, orientation='horizontal',
7080
label="Discrete intervals with extend='both' keyword")
7181

@@ -94,8 +104,10 @@
94104
bounds = [1, 2, 4, 7, 8]
95105
norm = mpl.colors.BoundaryNorm(bounds, cmap.N)
96106

107+
colorizer = mpl.colorizer.Colorizer(norm=norm, cmap=cmap)
108+
97109
fig.colorbar(
98-
mpl.cm.ScalarMappable(cmap=cmap, norm=norm),
110+
mpl.colorizer.ColorizingArtist(colorizer),
99111
cax=ax, orientation='horizontal',
100112
extend='both',
101113
spacing='proportional',
@@ -116,8 +128,10 @@
116128
bounds = [-1.0, -0.5, 0.0, 0.5, 1.0]
117129
norm = mpl.colors.BoundaryNorm(bounds, cmap.N)
118130

131+
colorizer = mpl.colorizer.Colorizer(norm=norm, cmap=cmap)
132+
119133
fig.colorbar(
120-
mpl.cm.ScalarMappable(cmap=cmap, norm=norm),
134+
mpl.colorizer.ColorizingArtist(colorizer),
121135
cax=ax, orientation='horizontal',
122136
extend='both', extendfrac='auto',
123137
spacing='uniform',

lib/matplotlib/colorbar.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@
1616
import numpy as np
1717

1818
import matplotlib as mpl
19-
from matplotlib import _api, cbook, collections, cm, colors, contour, ticker
19+
from matplotlib import _api, cbook, collections, colors, contour, ticker
2020
import matplotlib.artist as martist
21+
import matplotlib.colorizer as mcolorizer
2122
import matplotlib.patches as mpatches
2223
import matplotlib.path as mpath
2324
import matplotlib.spines as mspines
@@ -199,12 +200,12 @@ class Colorbar:
199200
Draw a colorbar in an existing Axes.
200201
201202
Typically, colorbars are created using `.Figure.colorbar` or
202-
`.pyplot.colorbar` and associated with `.ScalarMappable`\s (such as an
203+
`.pyplot.colorbar` and associated with `.ColorizingArtist`\s (such as an
203204
`.AxesImage` generated via `~.axes.Axes.imshow`).
204205
205206
In order to draw a colorbar not associated with other elements in the
206207
figure, e.g. when showing a colormap by itself, one can create an empty
207-
`.ScalarMappable`, or directly pass *cmap* and *norm* instead of *mappable*
208+
`.ColorizingArtist`, or directly pass *cmap* and *norm* instead of *mappable*
208209
to `Colorbar`.
209210
210211
Useful public methods are :meth:`set_label` and :meth:`add_lines`.
@@ -244,7 +245,7 @@ def __init__(
244245
ax : `~matplotlib.axes.Axes`
245246
The `~.axes.Axes` instance in which the colorbar is drawn.
246247
247-
mappable : `.ScalarMappable`
248+
mappable : `.ColorizingArtist`
248249
The mappable whose colormap and norm will be used.
249250
250251
To show the colors versus index instead of on a 0-1 scale, set the
@@ -288,7 +289,8 @@ def __init__(
288289
colorbar and at the right for a vertical.
289290
"""
290291
if mappable is None:
291-
mappable = cm.ScalarMappable(norm=norm, cmap=cmap)
292+
colorizer = mcolorizer.Colorizer(norm=norm, cmap=cmap)
293+
mappable = mcolorizer.ColorizingArtist(colorizer)
292294

293295
self.mappable = mappable
294296
cmap = mappable.cmap

lib/matplotlib/figure.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,17 +1200,18 @@ def colorbar(
12001200
Parameters
12011201
----------
12021202
mappable
1203-
The `matplotlib.cm.ScalarMappable` (i.e., `.AxesImage`,
1203+
The `matplotlib.colorizer.ColorizingArtist` (i.e., `.AxesImage`,
12041204
`.ContourSet`, etc.) described by this colorbar. This argument is
12051205
mandatory for the `.Figure.colorbar` method but optional for the
12061206
`.pyplot.colorbar` function, which sets the default to the current
12071207
image.
12081208
1209-
Note that one can create a `.ScalarMappable` "on-the-fly" to
1210-
generate colorbars not attached to a previously drawn artist, e.g.
1209+
Note that one can create a `.colorizer.ColorizingArtist` "on-the-fly"
1210+
to generate colorbars not attached to a previously drawn artist, e.g.
12111211
::
12121212
1213-
fig.colorbar(cm.ScalarMappable(norm=norm, cmap=cmap), ax=ax)
1213+
cr = colorizer.Colorizer(norm=norm, cmap=cmap)
1214+
fig.colorbar(colorizer.ColorizingArtist(cr), ax=ax)
12141215
12151216
cax : `~matplotlib.axes.Axes`, optional
12161217
Axes into which the colorbar will be drawn. If `None`, then a new

0 commit comments

Comments
 (0)
0