Search code examples
pythonmatplotlibplotcontourcolorbar

Use of "extend" in a contourf plot with a discrete colorbar not working


I would like to create a contourf plot with an imposed maximum value and with everything above that value shaded with the last color of the colorbar. In the example code below, which reproduces my problem in my setup, I would like the colorbar to range between -1 and 1, with an extend arrow indicating that values above 1.0 will be shaded with the last color of the colorbar. However, although I have tried several solutions from various stackexchange discussions, the colorbar ranges between -4 and 4, and there is no extend arrow. Please see the minimum reproducible example below.

# import matplotlib (v 3.1.1)
import matplotlib.colors as colors
import matplotlib.pyplot as plt
import matplotlib.path as mpath
import matplotlib as mpl
# import numpy (v 1.17.2)
import numpy as np

# define grid
lon = np.linspace(start = 0, stop = 359, num = 360)
lat = np.linspace(start = -78, stop = -25, num = 52)
[X,Y] = np.meshgrid(lon, lat)

# generate random gaussian data for example purposes
mean = [0, 0]
cov = [[1, 0], [0, 100]] 
zz = np.random.multivariate_normal(mean, cov, (np.size(lon),np.size(lat))).T
Z = zz[0,:,:]

# illutrate the maximum value of Z
np.max(Z)

# create plot
plt.figure(figsize=(10, 12))

# select plotting levels (missing min/max on purpose)
mylevs = [-1.0, -0.5, 0, 0.5, 1.0]

# colormap
cmap_cividis = plt.cm.get_cmap('cividis',len(mylevs))
mycolors = list(cmap_cividis(np.arange(len(mylevs))))
cmap = colors.ListedColormap(mycolors[:-1], "")
# set over-color to last color of list 
cmap.set_over(mycolors[-1])

# contour plot: random pattern 
C1 = plt.contourf(X, Y, Z, cmap = cmap, vmin=-1.0, vmax=1.0, 
                  norm = colors.BoundaryNorm(mylevs, ncolors=len(mylevs)-1, clip=False))

# create colorbar
cbar = plt.colorbar(C1, orientation="horizontal", extend='max')
cbar.ax.tick_params(labelsize=20)
cbar.set_label('Random field', size='xx-large')

I would like the colorbar to stop at 1.0, with an extend arrow pointing to the right, shaded by the last color of the colorbar. Thanks in advance for any help you can provide.

Link to example image produced by the above code


Solution

  • Does this solve it?

    fig,ax = plt.subplots()
    
    mylevs = [-1.0, -0.5, 0, 0.5, 1.0]
    
    C1 = ax.contourf(X, Y, Z, cmap = cmap, vmin=-1.0, vmax=1.0,levels=mylevs,extend='both')
    fig.colorbar(C1)
    

    enter image description here