Skip to content

Unexpected keyword error in dataarray_plot.py #11104

@pengjiaqiang86

Description

@pengjiaqiang86

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions