-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
What happened?
When I tried to plot 2D flow field (Time * Nx * Ny np array), I got "AxesImage.set() got an unexpected keyword argument 'msg'", which I found came from dataarray_plot._plot2d.newplotfunc. Here is the detail:
OS: Ubuntu 24.04 LTS, WSL2
python version: 3.12.8
numpy version: 2.2.6
xarray version: 2025.3.0
matplotlib version: 3.10.0 (newest on Jan. 26 2026)
My code snippet:
# load into xarray for visualization and analysis
ds = xarray.Dataset(
{
'u': (('time', 'x', 'y'), trajectory[0].data), # (10, 128, 128) array
'v': (('time', 'x', 'y'), trajectory[1].data), # (10, 128, 128) array
},
coords={
'x': grid.axes()[0], # (128,) array
'y': grid.axes()[1], # (128,) array
'time': dt * inner_steps * np.arange(1, outer_steps + 1) # (10,) array
}
)
ds["vorticity"] = ds["v"].differentiate("x") - ds["u"].differentiate("y") # (10, 128, 128) array
# Plot the x-velocity
ds.pipe(lambda ds: ds.u).plot.imshow('x', 'y', col='time', cmap=seaborn.cm.rocket, robust=True, col_wrap=4, aspect=2)
The error message is attached below.
What did you expect to happen?
No response
Minimal Complete Verifiable Example
# /// script
# requires-python = ">=3.11"
# dependencies = [
# "xarray[complete]@git+https://github.com/pydata/xarray.git@main",
# ]
# ///
#
# This script automatically imports the development branch of xarray to check for issues.
# Please delete this header if you have _not_ tested this script with `uv run`!
import xarray as xr
xr.show_versions()
# your reproducer code ...
# load into xarray for visualization and analysis
ds = xarray.Dataset(
{
'u': (('time', 'x', 'y'), np.random.randn(10, 128, 128)), # (10, 128, 128) array
'v': (('time', 'x', 'y'), np.random.randn(10, 128, 128)), # (10, 128, 128) array
},
coords={
'x': np.linspace(0, 2*np.pi, 128), # (128,) array
'y': np.linspace(0, 2*np.pi, 128), # (128,) array
'time': np.linspace(0, 1, 10) # (10,) array
}
)
ds.u.plot.imshow('x', 'y', col='time')Steps to reproduce
Just run the minimal complete verifiable example.
MVCE confirmation
- Minimal example — the example is as focused as reasonably possible to demonstrate the underlying issue in xarray.
- Complete example — the example is self-contained, including all data and the text of any traceback.
- Verifiable example — the example copy & pastes into an IPython prompt or Binder notebook, returning the result.
- New issue — a search of GitHub Issues suggests this is not a duplicate.
- Recent environment — the issue occurs with the latest version of xarray and its dependencies.
Relevant log output
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[20], line 14
1 # load into xarray for visualization and analysis
2 ds = xarray.Dataset(
3 {
4 'u': (('time', 'x', 'y'), np.random.randn(10, 128, 128)), # (10, 128, 128) array
(...) 11 }
12 )
---> 14 ds.u.plot.imshow('x', 'y', col='time')
File ***/site-packages/xarray/plot/accessor.py:421, in DataArrayPlotAccessor.imshow(self, *args, **kwargs)
419 @functools.wraps(dataarray_plot.imshow, assigned=("__doc__",))
420 def imshow(self, *args, **kwargs) -> AxesImage | FacetGrid[DataArray]:
--> 421 return dataarray_plot.imshow(self._da, *args, **kwargs)
File ***/site-packages/xarray/plot/dataarray_plot.py:1507, in _plot2d.<locals>.newplotfunc(***failed resolving arguments***)
1505 # Need the decorated plotting function
1506 allargs["plotfunc"] = globals()[plotfunc.__name__]
-> 1507 return _easy_facetgrid(darray, kind="dataarray", **allargs)
1509 if darray.ndim == 0 or darray.size == 0:
1510 # TypeError to be consistent with pandas
1511 raise TypeError("No numeric data to plot.")
File ***/site-packages/xarray/plot/facetgrid.py:1072, in _easy_facetgrid(data, plotfunc, kind, x, y, row, col, col_wrap, sharex, sharey, aspect, size, subplot_kws, ax, figsize, **kwargs)
1069 return g.map_dataarray_line(plotfunc, x, y, **kwargs)
1071 if kind == "dataarray":
-> 1072 return g.map_dataarray(plotfunc, x, y, **kwargs)
1074 if kind == "plot1d":
1075 return g.map_plot1d(plotfunc, x, y, **kwargs)
File ***/site-packages/xarray/plot/facetgrid.py:373, in FacetGrid.map_dataarray(self, func, x, y, **kwargs)
371 if d is not None:
372 subset = self.data.loc[d]
--> 373 mappable = func(
374 subset, x=x, y=y, ax=ax, **func_kwargs, _is_facetgrid=True
375 )
376 self._mappables.append(mappable)
378 self._finalize_grid(x, y)
File ***/site-packages/xarray/plot/dataarray_plot.py:1607, in _plot2d.<locals>.newplotfunc(***failed resolving arguments***)
1603 raise ValueError("plt.imshow's `aspect` kwarg is not available in xarray")
1605 ax = get_axis(figsize, size, aspect, ax, **subplot_kws)
-> 1607 primitive = plotfunc(
1608 xplt,
1609 yplt,
1610 zval,
1611 ax=ax,
1612 cmap=cmap_params["cmap"],
1613 vmin=cmap_params["vmin"],
1614 vmax=cmap_params["vmax"],
1615 norm=cmap_params["norm"],
1616 **kwargs,
1617 )
1619 # Label the plot with metadata
1620 if add_labels:
File ***/site-packages/xarray/plot/dataarray_plot.py:1866, in imshow(x, y, z, ax, **kwargs)
1863 z = z.copy()
1864 z[np.any(z.mask, axis=-1), -1] = 0
-> 1866 primitive = ax.imshow(z, **defaults)
1868 # If x or y are strings the ticklabels have been replaced with
1869 # integer indices. Replace them back to strings:
1870 for axis, v in [("x", x), ("y", y)]:
File ***/site-packages/matplotlib/__init__.py:1521, in _preprocess_data.<locals>.inner(ax, data, *args, **kwargs)
1518 @functools.wraps(func)
1519 def inner(ax, *args, data=None, **kwargs):
1520 if data is None:
-> 1521 return func(
1522 ax,
1523 *map(cbook.sanitize_sequence, args),
1524 **{k: cbook.sanitize_sequence(v) for k, v in kwargs.items()})
1526 bound = new_sig.bind(ax, *args, **kwargs)
1527 auto_label = (bound.arguments.get(label_namer)
1528 or bound.kwargs.get(label_namer))
File ***/site-packages/matplotlib/axes/_axes.py:5931, in Axes.imshow(self, X, cmap, norm, aspect, interpolation, alpha, vmin, vmax, colorizer, origin, extent, interpolation_stage, filternorm, filterrad, resample, url, **kwargs)
5713 @_preprocess_data()
5714 @_docstring.interpd
5715 def imshow(self, X, cmap=None, norm=None, *, aspect=None,
(...) 5718 interpolation_stage=None, filternorm=True, filterrad=4.0,
5719 resample=None, url=None, **kwargs):
5720 """
5721 Display data as an image, i.e., on a 2D regular raster.
5722
(...) 5929 (unassociated) alpha representation.
5930 """
-> 5931 im = mimage.AxesImage(self, cmap=cmap, norm=norm, colorizer=colorizer,
5932 interpolation=interpolation, origin=origin,
5933 extent=extent, filternorm=filternorm,
5934 filterrad=filterrad, resample=resample,
5935 interpolation_stage=interpolation_stage,
5936 **kwargs)
5938 if aspect is None and not (
5939 im.is_transform_set()
5940 and not im.get_transform().contains_branch(self.transData)):
5941 aspect = mpl.rcParams['image.aspect']
File ***/site-packages/matplotlib/image.py:874, in AxesImage.__init__(self, ax, cmap, norm, colorizer, interpolation, origin, extent, filternorm, filterrad, resample, interpolation_stage, **kwargs)
857 def __init__(self, ax,
858 *,
859 cmap=None,
(...) 869 **kwargs
870 ):
872 self._extent = extent
--> 874 super().__init__(
875 ax,
876 cmap=cmap,
877 norm=norm,
878 colorizer=colorizer,
879 interpolation=interpolation,
880 origin=origin,
881 filternorm=filternorm,
882 filterrad=filterrad,
883 resample=resample,
884 interpolation_stage=interpolation_stage,
885 **kwargs
886 )
File ***/site-packages/matplotlib/image.py:277, in _ImageBase.__init__(self, ax, cmap, norm, colorizer, interpolation, origin, filternorm, filterrad, resample, interpolation_stage, **kwargs)
273 self.axes = ax
275 self._imcache = None
--> 277 self._internal_update(kwargs)
File ***/site-packages/matplotlib/artist.py:1233, in Artist._internal_update(self, kwargs)
1226 def _internal_update(self, kwargs):
1227 """
1228 Update artist properties without prenormalizing them, but generating
1229 errors as if calling `set`.
1230
1231 The lack of prenormalization is to maintain backcompatibility.
1232 """
-> 1233 return self._update_props(
1234 kwargs, "{cls.__name__}.set() got an unexpected keyword argument "
1235 "{prop_name!r}")
File ***/site-packages/matplotlib/artist.py:1206, in Artist._update_props(self, props, errfmt)
1204 func = getattr(self, f"set_{k}", None)
1205 if not callable(func):
-> 1206 raise AttributeError(
1207 errfmt.format(cls=type(self), prop_name=k),
1208 name=k)
1209 ret.append(func(v))
1210 if ret:
AttributeError: AxesImage.set() got an unexpected keyword argument 'msg'Anything else we need to know?
In dataarray_plot._plot2d.newplotfunc, this line of code allargs = locals().copy() added the local variable into allargs, which contains key msg and triggers the error from matplotlib.
Even though I am not using the newest version, I find this line of code still exists in the latest release.
Environment
Details
INSTALLED VERSIONS
commit: None
python: 3.12.8 | packaged by Anaconda, Inc. | (main, Dec 11 2024, 16:31:09) [GCC 11.2.0]
python-bits: 64
OS: Linux
OS-release: 6.6.87.2-microsoft-standard-WSL2
machine: x86_64
processor: x86_64
byteorder: little
LC_ALL: None
LANG: C.UTF-8
LOCALE: ('C', 'UTF-8')
libhdf5: 1.14.6
libnetcdf: 4.9.3
xarray: 2025.3.0
pandas: 2.2.3
numpy: 2.2.6
scipy: 1.15.3
netCDF4: 1.7.4
pydap: None
h5netcdf: None
h5py: None
zarr: None
cftime: 1.6.5
nc_time_axis: None
iris: None
bottleneck: None
dask: None
distributed: None
matplotlib: 3.10.0
cartopy: None
seaborn: 0.13.2
numbagg: None
fsspec: 2025.5.1
cupy: None
pint: None
sparse: None
flox: None
numpy_groupies: None
setuptools: 78.1.1
pip: 25.3
conda: None
pytest: None
mypy: None
IPython: 9.2.0
sphinx: None