Question: I have a plot that looks like this  I cannot understand how to manually change or set the range of data values for the colorbar. I would like to experiment with ranges based on the data values shown in the plots and change the colorbar to (-4,4). I see that plt.clim, vmin and vmax are functions to possibly use. Here is my code: import cdsapi import xarray as xr import matplotlib.pyplot as plt import numpy as np import cartopy.crs as ccrs # Also requires cfgrib library. c = cdsapi.Client() url = c.retrieve( 'reanalysis-era5-single-levels-monthly-means', { 'product_type': 'monthly_averaged_reanalysis', 'format': 'grib', 'variable': ['100m_u_component_of_wind','100m_v_component_of_wind'], 'year': ['2006','2007','2008','2009','2010','2011','2012','2013','2014','2015','2016','2017','2018','2019','2020','2021'], 'month': ['01','02','03','04','05','06','07','08','09','10','11','12'], 'time': '00:00', 'grid': [0.25, 0.25], 'area': [70.00, -180.00, -40.00, 180.00], }, "C:\\Users\\U321103\\.spyder-py3\\ERA5_MAPPING\\100m_wind_U_V.grib") path = "C:\\Users\\U321103\\.spyder-py3\\ERA5_MAPPING\\100m_wind_U_V.grib" ds = xr.load_dataset(path, engine='cfgrib') wind_abs = np.sqrt(ds.u100**2 + ds.v100**2) monthly_means = wind_abs.mean(dim='time') wind_abs_clim = wind_abs.sel(time=slice('2006-01','2020-12')).groupby('time.month').mean(dim='time') # select averaging period wind_abs_anom = ((wind_abs.groupby('time.month') / wind_abs_clim))-1 #deviation from climo fg = wind_abs_anom.sel(time=slice('2021-01',None)).groupby('time.month').mean(dim='time').plot(col='month', col_wrap=3,transform=ccrs.PlateCarree(), cbar_kwargs={'orientation':'horizontal','shrink':0.6, 'aspect':40,'label':'Percent Deviation'},robust=False,subplot_kws={'projection': ccrs.Mercator()}) fg.map(lambda: plt.gca().coastlines()) 

Answer: I was able to reproduce your figure and found that I could add vmin and vmax as shown below. For some reason that meant I also had to specify the colormap, otherwise I ended up with viridis. But the code below works for me (with a bit of refactoring as I got it working — the only material change here is in the plotting section at the bottom). First, loading the data: import cdsapi c = cdsapi.Client() params = { 'product_type': 'monthly_averaged_reanalysis', 'format': 'grib', 'variable': ['100m_u_component_of_wind', '100m_v_component_of_wind'], 'year': [f'{n}' for n in range(2006, 2022)], 'month': [f'{n:02d}' for n in range(1, 13)], 'time': '00:00', 'grid': [0.25, 0.25], 'area': [70.00, -180.00, -40.00, 180.00], } path = '100m_wind_U_V.grib' url = c.retrieve('reanalysis-era5-single-levels-monthly-means', params, path, )  Then there's the data pipeline: import xarray as xr import numpy as np # Also need cfgrib library. ds = xr.load_dataset(path, engine='cfgrib') wind_abs = np.sqrt(ds.u100**2 + ds.v100**2) monthly_means = wind_abs.mean(dim='time') wind_abs_clim = (wind_abs.sel(time=slice('2006-01','2020-12')) .groupby('time.month') .mean(dim='time')) wind_abs_anom = ((wind_abs.groupby('time.month') / wind_abs_clim)) - 1  Finally the plotting: import cartopy.crs as ccrs import matplotlib.pyplot as plt cbar_kwargs = {'orientation':'horizontal', 'shrink':0.6, 'aspect':40, 'label':'Percent Deviation'} subplot_kws = {'projection': ccrs.Mercator()} fg = (wind_abs_anom.sel(time=slice('2021-01', None)) .groupby('time.month') .mean(dim='time') .plot(col='month', col_wrap=3, transform=ccrs.PlateCarree(), cmap='RdBu_r', vmin=-3, vmax=3, # <-- New bit. cbar_kwargs=cbar_kwargs, robust=False, subplot_kws=subplot_kws )) fg.map(lambda: plt.gca().coastlines())  Sometimes I'll use a percentile to control the values for vmin and vmax automatically, like max_ = np.percentile(data, 99), then vmin=-max_, vmax=max_. This deals nicely with outliers that stretch the colormap, but it requires you to be able to calculate those values before making the plot. If you want to start having more control over the plot, it might be a good idea to stop using the xarray plotting interface and use matplotlib and cartopy directly. Here's what that might look like (replacing all of the plotting code above): import cartopy.crs as ccrs import matplotlib.pyplot as plt sel = wind_abs_anom.sel(time=slice('2021-01', None)) left, *_, right = wind_abs_anom.longitude top, *_, bottom = wind_abs_anom.latitude # Min and max latitude. extent = [left, right, bottom, top] fig, axs = plt.subplots(nrows=2, ncols=3, figsize=(15, 6), subplot_kw={'projection': ccrs.PlateCarree()}, ) for ax, (month, group) in zip(axs.flat, sel.groupby('time.month')): mean = group.mean(dim='time') im = ax.imshow(mean, transform=ccrs.PlateCarree(), extent=extent, cmap='RdBu_r', vmin=-3, vmax=3) ax.set_title(f'month = {month}') ax.coastlines() cbar_ax = fig.add_axes([0.2, 0.0, 0.6, 0.05]) # Left, bottom, width, height. cbar = fig.colorbar(im, cax=cbar_ax, extend='both', orientation='horizontal') cbar.set_label('Percent deviation') plt.show()  For some reason, when I try to use ccra.Mercator() for the map, the data gets distorted; maybe you can figure that bit out.