Skip to content

Commit bb0a4eb

Browse files
committed
DOC: Clarify/simplify example of multiple images with one colorbar
1 parent 199c31f commit bb0a4eb

File tree

1 file changed

+44
-37
lines changed

1 file changed

+44
-37
lines changed
Lines changed: 44 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
"""
2-
===============
3-
Multiple images
4-
===============
2+
=================================
3+
Multiple images with one colorbar
4+
=================================
55
6-
Make a set of images with a single colormap, norm, and colorbar.
6+
Use a single colorbar for multiple images.
7+
8+
Currently, a colorbar can only be associated with one image. To ensure that
9+
the colorbar is representative for multiple images, we have to ensure that
10+
all images use the same color mapping. The most important aspect is the
11+
data normalization. By explicitly creating a norm and using that for all
12+
images, we ensure that all images are scaled consistently.
713
"""
814

915
import matplotlib.pyplot as plt
@@ -12,47 +18,50 @@
1218
from matplotlib import colors
1319

1420
np.random.seed(19680801)
15-
Nr = 3
16-
Nc = 2
1721

18-
fig, axs = plt.subplots(Nr, Nc)
22+
datasets = [
23+
(i+1)/10 * np.random.rand(10, 20)
24+
for i in range(4)
25+
]
26+
27+
fig, axs = plt.subplots(2, 2)
1928
fig.suptitle('Multiple images')
2029

21-
images = []
22-
for i in range(Nr):
23-
for j in range(Nc):
24-
# Generate data with a range that varies from one plot to the next.
25-
data = ((1 + i + j) / 10) * np.random.rand(10, 20)
26-
images.append(axs[i, j].imshow(data))
27-
axs[i, j].label_outer()
30+
# create a single norm to be shared across all images
31+
norm = colors.Normalize(vmin=np.max(datasets), vmax=np.min(datasets))
2832

29-
# Find the min and max of all colors for use in setting the color scale.
30-
vmin = min(image.get_array().min() for image in images)
31-
vmax = max(image.get_array().max() for image in images)
32-
norm = colors.Normalize(vmin=vmin, vmax=vmax)
33-
for im in images:
34-
im.set_norm(norm)
33+
images = []
34+
for ax, data in zip(axs.flat, datasets):
35+
images.append(ax.imshow(data, norm=norm))
3536

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

38-
39-
# Make images respond to changes in the norm of other images (e.g. via the
40-
# "edit axis, curves and images parameters" GUI on Qt), but be careful not to
41-
# recurse infinitely!
42-
def update(changed_image):
43-
for im in images:
44-
if (changed_image.get_cmap() != im.get_cmap()
45-
or changed_image.get_clim() != im.get_clim()):
46-
im.set_cmap(changed_image.get_cmap())
47-
im.set_clim(changed_image.get_clim())
48-
49-
50-
for im in images:
51-
im.callbacks.connect('changed', update)
52-
5339
plt.show()
5440

5541
# %%
42+
# The colors are now kept consistent across all images when changing the
43+
# scaling, e.g. through zooming in the colorbar or via the "edit axis,
44+
# curves and images parameters" GUI of the Qt backend.
45+
#
46+
# While the norm is shared, the colormaps are not. This is often ok
47+
# because colormaps are usually not changed dynamically. However, a user
48+
# could change the colormap of an individual image through the
49+
# "edit axis, curves and images parameters" GUI of the Qt backend.
50+
# Unlike with a norm, it does not help to share colormaps between images.
51+
# Changes to the norm limits modify the norm object in place and thus
52+
# propagate to all images. But changing a colormap sets a new colormap
53+
# object to the images and thus does not propagate to the other images.
54+
# To make all other images follow, you could additionally sync the
55+
# colormaps using the following code::
56+
#
57+
# def sync_cmaps(changed_image):
58+
# for im in images:
59+
# if changed_image.get_cmap() != im.get_cmap():
60+
# im.set_cmap(changed_image.get_cmap())
61+
#
62+
# for im in images:
63+
# im.callbacks.connect('changed', sync_cmaps)
64+
#
5665
#
5766
# .. admonition:: References
5867
#
@@ -63,6 +72,4 @@ def update(changed_image):
6372
# - `matplotlib.figure.Figure.colorbar` / `matplotlib.pyplot.colorbar`
6473
# - `matplotlib.colors.Normalize`
6574
# - `matplotlib.cm.ScalarMappable.set_cmap`
66-
# - `matplotlib.cm.ScalarMappable.set_norm`
67-
# - `matplotlib.cm.ScalarMappable.set_clim`
6875
# - `matplotlib.cbook.CallbackRegistry.connect`

0 commit comments

Comments
 (0)