Skip to content

Move matplotlib to an optional [plot] extra to slim the default install #2494

@brendancol

Description

@brendancol

Reason or Problem

A plain pip install xarray-spatial installs matplotlib and everything it
depends on: pillow, fonttools, kiwisolver, contourpy, cycler, pyparsing. None
of these are needed to run a spatial operation. matplotlib is listed in
install_requires in setup.cfg, but nothing in the package imports it at module
top level. Every use is a lazy import inside a plotting helper (.xrs.plot in
accessor.py, the plotting paths in zonal.py, and bump.py). So a user who
only wants the compute functions still pays for the whole plotting stack.

Proposal

Move matplotlib out of install_requires and into an optional plot extra. It
then installs only when asked for, via pip install xarray-spatial[plot].

Design:

  • Remove matplotlib from [options] install_requires in setup.cfg.
  • Add a plot = matplotlib entry under [options.extras_require].
  • Add a small _require_matplotlib() helper that raises a clear ImportError
    pointing at pip install xarray-spatial[plot] when matplotlib is missing.
  • Call that helper at the top of each plotting entry point. The
    _listed_colormap_from_attrs helper in accessor.py already returns None on
    ImportError and runs on the read path rather than a plot request, so it stays
    as it is.

Usage: pip install xarray-spatial for compute only;
pip install xarray-spatial[plot] when you want .xrs.plot() and the other
plotting helpers.

Value: Smaller default install and fewer transitive dependencies, which
helps compute-only and CI environments in particular.

Drawbacks

This changes behavior. Anyone who relied on matplotlib showing up implicitly
will need the [plot] extra or their own matplotlib install.

Alternatives

Keep matplotlib as a hard dependency. That forces the plotting stack on every
user, which is the thing this issue is trying to fix.

Note: pandas can't be dropped the same way. xarray requires pandas>=2.2, and a
few core modules import it at top level.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions