Colormap Normalisation Giving Unexpected/Incorrect Output
See original GitHub issueThe behaviour when specifying “norm” for a colormap normalisation does not work as anticipated.
Below I use the example code from matplotlib and apply the same normalisation to the DataArray version of the data but get very different results.
MCVE Code Sample
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as colors
import xarray
#example from https://matplotlib.org/3.1.1/tutorials/colors/colormapnorms.html
#for colormap normalisation
N = 100
X, Y = np.mgrid[-3:3:complex(0, N), -2:2:complex(0, N)]
Z1 = np.exp(-X**2 - Y**2)
Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
Z = (Z1 - Z2) * 2
fig, ax = plt.subplots(2, 1, figsize=(8, 8))
ax = ax.flatten()
bounds = np.linspace(-1, 1, 10)
norm = colors.BoundaryNorm(boundaries=bounds, ncolors=256)
ax[0].pcolormesh(X, Y, Z,
norm=norm,
cmap='RdBu_r')
#now add data into dataset and plot it using same normalisation
data = xarray.DataArray(Z, dims=('x', 'y'), coords={'x': X[:,0], 'y': Y[0,:]})
data.plot(ax=ax[1], x='x', y='y', norm=norm, add_colorbar=False)
plt.show()
Expected Output
Top is expected, bottom is actual

Problem Description
Colormap normalisation appears to be broken in xarray
Versions
Output of <tt>xr.show_versions()</tt>
xarray.show_versions()
INSTALLED VERSIONS
commit: None python: 3.7.3 | packaged by conda-forge | (default, Jul 1 2019, 21:52:21) [GCC 7.3.0] python-bits: 64 OS: Linux OS-release: 3.10.0-957.21.3.el7.x86_64 machine: x86_64 processor: x86_64 byteorder: little LC_ALL: None LANG: en_GB.UTF-8 LOCALE: en_GB.UTF-8 libhdf5: 1.10.4 libnetcdf: 4.6.2
xarray: 0.15.1 pandas: 0.25.1 numpy: 1.17.2 scipy: 1.3.1 netCDF4: 1.5.1.2 pydap: None h5netcdf: None h5py: 2.9.0 Nio: None zarr: None cftime: 1.0.3.4 nc_time_axis: None PseudoNetCDF: None rasterio: 1.0.28 cfgrib: None iris: 2.2.0 bottleneck: None dask: 2.5.2 distributed: 2.5.2 matplotlib: 3.1.1 cartopy: 0.17.0 seaborn: 0.9.0 numbagg: None setuptools: 41.4.0 pip: 19.2.3 conda: None pytest: None IPython: 7.8.0 sphinx: None
Issue Analytics
- State:
- Created 3 years ago
- Reactions:1
- Comments:7 (1 by maintainers)
If you use
it works. A new norm with
ncolors=9
is built in_build_discrete_cmap
- however, it is not used asnorm
is already defined:https://github.com/pydata/xarray/blob/2542a63f6ebed1a464af7fc74b9f3bf302925803/xarray/plot/utils.py#L290-L292
The fix might be to use:
this breaks one test which is probably fixable (it tests that the norm is not changed when it is given).
Note that mpl seems to use a
LinearSegmentedColormap
while xarray creates aListedColormap
.I also have an issue where xarray doesn’t produce the correct plot when normalizing with BoundaryNorm:
First one is from matplotlib:
Second one is from xarray:
I also get the following traceback after running the script:
Output of <tt>xr.show_versions()</tt>
INSTALLED VERSIONS
commit: None python: 3.10.0 | packaged by conda-forge | (default, Nov 20 2021, 02:25:18) [GCC 9.4.0] python-bits: 64 OS: Linux OS-release: 5.14.18-300.fc35.x86_64 machine: x86_64 processor: x86_64 byteorder: little LC_ALL: None LANG: en_GB.UTF-8 LOCALE: (‘en_GB’, ‘UTF-8’) libhdf5: 1.12.1 libnetcdf: 4.8.1
xarray: 0.20.1 pandas: 1.3.4 numpy: 1.21.4 scipy: 1.7.2 netCDF4: 1.5.8 pydap: None h5netcdf: None h5py: None Nio: None zarr: None cftime: 1.5.1.1 nc_time_axis: None PseudoNetCDF: None rasterio: None cfgrib: None iris: None bottleneck: None dask: None distributed: None matplotlib: 3.5.0 cartopy: 0.20.1 seaborn: None numbagg: None fsspec: None cupy: None pint: None sparse: None setuptools: 59.2.0 pip: 21.3.1 conda: None pytest: None IPython: 7.29.0 sphinx: None