Skip to content

PyPlot backend: global rcParams mutation + accumulated deprecation bugs -- needs a scoped-style rework #646

Description

@petercorke

The core problem

roboticstoolbox/backends/PyPlot/PyPlot.py and PyPlot2.py apply their visual style by mutating global matplotlib state at import/instantiation time:

matplotlib.rcParams["pdf.fonttype"] = 42
matplotlib.rcParams["ps.fonttype"] = 42
plt.style.use("ggplot")
matplotlib.rcParams["font.size"] = 7
matplotlib.rcParams["lines.linewidth"] = 0.5
matplotlib.rcParams["xtick.major.size"] = 1.5
matplotlib.rcParams["ytick.major.size"] = 1.5
matplotlib.rcParams["axes.labelpad"] = 1

Confirmed via direct reproduction (2026-08): merely import roboticstoolbox no longer triggers this (the module is lazily imported now, only loaded via load_backend()), so #480's literal reported repro is fixed. But actually using the pyplot backend once (robot.plot(q, backend="pyplot")) still mutates 24 global rcParams for the rest of the Python process -- grid visibility, facecolor, font size, line width, color cycle, etc. -- which then silently changes the appearance of any other, unrelated matplotlib figure created afterward in the same session. This is exactly the symptom in #480's screenshots.

The proper fix is to scope the style to RTB's own figures only, e.g. wrapping the PyPlot session's rendering calls in matplotlib.rc_context({...}) / plt.style.context("ggplot") instead of mutating matplotlib.rcParams directly, and setting per-axes equivalents (ax.set_prop_cycle(), ax.tick_params(), etc.) where matplotlib supports them instead of the global rcParam.

Why this is worth a dedicated pass, not another one-off patch

Several independent, unrelated bugs have turned up in this same backend in quick succession, each patched individually:

Each fix so far has been small and targeted, which is fine reactively, but the pattern suggests the PyPlot backend hasn't had a real audit against current matplotlib in some time. Worth a deliberate pass: scoped style application (this issue), a currency check against the matplotlib version(s) actually in pyproject.toml's support range, and maybe a smoke test that renders through every public PyPlot/PyPlot2 code path against the pinned matplotlib version in CI.

Ref: #480 (original report), #405/#645, #418/#642.

Metadata

Metadata

Assignees

No one assigned

    Labels

    tech-debtKnown technical debt / deferred cleanup, not a live bug

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions