Skip to content

SubplotManager is not standalone: bidirectional coupling with Figure #757

Description

@cvanelteren

Design follow-up from #698 / #677. Not a bug — the refactor is behaviour-preserving and the full suite is green. This is about whether the seam is where the plan says it is.

The manager sequencing in #677 positions SubplotManager as the leaf node: "SubplotManager: (standalone, only needs gridspec)". As extracted, it isn't standalone.

The dependency is bidirectional

SubplotManager reaches back into Figure for:

  • fig._layout_dirty
  • fig._format_signature
  • fig.add_subplot(...)
  • fig.format(...)
  • a function-local from .figure import Figure (_subplots.py:256) needed to call super(Figure, fig).add_subplot(...) — a deferred import that exists purely to break an import cycle.

And Figure's collaborators now call back through the figure to reach the manager: gridspec.py and axes/base.py use fig._get_subplot / fig._iter_subplots.

There's also a round trip: SubplotManager.add_subplots calls fig.add_subplot(...) (the public, decorated method) rather than self.add_subplot(...), so every subplot goes manager → figure → manager just to pick up @_clear_border_cache.

Net: the code moved to a new file, but the coupling didn't shrink. That's fine as a first step — it just means the "standalone" edge in the #677 dependency graph isn't real yet, and the managers that are supposed to depend on this one will inherit the cycle.

Bonus: parse_proj doesn't belong here

SubplotManager.parse_proj never uses self except to call self.parse_backend(...), which is itself a @staticmethod. Projection parsing is a pure function of its arguments, and the class docstring already admits it's a third concern ("subplot creation, gridspec ownership, and projection parsing").

Making it a @staticmethod or a module-level function would be a strict simplification — and it also makes the fix for the ui.py signature coupling (filed separately) trivial.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    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