1
1
"""
2
- ===============
3
- Multiple images
4
- ===============
2
+ =================================
3
+ Multiple images with one colorbar
4
+ =================================
5
5
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.
7
13
"""
8
14
9
15
import matplotlib .pyplot as plt
12
18
from matplotlib import colors
13
19
14
20
np .random .seed (19680801 )
15
- Nr = 3
16
- Nc = 2
17
21
18
- fig , axs = plt .subplots (Nr , Nc )
22
+ datasets = [
23
+ (i + 1 )/ 10 * np .random .rand (10 , 20 )
24
+ for i in range (6 )
25
+ ]
26
+
27
+ fig , axs = plt .subplots (3 , 2 )
19
28
fig .suptitle ('Multiple images' )
20
29
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 ))
28
32
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 ))
36
+ ax .label_outer ()
35
37
36
38
fig .colorbar (images [0 ], ax = axs , orientation = 'horizontal' , fraction = .1 )
37
39
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
-
53
40
plt .show ()
54
41
55
42
# %%
43
+ # The colors are now kept consistent across all images when changing the
44
+ # scaling, e.g. through zooming in the colorbar or via the "edit axis,
45
+ # curves and images parameters" GUI of the Qt backend.
46
+ #
47
+ # While the norm is shared, the colormaps are not. This is often ok
48
+ # because colormaps are usually not changed dynamically. However, a user
49
+ # could change the colormap of an individual image through the
50
+ # "edit axis, curves and images parameters" GUI of the Qt backend.
51
+ # Unlike with a norm, it does not help to share colormaps between images.
52
+ # Changes to the norm limits modify the norm object in place and thus
53
+ # propagate to all images. But changing a colormap sets a new colormap
54
+ # object to the images and thus does not propagate to the other images.
55
+ # To make all other images follow, you could additionally sync the
56
+ # colormaps using the following code::
57
+ #
58
+ # def sync_cmaps(changed_image):
59
+ # for im in images:
60
+ # if changed_image.get_cmap() != im.get_cmap():
61
+ # im.set_cmap(changed_image.get_cmap())
62
+ #
63
+ # for im in images:
64
+ # im.callbacks.connect('changed', sync_cmaps)
65
+ #
56
66
#
57
67
# .. admonition:: References
58
68
#
@@ -63,6 +73,4 @@ def update(changed_image):
63
73
# - `matplotlib.figure.Figure.colorbar` / `matplotlib.pyplot.colorbar`
64
74
# - `matplotlib.colors.Normalize`
65
75
# - `matplotlib.cm.ScalarMappable.set_cmap`
66
- # - `matplotlib.cm.ScalarMappable.set_norm`
67
- # - `matplotlib.cm.ScalarMappable.set_clim`
68
76
# - `matplotlib.cbook.CallbackRegistry.connect`
0 commit comments