I have Sea Ice Concentration data around Antarctica that range between -40 and +40 (see attached Figure) but I would like for the values between +10 and -10 to appear white in my map and colorbar because they do not represent sea ice concentration (they appear light green and light blue in the current Figure).
I do not want to exclude them from my array but rather want to assign them a specific color (in this case, white) and keep the jet colorscale for the other values.
I have looked at multiple other questions (i.e. How to change colorbar's color (in some particular value interval)?; Python matplotlib change default color for values exceeding colorbar range; **Reset default matplotlib colormap values after using 'set_under' or 'set_over')
but have not managed to apply those to my case.
I have tried to use 'set under','set over', 'set.bad' but have not managed to get what I would like. I have also tried to create my own colormap but haven't been successful either.
Would anyone be able to help?
Thanks.
UPDATE:
I have adapted the code from 'stackoverflow.com/a/41815114/5103802' (see Updated Code below) but my colors are not white for values [+10 -10] and 'jet' for above +10 and below -10 (see Figure below). The 'tmap' object seems to have messed up the colorscale. Any idea on how I could get the jet colorscale and leave the interval between -10 and +10 white?
Thanks for your help.
Updated code:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors
from mpl_toolkits.basemap import Basemap, cm, rcParams
HIGH_86 = a.variables['high_86'][:]
n=40
x = 10
lower = plt.cm.seismic(np.linspace(1-x, 0, n))
upper = plt.cm.seismic(np.linspace(0, x, n))
white1 = plt.cm.seismic(np.ones(10)*x)
white2 = plt.cm.seismic(np.ones(10)*-(x))
colors = np.vstack((lower, white1, white2, upper))
tmap = matplotlib.colors.LinearSegmentedColormap.from_list('terrain_map_white', colors)
x = HIGH_86
lats = a.variables['latitude'][:]
lons = a.variables['longitude'][:]
lons, lats = np.meshgrid(lons,lats)
fig, ax = plt.subplots()
m2 = Basemap(projection='spstere',boundinglat=-50,lon_0=180,resolution='l')
CS2 = m2.contourf(lons,lats,x,cmap=tmap,latlon=True)
cbar = m2.colorbar(CS2,location='right', pad="12%")
m2.drawparallels(np.arange(-90.,99.,60.),labels=[False,False,False,False])
m2.drawmeridians(np.arange(-180.,180.,90.),labels=[True,False,False,True])
m2.drawcoastlines()
m1.fillcontinents(color='grey')
plt.title('SIE Anomaly')
plt.show()
I assume you have read the linked question and it's answer. It clearly states
Colormaps are always ranged between 0 and 1.
and further explains how to arrive at a suitable colormap. It thus makes no sense to supply values of 10 or -9 to the colormap.
While you could directly copy the code from the answer here and would receive a decent result, you may of course also refine it to match this specific case, where one may go for 80 colors, 30 from the lower part of the colormap, 30 from the upper part and the remaining 20 in the middle to be white.
n=30
x = 0.5
lower = plt.cm.seismic(np.linspace(0, x, n))
white = plt.cm.seismic(np.ones(80-2*n)*x)
upper = plt.cm.seismic(np.linspace(1-x, 1, n))
colors = np.vstack((lower, white, upper))
tmap = matplotlib.colors.LinearSegmentedColormap.from_list('map_white', colors)
In order to get the jet colormap, which does not have white in it, an array of ones may be used in the middle
n=30
x = 0.5
cmap = plt.cm.jet
lower = cmap(np.linspace(0, x, n))
white = np.ones((80-2*n,4))
upper = cmap(np.linspace(1-x, 1, n))
colors = np.vstack((lower, white, upper))
tmap = matplotlib.colors.LinearSegmentedColormap.from_list('map_white', colors)
Complete code to reproduce the image above:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors
n=30
x = 0.5
cmap = plt.cm.jet
lower = cmap(np.linspace(0, x, n))
white = np.ones((80-2*n,4))
upper = cmap(np.linspace(1-x, 1, n))
colors = np.vstack((lower, white, upper))
tmap = matplotlib.colors.LinearSegmentedColormap.from_list('map_white', colors)
x = np.linspace(0,10)
X,Y = np.meshgrid(x,x)
z = np.sin(X) * np.cos(Y*0.4)*40
fig, ax = plt.subplots()
im = ax.contourf(z, cmap=tmap, vmin=-40, vmax=40)
plt.colorbar(im)
plt.show()