Skip to content

DOC: Add a JupyterLite-powered REPL to the Matplotlib documentation's landing page, and enable interactive galleries #29506

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 37 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
fae43c3
Add replite console to the users docs
martinRenou Mar 10, 2022
e5ecaac
Update gallery and add link to the JupyterLite deployment
martinRenou Jul 26, 2022
2374f55
Use latest jupyterlite-xeus-python
martinRenou Aug 5, 2022
7c75115
Use recursive glob for the content
martinRenou Aug 16, 2022
c92ca21
JupyterLite dependencies now available with conda-forge
agriyakhetarpal Jan 16, 2025
47b4b42
Move gallery sentence below the REPL iframe
agriyakhetarpal Jan 16, 2025
251ab4b
Disable Pyodide kernel, Xeus is already configured
agriyakhetarpal Jan 21, 2025
5194b89
Disable `rstcheck` for Replite directive
agriyakhetarpal Jan 21, 2025
7c7dce7
Ignore unintended Jupytext/Sphinx-Gallery warning
agriyakhetarpal Jan 21, 2025
9786561
Ignore JupyterLite contents and doit file
agriyakhetarpal Jan 21, 2025
ede0d71
Remove JupyterLite contents with `make clean`
agriyakhetarpal Jan 21, 2025
0faaf52
Add missing environment, fix JupyterLite builds
agriyakhetarpal Jan 21, 2025
5ebdd52
Fix the REPL's size and formatting
agriyakhetarpal Jan 21, 2025
a26fbf3
Disable Sphinx-Gallery's JupyterLite integration for now
agriyakhetarpal Jan 21, 2025
2ccd369
Drop `XeusPythonEnv` for env file, add WASM deps
agriyakhetarpal Jan 22, 2025
3601e38
Optimise JupyterLite for build size
agriyakhetarpal Jan 22, 2025
3e08f5f
Add note about Xeus environment file
agriyakhetarpal Jan 22, 2025
f74bec7
Fix: incorrect kernel name
agriyakhetarpal Jan 22, 2025
5422940
Use `kbd` directive for highlighting keys
agriyakhetarpal Jan 22, 2025
22ce559
Mark live example as "experimental"
agriyakhetarpal Jan 23, 2025
34611e1
Add gallery contents to JupyterLite deployment
agriyakhetarpal Jan 23, 2025
c170ede
Missing kernel, add xeus-python
agriyakhetarpal Jan 23, 2025
3078611
Add custom storage name
agriyakhetarpal Jan 23, 2025
5ec29f3
Properly ignore extra contents
agriyakhetarpal Jan 23, 2025
759f78c
Silence JupyterLite now that we're done
agriyakhetarpal Jan 23, 2025
4fed028
Debug: un-silence JupyterLite build
agriyakhetarpal Jan 23, 2025
d8d63da
Pin NumPy to <2
agriyakhetarpal Jan 23, 2025
cf3a737
Reminder for silencing JupyterLite
agriyakhetarpal Jan 23, 2025
3faa465
Move the REPL to Gallery intro page
agriyakhetarpal Jan 23, 2025
451ae62
Don't ignore JupyterLite env file from linting
agriyakhetarpal Jan 24, 2025
86a5f7c
Link to Jupytext-related jupyterlite-sphinx issue
agriyakhetarpal Jan 24, 2025
55fe769
Don't update MEP-12
agriyakhetarpal Jan 24, 2025
f0d4de4
Remove REPL from galleries page
agriyakhetarpal Jan 24, 2025
6ad6e46
Try installing `pip` packages into a venv
agriyakhetarpal Jan 24, 2025
94e4246
Activate venv before docs build
agriyakhetarpal Jan 24, 2025
260d3d7
Revert "Activate venv before docs build"
agriyakhetarpal Jan 27, 2025
a60b9d0
Revert "Try installing `pip` packages into a venv"
agriyakhetarpal Jan 27, 2025
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
13 changes: 13 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,16 @@ commands:
python -m pip install --upgrade --user wheel
python -m pip install --upgrade --user 'setuptools!=60.6.0'

