Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit e68bfdb

Browse filesBrowse files
timhoffmmeeseeksmachine
authored andcommitted
Backport PR #28546: DOC: Clarify/simplify example of multiple images with one colorbar
1 parent 486e1e2 commit e68bfdb
Copy full SHA for e68bfdb

File tree

1 file changed

+51
-37
lines changed
Filter options

1 file changed

+51
-37
lines changed
+51-37Lines changed: 51 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
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 connected to one image. The connection
9+
guarantees that the data coloring is consistent with the colormap scale
10+
(i.e. the color of value *x* in the colormap is used for coloring a data
11+
value *x* in the image).
12+
13+
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.
717
"""
818

919
import matplotlib.pyplot as plt
@@ -12,47 +22,53 @@
1222
from matplotlib import colors
1323

1424
np.random.seed(19680801)
15-
Nr = 3
16-
Nc = 2
1725

18-
fig, axs = plt.subplots(Nr, Nc)
26+
datasets = [
27+
(i+1)/10 * np.random.rand(10, 20)
28+
for i in range(4)
29+
]
30+
31+
fig, axs = plt.subplots(2, 2)
1932
fig.suptitle('Multiple images')
2033

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()
34+
# create a single norm to be shared across all images
35+
norm = colors.Normalize(vmin=np.min(datasets), vmax=np.max(datasets))
2836

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)
37+
images = []
38+
for ax, data in zip(axs.flat, datasets):
39+
images.append(ax.imshow(data, norm=norm))
3540

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

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-
5343
plt.show()
5444

5545
# %%
46+
# The colors are now kept consistent across all images when changing the
47+
# 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+
#
5672
#
5773
# .. admonition:: References
5874
#
@@ -63,6 +79,4 @@ def update(changed_image):
6379
# - `matplotlib.figure.Figure.colorbar` / `matplotlib.pyplot.colorbar`
6480
# - `matplotlib.colors.Normalize`
6581
# - `matplotlib.cm.ScalarMappable.set_cmap`
66-
# - `matplotlib.cm.ScalarMappable.set_norm`
67-
# - `matplotlib.cm.ScalarMappable.set_clim`
6882
# - `matplotlib.cbook.CallbackRegistry.connect`

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.