diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index c6ecc2f2..9f3eafb7 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -24,3 +24,18 @@ jobs: run: uv build - name: Check package run: uvx twine check --strict dist/*.whl + + docs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + with: + submodules: true + fetch-depth: 0 + - name: Pull latest notebooks + # Match RTD: render whatever is on notebooks-repo main, not the pinned SHA. + run: git submodule update --init --remote --recursive + - name: Install uv + uses: astral-sh/setup-uv@v7 + - name: Build docs + run: uvx --with="virtualenv<21" hatch run docs:build diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..a7d91b87 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "docs/notebooks"] + path = docs/notebooks + url = https://github.com/scverse/spatialdata-plot-notebooks.git + branch = main diff --git a/.readthedocs.yaml b/.readthedocs.yaml index cfd291d3..c5deab19 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -6,6 +6,12 @@ build: python: "3.13" nodejs: latest jobs: + post_checkout: + # Always render the latest notebooks-repo main, not the SHA pinned in + # this repo's index. Trade-off: docs at older lib tags are not bit-for-bit + # reproducible for the gallery — a re-build shows whatever the notebooks + # repo's main looked like at build time. + - git submodule update --init --remote --recursive create_environment: - asdf plugin add uv - asdf install uv latest @@ -15,3 +21,7 @@ build: # TODO: remove "--with=virtualenv<21" once hatch is compatible with virtualenv 21+ (pypa/hatch#2193) - uvx "--with=virtualenv<21" hatch run docs:build - mv docs/_build $READTHEDOCS_OUTPUT + +submodules: + include: all + recursive: false diff --git a/README.md b/README.md index caa93e82..416fb521 100644 --- a/README.md +++ b/README.md @@ -30,8 +30,9 @@ In concordance with the general SpatialData philosophy, all modalities of the ma For more information on the `spatialdata-plot` library, please refer to the [documentation](https://spatialdata.scverse.org/projects/plot/en/latest/index.html). In particular, the +- [Gallery][link-gallery] — executable example notebooks demonstrating the plotting capabilities. - [API documentation][link-api]. -- [Example notebooks][link-notebooks] (section "Visiualizations") +- [SpatialData example notebooks][link-notebooks] (section "Visualizations") for plotting in the context of broader analyses. ## Installation @@ -65,6 +66,7 @@ Marconato, L., Palla, G., Yamauchi, K.A. et al. SpatialData: an open and univers [issue-tracker]: https://github.com/scverse/spatialdata-plot/issues [link-docs]: https://spatialdata-plot.readthedocs.io [link-api]: https://spatialdata.scverse.org/projects/plot/en/stable/api.html +[link-gallery]: https://spatialdata.scverse.org/projects/plot/en/stable/gallery.html [link-design-doc]: https://spatialdata.scverse.org/en/stable/design_doc.html [link-notebooks]: https://spatialdata.scverse.org/en/stable/tutorials/notebooks/notebooks.html [//]: # "numfocus-fiscal-sponsor-attribution" diff --git a/docs/_static/gallery/getting_started.png b/docs/_static/gallery/getting_started.png new file mode 100644 index 00000000..68600f15 Binary files /dev/null and b/docs/_static/gallery/getting_started.png differ diff --git a/docs/conf.py b/docs/conf.py index 3e7591a8..fd5c69ce 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -56,6 +56,7 @@ "sphinx.ext.intersphinx", "sphinx.ext.autosummary", "sphinx.ext.napoleon", + "sphinx_design", "sphinxcontrib.bibtex", "sphinxcontrib.katex", "sphinx_autodoc_typehints", @@ -114,10 +115,13 @@ "Thumbs.db", ".DS_Store", "**.ipynb_checkpoints", - "tutorials/notebooks/index.md", - "tutorials/notebooks/README.md", - "tutorials/notebooks/references.md", - "tutorials/notebooks/notebooks/paper_reproducibility/*", + # Submodule meta-files: these document the notebooks repo itself, not + # spatialdata-plot, and should not be rendered into our docs. + "notebooks/README.md", + "notebooks/CONTRIBUTING.md", + "notebooks/LICENSE", + "notebooks/.github/**", + "notebooks/pyproject.toml", ] diff --git a/docs/contributing.md b/docs/contributing.md index d8b8f1e5..76e42673 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -251,7 +251,7 @@ This project uses [sphinx][] with the following features: - The [myst][] extension allows to write documentation in markdown/Markedly Structured Text - [Numpy-style docstrings][numpydoc] (through the [napoleon][numpydoc-napoleon] extension). -- Jupyter notebooks as tutorials through [myst-nb][] (See [Tutorials with myst-nb](#tutorials-with-myst-nb-and-jupyter-notebooks)) +- Jupyter notebooks as tutorials through [myst-nb][] (See [Gallery notebooks (submodule)](#gallery-notebooks-submodule)) - [sphinx-autodoc-typehints][], to automatically reference annotated input and output types - Citations (like {cite:p}`Virshup_2023`) can be included with [sphinxcontrib-bibtex](https://sphinxcontrib-bibtex.readthedocs.io/) @@ -264,16 +264,48 @@ See scanpy's {doc}`scanpy:dev/documentation` for more information on how to writ [numpydoc]: https://numpydoc.readthedocs.io/en/latest/format.html [sphinx-autodoc-typehints]: https://github.com/tox-dev/sphinx-autodoc-typehints -### Tutorials with myst-nb and jupyter notebooks +### Gallery notebooks (submodule) -The documentation is set-up to render jupyter notebooks stored in the `docs/notebooks` directory using [myst-nb][]. -Currently, only notebooks in `.ipynb` format are supported that will be included with both their input and output cells. -It is your responsibility to update and re-run the notebook whenever necessary. +The gallery rendered into the docs lives in a separate repository, +[`scverse/spatialdata-plot-notebooks`][notebooks-repo], mounted here as a git +submodule at `docs/notebooks/`. This follows the scverse convention used by +`anndata`, `spatialdata`, `scvi-tools`, and `squidpy`. -If you are interested in automatically running notebooks as part of the continuous integration, -please check out [this feature request][issue-render-notebooks] in the `cookiecutter-scverse` repository. +Notebooks are pre-executed by humans and committed with their outputs; the +docs build performs no execution and pulls no data. A scheduled CI job in the +notebooks repo re-executes every notebook against the latest +`spatialdata-plot` release and fails on output drift. -[issue-render-notebooks]: https://github.com/scverse/cookiecutter-scverse/issues/40 +#### Working with the gallery locally + +```bash +# First-time clone — pull this repo with submodules +git clone --recurse-submodules https://github.com/scverse/spatialdata-plot.git + +# Already cloned without submodules — initialise after the fact +git submodule update --init --recursive + +# Pull the latest gallery content from the notebooks repo's main branch +git submodule update --remote docs/notebooks +``` + +ReadTheDocs is configured (`submodules: include: all` in `.readthedocs.yaml`) +to fetch the submodule on every build, so PR previews always render the +current pinned gallery content. + +#### Adding or editing a notebook + +Notebook changes are made in the [notebooks repo][notebooks-repo], not here. +See its `CONTRIBUTING.md` for the workflow. After your notebook PR merges +there, open a small follow-up PR in this repo bumping the submodule pin: + +```bash +git submodule update --remote docs/notebooks +git add docs/notebooks +git commit -m "Bump notebooks submodule" +``` + +[notebooks-repo]: https://github.com/scverse/spatialdata-plot-notebooks #### Hints @@ -286,6 +318,17 @@ please check out [this feature request][issue-render-notebooks] in the `cookiecu ### Building the docs locally +:::{important} +The docs include a git submodule (`docs/notebooks` → `spatialdata-plot-notebooks`). +If you cloned this repo without `--recurse-submodules`, initialise it once before building: + +```bash +git submodule update --init --recursive +``` + +Without the submodule, the gallery pages will be missing and sphinx will warn about broken toctree entries. +::: + :::::{tabs} ::::{group-tab} Hatch diff --git a/docs/gallery.md b/docs/gallery.md new file mode 100644 index 00000000..e921d7d9 --- /dev/null +++ b/docs/gallery.md @@ -0,0 +1,43 @@ +# Gallery + +Curated, runnable examples demonstrating `spatialdata-plot` on real +spatial-omics datasets and on the lightweight `blobs` dataset. + +Sources live in +[`scverse/spatialdata-plot-notebooks`](https://github.com/scverse/spatialdata-plot-notebooks); +every notebook is executable end-to-end and re-executed on a weekly schedule +against the latest `spatialdata-plot` release. + +## Tutorials + +End-to-end workflows on real datasets. + +::::{grid} 1 2 2 2 +:gutter: 3 + +:::{grid-item-card} Getting started +:link: notebooks/tutorials/getting_started +:link-type: doc +:img-top: _static/gallery/getting_started.png + +The fluent `.pl` API, layering, and styling — on the in-memory `blobs` +dataset. Ideal first read. +::: + +:::: + +## Examples + +```{note} +No focused examples yet — contributions welcome! See +[CONTRIBUTING](https://github.com/scverse/spatialdata-plot-notebooks/blob/main/CONTRIBUTING.md) +in the notebooks repo for how to add one. +``` + +```{toctree} +:hidden: +:maxdepth: 2 + +notebooks/tutorials/index +notebooks/examples/index +``` diff --git a/docs/index.md b/docs/index.md index 53ff8f2a..4aafabc5 100644 --- a/docs/index.md +++ b/docs/index.md @@ -4,8 +4,9 @@ ```{toctree} :hidden: true -:maxdepth: 1 +:maxdepth: 2 +gallery.md api.md changelog.md contributing.md diff --git a/docs/notebooks b/docs/notebooks new file mode 160000 index 00000000..e0ac82ac --- /dev/null +++ b/docs/notebooks @@ -0,0 +1 @@ +Subproject commit e0ac82ace2e4a754a71682e6ee57ab24ec3ec353 diff --git a/pyproject.toml b/pyproject.toml index bf21ab7b..7ebf7057 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,6 +55,7 @@ doc = [ "sphinx-autodoc-typehints", "sphinx-book-theme>=1", "sphinx-copybutton", + "sphinx-design", "sphinx-tabs", "sphinxcontrib-bibtex>=1", "sphinxcontrib-katex",