mamba-install:
description: Install micromamba so it can be used for building the emscripten-forge environment
steps:
- run:
name: Install micromamba
command: |
curl -Ls https://micro.mamba.pm/api/micromamba/linux-64/latest | tar -xvj bin/micromamba
pwd
ls

doc-deps-install:
parameters:
numpy_version:
Expand Down Expand Up @@ -138,6 +148,8 @@ commands:
- run:
name: Build documentation
command: |
export PATH="$(pwd)/../bin:$PATH"
echo $PATH
# Set epoch to date of latest tag.
export SOURCE_DATE_EPOCH="$(git log -1 --format=%at $(git describe --abbrev=0))"
# Set release mode only when deploying to devdocs.
Expand Down Expand Up @@ -228,6 +240,7 @@ jobs:
- apt-install
- fonts-install
- pip-install
- mamba-install

- doc-deps-install
- mpl-install
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,7 @@ lib/matplotlib/backends/web_backend/node_modules/
lib/matplotlib/backends/web_backend/package-lock.json

LICENSE/LICENSE_QHULL

# JupyterLite
.jupyterlite.doit.db
/doc/jupyterlite_contents
2 changes: 2 additions & 0 deletions doc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ clean:
rm -rf "$(SOURCEDIR)/sphinxext/__pycache__"
rm -f $(SOURCEDIR)/_static/constrained_layout*.png
rm -f $(SOURCEDIR)/sg_execution_times.rst
rm -rf $(SOURCEDIR)/jupyterlite_contents
rm -rf $(SOURCEDIR)/.jupyterlite.doit.db

show:
@python -c "import webbrowser; webbrowser.open_new_tab('file://$(shell pwd)/build/html/index.html')"
Expand Down
33 changes: 32 additions & 1 deletion doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,16 @@ def _parse_skip_subdirs_file():
# usage in the gallery.
warnings.filterwarnings('error', append=True)

# Prevent Sphinx-Gallery and jupytext incompatibility warning. This is spurious
# and can be ignored for our use case. This has to be added before importing
# jupyterlite_sphinx below, so that we can block the warning before it is raised.
# TODO: Fix this in jupyterlite-sphinx
# https://github.com/jupyterlite/jupyterlite-sphinx/issues/258
warnings.filterwarnings('ignore', category=UserWarning,
message=(
r'(\n|.)*Sphinx Gallery in version 0.18.0 is not '
r'supported by Jupytext'))

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = [
Expand All @@ -128,7 +138,7 @@ def _parse_skip_subdirs_file():
'sphinxext.redirect_from',
'sphinx_copybutton',
'sphinx_design',
'sphinx_tags',
'jupyterlite_sphinx',
]

exclude_patterns = [
Expand Down Expand Up @@ -305,6 +315,10 @@ def autodoc_process_bases(app, name, obj, options, bases):
'within_subsection_order': gallery_order_subsectionorder,
'capture_repr': (),
'copyfile_regex': r'.*\.rst',
# Disable Sphinx-Gallery's JupyterLite integration until there's
# further notice. It comes from our usage of jupyterlite-sphinx
# as a registered extension.
'jupyterlite': None,
}

if parse_version(sphinx_gallery.__version__) >= parse_version('0.17.0'):
Expand Down Expand Up @@ -767,6 +781,23 @@ def js_tag_with_cache_busting(js):
1),
]

# JupyterLite config
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way this can be disabled by default and enabled by a flag? This could be set on CI and in release mode. I'm not sure we want to be paying the build costs locally for every developer. But since the build failed, I'm not sure exactly how large that build time cost is, so it could be negligible for all I know.

Copy link
Author

@agriyakhetarpal agriyakhetarpal Jan 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The build time cost is around ~15 seconds for me locally, which seems negligible in comparison to the rest of the docs build – I've been building with html-noplot at this time, so it would even lesser of a fraction with CI builds which would be longer.

But to answer whether this can be disabled, I can check for the DEVDOCS and is_release_build constants so that this is avoided on local builds, as this concern was also raised from the perspective of downstream packagers in the older PR #22634. It could make debugging a build that's failing in CI a bit of a pain, though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, let's see how long it ends up taking first.


