petercorke / petercorke/robotics-toolbox-python
PyPlot backend: global rcParams mutation + accumulated deprecation bugs -- needs a scoped-style rework
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 3.5k
- Forks
- 624
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 53
Description
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:
- #405 / PR #645 --
robot.plot(..., movie=...)crashed outright (missing import + a matplotlib Agg canvas method removed sincetostring_rgb()). - #418 / PR #642 --
options=merge crashed on scalar-valued plot options (jointaxislength,eelength). - #405, #480, #481, #509 (title/body) -- a cluster of matplotlib API deprecations (
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 public PyPlot/PyPlot2 code path against the pinned matplotlib version in CI.
Ref: #480 (original report), #405/#645, #418/#642.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with roboticstoolbox/backends/PyPlot/PyPlot.py and PyPlot2.py, then inspect how load_backend() creates and renders PyPlot sessions. Compare the current global rcParams and plt.style.use calls with the scoped-style and per-axes approaches described in the issue, and check the supported matplotlib range in pyproject.toml. Done means RTB figures retain their intended style without changing unrelated matplotlib figures, with the relevant public PyPlot/PyPlot2 paths checked against the supported version.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- data-visualization
- Issue type
- Refactor
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100