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 85213e2

Browse filesBrowse files
authored
Merge pull request #27729 from QuLogic/cmap-norm
DOC: Improve colormap normalization example
2 parents e470c70 + ffa4556 commit 85213e2
Copy full SHA for 85213e2

File tree

Expand file treeCollapse file tree

1 file changed

+81
-72
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+81
-72
lines changed

‎galleries/examples/images_contours_and_fields/colormap_normalizations.py

Copy file name to clipboardExpand all lines: galleries/examples/images_contours_and_fields/colormap_normalizations.py
+81-72Lines changed: 81 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -13,85 +13,90 @@
1313

1414
import matplotlib.colors as colors
1515

16-
# %%
17-
# Lognorm: Instead of pcolor log10(Z1) you can have colorbars that have
18-
# the exponential labels using a norm.
19-
2016
N = 100
21-
X, Y = np.mgrid[-3:3:complex(0, N), -2:2:complex(0, N)]
2217

23-
# A low hump with a spike coming out of the top. Needs to have
24-
# z/colour axis on a log scale, so we see both hump and spike.
25-
# A linear scale only shows the spike.
18+
# %%
19+
# LogNorm
20+
# -------
21+
# This example data has a low hump with a spike coming out of its center. If plotted
22+
# using a linear colour scale, then only the spike will be visible. To see both hump and
23+
# spike, this requires the z/colour axis on a log scale.
24+
#
25+
# Instead of transforming the data with ``pcolor(log10(Z))``, the color mapping can be
26+
# made logarithmic using a `.LogNorm`.
2627

28+
X, Y = np.mgrid[-3:3:complex(0, N), -2:2:complex(0, N)]
2729
Z1 = np.exp(-X**2 - Y**2)
2830
Z2 = np.exp(-(X * 10)**2 - (Y * 10)**2)
2931
Z = Z1 + 50 * Z2
3032

3133
fig, ax = plt.subplots(2, 1)
3234

33-
pcm = ax[0].pcolor(X, Y, Z,
34-
norm=colors.LogNorm(vmin=Z.min(), vmax=Z.max()),
35-
cmap='PuBu_r', shading='nearest')
36-
fig.colorbar(pcm, ax=ax[0], extend='max')
37-
38-
pcm = ax[1].pcolor(X, Y, Z, cmap='PuBu_r', shading='nearest')
39-
fig.colorbar(pcm, ax=ax[1], extend='max')
35+
pcm = ax[0].pcolor(X, Y, Z, cmap='PuBu_r', shading='nearest')
36+
fig.colorbar(pcm, ax=ax[0], extend='max', label='linear scaling')
4037

38+
pcm = ax[1].pcolor(X, Y, Z, cmap='PuBu_r', shading='nearest',
39+
norm=colors.LogNorm(vmin=Z.min(), vmax=Z.max()))
40+
fig.colorbar(pcm, ax=ax[1], extend='max', label='LogNorm')
4141

4242
# %%
43-
# PowerNorm: Here a power-law trend in X partially obscures a rectified
44-
# sine wave in Y. We can remove the power law using a PowerNorm.
43+
# PowerNorm
44+
# ---------
45+
# This example data mixes a power-law trend in X with a rectified sine wave in Y. If
46+
# plotted using a linear colour scale, then the power-law trend in X partially obscures
47+
# the sine wave in Y.
48+
#
49+
# The power law can be removed using a `.PowerNorm`.
4550

4651
X, Y = np.mgrid[0:3:complex(0, N), 0:2:complex(0, N)]
47-
Z1 = (1 + np.sin(Y * 10.)) * X**2
52+
Z = (1 + np.sin(Y * 10)) * X**2
4853

4954
fig, ax = plt.subplots(2, 1)
5055

51-
pcm = ax[0].pcolormesh(X, Y, Z1, norm=colors.PowerNorm(gamma=1. / 2.),
52-
cmap='PuBu_r', shading='nearest')
53-
fig.colorbar(pcm, ax=ax[0], extend='max')
56+
pcm = ax[0].pcolormesh(X, Y, Z, cmap='PuBu_r', shading='nearest')
57+
fig.colorbar(pcm, ax=ax[0], extend='max', label='linear scaling')
5458

55-
pcm = ax[1].pcolormesh(X, Y, Z1, cmap='PuBu_r', shading='nearest')
56-
fig.colorbar(pcm, ax=ax[1], extend='max')
59+
pcm = ax[1].pcolormesh(X, Y, Z, cmap='PuBu_r', shading='nearest',
60+
norm=colors.PowerNorm(gamma=0.5))
61+
fig.colorbar(pcm, ax=ax[1], extend='max', label='PowerNorm')
5762

5863
# %%
59-
# SymLogNorm: two humps, one negative and one positive, The positive
60-
# with 5-times the amplitude. Linearly, you cannot see detail in the
61-
# negative hump. Here we logarithmically scale the positive and
62-
# negative data separately.
64+
# SymLogNorm
65+
# ----------
66+
# This example data has two humps, one negative and one positive, The positive hump has
67+
# 5 times the amplitude of the negative. If plotted with a linear colour scale, then
68+
# the detail in the negative hump is obscured.
69+
#
70+
# Here we logarithmically scale the positive and negative data separately with
71+
# `.SymLogNorm`.
6372
#
6473
# Note that colorbar labels do not come out looking very good.
6574

6675
X, Y = np.mgrid[-3:3:complex(0, N), -2:2:complex(0, N)]
67-
Z = 5 * np.exp(-X**2 - Y**2)
76+
Z1 = np.exp(-X**2 - Y**2)
77+
Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
78+
Z = (5 * Z1 - Z2) * 2
6879

6980
fig, ax = plt.subplots(2, 1)
7081

71-
pcm = ax[0].pcolormesh(X, Y, Z,
72-
norm=colors.SymLogNorm(linthresh=0.03, linscale=0.03,
73-
vmin=-1.0, vmax=1.0, base=10),
74-
cmap='RdBu_r', shading='nearest')
75-
fig.colorbar(pcm, ax=ax[0], extend='both')
82+
pcm = ax[0].pcolormesh(X, Y, Z, cmap='RdBu_r', shading='nearest',
83+
vmin=-np.max(Z))
84+
fig.colorbar(pcm, ax=ax[0], extend='both', label='linear scaling')
7685

77-
pcm = ax[1].pcolormesh(X, Y, Z, cmap='RdBu_r', vmin=-np.max(Z),
78-
shading='nearest')
79-
fig.colorbar(pcm, ax=ax[1], extend='both')
86+
pcm = ax[1].pcolormesh(X, Y, Z, cmap='RdBu_r', shading='nearest',
87+
norm=colors.SymLogNorm(linthresh=0.015,
88+
vmin=-10.0, vmax=10.0, base=10))
89+
fig.colorbar(pcm, ax=ax[1], extend='both', label='SymLogNorm')
8090

8191
# %%
82-
# Custom Norm: An example with a customized normalization. This one
83-
# uses the example above, and normalizes the negative data differently
84-
# from the positive.
92+
# Custom Norm
93+
# -----------
94+
# Alternatively, the above example data can be scaled with a customized normalization.
95+
# This one normalizes the negative data differently from the positive.
8596

86-
X, Y = np.mgrid[-3:3:complex(0, N), -2:2:complex(0, N)]
87-
Z1 = np.exp(-X**2 - Y**2)
88-
Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
89-
Z = (Z1 - Z2) * 2
9097

9198
# Example of making your own norm. Also see matplotlib.colors.
9299
# From Joe Kington: This one gives two different linear ramps:
93-
94-
95100
class MidpointNormalize(colors.Normalize):
96101
def __init__(self, vmin=None, vmax=None, midpoint=None, clip=False):
97102
self.midpoint = midpoint
@@ -107,38 +112,42 @@ def __call__(self, value, clip=None):
107112
# %%
108113
fig, ax = plt.subplots(2, 1)
109114

