html_url,issue_url,id,node_id,user,created_at,updated_at,author_association,body,reactions,performed_via_github_app,issue https://github.com/pydata/xarray/issues/4061#issuecomment-1464035444,https://api.github.com/repos/pydata/xarray/issues/4061,1464035444,IC_kwDOAMm_X85XQ2h0,60435591,2023-03-10T16:10:44Z,2023-03-10T16:10:44Z,CONTRIBUTOR,"@rjp23 with the latest update to the PR (thanks to @jklymak), your example code produced identical figures without changing it.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,618141254 https://github.com/pydata/xarray/issues/4061#issuecomment-1456441488,https://api.github.com/repos/pydata/xarray/issues/4061,1456441488,IC_kwDOAMm_X85Wz4iQ,31730876,2023-03-06T16:20:20Z,2023-03-06T16:20:20Z,NONE,"I’m not sure that’s a solution if we argue that xarray should do what matplotlib does with the same keywords. I can test if this “works” and will report back but it’s still not a fix.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,618141254 https://github.com/pydata/xarray/issues/4061#issuecomment-1456434882,https://api.github.com/repos/pydata/xarray/issues/4061,1456434882,IC_kwDOAMm_X85Wz27C,60435591,2023-03-06T16:16:31Z,2023-03-06T16:16:31Z,CONTRIBUTOR,@rjp23: could you close the issue if this indeed resolves your problem?,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,618141254 https://github.com/pydata/xarray/issues/4061#issuecomment-1446096001,https://api.github.com/repos/pydata/xarray/issues/4061,1446096001,IC_kwDOAMm_X85WMayB,60435591,2023-02-27T10:43:51Z,2023-02-27T11:16:59Z,CONTRIBUTOR,"As suggested by https://github.com/pydata/xarray/pull/7553#discussion_r1117264787, pass `levels=bounds` instead of `norm=norm` to `data.plot()`. Your example code results in a plot as expected. Would this solve your issue? ``` 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', levels=bounds, add_colorbar=False) ``` ![image](https://user-images.githubusercontent.com/60435591/221542907-55086ebb-241c-4879-82c1-849176983993.png) ","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,618141254 https://github.com/pydata/xarray/issues/4061#issuecomment-977165503,https://api.github.com/repos/pydata/xarray/issues/4061,977165503,IC_kwDOAMm_X846Ply_,33153877,2021-11-23T21:01:17Z,2021-11-23T21:01:17Z,NONE,"I also have an issue where xarray doesn't produce the correct plot when normalizing with BoundaryNorm: ```python import xarray as xr import matplotlib.pyplot as plt import matplotlib.colors as colors from cmcrameri import cm airtemps = xr.tutorial.open_dataset(""air_temperature"") # Convert to Celsius. air = airtemps.air - 273.15 air.attrs = airtemps.air.attrs air.attrs[""units""] = ""deg C"" # Select a timestep. air2d = air.isel(time=500) # Plotting discrete bounds with matplotlib works fine. bounds = [x for x in range(-30, 31, 10)] norm = colors.BoundaryNorm(boundaries=bounds, extend='both', ncolors=cm.vik.N) fig, ax = plt.subplots() cs = ax.pcolormesh(air2d.lon, air2d.lat, air2d, cmap=cm.vik, norm=norm) fig.colorbar(cs) plt.show() # Plotting with xarray doesn't work. fig, ax = plt.subplots() air2d.plot.pcolormesh(ax=ax, norm=norm) plt.show() ``` First one is from matplotlib: ![matplotlib](https://user-images.githubusercontent.com/33153877/143118949-f2a982ff-3fb1-4f14-8d8d-982ea8ead575.png) Second one is from xarray: ![xarray](https://user-images.githubusercontent.com/33153877/143118956-5a73a03e-7535-4d22-aaf8-987c4496e539.png) I also get the following traceback after running the script: ```bash Traceback (most recent call last): File ""/home/michael/miniconda3/envs/testing_xarray/lib/python3.10/site-packages/matplotlib/cbook/__init__.py"", line 287, in process func(*args, **kwargs) File ""/home/michael/miniconda3/envs/testing_xarray/lib/python3.10/site-packages/matplotlib/backend_bases.py"", line 3056, in mouse_move s = self._mouse_event_to_message(event) File ""/home/michael/miniconda3/envs/testing_xarray/lib/python3.10/site-packages/matplotlib/backend_bases.py"", line 3048, in _mouse_event_to_message data_str = a.format_cursor_data(data).rstrip() File ""/home/michael/miniconda3/envs/testing_xarray/lib/python3.10/site-packages/matplotlib/artist.py"", line 1282, in format_cursor_data neighbors = self.norm.inverse( File ""/home/michael/miniconda3/envs/testing_xarray/lib/python3.10/site-packages/matplotlib/colors.py"", line 1832, in inverse raise ValueError(""BoundaryNorm is not invertible"") ValueError: BoundaryNorm is not invertible ```
Output of xr.show_versions() 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
","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,618141254 https://github.com/pydata/xarray/issues/4061#issuecomment-630280798,https://api.github.com/repos/pydata/xarray/issues/4061,630280798,MDEyOklzc3VlQ29tbWVudDYzMDI4MDc5OA==,2448579,2020-05-18T16:03:40Z,2020-05-18T16:03:40Z,MEMBER,Seems like we should do whatever mpl does when given a norm and a colormap,"{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,618141254 https://github.com/pydata/xarray/issues/4061#issuecomment-629695308,https://api.github.com/repos/pydata/xarray/issues/4061,629695308,MDEyOklzc3VlQ29tbWVudDYyOTY5NTMwOA==,10194086,2020-05-16T19:30:14Z,2020-05-16T19:30:14Z,MEMBER,"That's probably gonna need a `extend=""both""`","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,618141254 https://github.com/pydata/xarray/issues/4061#issuecomment-629689922,https://api.github.com/repos/pydata/xarray/issues/4061,629689922,MDEyOklzc3VlQ29tbWVudDYyOTY4OTkyMg==,31730876,2020-05-16T18:44:55Z,2020-05-16T18:44:55Z,NONE,"Neither of those solutions seem to work for diverging colormaps where the data extends outside the range, i.e. the < and > data ends up with no colour.","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,618141254 https://github.com/pydata/xarray/issues/4061#issuecomment-629387430,https://api.github.com/repos/pydata/xarray/issues/4061,629387430,MDEyOklzc3VlQ29tbWVudDYyOTM4NzQzMA==,10194086,2020-05-15T17:33:33Z,2020-05-15T17:33:33Z,MEMBER,"If you use ```python norm = colors.BoundaryNorm(boundaries=bounds, ncolors=9) ``` it works. A new norm with `ncolors=9` is built in `_build_discrete_cmap` - however, it is not used as `norm` is already defined: https://github.com/pydata/xarray/blob/2542a63f6ebed1a464af7fc74b9f3bf302925803/xarray/plot/utils.py#L290-L292 The fix might be to use: ```python if levels is not None or isinstance(norm, mpl.colors.BoundaryNorm): cmap, norm = _build_discrete_cmap(cmap, levels, extend, filled) ``` 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 a `ListedColormap`. ","{""total_count"": 1, ""+1"": 1, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,618141254 https://github.com/pydata/xarray/issues/4061#issuecomment-629197481,https://api.github.com/repos/pydata/xarray/issues/4061,629197481,MDEyOklzc3VlQ29tbWVudDYyOTE5NzQ4MQ==,10194086,2020-05-15T12:05:39Z,2020-05-15T12:05:39Z,MEMBER,"What should also work is `img = ds['var'].plot(ax=ax, cmap=cmap, levels=levels)`","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,618141254 https://github.com/pydata/xarray/issues/4061#issuecomment-628619788,https://api.github.com/repos/pydata/xarray/issues/4061,628619788,MDEyOklzc3VlQ29tbWVudDYyODYxOTc4OA==,31730876,2020-05-14T13:03:12Z,2020-05-14T13:03:12Z,NONE,"It might be useful to note here that my solution for now was just to pass the arrays directly to pcolormesh rather than going through the xarray plot interface. i.e. I changed from `img = ds['var'].plot(ax=ax, cmap=cmap, norm=norm)` to `img = ax.pcolormesh(ds.x.values, ds.y.values, ds.tas.values, cmap=cmap, norm=norm)` ","{""total_count"": 0, ""+1"": 0, ""-1"": 0, ""laugh"": 0, ""hooray"": 0, ""confused"": 0, ""heart"": 0, ""rocket"": 0, ""eyes"": 0}",,618141254