fix: make the sphinx-gallery scraper capture every shown figure - #5701
fix: make the sphinx-gallery scraper capture every shown figure#5701larsoner wants to merge 11 commits into
Conversation
|
Tried it (replaced I can see that the Plotly version in my env. is your branch because the UV log has the following line: ...
DEBUG Requirement already installed: plotly==6.9.0 (from git+https://github.com/larsoner/plotly.py@5ef36f39d12315835d211c39ae5ff2357c06a70b)
...Conf changes for Plotly PNG rendering are as described here. Folder structure for the # Sphinx gallery conf.
sphinx_gallery_conf = {
"examples_dirs": "sources/plot-gallery/examples", # `docs`-relative path to Python scripts
"gallery_dirs": "sources/plot-gallery/auto_examples", # `docs`-relative path to gallery outputs
"image_scrapers": ("matplotlib", "plotly.io._sg_scraper.plotly_sg_scraper",),
}Wouldn't it be simpler for Sphinx gallery to support a post-build hook (a custom function maybe) that created the thumbnails by resizing and exporting the full sized figures into PNGs in the appropriate location? |
Probe Kaleido/browser availability once per build; when unavailable, emit a single sphinx warning (suppressible via suppress_warnings = ["plotly.sg_scraper"]), embed shown figures inline in the rst instead of via files (sphinx-gallery requires an image file for every image path consumed), and let examples fall back to placeholder thumbnails. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- The _repr_html_ fallback (hit when the default renderer is not a mimetype renderer, e.g. sphinx_gallery_png) now sizes like the html renderers (default_height=525) instead of height:100%, which collapses or overflows in containers with no set height. - The scraper now embeds shown figures inline in the rst, wrapped in the same output_subarea div sphinx-gallery wraps captured HTML reprs in, so themes can style both kinds of embed with one hook; it no longer writes .html files next to the images. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A figure whose inline script draws while the page is still being parsed can be sized to a container whose width changes by the time loading finishes (e.g. pydata-sphinx-theme's secondary sidebar comes after the article in the DOM), leaving it clipped until a window resize. Append a per-figure script to the _repr_html_ fallback and the sphinx-gallery scraper embeds that calls Plotly.Plots.resize once on window load. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Move the dark-theme styling out of sphinx-gallery: sphinx-gallery should not carry plotly-specific CSS, so ship a scoped style with each embed (repr fallback and scraper) instead. The white padded card only shows on dark pages (data-theme toggles or OS preference); on light pages it is invisible. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
I don't think we should rework / discuss the SG API contracts here -- it'll be a much bigger discussion if needed, and require an understanding of design decisions and code evolution over the years where we settled on the existing design. Instead I'd like to see if we can get things working properly for you using this branch. Can you I confirmed this works in sphinx-gallery/sphinx-gallery#1635 (see the updated example render) so hopefully it works for you now! |
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Keep only the minimal sizing fix in basedatatypes (_repr_html_ fallback sizes like the html renderers). The dark-page card and the after-load resize now come from a single idempotent fix-up block the scraper appends to any code block that displayed a figure: repr-captured embeds and the scraper's own embeds both sit in an output_subarea div, so one :has() rule styles both, and one guarded listener resizes every figure. No more per-figure uuid/script plumbing outside scraper code. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Thx, I'll try it out, and let you know. |
|
@larsoner The changes seem to work (Plotly pointing to rev. I've done several local and remote (RTD) builds to check consistency and reproducibility. There are a few points you may wish to note:
WARNING: plotly static image export is unavailable, so example thumbnails will fall back to a placeholder image. Static export requires Kaleido and a Chromium-based browser; see https://plotly.com/python/static-image-export/ for installation instructions. The failure was: ValueError:
Image export using the "kaleido" engine requires the Kaleido package,
which can be installed using pip:and the result is placeholder thumbnails, but the correct full sized figures are still drawn in the HTML pages. It's probably a good idea to note this somewhere in the Sphinx gallery docs. RTD builds had placeholder thumbnails because although ...
jobs:
pre_install:
- uv run plotly_get_chrome -yOnce this is done, RTD builds are fine. P. S. I had an earlier version of the gallery working, that used statically generated images, and with some scripting it would have come very close to what I have now. But Sphinx gallery is a good solution, so it's fine. |
|
BTW in the gallery conf. it is enough to have: {
...
"image_scrapers": ("plotly",),
}You don't need |
Yeah we need some way to get the thumbnail image from the rendered HTML page. Likely also the slowdown cause but I'll check.
Yes you're right! |
|
I've removed the point about opaque thumbnails on-hover - I'm guessing this could be fixed with the theme CSS [?], but anyway it's not an essential. |
The vnd.plotly mimetype renderers produce no text/html bundle, so _repr_html_ takes the fallback branch, which now sizes like the html renderers (525px default). Also point the no-static-export warning at the plotly_get_chrome command, which is the fix when kaleido is installed but no browser is available (e.g. on ReadTheDocs). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Each static image export launches and tears down Chrome via kaleido (~1.6 s per figure; rendering itself is ~50 ms). Start kaleido's global sync server once from the availability probe so every export in the build reuses one browser; kaleido stops it atexit. Carries the same kopts (plotlyjs/mathjax/headers defaults) the per-call path would pass, and scopes away the resulting 'kopts ignored' warning. Brings the sphinx-gallery demo build from ~7 s to ~1 s of plotly example time. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Okay I pushed a change to reuse a single |
|
That appears to be quicker (no duplicate Chrome instances) - about 16 seconds total. That's fine. |
Link to issue
Closes #4722
Closes #4959
Closes sphinx-gallery/sphinx-gallery#1238
Closes sphinx-gallery/sphinx-gallery#1632
Description of change
Fix sphinx-gallery thumbnail generation!
Demo
Testing strategy
Added some unit tests to make sure it works. It uses SG (added to
dev_optionalso CIs install it) to make sure the contract holds.Additional information (optional)
I am a SG maintainer. I used Claude Opus 5 to draft the changes here but I iterated with it a lot and have reviewed the final diff.
Guidelines