I'm trying to create a pcolormesh plot with a discrete colorbar. The output should fulfil these criteria:
- The first level should be white
- The data should be cut off at some level
- Data above the cut off should have a separate colour (namely the last colour of the colormap)
I am almost there but the 'extend' keyword does not behave the way I would expect it to (the colour in the "max-arrow" is the same as for the last level - see example). How do I set values above 'vmax' to a separate colour (i.e., the last colour of whatever colormap I use)
import numpy as np
import xarray as xr
import matplotlib as mpl
import matplotlib.pyplot as plt
ds = xr.Dataset(
coords={'lon': np.arange(-180, 180, 10),
'lat': np.arange(-85, 90, 10)},
data_vars={'data': (('lat', 'lon'), np.random.rand(18, 36))})
cmap = plt.cm.get_cmap('Reds')
cmap.set_under('w')
# cmap.set_over() # do something here?
levels = np.arange(0, .7, .1)
ds.data.plot.pcolormesh(
cmap=cmap,
vmin=levels[1],
# vmax=levels[-1],
extend='max',
norm = mpl.colors.BoundaryNorm(levels, ncolors=cmap.N, clip=False)
)
I'm using xarray but the behaviour is the same for plt.pcolormesh:
p = plt.pcolormesh(
np.arange(-180, 180, 10),
np.arange(-85, 90, 10),
np.random.rand(18, 36),
cmap=cmap,
vmin=levels[1],
# vmax=levels[-1],
norm = mpl.colors.BoundaryNorm(levels, ncolors=cmap.N, clip=False)
)
plt.colorbar(p, extend='max')
Indeed, if you set
cmap.set_over("blue")
you would see blue as the color of the values exceeding the maximum value.However, if you want to use the last color of the colormap as that color for
set_over
you need to make a colormap, which stops at the second last color. To that end, the following rationale may be used. If we aim at 6 different colors from a colormap plus the color for overshooting values, we take 7 colors from that colormap, replace the first with white color and use the first 6 colors as the colors for the boundary interval. The last colors is then used as the color for overshooting values.