jupyterlite_bind_ipynb_suffix = False
# Include the gallery examples in the JupyterLite deployment.
# .zip,.png,.gif, .json and other extra file formats generated by
# Sphinx-Gallery are ignored via the LiteBuildConfig/extra_ignore_contents
# key in the jupyter_lite_config.json file.
jupyterlite_contents = ["gallery/**"]
# Set this to False to aid debugging locally or in CI. It is silenced
# by default as there is no way to disable the JupyterLite output in
# parts right now, and it can be quite verbose.
jupyterlite_silence = False # set to False when merging
jupyterlite_build_command_options = {
"XeusAddon.environment_file": "jupyterlite_environment.yml",
}


# numpydoc config

numpydoc_show_class_members = False
Expand Down
23 changes: 23 additions & 0 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,29 @@ Learn
- figures: `.pyplot.figure`
- subplots: `.pyplot.subplots`, `.pyplot.subplot_mosaic`

Live example (experimental)
===========================

Try Matplotlib directly in this documentation (press :kbd:`shift` + :kbd:`Enter` to execute code)!

.. rstcheck: ignore-directives=replite
.. replite::
:kernel: xeus-python
:height: 600px
:prompt: Try Matplotlib!
:execute: False

%matplotlib inline

import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure()
plt.plot(np.sin(np.linspace(0, 20, 100)))
plt.show();

Alternatively, you can try the gallery examples in `our JupyterLite deployment <./lite/lab>`__.

Community
=========

Expand Down
10 changes: 10 additions & 0 deletions doc/jupyter-lite.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"jupyter-lite-schema-version": 0,
"jupyter-config-data": {
"disabledExtensions": [
"@jupyterlite/javascript-kernel-extension",
"@jupyterlite/pyodide-kernel-extension"
],
"contentsStorageName": "JupyterLite Matplotlib Docs Storage"
}
}
7 changes: 7 additions & 0 deletions doc/jupyter_lite_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is there a jupyter-lite.json and jupyter_lite_config.json? These seem redundantly (or at least non-descriptively) named.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've always been confused about this myself. One is for the CLI, one is for the JupyterLite frontend. The naming is pretty bad.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The JupyterLite CLI is a traitlets based app, so jupyter_lite_config.json follows the naming convention as other apps, like voila.json or jupyter_server_config.json. It is indeed for build time configuration (when running the JupyterLite CLI, for example with jupyter lite build).

jupyter-lite.json is for runtime configuration when loading the page. It is similar to the page_config.json used in JupyterLab.

Agree this can be confusing. Maybe JupyterLite could also support loading page_config.json files so users could choose a different name for the file?

For more information: https://jupyterlite.readthedocs.io/en/stable/howto/configure/config_files.html

"LiteBuildConfig": {
"extra_ignore_contents": ["\\.(rst|zip|pickle|py|json|svg|md5|png|gif)"],
"no_unused_shared_packages": true,
"no_sourcemaps": true
}
}
18 changes: 18 additions & 0 deletions doc/jupyterlite_environment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# This environment file is added via the XeusAddon.environment_file
# key in the jupyterlite_build_command_options dict in conf.py. See
# https://jupyterlite-sphinx.readthedocs.io/en/stable/configuration.html
# for more information on additional configuration options.
---

name: mpl-wasm-docs
channels:
- https://repo.mamba.pm/emscripten-forge
- conda-forge
dependencies:
# for examples in the gallery
# temporary: pin NumPy to <2 for now, see https://github.com/emscripten-forge/recipes/issues/1766
- numpy==1.26.4
- matplotlib
- ipympl
# a kernel for running them
- xeus-python
2 changes: 2 additions & 0 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ dependencies:
- joblib # needed for sphinx-gallery[parallel]
- sphinx-design
- sphinx-tags>=0.4.0
- jupyterlite-sphinx>=0.18.0
- jupyterlite-xeus>=3.0.2
- pystemmer
- pip
- pip:
Expand Down
2 changes: 2 additions & 0 deletions requirements/doc/doc-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,5 @@ sphinx-copybutton
sphinx-design
sphinx-gallery[parallel]>=0.12.0
sphinx-tags>=0.4.0
jupyterlite-sphinx>=0.18.0
jupyterlite-xeus>=3.0.2
Loading