From d17aa208bbd22fd8bb038df09fe7ddf091764458 Mon Sep 17 00:00:00 2001 From: Max Date: Sat, 7 Nov 2026 15:27:26 +0000 Subject: [PATCH] Docs: web figures in the Plotly tutorial. --- docs/src/content/docs/guides/web-figures.md | 9 ++- tutorials/tutorial_08_plotly.ipynb | 77 +++++++++++++++++++++ 2 files changed, 83 insertions(+), 3 deletions(-) diff --git a/docs/src/content/docs/guides/web-figures.md b/docs/src/content/docs/guides/web-figures.md index 7db2373..5b8a5ec 100644 --- a/docs/src/content/docs/guides/web-figures.md +++ b/docs/src/content/docs/guides/web-figures.md @@ -43,11 +43,14 @@ import PlotlyFigure from '@max-models/starlight-theme/components/PlotlyFigure.as The path is relative to the site root; the component adds the site's base path. :::note -The theme's `PlotlyFigure` already loads plotly.js on demand and recolours text, grid and -backgrounds. The data palette and the hints below take effect with the next release of -starlight-theme. +The data palette and the hints below need starlight-theme 0.8 or later; sites on the `v0` tag +of its docs workflow get it without a change. ::: +A figure shown in a notebook of the docs (`fig` as the last line of a cell) is embedded the same +way, without saving it: the docs build writes the notebook's Plotly outputs as figures for +`PlotlyFigure`. The [Plotly tutorial](/maxplotlib/tutorials/tutorial-08-plotly/) shows both. + ## The format The file is Plotly figure JSON: `data`, `layout` and, for an animation, `frames`. Compared with diff --git a/tutorials/tutorial_08_plotly.ipynb b/tutorials/tutorial_08_plotly.ipynb index 0bc6123..ec27496 100644 --- a/tutorials/tutorial_08_plotly.ipynb +++ b/tutorials/tutorial_08_plotly.ipynb @@ -399,6 +399,7 @@ "metadata": {}, "outputs": [], "source": [ + "import json\n", "import os\n", "\n", "canvas.savefig(\"figure_bundled.html\", backend=\"plotly\")\n", @@ -432,6 +433,82 @@ "cell_type": "markdown", "id": "24", "metadata": {}, + "source": [ + "## 9 · Web figures for a docs site\n", + "\n", + "A page of a max-models docs site (the Starlight theme) shows Plotly figures without\n", + "plotly.js in the figure file. Save the canvas as a **web figure**, `.plotly.json`:\n", + "Plotly JSON without a template, a fixed size or backgrounds of its own, so the page draws it\n", + "in the site's light or dark colours." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "25", + "metadata": {}, + "outputs": [], + "source": [ + "x = np.linspace(0, 2 * np.pi, 200)\n", + "\n", + "canvas = Canvas(width=\"10cm\", ratio=0.5)\n", + "canvas.plot(x, np.sin(x), label=\"sin(x)\")\n", + "canvas.plot(x, np.cos(x), label=\"cos(x)\")\n", + "canvas.plot(x, 0 * x, color=\"black\", linewidth=0.8) # a reference line\n", + "canvas.set_xlabel(\"x\")\n", + "canvas.set_title(\"Two waves\")\n", + "canvas.set_legend(True)\n", + "\n", + "canvas.savefig(\"waves.plotly.json\", backend=\"plotly\")\n", + "print(f\"waves.plotly.json: {os.path.getsize('waves.plotly.json') / 1024:.0f} kB\")\n", + "\n", + "web = json.loads(canvas.to_json(alt=\"A sine and a cosine wave over one period\"))\n", + "print(web[\"layout\"][\"meta\"][\"web\"])\n", + "print([trace.get(\"line\", {}).get(\"color\") for trace in web[\"data\"]])" + ] + }, + { + "cell_type": "markdown", + "id": "26", + "metadata": {}, + "source": [ + "The two waves have no colour of their own, so they take the site's data palette, in order; a\n", + "trace in a default colour (Matplotlib's `C0`..`C9`, Plotly's default colours, Okabe–Ito) would\n", + "take the palette colour of its position. The black reference line takes the text colour, so it\n", + "stays visible in dark mode. Other colours you name, such as `\"steelblue\"` above, stay as they\n", + "are. The\n", + "hints in `layout.meta.web` give the page the aspect ratio of the canvas and a text\n", + "alternative.\n", + "\n", + "To embed the file, put it under `docs/public/` and use the theme's `PlotlyFigure` in an MDX\n", + "page; plotly.js is loaded only when the figure scrolls into view:\n", + "\n", + "```mdx\n", + "import PlotlyFigure from '@max-models/starlight-theme/components/PlotlyFigure.astro';\n", + "\n", + "\n", + "```\n", + "\n", + "A figure shown in a notebook (`fig` as the last line of a cell) needs nothing of this: the docs\n", + "site turns the notebook's Plotly outputs into the same kind of figure, which is how the figures\n", + "on this page are shown. The [web figures guide](/maxplotlib/guides/web-figures/) has the format.\n", + "And the figure of the last cell, shown here, takes the palette too:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "27", + "metadata": {}, + "outputs": [], + "source": [ + "fig = canvas.show(backend=\"plotly\")" + ] + }, + { + "cell_type": "markdown", + "id": "28", + "metadata": {}, "source": [ "## Summary\n", "\n",