110-
pcm = ax[0].pcolormesh(X, Y, Z,
111-
norm=MidpointNormalize(midpoint=0.),
112-
cmap='RdBu_r', shading='nearest')
113-
fig.colorbar(pcm, ax=ax[0], extend='both')
115+
pcm = ax[0].pcolormesh(X, Y, Z, cmap='RdBu_r', shading='nearest',
116+
vmin=-np.max(Z))
117+
fig.colorbar(pcm, ax=ax[0], extend='both', label='linear scaling')
114118

115-
pcm = ax[1].pcolormesh(X, Y, Z, cmap='RdBu_r', vmin=-np.max(Z),
116-
shading='nearest')
117-
fig.colorbar(pcm, ax=ax[1], extend='both')
119+
pcm = ax[1].pcolormesh(X, Y, Z, cmap='RdBu_r', shading='nearest',
120+
norm=MidpointNormalize(midpoint=0))
121+
fig.colorbar(pcm, ax=ax[1], extend='both', label='Custom norm')
118122

119123
# %%
120-
# BoundaryNorm: For this one you provide the boundaries for your colors,
121-
# and the Norm puts the first color in between the first pair, the
122-
# second color between the second pair, etc.
123-
124-
fig, ax = plt.subplots(3, 1, figsize=(8, 8))
125-
ax = ax.flatten()
126-
# even bounds gives a contour-like effect
127-
bounds = np.linspace(-1, 1, 10)
128-
norm = colors.BoundaryNorm(boundaries=bounds, ncolors=256)
129-
pcm = ax[0].pcolormesh(X, Y, Z,
130-
norm=norm,
131-
cmap='RdBu_r', shading='nearest')
132-
fig.colorbar(pcm, ax=ax[0], extend='both', orientation='vertical')
124+
# BoundaryNorm
125+
# ------------
126+
# For arbitrarily dividing the color scale, the `.BoundaryNorm` may be used; by
127+
# providing the boundaries for colors, this norm puts the first color in between the
128+
# first pair, the second color between the second pair, etc.
129+
130+
fig, ax = plt.subplots(3, 1, layout='constrained')
133131

134-
# uneven bounds changes the colormapping:
135-
bounds = np.array([-0.25, -0.125, 0, 0.5, 1])
132+
pcm = ax[0].pcolormesh(X, Y, Z, cmap='RdBu_r', shading='nearest',
133+
vmin=-np.max(Z))
134+
fig.colorbar(pcm, ax=ax[0], extend='both', orientation='vertical',
135+
label='linear scaling')
136+
137+
# Evenly-spaced bounds gives a contour-like effect.
138+
bounds = np.linspace(-2, 2, 11)
136139
norm = colors.BoundaryNorm(boundaries=bounds, ncolors=256)
137-
pcm = ax[1].pcolormesh(X, Y, Z, norm=norm, cmap='RdBu_r', shading='nearest')
138-
fig.colorbar(pcm, ax=ax[1], extend='both', orientation='vertical')
140+
pcm = ax[1].pcolormesh(X, Y, Z, cmap='RdBu_r', shading='nearest',
141+
norm=norm)
142+
fig.colorbar(pcm, ax=ax[1], extend='both', orientation='vertical',
143+
label='BoundaryNorm\nlinspace(-2, 2, 11)')
139144

140-
pcm = ax[2].pcolormesh(X, Y, Z, cmap='RdBu_r', vmin=-np.max(Z1),
141-
shading='nearest')
142-
fig.colorbar(pcm, ax=ax[2], extend='both', orientation='vertical')
145+
# Unevenly-spaced bounds changes the colormapping.
146+
bounds = np.array([-1, -0.5, 0, 2.5, 5])
147+
norm = colors.BoundaryNorm(boundaries=bounds, ncolors=256)
148+
pcm = ax[2].pcolormesh(X, Y, Z, cmap='RdBu_r', shading='nearest',
149+
norm=norm)
150+
fig.colorbar(pcm, ax=ax[2], extend='both', orientation='vertical',
151+
label='BoundaryNorm\n[-1, -0.5, 0, 2.5, 5]')
143152

144153
plt.show()

0 commit comments

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