Skip to content

Migrate visualization layer from Plotly to matplotlib#83

Draft
OmerShubi wants to merge 1 commit into
mainfrom
matplotlib-migration
Draft

Migrate visualization layer from Plotly to matplotlib#83
OmerShubi wants to merge 1 commit into
mainfrom
matplotlib-migration

Conversation

@OmerShubi

Copy link
Copy Markdown
Contributor

Re-opened from #64 after renaming the branch (claude/kind-gagarin-2c5f63matplotlib-migration); same commit, unchanged.

Summary

Replaces the entire visualization layer (scanpath, heatmaps, comparison, animation, and the research charts) with matplotlib. The biggest practical win: static export (PNG/SVG/PDF) and the GIF/MP4 animation rasterizer are now fully in-process — no Kaleido, no headless Chrome, no chromium system package. The hard-won true-to-scale word labels are preserved and validated at the documented ~0.28 font-to-box ratio.

Net: 33 files, +2893/−3104 — the migration removed more code than it added (Plotly's frame-masking/slider/updatemenus machinery and the Kaleido warm-server logic are gone).

What changed

  • New scanpath_studio/mpl_render.py — the rendering foundation: a fixed render DPI, screen-px↔point unit conversions, Plotly-compatible colour / colorscale / dash parsing (so constants.py and saved plot configs are untouched), and exact-pixel figure scaffolding.
  • plots.py — every builder returns a matplotlib Figure; make_scanpath_animation returns a new ScanpathAnimation dataclass. The true-to-scale text math is unchanged; saccades are a single LineCollection (preserves the old one-trace perf bound).
  • tabs.py render layer — spatial plots embed as a fixed-size inline SVG, uniformly CSS-scaled to the column (the true-to-scale trick, minus the Plotly.js CDN); the animation embeds the to_jshtml interactive player (play/pause/scrub); research charts use st.pyplot.
  • animation_export.py — keeps the GIF/MP4 encode half verbatim; only the Kaleido frame rasterizer is swapped for matplotlib savefig.
  • export.py / api.save_figuresavefig dispatch for PNG/SVG/PDF; HTML is now a self-contained SVG page; animations export as the to_jshtml player.
  • Depsmatplotlib in, plotly + kaleido out; packages.txt (chromium) deleted. Docs / CHANGELOG / AGENTS / CLAUDE.md updated.
  • Tests — the figure-coupled suites now assert matplotlib artists (new tests/mpl_helpers.py documents the artist-label contract).

Notable behaviour

  • No browser anywhere. Export and animation rasterizing run in-process (MP4 uses the already-bundled imageio[ffmpeg]); animation export is much faster (no ~10s Chrome cold start).
  • The on-screen animation player inlines every frame as base64 PNG, so it's heavier than the old vector Plotly animation; the player is capped at 250 frames (total runtime preserved). GIF/MP4 export keeps its own separate cap.
  • Two rendering bugs surfaced by the new tests were fixed (animation trail color-array masking; hollow markers). Saccade-direction arrows render as proper arrowheads (data-unit quiver width) instead of blobs.

Verification

  • Full test suite green (427 passed); ruff format + ruff check clean.
  • Verified live in the browser: static scanpath, per-word heatmap, the interactive animation player, and saccade arrows all render with zero console errors.

🤖 Generated with Claude Code

Replace the entire figure layer (scanpath, heatmaps, comparison, animation,
research charts) with matplotlib. Static export (PNG/SVG/PDF) and the GIF/MP4
animation rasterizer are now fully in-process — no Kaleido, no headless Chrome,
no chromium system package. The true-to-scale word labels are preserved
(validated at the documented ~0.28 font-to-box ratio).

- New mpl_render.py: render DPI, px<->pt unit conversions, Plotly-compatible
  colour/colorscale/dash parsing, exact-pixel figure scaffolding.
- plots.py builders return matplotlib Figures; make_scanpath_animation returns a
  ScanpathAnimation (FuncAnimation + an on-screen to_jshtml interactive player).
- tabs.py renders spatial plots as a fixed-size inline SVG uniformly CSS-scaled
  to the column (true-to-scale); research charts via st.pyplot.
- export.py / api.save_figure: savefig dispatch; HTML is a self-contained SVG
  page; animations export as the to_jshtml player.
- Drop plotly + kaleido deps, add matplotlib; remove packages.txt (chromium).
- Rewrite the figure-coupled tests to assert matplotlib artists
  (new tests/mpl_helpers.py); full suite green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant