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 (4 )
25
+ ]
26
+
27
+ fig ,axs = plt .subplots (2 ,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 ))
35
36
36
37
fig .colorbar (images [0 ],ax = axs ,orientation = 'horizontal' ,fraction = .1 )
37
38
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
39
plt .show ()
54
40
55
41
# %%
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
+ #
56
65
#
57
66
# .. admonition:: References
58
67
#
@@ -63,6 +72,4 @@ def update(changed_image):
63
72
# - `matplotlib.figure.Figure.colorbar` / `matplotlib.pyplot.colorbar`
64
73
# - `matplotlib.colors.Normalize`
65
74
# - `matplotlib.cm.ScalarMappable.set_cmap`
66
- # - `matplotlib.cm.ScalarMappable.set_norm`
67
- # - `matplotlib.cm.ScalarMappable.set_clim`
68
75
# - `matplotlib.cbook.CallbackRegistry.connect`