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.
The core problem
roboticstoolbox/backends/PyPlot/PyPlot.pyandPyPlot2.pyapply their visual style by mutating global matplotlib state at import/instantiation time:Confirmed via direct reproduction (2026-08): merely
import roboticstoolboxno longer triggers this (the module is lazily imported now, only loaded viaload_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 mutatingmatplotlib.rcParamsdirectly, 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:
robot.plot(..., movie=...)crashed outright (missing import + a matplotlib Agg canvas method removed sincetostring_rgb()).options=merge crashed on scalar-valued plot options (jointaxislength,eelength).w_xaxis->xaxis,Slider()kwargs, colorbarax=) that all trace back to PyPlot never being updated alongside matplotlib's own API changes.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 publicPyPlot/PyPlot2code path against the pinned matplotlib version in CI.Ref: #480 (original report), #405/#645, #418/#642.