Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).

## Unreleased

### Fixed
- Fix the sphinx-gallery scraper so that it generates thumbnails for figures shown with `fig.show()` or displayed as the last expression of a code block, warns once (instead of failing the build) when static image export is unavailable, and no longer scrapes files belonging to other examples during parallel builds [[#4722](https://github.com/plotly/plotly.py/issues/4722), [#4959](https://github.com/plotly/plotly.py/issues/4959)], with thanks to @larsoner for the contribution!


## [7.0.0] - 2026-08-25

Expand Down
14 changes: 14 additions & 0 deletions plotly/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,20 @@ def hist_series(data_frame, **kwargs):
return histogram(data_frame, **new_kwargs)


def _get_sg_image_scraper():
"""Called by sphinx-gallery when ``"plotly"`` is listed in ``image_scrapers``.

See https://sphinx-gallery.github.io/stable/advanced.html#integrate-custom-scrapers-with-sphinx-gallery
"""
import plotly.io as pio
from plotly.io._sg_scraper import plotly_sg_scraper

# Not left to the import side effect: sphinx-gallery resolves the scraper
# repeatedly, so this also undoes any later renderer change.
pio.renderers.default = "sphinx_gallery_png"
return plotly_sg_scraper


def _jupyter_labextension_paths():
"""Called by Jupyter Lab Server to detect if it is a valid labextension and
to install the extension.
Expand Down
9 changes: 8 additions & 1 deletion plotly/basedatatypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -825,7 +825,14 @@ def _repr_html_(self):
if "text/html" in bundle:
return bundle["text/html"]
else:
return self.to_html(full_html=False, include_plotlyjs="cdn")
# Size like the html renderers do: "100%" height collapses or
# overflows in plain-HTML consumers such as sphinx-gallery.
return self.to_html(
full_html=False,
include_plotlyjs="cdn",
default_width="100%",
default_height=525,
)

def _repr_mimebundle_(self, include=None, exclude=None, validate=True, **kwargs):
"""
Expand Down
43 changes: 17 additions & 26 deletions plotly/io/_base_renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@
from os.path import isdir

from plotly import optional_imports
from plotly.io import to_json, to_image, write_image, write_html
from plotly.io import to_json, to_image, write_html
from plotly.io._utils import plotly_cdn_url
from plotly.offline.offline import _get_jconfig, get_plotlyjs
from plotly.tools import return_figure_from_figure_or_data

ipython_display = optional_imports.get_module("IPython.display")
IPython = optional_imports.get_module("IPython")
Expand Down Expand Up @@ -812,29 +811,21 @@ def to_mimebundle(self, fig_dict):
return {"text/html": html}


# Figures shown with the "sphinx_gallery_png" renderer are queued here until
# plotly.io._sg_scraper.plotly_sg_scraper collects them, so the renderer itself
# does not need to know where sphinx-gallery wants the files to be written.
sphinx_gallery_figures = []


class SphinxGalleryPngRenderer(ExternalRenderer):
# Note: This renderer was originally designed for use with the orca image generation utility
# before the introduction of kaleido. It has not been tested with kaleido, but I'm not aware
# of any reason why it shouldn't work.
"""Renderer used together with the sphinx-gallery image scraper.

Instead of displaying the figure, this renderer queues it in
``plotly.io._base_renderers.sphinx_gallery_figures``;
:func:`plotly.io._sg_scraper.plotly_sg_scraper` then writes each queued
figure to the gallery's image directory, both as an interactive HTML file
and as a static image used for the gallery thumbnail.
"""

def render(self, fig_dict):
stack = inspect.stack()
# Name of script from which plot function was called is retrieved
try:
filename = stack[3].filename # let's hope this is robust...
except Exception: # python 2
filename = stack[3][1]
filename_root, _ = os.path.splitext(filename)
filename_html = filename_root + ".html"
filename_png = filename_root + ".png"
figure = return_figure_from_figure_or_data(fig_dict, True)
_ = write_html(fig_dict, file=filename_html, include_plotlyjs="cdn")
try:
write_image(figure, filename_png)
except (ValueError, ImportError, RuntimeError) as e:
raise RuntimeError(
"kaleido and psutil are required to use the `sphinx_gallery_png` renderer. "
"See https://plotly.com/python/static-image-export/ for instructions on "
"how to install kaleido. Alternatively, you can use the `sphinx_gallery` "
"renderer (note that png thumbnails can only be generated with "
"the `sphinx_gallery_png` renderer)."
) from e
sphinx_gallery_figures.append(fig_dict)
Loading