Add interactive region annotation tutorial - #5

Merged
timtreis merged 8 commits into
mainfrom
tutorial/interactive-annotate
May 27, 2026
Merged

Add interactive region annotation tutorial#5
timtreis merged 8 commits into
mainfrom
tutorial/interactive-annotate

Conversation

@timtreis

@timtreistimtreis commented May 21, 2026

Copy link
Copy Markdown
Member

Adds examples/interactive_annotate.ipynb for sdata.pl.annotate(), backed by anybioimage's BioImageViewer.

  • Loads squidpy.datasets.visium_hne_sdata() and renders the H&E.
  • Widget call is a markdown block, not a code cell — the docs build has no live JS runtime.
  • interactive_annotate.gif shows the live UX in the rendered docs.
  • A simulated ShapesModel.parse(...) cell stands in for a real draw + Save so downstream cells (overlay, polygon_query) execute reproducibly in CI.
  • examples/index.md: gallery card + toctree entry.

Adds examples/interactive_annotate.ipynb covering the new
`sdata.pl.annotate()` API from scverse/spatialdata-plot#684. Uses the
same `squidpy.datasets.visium_hne_sdata()` dataset as
visium_mouse_brain.ipynb so the download cache is shared.
Structure follows the existing examples/ pattern:
- Intro + dataset citation + install hint for the [interactive] extra
- Load → render the image so the reader sees what to annotate
- Widget invocation shown in a markdown fenced block (the static docs
build can't execute the anywidget JS runtime; live-kernel users copy
the snippet)
- GIF placeholder cell — replace interactive_annotate.gif with a real
recording before merging
- "What the widget produces": a code cell that builds the equivalent
ShapesModel directly via shapely + ShapesModel.parse, so downstream
cells reproduce in the docs build without the widget
- Overlay with render_shapes; polygon-crop via sd.polygon_query
- Watermark block matching the other tutorials
Wires the new entry into examples/index.md alongside the Visium card.
Outstanding before merge:
- Replace the hippocampus polygon coordinates with values from an
actual annotation pass against visium_hne_sdata
- Record interactive_annotate.gif (~3-5 s of drawing/saving)
- Add interactive_annotate.png thumbnail for the gallery grid card
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@review-notebook-app

Copy link
Copy Markdown

Check out this pull request on ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

timtreisand others added 3 commits May 27, 2026 03:10
Pixi 0.54.2 refuses to load `[tool.pixi]` with dotted-key children
(`workspace.channels = [...]`, `dependencies.python = ">=3.11"`, …)
and requires one of `[tool.pixi.workspace]` / `.project` / `.package`
as a real TOML table header. Rewrite the inline-dotted block into
explicit `[tool.pixi.workspace]`, `[tool.pixi.dependencies]`,
`[tool.pixi.pypi-dependencies]`, and `[tool.pixi.tasks]` sections so
`pixi install` and `pixi run kernel-install` actually work.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Move existing thumbnails from beside their notebooks to a shared
`_static/img/` directory (Sphinx convention) so all gallery media
lives in one place:
examples/visium_mouse_brain.png -> _static/img/visium_mouse_brain.png
tutorials/getting_started.png -> _static/img/getting_started.png
tutorials/color_and_palette.png -> _static/img/color_and_palette.png
Update the `:img-top:` references in `examples/index.md` and
`tutorials/index.md` to point at `../_static/img/<slug>.png`.
Add step 6 to `CONTRIBUTING.md` documenting the convention: gallery
thumbnails and notebook-embedded GIFs / screenshots go under
`_static/img/`, never next to the notebook itself. Renumber the
following CI step accordingly.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The widget pivoted from the custom anywidget+JS canvas to the
external `anybioimage` library's `BioImageViewer` (see
scverse/spatialdata-plot#684). Update the tutorial to match:
- Intro: replace the anywidget/SVG architecture blurb with a
description of the `BioImageViewer` backend.
- Launch section: rewrite the API signature from the old positional
`annotate(coordinate_system, element, persist=True)` to the new
keyword-only chain-step form `.pl.render_images(...).pl.annotate(
coordinate_systems=...)`. Drop the lasso tool (no longer present)
and the JS-canvas-specific shortcut list. Replace the "Write to
disk" button with a `sdata.write_element(<name>)` follow-up note.
- Polygon query cell: pass the actual shapely geometry rather than
the whole `GeoDataFrame`. spatialdata's `polygon_query` overload
for `DataArray`/`DataTree` calls `GeoDataFrame(geometry=[polygon])`
internally, which fails with `GeometryTypeError: Unknown geometry
type: 'featurecollection'` if passed a nested gdf.
- Watermark: drop `anywidget` (transitive dep that isn't imported by
any executable cell) to keep the watermark report honest.
- Add a `warnings.filterwarnings("ignore")` housekeeping cell ahead
of the squidpy dataset load so the notebook's recorded outputs
don't leak Zarr v3 deprecation chatter into the docs build.
- Add the recorded GIF (`_static/img/interactive_annotate.gif`) and
a placeholder PNG thumbnail (regenerate before merging).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions

github-actionsBot commented May 27, 2026

Copy link
Copy Markdown

📖 Docs preview: https://scverse.org/spatialdata-plot-notebooks/pr-5/gallery.html

Built from ef91a72; redeployed on every push.

github-actionsBot pushed a commit that referenced this pull request May 27, 2026
@timtreistimtreis changed the title Add interactive region annotation tutorial (skeleton)Add interactive region annotation tutorialMay 27, 2026
@timtreis
timtreis marked this pull request as ready for review May 27, 2026 14:15
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
0.4.0 ships `sdata.pl.annotate()` (scverse/spatialdata-plot#684), so the
tutorial can require the published wheel instead of an editable path.
Re-executed the notebook to refresh the watermark output to 0.4.0.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
@timtreis
timtreis merged commit d891121 into mainMay 27, 2026
4 checks passed
@timtreis
timtreis deleted the tutorial/interactive-annotate branch May 27, 2026 15:36
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@timtreis
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Add interactive region annotation tutorial - #5

Merged
timtreis merged 8 commits into
mainfrom
tutorial/interactive-annotate
May 27, 2026
Merged

Add interactive region annotation tutorial#5
timtreis merged 8 commits into
mainfrom
tutorial/interactive-annotate

Conversation

@timtreis

@timtreistimtreis commented May 21, 2026

Copy link
Copy Markdown
Member

Adds examples/interactive_annotate.ipynb for sdata.pl.annotate(), backed by anybioimage's BioImageViewer.

  • Loads squidpy.datasets.visium_hne_sdata() and renders the H&E.
  • Widget call is a markdown block, not a code cell — the docs build has no live JS runtime.
  • interactive_annotate.gif shows the live UX in the rendered docs.
  • A simulated ShapesModel.parse(...) cell stands in for a real draw + Save so downstream cells (overlay, polygon_query) execute reproducibly in CI.
  • examples/index.md: gallery card + toctree entry.

Adds examples/interactive_annotate.ipynb covering the new
`sdata.pl.annotate()` API from scverse/spatialdata-plot#684. Uses the
same `squidpy.datasets.visium_hne_sdata()` dataset as
visium_mouse_brain.ipynb so the download cache is shared.
Structure follows the existing examples/ pattern:
- Intro + dataset citation + install hint for the [interactive] extra
- Load → render the image so the reader sees what to annotate
- Widget invocation shown in a markdown fenced block (the static docs
build can't execute the anywidget JS runtime; live-kernel users copy
the snippet)
- GIF placeholder cell — replace interactive_annotate.gif with a real
recording before merging
- "What the widget produces": a code cell that builds the equivalent
ShapesModel directly via shapely + ShapesModel.parse, so downstream
cells reproduce in the docs build without the widget
- Overlay with render_shapes; polygon-crop via sd.polygon_query
- Watermark block matching the other tutorials
Wires the new entry into examples/index.md alongside the Visium card.
Outstanding before merge:
- Replace the hippocampus polygon coordinates with values from an
actual annotation pass against visium_hne_sdata
- Record interactive_annotate.gif (~3-5 s of drawing/saving)
- Add interactive_annotate.png thumbnail for the gallery grid card
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@review-notebook-app

Copy link
Copy Markdown

Check out this pull request on ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

timtreisand others added 3 commits May 27, 2026 03:10
Pixi 0.54.2 refuses to load `[tool.pixi]` with dotted-key children
(`workspace.channels = [...]`, `dependencies.python = ">=3.11"`, …)
and requires one of `[tool.pixi.workspace]` / `.project` / `.package`
as a real TOML table header. Rewrite the inline-dotted block into
explicit `[tool.pixi.workspace]`, `[tool.pixi.dependencies]`,
`[tool.pixi.pypi-dependencies]`, and `[tool.pixi.tasks]` sections so
`pixi install` and `pixi run kernel-install` actually work.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Move existing thumbnails from beside their notebooks to a shared
`_static/img/` directory (Sphinx convention) so all gallery media
lives in one place:
examples/visium_mouse_brain.png -> _static/img/visium_mouse_brain.png
tutorials/getting_started.png -> _static/img/getting_started.png
tutorials/color_and_palette.png -> _static/img/color_and_palette.png
Update the `:img-top:` references in `examples/index.md` and
`tutorials/index.md` to point at `../_static/img/<slug>.png`.
Add step 6 to `CONTRIBUTING.md` documenting the convention: gallery
thumbnails and notebook-embedded GIFs / screenshots go under
`_static/img/`, never next to the notebook itself. Renumber the
following CI step accordingly.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The widget pivoted from the custom anywidget+JS canvas to the
external `anybioimage` library's `BioImageViewer` (see
scverse/spatialdata-plot#684). Update the tutorial to match:
- Intro: replace the anywidget/SVG architecture blurb with a
description of the `BioImageViewer` backend.
- Launch section: rewrite the API signature from the old positional
`annotate(coordinate_system, element, persist=True)` to the new
keyword-only chain-step form `.pl.render_images(...).pl.annotate(
coordinate_systems=...)`. Drop the lasso tool (no longer present)
and the JS-canvas-specific shortcut list. Replace the "Write to
disk" button with a `sdata.write_element(<name>)` follow-up note.
- Polygon query cell: pass the actual shapely geometry rather than
the whole `GeoDataFrame`. spatialdata's `polygon_query` overload
for `DataArray`/`DataTree` calls `GeoDataFrame(geometry=[polygon])`
internally, which fails with `GeometryTypeError: Unknown geometry
type: 'featurecollection'` if passed a nested gdf.
- Watermark: drop `anywidget` (transitive dep that isn't imported by
any executable cell) to keep the watermark report honest.
- Add a `warnings.filterwarnings("ignore")` housekeeping cell ahead
of the squidpy dataset load so the notebook's recorded outputs
don't leak Zarr v3 deprecation chatter into the docs build.
- Add the recorded GIF (`_static/img/interactive_annotate.gif`) and
a placeholder PNG thumbnail (regenerate before merging).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions

github-actionsBot commented May 27, 2026

Copy link
Copy Markdown

📖 Docs preview: https://scverse.org/spatialdata-plot-notebooks/pr-5/gallery.html

Built from ef91a72; redeployed on every push.

github-actionsBot pushed a commit that referenced this pull request May 27, 2026
@timtreistimtreis changed the title Add interactive region annotation tutorial (skeleton)Add interactive region annotation tutorialMay 27, 2026
@timtreis
timtreis marked this pull request as ready for review May 27, 2026 14:15
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
0.4.0 ships `sdata.pl.annotate()` (scverse/spatialdata-plot#684), so the
tutorial can require the published wheel instead of an editable path.
Re-executed the notebook to refresh the watermark output to 0.4.0.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
@timtreis
timtreis merged commit d891121 into mainMay 27, 2026
4 checks passed
@timtreis
timtreis deleted the tutorial/interactive-annotate branch May 27, 2026 15:36
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@timtreis
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add interactive region annotation tutorial - #5

Merged
timtreis merged 8 commits into
mainfrom
tutorial/interactive-annotate
May 27, 2026
Merged

Add interactive region annotation tutorial#5
timtreis merged 8 commits into
mainfrom
tutorial/interactive-annotate

Conversation

@timtreis

@timtreistimtreis commented May 21, 2026

Copy link
Copy Markdown
Member

Adds examples/interactive_annotate.ipynb for sdata.pl.annotate(), backed by anybioimage's BioImageViewer.

  • Loads squidpy.datasets.visium_hne_sdata() and renders the H&E.
  • Widget call is a markdown block, not a code cell — the docs build has no live JS runtime.
  • interactive_annotate.gif shows the live UX in the rendered docs.
  • A simulated ShapesModel.parse(...) cell stands in for a real draw + Save so downstream cells (overlay, polygon_query) execute reproducibly in CI.
  • examples/index.md: gallery card + toctree entry.

Adds examples/interactive_annotate.ipynb covering the new
`sdata.pl.annotate()` API from scverse/spatialdata-plot#684. Uses the
same `squidpy.datasets.visium_hne_sdata()` dataset as
visium_mouse_brain.ipynb so the download cache is shared.
Structure follows the existing examples/ pattern:
- Intro + dataset citation + install hint for the [interactive] extra
- Load → render the image so the reader sees what to annotate
- Widget invocation shown in a markdown fenced block (the static docs
build can't execute the anywidget JS runtime; live-kernel users copy
the snippet)
- GIF placeholder cell — replace interactive_annotate.gif with a real
recording before merging
- "What the widget produces": a code cell that builds the equivalent
ShapesModel directly via shapely + ShapesModel.parse, so downstream
cells reproduce in the docs build without the widget
- Overlay with render_shapes; polygon-crop via sd.polygon_query
- Watermark block matching the other tutorials
Wires the new entry into examples/index.md alongside the Visium card.
Outstanding before merge:
- Replace the hippocampus polygon coordinates with values from an
actual annotation pass against visium_hne_sdata
- Record interactive_annotate.gif (~3-5 s of drawing/saving)
- Add interactive_annotate.png thumbnail for the gallery grid card
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@review-notebook-app

Copy link
Copy Markdown

Check out this pull request on ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

timtreisand others added 3 commits May 27, 2026 03:10
Pixi 0.54.2 refuses to load `[tool.pixi]` with dotted-key children
(`workspace.channels = [...]`, `dependencies.python = ">=3.11"`, …)
and requires one of `[tool.pixi.workspace]` / `.project` / `.package`
as a real TOML table header. Rewrite the inline-dotted block into
explicit `[tool.pixi.workspace]`, `[tool.pixi.dependencies]`,
`[tool.pixi.pypi-dependencies]`, and `[tool.pixi.tasks]` sections so
`pixi install` and `pixi run kernel-install` actually work.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Move existing thumbnails from beside their notebooks to a shared
`_static/img/` directory (Sphinx convention) so all gallery media
lives in one place:
examples/visium_mouse_brain.png -> _static/img/visium_mouse_brain.png
tutorials/getting_started.png -> _static/img/getting_started.png
tutorials/color_and_palette.png -> _static/img/color_and_palette.png
Update the `:img-top:` references in `examples/index.md` and
`tutorials/index.md` to point at `../_static/img/<slug>.png`.
Add step 6 to `CONTRIBUTING.md` documenting the convention: gallery
thumbnails and notebook-embedded GIFs / screenshots go under
`_static/img/`, never next to the notebook itself. Renumber the
following CI step accordingly.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The widget pivoted from the custom anywidget+JS canvas to the
external `anybioimage` library's `BioImageViewer` (see
scverse/spatialdata-plot#684). Update the tutorial to match:
- Intro: replace the anywidget/SVG architecture blurb with a
description of the `BioImageViewer` backend.
- Launch section: rewrite the API signature from the old positional
`annotate(coordinate_system, element, persist=True)` to the new
keyword-only chain-step form `.pl.render_images(...).pl.annotate(
coordinate_systems=...)`. Drop the lasso tool (no longer present)
and the JS-canvas-specific shortcut list. Replace the "Write to
disk" button with a `sdata.write_element(<name>)` follow-up note.
- Polygon query cell: pass the actual shapely geometry rather than
the whole `GeoDataFrame`. spatialdata's `polygon_query` overload
for `DataArray`/`DataTree` calls `GeoDataFrame(geometry=[polygon])`
internally, which fails with `GeometryTypeError: Unknown geometry
type: 'featurecollection'` if passed a nested gdf.
- Watermark: drop `anywidget` (transitive dep that isn't imported by
any executable cell) to keep the watermark report honest.
- Add a `warnings.filterwarnings("ignore")` housekeeping cell ahead
of the squidpy dataset load so the notebook's recorded outputs
don't leak Zarr v3 deprecation chatter into the docs build.
- Add the recorded GIF (`_static/img/interactive_annotate.gif`) and
a placeholder PNG thumbnail (regenerate before merging).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions

github-actionsBot commented May 27, 2026

Copy link
Copy Markdown

📖 Docs preview: https://scverse.org/spatialdata-plot-notebooks/pr-5/gallery.html

Built from ef91a72; redeployed on every push.

github-actionsBot pushed a commit that referenced this pull request May 27, 2026
@timtreistimtreis changed the title Add interactive region annotation tutorial (skeleton)Add interactive region annotation tutorialMay 27, 2026
@timtreis
timtreis marked this pull request as ready for review May 27, 2026 14:15
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
0.4.0 ships `sdata.pl.annotate()` (scverse/spatialdata-plot#684), so the
tutorial can require the published wheel instead of an editable path.
Re-executed the notebook to refresh the watermark output to 0.4.0.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
@timtreis
timtreis merged commit d891121 into mainMay 27, 2026
4 checks passed
@timtreis
timtreis deleted the tutorial/interactive-annotate branch May 27, 2026 15:36
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@timtreis
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add interactive region annotation tutorial - #5

Merged
timtreis merged 8 commits into
mainfrom
tutorial/interactive-annotate
May 27, 2026
Merged

Add interactive region annotation tutorial#5
timtreis merged 8 commits into
mainfrom
tutorial/interactive-annotate

Conversation

@timtreis

@timtreistimtreis commented May 21, 2026

Copy link
Copy Markdown
Member

Adds examples/interactive_annotate.ipynb for sdata.pl.annotate(), backed by anybioimage's BioImageViewer.

  • Loads squidpy.datasets.visium_hne_sdata() and renders the H&E.
  • Widget call is a markdown block, not a code cell — the docs build has no live JS runtime.
  • interactive_annotate.gif shows the live UX in the rendered docs.
  • A simulated ShapesModel.parse(...) cell stands in for a real draw + Save so downstream cells (overlay, polygon_query) execute reproducibly in CI.
  • examples/index.md: gallery card + toctree entry.

Adds examples/interactive_annotate.ipynb covering the new
`sdata.pl.annotate()` API from scverse/spatialdata-plot#684. Uses the
same `squidpy.datasets.visium_hne_sdata()` dataset as
visium_mouse_brain.ipynb so the download cache is shared.
Structure follows the existing examples/ pattern:
- Intro + dataset citation + install hint for the [interactive] extra
- Load → render the image so the reader sees what to annotate
- Widget invocation shown in a markdown fenced block (the static docs
build can't execute the anywidget JS runtime; live-kernel users copy
the snippet)
- GIF placeholder cell — replace interactive_annotate.gif with a real
recording before merging
- "What the widget produces": a code cell that builds the equivalent
ShapesModel directly via shapely + ShapesModel.parse, so downstream
cells reproduce in the docs build without the widget
- Overlay with render_shapes; polygon-crop via sd.polygon_query
- Watermark block matching the other tutorials
Wires the new entry into examples/index.md alongside the Visium card.
Outstanding before merge:
- Replace the hippocampus polygon coordinates with values from an
actual annotation pass against visium_hne_sdata
- Record interactive_annotate.gif (~3-5 s of drawing/saving)
- Add interactive_annotate.png thumbnail for the gallery grid card
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@review-notebook-app

Copy link
Copy Markdown

Check out this pull request on ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

timtreisand others added 3 commits May 27, 2026 03:10
Pixi 0.54.2 refuses to load `[tool.pixi]` with dotted-key children
(`workspace.channels = [...]`, `dependencies.python = ">=3.11"`, …)
and requires one of `[tool.pixi.workspace]` / `.project` / `.package`
as a real TOML table header. Rewrite the inline-dotted block into
explicit `[tool.pixi.workspace]`, `[tool.pixi.dependencies]`,
`[tool.pixi.pypi-dependencies]`, and `[tool.pixi.tasks]` sections so
`pixi install` and `pixi run kernel-install` actually work.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Move existing thumbnails from beside their notebooks to a shared
`_static/img/` directory (Sphinx convention) so all gallery media
lives in one place:
examples/visium_mouse_brain.png -> _static/img/visium_mouse_brain.png
tutorials/getting_started.png -> _static/img/getting_started.png
tutorials/color_and_palette.png -> _static/img/color_and_palette.png
Update the `:img-top:` references in `examples/index.md` and
`tutorials/index.md` to point at `../_static/img/<slug>.png`.
Add step 6 to `CONTRIBUTING.md` documenting the convention: gallery
thumbnails and notebook-embedded GIFs / screenshots go under
`_static/img/`, never next to the notebook itself. Renumber the
following CI step accordingly.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The widget pivoted from the custom anywidget+JS canvas to the
external `anybioimage` library's `BioImageViewer` (see
scverse/spatialdata-plot#684). Update the tutorial to match:
- Intro: replace the anywidget/SVG architecture blurb with a
description of the `BioImageViewer` backend.
- Launch section: rewrite the API signature from the old positional
`annotate(coordinate_system, element, persist=True)` to the new
keyword-only chain-step form `.pl.render_images(...).pl.annotate(
coordinate_systems=...)`. Drop the lasso tool (no longer present)
and the JS-canvas-specific shortcut list. Replace the "Write to
disk" button with a `sdata.write_element(<name>)` follow-up note.
- Polygon query cell: pass the actual shapely geometry rather than
the whole `GeoDataFrame`. spatialdata's `polygon_query` overload
for `DataArray`/`DataTree` calls `GeoDataFrame(geometry=[polygon])`
internally, which fails with `GeometryTypeError: Unknown geometry
type: 'featurecollection'` if passed a nested gdf.
- Watermark: drop `anywidget` (transitive dep that isn't imported by
any executable cell) to keep the watermark report honest.
- Add a `warnings.filterwarnings("ignore")` housekeeping cell ahead
of the squidpy dataset load so the notebook's recorded outputs
don't leak Zarr v3 deprecation chatter into the docs build.
- Add the recorded GIF (`_static/img/interactive_annotate.gif`) and
a placeholder PNG thumbnail (regenerate before merging).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions

github-actionsBot commented May 27, 2026

Copy link
Copy Markdown

📖 Docs preview: https://scverse.org/spatialdata-plot-notebooks/pr-5/gallery.html

Built from ef91a72; redeployed on every push.

github-actionsBot pushed a commit that referenced this pull request May 27, 2026
@timtreistimtreis changed the title Add interactive region annotation tutorial (skeleton)Add interactive region annotation tutorialMay 27, 2026
@timtreis
timtreis marked this pull request as ready for review May 27, 2026 14:15
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
0.4.0 ships `sdata.pl.annotate()` (scverse/spatialdata-plot#684), so the
tutorial can require the published wheel instead of an editable path.
Re-executed the notebook to refresh the watermark output to 0.4.0.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
@timtreis
timtreis merged commit d891121 into mainMay 27, 2026
4 checks passed
@timtreis
timtreis deleted the tutorial/interactive-annotate branch May 27, 2026 15:36
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@timtreis
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Add interactive region annotation tutorial - #5

Merged
timtreis merged 8 commits into
mainfrom
tutorial/interactive-annotate
May 27, 2026
Merged

Add interactive region annotation tutorial#5
timtreis merged 8 commits into
mainfrom
tutorial/interactive-annotate

Conversation

@timtreis

@timtreistimtreis commented May 21, 2026

Copy link
Copy Markdown
Member

Adds examples/interactive_annotate.ipynb for sdata.pl.annotate(), backed by anybioimage's BioImageViewer.

  • Loads squidpy.datasets.visium_hne_sdata() and renders the H&E.
  • Widget call is a markdown block, not a code cell — the docs build has no live JS runtime.
  • interactive_annotate.gif shows the live UX in the rendered docs.
  • A simulated ShapesModel.parse(...) cell stands in for a real draw + Save so downstream cells (overlay, polygon_query) execute reproducibly in CI.
  • examples/index.md: gallery card + toctree entry.

Adds examples/interactive_annotate.ipynb covering the new
`sdata.pl.annotate()` API from scverse/spatialdata-plot#684. Uses the
same `squidpy.datasets.visium_hne_sdata()` dataset as
visium_mouse_brain.ipynb so the download cache is shared.
Structure follows the existing examples/ pattern:
- Intro + dataset citation + install hint for the [interactive] extra
- Load → render the image so the reader sees what to annotate
- Widget invocation shown in a markdown fenced block (the static docs
build can't execute the anywidget JS runtime; live-kernel users copy
the snippet)
- GIF placeholder cell — replace interactive_annotate.gif with a real
recording before merging
- "What the widget produces": a code cell that builds the equivalent
ShapesModel directly via shapely + ShapesModel.parse, so downstream
cells reproduce in the docs build without the widget
- Overlay with render_shapes; polygon-crop via sd.polygon_query
- Watermark block matching the other tutorials
Wires the new entry into examples/index.md alongside the Visium card.
Outstanding before merge:
- Replace the hippocampus polygon coordinates with values from an
actual annotation pass against visium_hne_sdata
- Record interactive_annotate.gif (~3-5 s of drawing/saving)
- Add interactive_annotate.png thumbnail for the gallery grid card
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@review-notebook-app

Copy link
Copy Markdown

Check out this pull request on ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

timtreisand others added 3 commits May 27, 2026 03:10
Pixi 0.54.2 refuses to load `[tool.pixi]` with dotted-key children
(`workspace.channels = [...]`, `dependencies.python = ">=3.11"`, …)
and requires one of `[tool.pixi.workspace]` / `.project` / `.package`
as a real TOML table header. Rewrite the inline-dotted block into
explicit `[tool.pixi.workspace]`, `[tool.pixi.dependencies]`,
`[tool.pixi.pypi-dependencies]`, and `[tool.pixi.tasks]` sections so
`pixi install` and `pixi run kernel-install` actually work.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Move existing thumbnails from beside their notebooks to a shared
`_static/img/` directory (Sphinx convention) so all gallery media
lives in one place:
examples/visium_mouse_brain.png -> _static/img/visium_mouse_brain.png
tutorials/getting_started.png -> _static/img/getting_started.png
tutorials/color_and_palette.png -> _static/img/color_and_palette.png
Update the `:img-top:` references in `examples/index.md` and
`tutorials/index.md` to point at `../_static/img/<slug>.png`.
Add step 6 to `CONTRIBUTING.md` documenting the convention: gallery
thumbnails and notebook-embedded GIFs / screenshots go under
`_static/img/`, never next to the notebook itself. Renumber the
following CI step accordingly.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The widget pivoted from the custom anywidget+JS canvas to the
external `anybioimage` library's `BioImageViewer` (see
scverse/spatialdata-plot#684). Update the tutorial to match:
- Intro: replace the anywidget/SVG architecture blurb with a
description of the `BioImageViewer` backend.
- Launch section: rewrite the API signature from the old positional
`annotate(coordinate_system, element, persist=True)` to the new
keyword-only chain-step form `.pl.render_images(...).pl.annotate(
coordinate_systems=...)`. Drop the lasso tool (no longer present)
and the JS-canvas-specific shortcut list. Replace the "Write to
disk" button with a `sdata.write_element(<name>)` follow-up note.
- Polygon query cell: pass the actual shapely geometry rather than
the whole `GeoDataFrame`. spatialdata's `polygon_query` overload
for `DataArray`/`DataTree` calls `GeoDataFrame(geometry=[polygon])`
internally, which fails with `GeometryTypeError: Unknown geometry
type: 'featurecollection'` if passed a nested gdf.
- Watermark: drop `anywidget` (transitive dep that isn't imported by
any executable cell) to keep the watermark report honest.
- Add a `warnings.filterwarnings("ignore")` housekeeping cell ahead
of the squidpy dataset load so the notebook's recorded outputs
don't leak Zarr v3 deprecation chatter into the docs build.
- Add the recorded GIF (`_static/img/interactive_annotate.gif`) and
a placeholder PNG thumbnail (regenerate before merging).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions

github-actionsBot commented May 27, 2026

Copy link
Copy Markdown

📖 Docs preview: https://scverse.org/spatialdata-plot-notebooks/pr-5/gallery.html

Built from ef91a72; redeployed on every push.

github-actionsBot pushed a commit that referenced this pull request May 27, 2026
@timtreistimtreis changed the title Add interactive region annotation tutorial (skeleton)Add interactive region annotation tutorialMay 27, 2026
@timtreis
timtreis marked this pull request as ready for review May 27, 2026 14:15
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
0.4.0 ships `sdata.pl.annotate()` (scverse/spatialdata-plot#684), so the
tutorial can require the published wheel instead of an editable path.
Re-executed the notebook to refresh the watermark output to 0.4.0.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
@timtreis
timtreis merged commit d891121 into mainMay 27, 2026
4 checks passed
@timtreis
timtreis deleted the tutorial/interactive-annotate branch May 27, 2026 15:36
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@timtreis
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add interactive region annotation tutorial - #5

Merged
timtreis merged 8 commits into
mainfrom
tutorial/interactive-annotate
May 27, 2026
Merged

Add interactive region annotation tutorial#5
timtreis merged 8 commits into
mainfrom
tutorial/interactive-annotate

Conversation

@timtreis

@timtreistimtreis commented May 21, 2026

Copy link
Copy Markdown
Member

Adds examples/interactive_annotate.ipynb for sdata.pl.annotate(), backed by anybioimage's BioImageViewer.

  • Loads squidpy.datasets.visium_hne_sdata() and renders the H&E.
  • Widget call is a markdown block, not a code cell — the docs build has no live JS runtime.
  • interactive_annotate.gif shows the live UX in the rendered docs.
  • A simulated ShapesModel.parse(...) cell stands in for a real draw + Save so downstream cells (overlay, polygon_query) execute reproducibly in CI.
  • examples/index.md: gallery card + toctree entry.

Adds examples/interactive_annotate.ipynb covering the new
`sdata.pl.annotate()` API from scverse/spatialdata-plot#684. Uses the
same `squidpy.datasets.visium_hne_sdata()` dataset as
visium_mouse_brain.ipynb so the download cache is shared.
Structure follows the existing examples/ pattern:
- Intro + dataset citation + install hint for the [interactive] extra
- Load → render the image so the reader sees what to annotate
- Widget invocation shown in a markdown fenced block (the static docs
build can't execute the anywidget JS runtime; live-kernel users copy
the snippet)
- GIF placeholder cell — replace interactive_annotate.gif with a real
recording before merging
- "What the widget produces": a code cell that builds the equivalent
ShapesModel directly via shapely + ShapesModel.parse, so downstream
cells reproduce in the docs build without the widget
- Overlay with render_shapes; polygon-crop via sd.polygon_query
- Watermark block matching the other tutorials
Wires the new entry into examples/index.md alongside the Visium card.
Outstanding before merge:
- Replace the hippocampus polygon coordinates with values from an
actual annotation pass against visium_hne_sdata
- Record interactive_annotate.gif (~3-5 s of drawing/saving)
- Add interactive_annotate.png thumbnail for the gallery grid card
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@review-notebook-app

Copy link
Copy Markdown

Check out this pull request on ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

timtreisand others added 3 commits May 27, 2026 03:10
Pixi 0.54.2 refuses to load `[tool.pixi]` with dotted-key children
(`workspace.channels = [...]`, `dependencies.python = ">=3.11"`, …)
and requires one of `[tool.pixi.workspace]` / `.project` / `.package`
as a real TOML table header. Rewrite the inline-dotted block into
explicit `[tool.pixi.workspace]`, `[tool.pixi.dependencies]`,
`[tool.pixi.pypi-dependencies]`, and `[tool.pixi.tasks]` sections so
`pixi install` and `pixi run kernel-install` actually work.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Move existing thumbnails from beside their notebooks to a shared
`_static/img/` directory (Sphinx convention) so all gallery media
lives in one place:
examples/visium_mouse_brain.png -> _static/img/visium_mouse_brain.png
tutorials/getting_started.png -> _static/img/getting_started.png
tutorials/color_and_palette.png -> _static/img/color_and_palette.png
Update the `:img-top:` references in `examples/index.md` and
`tutorials/index.md` to point at `../_static/img/<slug>.png`.
Add step 6 to `CONTRIBUTING.md` documenting the convention: gallery
thumbnails and notebook-embedded GIFs / screenshots go under
`_static/img/`, never next to the notebook itself. Renumber the
following CI step accordingly.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The widget pivoted from the custom anywidget+JS canvas to the
external `anybioimage` library's `BioImageViewer` (see
scverse/spatialdata-plot#684). Update the tutorial to match:
- Intro: replace the anywidget/SVG architecture blurb with a
description of the `BioImageViewer` backend.
- Launch section: rewrite the API signature from the old positional
`annotate(coordinate_system, element, persist=True)` to the new
keyword-only chain-step form `.pl.render_images(...).pl.annotate(
coordinate_systems=...)`. Drop the lasso tool (no longer present)
and the JS-canvas-specific shortcut list. Replace the "Write to
disk" button with a `sdata.write_element(<name>)` follow-up note.
- Polygon query cell: pass the actual shapely geometry rather than
the whole `GeoDataFrame`. spatialdata's `polygon_query` overload
for `DataArray`/`DataTree` calls `GeoDataFrame(geometry=[polygon])`
internally, which fails with `GeometryTypeError: Unknown geometry
type: 'featurecollection'` if passed a nested gdf.
- Watermark: drop `anywidget` (transitive dep that isn't imported by
any executable cell) to keep the watermark report honest.
- Add a `warnings.filterwarnings("ignore")` housekeeping cell ahead
of the squidpy dataset load so the notebook's recorded outputs
don't leak Zarr v3 deprecation chatter into the docs build.
- Add the recorded GIF (`_static/img/interactive_annotate.gif`) and
a placeholder PNG thumbnail (regenerate before merging).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions

github-actionsBot commented May 27, 2026

Copy link
Copy Markdown

📖 Docs preview: https://scverse.org/spatialdata-plot-notebooks/pr-5/gallery.html

Built from ef91a72; redeployed on every push.

github-actionsBot pushed a commit that referenced this pull request May 27, 2026
@timtreistimtreis changed the title Add interactive region annotation tutorial (skeleton)Add interactive region annotation tutorialMay 27, 2026
@timtreis
timtreis marked this pull request as ready for review May 27, 2026 14:15
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
0.4.0 ships `sdata.pl.annotate()` (scverse/spatialdata-plot#684), so the
tutorial can require the published wheel instead of an editable path.
Re-executed the notebook to refresh the watermark output to 0.4.0.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
@timtreis
timtreis merged commit d891121 into mainMay 27, 2026
4 checks passed
@timtreis
timtreis deleted the tutorial/interactive-annotate branch May 27, 2026 15:36
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@timtreis
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add interactive region annotation tutorial - #5

Merged
timtreis merged 8 commits into
mainfrom
tutorial/interactive-annotate
May 27, 2026
Merged

Add interactive region annotation tutorial#5
timtreis merged 8 commits into
mainfrom
tutorial/interactive-annotate

Conversation

@timtreis

@timtreistimtreis commented May 21, 2026

Copy link
Copy Markdown
Member

Adds examples/interactive_annotate.ipynb for sdata.pl.annotate(), backed by anybioimage's BioImageViewer.

  • Loads squidpy.datasets.visium_hne_sdata() and renders the H&E.
  • Widget call is a markdown block, not a code cell — the docs build has no live JS runtime.
  • interactive_annotate.gif shows the live UX in the rendered docs.
  • A simulated ShapesModel.parse(...) cell stands in for a real draw + Save so downstream cells (overlay, polygon_query) execute reproducibly in CI.
  • examples/index.md: gallery card + toctree entry.

Adds examples/interactive_annotate.ipynb covering the new
`sdata.pl.annotate()` API from scverse/spatialdata-plot#684. Uses the
same `squidpy.datasets.visium_hne_sdata()` dataset as
visium_mouse_brain.ipynb so the download cache is shared.
Structure follows the existing examples/ pattern:
- Intro + dataset citation + install hint for the [interactive] extra
- Load → render the image so the reader sees what to annotate
- Widget invocation shown in a markdown fenced block (the static docs
build can't execute the anywidget JS runtime; live-kernel users copy
the snippet)
- GIF placeholder cell — replace interactive_annotate.gif with a real
recording before merging
- "What the widget produces": a code cell that builds the equivalent
ShapesModel directly via shapely + ShapesModel.parse, so downstream
cells reproduce in the docs build without the widget
- Overlay with render_shapes; polygon-crop via sd.polygon_query
- Watermark block matching the other tutorials
Wires the new entry into examples/index.md alongside the Visium card.
Outstanding before merge:
- Replace the hippocampus polygon coordinates with values from an
actual annotation pass against visium_hne_sdata
- Record interactive_annotate.gif (~3-5 s of drawing/saving)
- Add interactive_annotate.png thumbnail for the gallery grid card
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@review-notebook-app

Copy link
Copy Markdown

Check out this pull request on ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

timtreisand others added 3 commits May 27, 2026 03:10
Pixi 0.54.2 refuses to load `[tool.pixi]` with dotted-key children
(`workspace.channels = [...]`, `dependencies.python = ">=3.11"`, …)
and requires one of `[tool.pixi.workspace]` / `.project` / `.package`
as a real TOML table header. Rewrite the inline-dotted block into
explicit `[tool.pixi.workspace]`, `[tool.pixi.dependencies]`,
`[tool.pixi.pypi-dependencies]`, and `[tool.pixi.tasks]` sections so
`pixi install` and `pixi run kernel-install` actually work.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Move existing thumbnails from beside their notebooks to a shared
`_static/img/` directory (Sphinx convention) so all gallery media
lives in one place:
examples/visium_mouse_brain.png -> _static/img/visium_mouse_brain.png
tutorials/getting_started.png -> _static/img/getting_started.png
tutorials/color_and_palette.png -> _static/img/color_and_palette.png
Update the `:img-top:` references in `examples/index.md` and
`tutorials/index.md` to point at `../_static/img/<slug>.png`.
Add step 6 to `CONTRIBUTING.md` documenting the convention: gallery
thumbnails and notebook-embedded GIFs / screenshots go under
`_static/img/`, never next to the notebook itself. Renumber the
following CI step accordingly.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The widget pivoted from the custom anywidget+JS canvas to the
external `anybioimage` library's `BioImageViewer` (see
scverse/spatialdata-plot#684). Update the tutorial to match:
- Intro: replace the anywidget/SVG architecture blurb with a
description of the `BioImageViewer` backend.
- Launch section: rewrite the API signature from the old positional
`annotate(coordinate_system, element, persist=True)` to the new
keyword-only chain-step form `.pl.render_images(...).pl.annotate(
coordinate_systems=...)`. Drop the lasso tool (no longer present)
and the JS-canvas-specific shortcut list. Replace the "Write to
disk" button with a `sdata.write_element(<name>)` follow-up note.
- Polygon query cell: pass the actual shapely geometry rather than
the whole `GeoDataFrame`. spatialdata's `polygon_query` overload
for `DataArray`/`DataTree` calls `GeoDataFrame(geometry=[polygon])`
internally, which fails with `GeometryTypeError: Unknown geometry
type: 'featurecollection'` if passed a nested gdf.
- Watermark: drop `anywidget` (transitive dep that isn't imported by
any executable cell) to keep the watermark report honest.
- Add a `warnings.filterwarnings("ignore")` housekeeping cell ahead
of the squidpy dataset load so the notebook's recorded outputs
don't leak Zarr v3 deprecation chatter into the docs build.
- Add the recorded GIF (`_static/img/interactive_annotate.gif`) and
a placeholder PNG thumbnail (regenerate before merging).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions

github-actionsBot commented May 27, 2026

Copy link
Copy Markdown

📖 Docs preview: https://scverse.org/spatialdata-plot-notebooks/pr-5/gallery.html

Built from ef91a72; redeployed on every push.

github-actionsBot pushed a commit that referenced this pull request May 27, 2026
@timtreistimtreis changed the title Add interactive region annotation tutorial (skeleton)Add interactive region annotation tutorialMay 27, 2026
@timtreis
timtreis marked this pull request as ready for review May 27, 2026 14:15
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
0.4.0 ships `sdata.pl.annotate()` (scverse/spatialdata-plot#684), so the
tutorial can require the published wheel instead of an editable path.
Re-executed the notebook to refresh the watermark output to 0.4.0.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
@timtreis
timtreis merged commit d891121 into mainMay 27, 2026
4 checks passed
@timtreis
timtreis deleted the tutorial/interactive-annotate branch May 27, 2026 15:36
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@timtreis
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Add interactive region annotation tutorial - #5

Merged
timtreis merged 8 commits into
mainfrom
tutorial/interactive-annotate
May 27, 2026
Merged

Add interactive region annotation tutorial#5
timtreis merged 8 commits into
mainfrom
tutorial/interactive-annotate

Conversation

@timtreis

@timtreistimtreis commented May 21, 2026

Copy link
Copy Markdown
Member

Adds examples/interactive_annotate.ipynb for sdata.pl.annotate(), backed by anybioimage's BioImageViewer.

  • Loads squidpy.datasets.visium_hne_sdata() and renders the H&E.
  • Widget call is a markdown block, not a code cell — the docs build has no live JS runtime.
  • interactive_annotate.gif shows the live UX in the rendered docs.
  • A simulated ShapesModel.parse(...) cell stands in for a real draw + Save so downstream cells (overlay, polygon_query) execute reproducibly in CI.
  • examples/index.md: gallery card + toctree entry.

Adds examples/interactive_annotate.ipynb covering the new
`sdata.pl.annotate()` API from scverse/spatialdata-plot#684. Uses the
same `squidpy.datasets.visium_hne_sdata()` dataset as
visium_mouse_brain.ipynb so the download cache is shared.
Structure follows the existing examples/ pattern:
- Intro + dataset citation + install hint for the [interactive] extra
- Load → render the image so the reader sees what to annotate
- Widget invocation shown in a markdown fenced block (the static docs
build can't execute the anywidget JS runtime; live-kernel users copy
the snippet)
- GIF placeholder cell — replace interactive_annotate.gif with a real
recording before merging
- "What the widget produces": a code cell that builds the equivalent
ShapesModel directly via shapely + ShapesModel.parse, so downstream
cells reproduce in the docs build without the widget
- Overlay with render_shapes; polygon-crop via sd.polygon_query
- Watermark block matching the other tutorials
Wires the new entry into examples/index.md alongside the Visium card.
Outstanding before merge:
- Replace the hippocampus polygon coordinates with values from an
actual annotation pass against visium_hne_sdata
- Record interactive_annotate.gif (~3-5 s of drawing/saving)
- Add interactive_annotate.png thumbnail for the gallery grid card
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@review-notebook-app

Copy link
Copy Markdown

Check out this pull request on ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

timtreisand others added 3 commits May 27, 2026 03:10
Pixi 0.54.2 refuses to load `[tool.pixi]` with dotted-key children
(`workspace.channels = [...]`, `dependencies.python = ">=3.11"`, …)
and requires one of `[tool.pixi.workspace]` / `.project` / `.package`
as a real TOML table header. Rewrite the inline-dotted block into
explicit `[tool.pixi.workspace]`, `[tool.pixi.dependencies]`,
`[tool.pixi.pypi-dependencies]`, and `[tool.pixi.tasks]` sections so
`pixi install` and `pixi run kernel-install` actually work.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Move existing thumbnails from beside their notebooks to a shared
`_static/img/` directory (Sphinx convention) so all gallery media
lives in one place:
examples/visium_mouse_brain.png -> _static/img/visium_mouse_brain.png
tutorials/getting_started.png -> _static/img/getting_started.png
tutorials/color_and_palette.png -> _static/img/color_and_palette.png
Update the `:img-top:` references in `examples/index.md` and
`tutorials/index.md` to point at `../_static/img/<slug>.png`.
Add step 6 to `CONTRIBUTING.md` documenting the convention: gallery
thumbnails and notebook-embedded GIFs / screenshots go under
`_static/img/`, never next to the notebook itself. Renumber the
following CI step accordingly.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The widget pivoted from the custom anywidget+JS canvas to the
external `anybioimage` library's `BioImageViewer` (see
scverse/spatialdata-plot#684). Update the tutorial to match:
- Intro: replace the anywidget/SVG architecture blurb with a
description of the `BioImageViewer` backend.
- Launch section: rewrite the API signature from the old positional
`annotate(coordinate_system, element, persist=True)` to the new
keyword-only chain-step form `.pl.render_images(...).pl.annotate(
coordinate_systems=...)`. Drop the lasso tool (no longer present)
and the JS-canvas-specific shortcut list. Replace the "Write to
disk" button with a `sdata.write_element(<name>)` follow-up note.
- Polygon query cell: pass the actual shapely geometry rather than
the whole `GeoDataFrame`. spatialdata's `polygon_query` overload
for `DataArray`/`DataTree` calls `GeoDataFrame(geometry=[polygon])`
internally, which fails with `GeometryTypeError: Unknown geometry
type: 'featurecollection'` if passed a nested gdf.
- Watermark: drop `anywidget` (transitive dep that isn't imported by
any executable cell) to keep the watermark report honest.
- Add a `warnings.filterwarnings("ignore")` housekeeping cell ahead
of the squidpy dataset load so the notebook's recorded outputs
don't leak Zarr v3 deprecation chatter into the docs build.
- Add the recorded GIF (`_static/img/interactive_annotate.gif`) and
a placeholder PNG thumbnail (regenerate before merging).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions

github-actionsBot commented May 27, 2026

Copy link
Copy Markdown

📖 Docs preview: https://scverse.org/spatialdata-plot-notebooks/pr-5/gallery.html

Built from ef91a72; redeployed on every push.

github-actionsBot pushed a commit that referenced this pull request May 27, 2026
@timtreistimtreis changed the title Add interactive region annotation tutorial (skeleton)Add interactive region annotation tutorialMay 27, 2026
@timtreis
timtreis marked this pull request as ready for review May 27, 2026 14:15
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
0.4.0 ships `sdata.pl.annotate()` (scverse/spatialdata-plot#684), so the
tutorial can require the published wheel instead of an editable path.
Re-executed the notebook to refresh the watermark output to 0.4.0.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
github-actionsBot pushed a commit that referenced this pull request May 27, 2026
@timtreis
timtreis merged commit d891121 into mainMay 27, 2026
4 checks passed
@timtreis
timtreis deleted the tutorial/interactive-annotate branch May 27, 2026 15:36
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@timtreis