From e539ac8e36bbdb1c51ebafaf2a911c2dbdc88a81 Mon Sep 17 00:00:00 2001
From: Mark Keller <7525285+keller-mark@users.noreply.github.com>
Date: Fri, 8 Aug 2025 10:02:38 -0400
Subject: [PATCH 01/10] Marimo conversion
---
...rowser_to_vitessce_config_conversion.ipynb | 217 ----
...rowser_to_vitessce_config_conversion.mo.py | 149 +++
docs/notebooks/config_to_python.ipynb | 184 ---
docs/notebooks/config_to_python.mo.py | 117 ++
docs/notebooks/data_conversion.ipynb | 103 --
docs/notebooks/data_conversion.mo.py | 90 ++
docs/notebooks/data_export_files.ipynb | 236 ----
docs/notebooks/data_export_files.mo.py | 229 ++++
docs/notebooks/data_export_s3.ipynb | 230 ----
docs/notebooks/data_export_s3.mo.py | 225 ++++
docs/notebooks/page_mode_comparative.ipynb | 490 -------
docs/notebooks/page_mode_comparative.mo.py | 461 +++++++
docs/notebooks/page_mode_example.ipynb | 197 ---
docs/notebooks/page_mode_example.mo.py | 185 +++
docs/notebooks/spatial_data.ipynb | 164 ---
docs/notebooks/spatial_data.mo.py | 181 +++
docs/notebooks/spatial_data_blobs.ipynb | 201 ---
docs/notebooks/spatial_data_blobs.mo.py | 187 +++
docs/notebooks/spatial_data_kpmp_vis.ipynb | 477 -------
docs/notebooks/spatial_data_kpmp_vis.mo.py | 450 +++++++
docs/notebooks/spatial_data_merfish.ipynb | 208 ---
docs/notebooks/spatial_data_merfish.mo.py | 196 +++
docs/notebooks/spatial_data_merfish_2.ipynb | 172 ---
docs/notebooks/spatial_data_merfish_2.mo.py | 180 +++
docs/notebooks/spatial_data_mouseliver.ipynb | 789 -----------
docs/notebooks/spatial_data_mouseliver.mo.py | 754 +++++++++++
.../spatial_data_mouseliver_remote.ipynb | 627 ---------
.../spatial_data_mouseliver_remote.mo.py | 560 ++++++++
docs/notebooks/spatial_data_visium_hd.ipynb | 247 ----
docs/notebooks/spatial_data_visium_hd.mo.py | 248 ++++
docs/notebooks/web_app_brain.ipynb | 253 ----
docs/notebooks/web_app_brain.mo.py | 249 ++++
.../notebooks/widget_anndata_with_image.ipynb | 130 --
.../notebooks/widget_anndata_with_image.mo.py | 126 ++
docs/notebooks/widget_brain.ipynb | 295 -----
docs/notebooks/widget_brain.mo.py | 288 ++++
docs/notebooks/widget_brain_h5ad.ipynb | 170 ---
docs/notebooks/widget_brain_h5ad.mo.py | 164 +++
.../widget_brain_with_base_dir.ipynb | 329 -----
.../widget_brain_with_base_dir.mo.py | 330 +++++
.../widget_brain_with_quality_metric.ipynb | 251 ----
.../widget_brain_with_quality_metric.mo.py | 244 ++++
docs/notebooks/widget_from_dict.ipynb | 108 --
docs/notebooks/widget_from_dict.mo.py | 94 ++
docs/notebooks/widget_genomic_profiles.ipynb | 220 ----
docs/notebooks/widget_genomic_profiles.mo.py | 209 +++
docs/notebooks/widget_imaging.ipynb | 114 --
docs/notebooks/widget_imaging.mo.py | 97 ++
docs/notebooks/widget_imaging_beta.ipynb | 168 ---
docs/notebooks/widget_imaging_beta.mo.py | 135 ++
.../widget_imaging_segmentation.ipynb | 118 --
.../widget_imaging_segmentation.mo.py | 94 ++
docs/notebooks/widget_loom.ipynb | 219 ----
docs/notebooks/widget_loom.mo.py | 218 ++++
docs/notebooks/widget_modify_config.ipynb | 1153 -----------------
docs/notebooks/widget_modify_config.mo.py | 141 ++
docs/notebooks/widget_neuroglancer.ipynb | 239 ----
docs/notebooks/widget_neuroglancer.mo.py | 224 ++++
docs/notebooks/widget_on_colab.ipynb | 137 --
docs/notebooks/widget_on_colab.mo.py | 125 ++
docs/notebooks/widget_pbmc.ipynb | 204 ---
docs/notebooks/widget_pbmc.mo.py | 190 +++
docs/notebooks/widget_pbmc_remote.ipynb | 139 --
docs/notebooks/widget_pbmc_remote.mo.py | 135 ++
docs/notebooks/widget_plugin_custom.ipynb | 184 ---
docs/notebooks/widget_plugin_custom.mo.py | 175 +++
docs/notebooks/widget_plugin_demo.ipynb | 122 --
docs/notebooks/widget_plugin_demo.mo.py | 112 ++
.../widget_plugin_spatial-query.ipynb | 152 ---
.../widget_plugin_spatial-query.mo.py | 134 ++
.../notebooks/widget_segmentations_beta.ipynb | 104 --
.../notebooks/widget_segmentations_beta.mo.py | 100 ++
docs/notebooks/widget_shortcut.ipynb | 176 ---
docs/notebooks/widget_shortcut.mo.py | 148 +++
74 files changed, 7944 insertions(+), 9527 deletions(-)
delete mode 100644 docs/notebooks/cellbrowser_to_vitessce_config_conversion.ipynb
create mode 100644 docs/notebooks/cellbrowser_to_vitessce_config_conversion.mo.py
delete mode 100644 docs/notebooks/config_to_python.ipynb
create mode 100644 docs/notebooks/config_to_python.mo.py
delete mode 100644 docs/notebooks/data_conversion.ipynb
create mode 100644 docs/notebooks/data_conversion.mo.py
delete mode 100644 docs/notebooks/data_export_files.ipynb
create mode 100644 docs/notebooks/data_export_files.mo.py
delete mode 100644 docs/notebooks/data_export_s3.ipynb
create mode 100644 docs/notebooks/data_export_s3.mo.py
delete mode 100644 docs/notebooks/page_mode_comparative.ipynb
create mode 100644 docs/notebooks/page_mode_comparative.mo.py
delete mode 100644 docs/notebooks/page_mode_example.ipynb
create mode 100644 docs/notebooks/page_mode_example.mo.py
delete mode 100644 docs/notebooks/spatial_data.ipynb
create mode 100644 docs/notebooks/spatial_data.mo.py
delete mode 100644 docs/notebooks/spatial_data_blobs.ipynb
create mode 100644 docs/notebooks/spatial_data_blobs.mo.py
delete mode 100644 docs/notebooks/spatial_data_kpmp_vis.ipynb
create mode 100644 docs/notebooks/spatial_data_kpmp_vis.mo.py
delete mode 100644 docs/notebooks/spatial_data_merfish.ipynb
create mode 100644 docs/notebooks/spatial_data_merfish.mo.py
delete mode 100644 docs/notebooks/spatial_data_merfish_2.ipynb
create mode 100644 docs/notebooks/spatial_data_merfish_2.mo.py
delete mode 100644 docs/notebooks/spatial_data_mouseliver.ipynb
create mode 100644 docs/notebooks/spatial_data_mouseliver.mo.py
delete mode 100644 docs/notebooks/spatial_data_mouseliver_remote.ipynb
create mode 100644 docs/notebooks/spatial_data_mouseliver_remote.mo.py
delete mode 100644 docs/notebooks/spatial_data_visium_hd.ipynb
create mode 100644 docs/notebooks/spatial_data_visium_hd.mo.py
delete mode 100644 docs/notebooks/web_app_brain.ipynb
create mode 100644 docs/notebooks/web_app_brain.mo.py
delete mode 100644 docs/notebooks/widget_anndata_with_image.ipynb
create mode 100644 docs/notebooks/widget_anndata_with_image.mo.py
delete mode 100644 docs/notebooks/widget_brain.ipynb
create mode 100644 docs/notebooks/widget_brain.mo.py
delete mode 100644 docs/notebooks/widget_brain_h5ad.ipynb
create mode 100644 docs/notebooks/widget_brain_h5ad.mo.py
delete mode 100644 docs/notebooks/widget_brain_with_base_dir.ipynb
create mode 100644 docs/notebooks/widget_brain_with_base_dir.mo.py
delete mode 100644 docs/notebooks/widget_brain_with_quality_metric.ipynb
create mode 100644 docs/notebooks/widget_brain_with_quality_metric.mo.py
delete mode 100644 docs/notebooks/widget_from_dict.ipynb
create mode 100644 docs/notebooks/widget_from_dict.mo.py
delete mode 100644 docs/notebooks/widget_genomic_profiles.ipynb
create mode 100644 docs/notebooks/widget_genomic_profiles.mo.py
delete mode 100644 docs/notebooks/widget_imaging.ipynb
create mode 100644 docs/notebooks/widget_imaging.mo.py
delete mode 100644 docs/notebooks/widget_imaging_beta.ipynb
create mode 100644 docs/notebooks/widget_imaging_beta.mo.py
delete mode 100644 docs/notebooks/widget_imaging_segmentation.ipynb
create mode 100644 docs/notebooks/widget_imaging_segmentation.mo.py
delete mode 100644 docs/notebooks/widget_loom.ipynb
create mode 100644 docs/notebooks/widget_loom.mo.py
delete mode 100644 docs/notebooks/widget_modify_config.ipynb
create mode 100644 docs/notebooks/widget_modify_config.mo.py
delete mode 100644 docs/notebooks/widget_neuroglancer.ipynb
create mode 100644 docs/notebooks/widget_neuroglancer.mo.py
delete mode 100644 docs/notebooks/widget_on_colab.ipynb
create mode 100644 docs/notebooks/widget_on_colab.mo.py
delete mode 100644 docs/notebooks/widget_pbmc.ipynb
create mode 100644 docs/notebooks/widget_pbmc.mo.py
delete mode 100644 docs/notebooks/widget_pbmc_remote.ipynb
create mode 100644 docs/notebooks/widget_pbmc_remote.mo.py
delete mode 100644 docs/notebooks/widget_plugin_custom.ipynb
create mode 100644 docs/notebooks/widget_plugin_custom.mo.py
delete mode 100644 docs/notebooks/widget_plugin_demo.ipynb
create mode 100644 docs/notebooks/widget_plugin_demo.mo.py
delete mode 100644 docs/notebooks/widget_plugin_spatial-query.ipynb
create mode 100644 docs/notebooks/widget_plugin_spatial-query.mo.py
delete mode 100644 docs/notebooks/widget_segmentations_beta.ipynb
create mode 100644 docs/notebooks/widget_segmentations_beta.mo.py
delete mode 100644 docs/notebooks/widget_shortcut.ipynb
create mode 100644 docs/notebooks/widget_shortcut.mo.py
diff --git a/docs/notebooks/cellbrowser_to_vitessce_config_conversion.ipynb b/docs/notebooks/cellbrowser_to_vitessce_config_conversion.ipynb
deleted file mode 100644
index 3ca1e0cf..00000000
--- a/docs/notebooks/cellbrowser_to_vitessce_config_conversion.ipynb
+++ /dev/null
@@ -1,217 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "710bc947",
- "metadata": {},
- "source": [
- "# Load UCSC Cell Browser project in Vitessce"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "fad939f6-bd8b-46f8-8dd1-f0816d8ca5b3",
- "metadata": {},
- "source": [
- "This notebook shows you how to use the `convert_cell_browser_project_to_anndata` function, which allows you to take an existing project, published in https://cells.ucsc.edu/ and:\n",
- "1. Convert it into the AnnData format that is supported by Vitessce\n",
- "2. Save the AnnData object as a Zarr store\n",
- "3. Configure Vitessce with the AnnData-Zarr store\n",
- "4. Render a Vitessce widget based on the config (step 3) directly in the notebook.\n",
- "\n",
- "The dataset that you choose to convert needs to be a valid UCSC Cell Browser \"project\", accessible from https://cells.ucsc.edu/, with a configuration available in https://github.com/ucscGenomeBrowser/cellbrowser-confs\n",
- "\n",
- "The `convert_cell_browser_project_to_anndata` function takes the name of that project as an input. For example, to convert this project, https://cells.ucsc.edu/?ds=adultPancreas, you will neeed to pass `\"adultPancreas\"` as the project name."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "id": "532fea6a-69d4-4cac-8afb-6d334dbe7ca1",
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "import json\n",
- "from os.path import join\n",
- "from vitessce import (\n",
- " convert_cell_browser_project_to_anndata,\n",
- " AnnDataWrapper,\n",
- " VitessceConfig,\n",
- ")\n",
- "from vitessce.data_utils import VAR_CHUNK_SIZE"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "a8077cfd-abc2-488d-9d91-83bc29a0bbe9",
- "metadata": {},
- "source": [
- "## 1. Convert UCSC Cell Browser project to a format that is supported by Vitessce\n",
- "#### Output:\n",
- "An AnnData object\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "743c2d61-d98c-4e8d-a821-d5fe0ec2d93b",
- "metadata": {},
- "outputs": [],
- "source": [
- "## 3. Convert UCSC Cell Browser project to a Vitessce view config"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 22,
- "id": "6fb3e7dc-baf8-49e9-9d24-264bcd668b49",
- "metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Converting CellBrowser config for project adultPancreas to Anndata-Zarr object\n",
- "Successfully fetched configuration: https://cells.ucsc.edu/adultPancreas/dataset.json.\n",
- "CellBrowser config is valid. Proceeding further with conversion.\n",
- "Downloading expression matrix ...\n",
- "Successfully downloaded expression matrix https://cells.ucsc.edu/adultPancreas/exprMatrix.tsv.gz.\n",
- "Loading expression matrix into Anndata object ...\n",
- "This dataset uses the format identifier|symbol for the ad.obs gene names (e.g. “ENSG0123123.3|HOX3”). We are keeping only the symbol.\n",
- "Adding cell metadata to Anndata object ...\n",
- "Successfully downloaded metadata meta.tsv.\n",
- "Successful extraction of the following coordinates and URLS: {'X_tsne': 'tMinusSNE.coords.tsv.gz'}\n",
- "Adding X_tsne to Anndata object ...\n",
- "X_tsne successfully added.\n",
- "Done adding coordinates to the Anndata object.\n",
- "Filtering out all non-marker genes from Anndata object ...\n",
- "Successfully filtered out all non-marker genes from Anndata object.\n",
- "About to write the Anndata object to the Zarr store. The following properties will be saved:\n",
- " Obs columns: ['cluster', 'age', 'age_unit', 'Key', 'experiment_name', 'fragAnalyzerRange', 'nCells', 'ng_ul', 'plate_nr', 'sample_recieve_date', 'chip_type', 'c1_chip_id', 'enrichment_method', 'capture_position', 'gene_body_coverage', 'intron_exon_ratio', 'mapped_reads', 'total_reads', 'n_genes']\n",
- " Obsm keys: ['X_tsne']\n",
- " Var columns: ['gene', 'n_cells']\n",
- "obsm X_tsne is an instance of DataFrame, converting it to numpy array.\n"
- ]
- }
- ],
- "source": [
- "# Example run, coverting \"adultPancreas\" project:\n",
- "adata = convert_cell_browser_project_to_anndata(project_name=\"adultPancreas\", keep_only_marker_genes=True)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "cf3cfcbe-4048-4a60-8988-b8c0eace23e2",
- "metadata": {},
- "source": [
- "## 2. Save the AnnData object as a Zarr store"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 24,
- "id": "8835ab53-2ee3-490e-a68c-c2d8952277a9",
- "metadata": {
- "scrolled": true
- },
- "outputs": [],
- "source": [
- "zarr_filepath = join(\"data\", \"out.adata.zarr\")\n",
- "os.makedirs(os.path.dirname(zarr_filepath), exist_ok=True)\n",
- "adata.write_zarr(zarr_filepath, chunks=[adata.shape[0], VAR_CHUNK_SIZE])"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "d61667b4-dc32-4376-bff1-b4a5bf74140f",
- "metadata": {},
- "source": [
- "## 3. Configure Vitessce with the AnnData-Zarr store"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 25,
- "id": "259c1804-2e67-4a92-bc90-5ba5e3dba7b3",
- "metadata": {},
- "outputs": [],
- "source": [
- "anndata_wrapper_inst = AnnDataWrapper(\n",
- " adata_path=zarr_filepath,\n",
- " obs_feature_matrix_path=\"X\",\n",
- " obs_embedding_paths=[\"obsm/X_tsne\"],\n",
- " obs_embedding_names=[\"t-SNE\"],\n",
- " obs_set_paths=[\"obs/cluster\", \"obs/age\"],\n",
- " obs_set_names=[\"cluster\", \"age\"],\n",
- ")\n",
- "vc = VitessceConfig(schema_version=\"1.0.15\", name=\"Vitessce configuration for CellBrowser project adultPancreas\")\n",
- "anndata_wrapper_inst.auto_view_config(vc)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "22e7d2fd-2c2e-4ce5-b551-7809cdc6568e",
- "metadata": {},
- "source": [
- "## 4. Render the Vitessce widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 26,
- "id": "cb9cb8e3-8ef4-49d9-b0a0-ba2f0fc80637",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "application/vnd.jupyter.widget-view+json": {
- "model_id": "e5878bf30e1f4428a14604731928972d",
- "version_major": 2,
- "version_minor": 0
- },
- "text/plain": [
- "VitessceWidget(config={'version': '1.0.15', 'name': 'Vitessce configuration for CellBrowser project adultPancr…"
- ]
- },
- "execution_count": 26,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "774b8156-5cc6-4d17-884b-595957366230",
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.9.0"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/docs/notebooks/cellbrowser_to_vitessce_config_conversion.mo.py b/docs/notebooks/cellbrowser_to_vitessce_config_conversion.mo.py
new file mode 100644
index 00000000..157ee36d
--- /dev/null
+++ b/docs/notebooks/cellbrowser_to_vitessce_config_conversion.mo.py
@@ -0,0 +1,149 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Load UCSC Cell Browser project in Vitessce
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ This notebook shows you how to use the `convert_cell_browser_project_to_anndata` function, which allows you to take an existing project, published in https://cells.ucsc.edu/ and:
+ 1. Convert it into the AnnData format that is supported by Vitessce
+ 2. Save the AnnData object as a Zarr store
+ 3. Configure Vitessce with the AnnData-Zarr store
+ 4. Render a Vitessce widget based on the config (step 3) directly in the notebook.
+
+ The dataset that you choose to convert needs to be a valid UCSC Cell Browser "project", accessible from https://cells.ucsc.edu/, with a configuration available in https://github.com/ucscGenomeBrowser/cellbrowser-confs
+
+ The `convert_cell_browser_project_to_anndata` function takes the name of that project as an input. For example, to convert this project, https://cells.ucsc.edu/?ds=adultPancreas, you will neeed to pass `"adultPancreas"` as the project name.
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ import os
+ import json
+ from os.path import join
+ from vitessce import (
+ convert_cell_browser_project_to_anndata,
+ AnnDataWrapper,
+ VitessceConfig,
+ )
+ from vitessce.data_utils import VAR_CHUNK_SIZE
+ return (
+ AnnDataWrapper,
+ VAR_CHUNK_SIZE,
+ VitessceConfig,
+ convert_cell_browser_project_to_anndata,
+ join,
+ os,
+ )
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 1. Convert UCSC Cell Browser project to a format that is supported by Vitessce
+ #### Output:
+ An AnnData object
+
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ ## 3. Convert UCSC Cell Browser project to a Vitessce view config
+ return
+
+
+@app.cell
+def _(convert_cell_browser_project_to_anndata):
+ # Example run, coverting "adultPancreas" project:
+ adata = convert_cell_browser_project_to_anndata(project_name="adultPancreas", keep_only_marker_genes=True)
+ return (adata,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 2. Save the AnnData object as a Zarr store
+ """
+ )
+ return
+
+
+@app.cell
+def _(VAR_CHUNK_SIZE, adata, join, os):
+ zarr_filepath = join("data", "out.adata.zarr")
+ os.makedirs(os.path.dirname(zarr_filepath), exist_ok=True)
+ adata.write_zarr(zarr_filepath, chunks=[adata.shape[0], VAR_CHUNK_SIZE])
+ return (zarr_filepath,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 3. Configure Vitessce with the AnnData-Zarr store
+ """
+ )
+ return
+
+
+@app.cell
+def _(AnnDataWrapper, VitessceConfig, zarr_filepath):
+ anndata_wrapper_inst = AnnDataWrapper(
+ adata_path=zarr_filepath,
+ obs_feature_matrix_path="X",
+ obs_embedding_paths=["obsm/X_tsne"],
+ obs_embedding_names=["t-SNE"],
+ obs_set_paths=["obs/cluster", "obs/age"],
+ obs_set_names=["cluster", "age"],
+ )
+ vc = VitessceConfig(schema_version="1.0.15", name="Vitessce configuration for CellBrowser project adultPancreas")
+ anndata_wrapper_inst.auto_view_config(vc)
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 4. Render the Vitessce widget
+ """
+ )
+ return
+
+
+@app.cell
+def _(vc):
+ vw = vc.widget()
+ vw
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/config_to_python.ipynb b/docs/notebooks/config_to_python.ipynb
deleted file mode 100644
index ed5e2d89..00000000
--- a/docs/notebooks/config_to_python.ipynb
+++ /dev/null
@@ -1,184 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "10f1c457-d0c8-4630-8e49-45df13b9c6d0",
- "metadata": {},
- "source": [
- "# Generate Python code to reconstruct a VitessceConfig instance"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "67d5193a",
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import VitessceConfig, VitessceChainableConfig, VitessceConfigDatasetFile"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "721dacde",
- "metadata": {},
- "outputs": [],
- "source": [
- "from example_configs import dries as dries_config"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "0954be13-6157-4e72-871d-4b1cd6b36ff0",
- "metadata": {},
- "source": [
- "## Load a view config from a dict representation"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "61000b61",
- "metadata": {
- "scrolled": true
- },
- "outputs": [],
- "source": [
- "vc = VitessceConfig.from_dict(dries_config)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "0999e895-194e-4890-9cf7-b7c7cc60c9ee",
- "metadata": {},
- "source": [
- "## Print to JSON"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "f777b428-4d75-487e-b08d-9d66f30fbe9a",
- "metadata": {},
- "outputs": [],
- "source": [
- "import json\n",
- "print(json.dumps(vc.to_dict(), indent=2))"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "6b51dc66-096c-4c69-a041-62c5bdd523e7",
- "metadata": {},
- "source": [
- "## Print to Python\n",
- "\n",
- "The `vc.to_python` function generates formatted Python code which can be used to re-generate the `vc` instance."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "15ae4ca3-490e-4b99-ae4d-8fafedf60885",
- "metadata": {},
- "outputs": [],
- "source": [
- "imports, code = vc.to_python()"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "619a87f0-9eff-49c0-a092-7859c2a54d16",
- "metadata": {},
- "source": [
- "The first value returned is a list of classes used by the code snippet."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "6ec458e3-1970-42ab-876c-cc7407d9cc19",
- "metadata": {},
- "outputs": [],
- "source": [
- "imports"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "0a458da5-9fe1-45fa-b6d5-a09acb3493d3",
- "metadata": {},
- "outputs": [],
- "source": [
- "print(code)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "e47433f0-0b65-4204-becb-ec9b0c59b731",
- "metadata": {},
- "source": [
- "The second value is the code snippet. When evaluated, the result will be a new `VitessceConfig` instance."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "a82a7938-923c-4947-bdf9-49d1f30134f6",
- "metadata": {},
- "source": [
- "## Evaluate the code and render a Vitessce widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "94434a43",
- "metadata": {},
- "outputs": [],
- "source": [
- "reconstructed_vc = eval(code)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "bf0110ff",
- "metadata": {},
- "outputs": [],
- "source": [
- "reconstructed_vc.widget()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "96bf94ce-1963-4ec3-8661-178e6adbbcb7",
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.8.0"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/docs/notebooks/config_to_python.mo.py b/docs/notebooks/config_to_python.mo.py
new file mode 100644
index 00000000..a9d825bc
--- /dev/null
+++ b/docs/notebooks/config_to_python.mo.py
@@ -0,0 +1,117 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App(width="medium")
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(r"""# Generate Python code to reconstruct a VitessceConfig instance""")
+ return
+
+
+@app.cell
+def _():
+ from vitessce import VitessceConfig, VitessceChainableConfig, VitessceConfigDatasetFile
+ return (VitessceConfig,)
+
+
+@app.cell
+def _():
+ from example_configs import dries as dries_config
+ return (dries_config,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(r"""## Load a view config from a dict representation""")
+ return
+
+
+@app.cell
+def _(VitessceConfig, dries_config):
+ vc = VitessceConfig.from_dict(dries_config)
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(r"""## Print to JSON""")
+ return
+
+
+@app.cell
+def _(vc):
+ import json
+ print(json.dumps(vc.to_dict(), indent=2))
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Print to Python
+
+ The `vc.to_python` function generates formatted Python code which can be used to re-generate the `vc` instance.
+ """
+ )
+ return
+
+
+@app.cell
+def _(vc):
+ imports, code = vc.to_python()
+ return code, imports
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(r"""The first value returned is a list of classes used by the code snippet.""")
+ return
+
+
+@app.cell
+def _(imports):
+ imports
+ return
+
+
+@app.cell
+def _(code):
+ print(code)
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(r"""The second value is the code snippet. When evaluated, the result will be a new `VitessceConfig` instance.""")
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(r"""## Evaluate the code and render a Vitessce widget""")
+ return
+
+
+@app.cell
+def _(code):
+ reconstructed_vc = eval(code)
+ return (reconstructed_vc,)
+
+
+@app.cell
+def _(reconstructed_vc):
+ reconstructed_vc.widget()
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/data_conversion.ipynb b/docs/notebooks/data_conversion.ipynb
deleted file mode 100644
index 69f3f66f..00000000
--- a/docs/notebooks/data_conversion.ipynb
+++ /dev/null
@@ -1,103 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Data Preparation Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Convert data manually"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "When running the Vitessce widget, data is converted on-the-fly into formats that the Vitessce JavaScript component can render.\n",
- "The converted data is stored in temporary files, preventing long-term use of the converted files.\n",
- "\n",
- "However, the data conversion utilities used by the widget are exposed so that their outputs can be saved to regular files.\n",
- "This allows the files to be saved for future use with the Vitessce web application by serving the files locally or moving the files onto an object storage system such as AWS S3 (for long-term storage and data sharing).\n",
- "\n",
- "This notebook demonstrates how to save the processed outputs of the `AnnDataWrapper` and `SnapWrapper` classes."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import SnapWrapper\n",
- "from os.path import join\n",
- "from scipy.io import mmread\n",
- "import pandas as pd\n",
- "import numpy as np\n",
- "import json"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "mtx = mmread(join('data', 'snapatac', 'filtered_cell_by_bin.mtx'))\n",
- "barcodes_df = pd.read_csv(join('data', 'snapatac', 'barcodes.txt'), header=None)\n",
- "bins_df = pd.read_csv(join('data', 'snapatac', 'bins.txt'), header=None)\n",
- "clusters_df = pd.read_csv(join('data', 'snapatac', 'umap_coords_clusters.csv'), index_col=0)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "zarr_filepath = join('data', 'snapatac', 'out.snap.multires.zarr')\n",
- "\n",
- "w = SnapWrapper(mtx, barcodes_df, bins_df, clusters_df)\n",
- "\n",
- "cells_json = w.create_cells_json()\n",
- "cell_sets_json = w.create_cell_sets_json()\n",
- "\n",
- "with open(join('data', 'snapatac', 'out.cells.json'), 'w') as f:\n",
- " json.dump(cells_json, f)\n",
- "\n",
- "with open(join('data', 'snapatac', 'out.cell-sets.json'), 'w') as f:\n",
- " json.dump(cell_sets_json, f)\n",
- "\n",
- "\n",
- "w.create_genomic_multivec_zarr(zarr_filepath)"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.8.0"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/data_conversion.mo.py b/docs/notebooks/data_conversion.mo.py
new file mode 100644
index 00000000..d1a94e09
--- /dev/null
+++ b/docs/notebooks/data_conversion.mo.py
@@ -0,0 +1,90 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Data Preparation Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Convert data manually
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ When running the Vitessce widget, data is converted on-the-fly into formats that the Vitessce JavaScript component can render.
+ The converted data is stored in temporary files, preventing long-term use of the converted files.
+
+ However, the data conversion utilities used by the widget are exposed so that their outputs can be saved to regular files.
+ This allows the files to be saved for future use with the Vitessce web application by serving the files locally or moving the files onto an object storage system such as AWS S3 (for long-term storage and data sharing).
+
+ This notebook demonstrates how to save the processed outputs of the `AnnDataWrapper` and `SnapWrapper` classes.
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ from vitessce import SnapWrapper
+ from os.path import join
+ from scipy.io import mmread
+ import pandas as pd
+ import numpy as np
+ import json
+ return SnapWrapper, join, json, mmread, pd
+
+
+@app.cell
+def _(join, mmread, pd):
+ mtx = mmread(join('data', 'snapatac', 'filtered_cell_by_bin.mtx'))
+ barcodes_df = pd.read_csv(join('data', 'snapatac', 'barcodes.txt'), header=None)
+ bins_df = pd.read_csv(join('data', 'snapatac', 'bins.txt'), header=None)
+ clusters_df = pd.read_csv(join('data', 'snapatac', 'umap_coords_clusters.csv'), index_col=0)
+ return barcodes_df, bins_df, clusters_df, mtx
+
+
+@app.cell
+def _(SnapWrapper, barcodes_df, bins_df, clusters_df, join, json, mtx):
+ zarr_filepath = join('data', 'snapatac', 'out.snap.multires.zarr')
+
+ w = SnapWrapper(mtx, barcodes_df, bins_df, clusters_df)
+
+ cells_json = w.create_cells_json()
+ cell_sets_json = w.create_cell_sets_json()
+
+ with open(join('data', 'snapatac', 'out.cells.json'), 'w') as f:
+ json.dump(cells_json, f)
+
+ with open(join('data', 'snapatac', 'out.cell-sets.json'), 'w') as f:
+ json.dump(cell_sets_json, f)
+
+
+ w.create_genomic_multivec_zarr(zarr_filepath)
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/data_export_files.ipynb b/docs/notebooks/data_export_files.ipynb
deleted file mode 100644
index d2b17c6e..00000000
--- a/docs/notebooks/data_export_files.ipynb
+++ /dev/null
@@ -1,236 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Data Preparation Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Export data to local files"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 1. Import dependencies\n",
- "\n",
- "We need to import the classes and functions that we will be using from the corresponding packages."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "import json\n",
- "from urllib.parse import quote_plus\n",
- "from os.path import join, isfile, isdir\n",
- "from urllib.request import urlretrieve\n",
- "from anndata import read_h5ad\n",
- "import scanpy as sc\n",
- "\n",
- "from vitessce import (\n",
- " VitessceWidget,\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " AnnDataWrapper,\n",
- ")\n",
- "from vitessce.data_utils import (\n",
- " optimize_adata,\n",
- " VAR_CHUNK_SIZE,\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 2. Download and process data\n",
- "\n",
- "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "adata_filepath = join(\"data\", \"habib17.processed.h5ad\")\n",
- "if not isfile(adata_filepath):\n",
- " os.makedirs(\"data\", exist_ok=True)\n",
- " urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)\n",
- "\n",
- "adata = read_h5ad(adata_filepath)\n",
- "top_dispersion = adata.var[\"dispersions_norm\"][\n",
- " sorted(\n",
- " range(len(adata.var[\"dispersions_norm\"])),\n",
- " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
- " )[-51:][0]\n",
- "]\n",
- "adata.var[\"top_highly_variable\"] = (\n",
- " adata.var[\"dispersions_norm\"] > top_dispersion\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "zarr_filepath = join(\"data\", \"habib17.processed.zarr\")\n",
- "if not isdir(zarr_filepath):\n",
- " adata = optimize_adata(\n",
- " adata,\n",
- " obs_cols=[\"CellType\"],\n",
- " obsm_keys=[\"X_umap\"],\n",
- " var_cols=[\"top_highly_variable\"],\n",
- " optimize_X=True,\n",
- " )\n",
- " adata.write_zarr(zarr_filepath, chunks=[adata.shape[0], VAR_CHUNK_SIZE])"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 3. Create the Vitessce configuration"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Set up the configuration by adding the views and datasets of interest."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', description='COVID-19 Healthy Donor Brain')\n",
- "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
- " adata_path=zarr_filepath,\n",
- " obs_embedding_paths=[\"obsm/X_umap\"],\n",
- " obs_embedding_names=[\"UMAP\"],\n",
- " obs_set_paths=[\"obs/CellType\"],\n",
- " obs_set_names=[\"Cell Type\"],\n",
- " obs_feature_matrix_path=\"X\",\n",
- " feature_filter_path=\"var/top_highly_variable\"\n",
- "))\n",
- "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"X_umap\")\n",
- "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
- "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
- "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)\n",
- "vc.layout((scatterplot | (cell_sets / genes)) / heatmap);"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 4. Export files to a local directory\n",
- "\n",
- "The `.export(to='files')` method on the view config instance will export files to the specified directory `out_dir`. The `base_url` parameter is required so that the file URLs in the view config point to the location where you ultimately intend to serve the files."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "config_dict = vc.export(to='files', base_url='http://localhost:3000', out_dir='./test')"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 5. Serve the files"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Now that the files have been saved to the `./test` directory, they can be served by any static web server.\n",
- "\n",
- "If you would like to serve the files locally, we recommend [http-server](https://github.com/http-party/http-server) which can be installed with NPM or Homebrew:\n",
- "```sh\n",
- "cd test\n",
- "http-server ./ --cors -p 3000\n",
- "```"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 6. View on vitessce.io\n",
- "\n",
- "The returned view config dict can be converted to a URL, and if the files are served on the internet (rather than locally), this URL can be used to share the interactive visualizations with colleagues."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vitessce_url = \"http://vitessce.io/?url=data:,\" + quote_plus(json.dumps(config_dict))\n",
- "import webbrowser\n",
- "webbrowser.open(vitessce_url)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.8.0"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/data_export_files.mo.py b/docs/notebooks/data_export_files.mo.py
new file mode 100644
index 00000000..a3f3d968
--- /dev/null
+++ b/docs/notebooks/data_export_files.mo.py
@@ -0,0 +1,229 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Data Preparation Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Export data to local files
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 1. Import dependencies
+
+ We need to import the classes and functions that we will be using from the corresponding packages.
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ import os
+ import json
+ from urllib.parse import quote_plus
+ from os.path import join, isfile, isdir
+ from urllib.request import urlretrieve
+ from anndata import read_h5ad
+ import scanpy as sc
+
+ from vitessce import (
+ VitessceWidget,
+ VitessceConfig,
+ Component as cm,
+ CoordinationType as ct,
+ AnnDataWrapper,
+ )
+ from vitessce.data_utils import (
+ optimize_adata,
+ VAR_CHUNK_SIZE,
+ )
+ return (
+ AnnDataWrapper,
+ VAR_CHUNK_SIZE,
+ VitessceConfig,
+ cm,
+ isdir,
+ isfile,
+ join,
+ json,
+ optimize_adata,
+ os,
+ quote_plus,
+ read_h5ad,
+ urlretrieve,
+ )
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 2. Download and process data
+
+ For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17.
+ """
+ )
+ return
+
+
+@app.cell
+def _(isfile, join, os, read_h5ad, urlretrieve):
+ adata_filepath = join("data", "habib17.processed.h5ad")
+ if not isfile(adata_filepath):
+ os.makedirs("data", exist_ok=True)
+ urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)
+
+ adata = read_h5ad(adata_filepath)
+ top_dispersion = adata.var["dispersions_norm"][
+ sorted(
+ range(len(adata.var["dispersions_norm"])),
+ key=lambda k: adata.var["dispersions_norm"][k],
+ )[-51:][0]
+ ]
+ adata.var["top_highly_variable"] = (
+ adata.var["dispersions_norm"] > top_dispersion
+ )
+ return (adata,)
+
+
+@app.cell
+def _(VAR_CHUNK_SIZE, adata, isdir, join, optimize_adata):
+ zarr_filepath = join('data', 'habib17.processed.zarr')
+ if not isdir(zarr_filepath):
+ adata_1 = optimize_adata(adata, obs_cols=['CellType'], obsm_keys=['X_umap'], var_cols=['top_highly_variable'], optimize_X=True)
+ adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])
+ return (zarr_filepath,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 3. Create the Vitessce configuration
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ Set up the configuration by adding the views and datasets of interest.
+ """
+ )
+ return
+
+
+@app.cell
+def _(AnnDataWrapper, VitessceConfig, cm, zarr_filepath):
+ vc = VitessceConfig(schema_version="1.0.15", name='Habib et al', description='COVID-19 Healthy Donor Brain')
+ dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(
+ adata_path=zarr_filepath,
+ obs_embedding_paths=["obsm/X_umap"],
+ obs_embedding_names=["UMAP"],
+ obs_set_paths=["obs/CellType"],
+ obs_set_names=["Cell Type"],
+ obs_feature_matrix_path="X",
+ feature_filter_path="var/top_highly_variable"
+ ))
+ scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping="X_umap")
+ cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)
+ genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)
+ heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)
+ vc.layout((scatterplot | (cell_sets / genes)) / heatmap);
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 4. Export files to a local directory
+
+ The `.export(to='files')` method on the view config instance will export files to the specified directory `out_dir`. The `base_url` parameter is required so that the file URLs in the view config point to the location where you ultimately intend to serve the files.
+ """
+ )
+ return
+
+
+@app.cell
+def _(vc):
+ config_dict = vc.export(to='files', base_url='http://localhost:3000', out_dir='./test')
+ return (config_dict,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 5. Serve the files
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ Now that the files have been saved to the `./test` directory, they can be served by any static web server.
+
+ If you would like to serve the files locally, we recommend [http-server](https://github.com/http-party/http-server) which can be installed with NPM or Homebrew:
+ ```sh
+ cd test
+ http-server ./ --cors -p 3000
+ ```
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 6. View on vitessce.io
+
+ The returned view config dict can be converted to a URL, and if the files are served on the internet (rather than locally), this URL can be used to share the interactive visualizations with colleagues.
+ """
+ )
+ return
+
+
+@app.cell
+def _(config_dict, json, quote_plus):
+ vitessce_url = "http://vitessce.io/?url=data:," + quote_plus(json.dumps(config_dict))
+ import webbrowser
+ webbrowser.open(vitessce_url)
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/data_export_s3.ipynb b/docs/notebooks/data_export_s3.ipynb
deleted file mode 100644
index c84a0e43..00000000
--- a/docs/notebooks/data_export_s3.ipynb
+++ /dev/null
@@ -1,230 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Data Preparation Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Export data to AWS S3"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 1. Import dependencies\n",
- "\n",
- "We need to import the classes and functions that we will be using from the corresponding packages."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "import boto3\n",
- "import json\n",
- "from urllib.parse import quote_plus\n",
- "from os.path import join, isfile, isdir\n",
- "from urllib.request import urlretrieve\n",
- "from anndata import read_h5ad\n",
- "import scanpy as sc\n",
- "\n",
- "from vitessce import (\n",
- " VitessceWidget,\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " AnnDataWrapper,\n",
- ")\n",
- "from vitessce.data_utils import (\n",
- " optimize_adata,\n",
- " VAR_CHUNK_SIZE,\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 2. Download and process data\n",
- "\n",
- "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "adata_filepath = join(\"data\", \"habib17.processed.h5ad\")\n",
- "if not isfile(adata_filepath):\n",
- " os.makedirs(\"data\", exist_ok=True)\n",
- " urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)\n",
- "\n",
- "adata = read_h5ad(adata_filepath)\n",
- "top_dispersion = adata.var[\"dispersions_norm\"][\n",
- " sorted(\n",
- " range(len(adata.var[\"dispersions_norm\"])),\n",
- " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
- " )[-51:][0]\n",
- "]\n",
- "adata.var[\"top_highly_variable\"] = (\n",
- " adata.var[\"dispersions_norm\"] > top_dispersion\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "zarr_filepath = join(\"data\", \"habib17.processed.zarr\")\n",
- "if not isdir(zarr_filepath):\n",
- " adata = optimize_adata(\n",
- " adata,\n",
- " obs_cols=[\"CellType\"],\n",
- " obsm_keys=[\"X_umap\"],\n",
- " var_cols=[\"top_highly_variable\"],\n",
- " optimize_X=True,\n",
- " )\n",
- " adata.write_zarr(zarr_filepath, chunks=[adata.shape[0], VAR_CHUNK_SIZE])"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 3. Create the Vitessce configuration"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Set up the configuration by adding the views and datasets of interest."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', description='COVID-19 Healthy Donor Brain')\n",
- "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
- " adata_path=zarr_filepath,\n",
- " obs_embedding_paths=[\"obsm/X_umap\"],\n",
- " obs_embedding_names=[\"UMAP\"],\n",
- " obs_set_paths=[\"obs/CellType\"],\n",
- " obs_set_names=[\"Cell Type\"],\n",
- " obs_feature_matrix_path=\"X\",\n",
- " feature_filter_path=\"var/top_highly_variable\"\n",
- "))\n",
- "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
- "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
- "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
- "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)\n",
- "vc.layout((scatterplot | (cell_sets / genes)) / heatmap);"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 4. Create a `boto3` resource with S3 credentials"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "s3 = boto3.resource(\n",
- " service_name='s3',\n",
- " aws_access_key_id=os.environ['VITESSCE_S3_ACCESS_KEY_ID'],\n",
- " aws_secret_access_key=os.environ['VITESSCE_S3_SECRET_ACCESS_KEY'],\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 5. Upload files to S3\n",
- "\n",
- "The `.export(to='S3')` method on the view config instance will upload all data objects to the specified bucket. Then, the processed view config will be returned as a `dict`, with the file URLs filled in, pointing to the S3 bucket files. For more information about configuring the S3 bucket so that files are accessible over the internet, visit the \"Hosting Data\" page of our core documentation site."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "config_dict = vc.export(to='S3', s3=s3, bucket_name='vitessce-export-examples', prefix='test')"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 6. View on vitessce.io\n",
- "\n",
- "The returned view config dict can be converted to a URL, and can be used to share the interactive visualizations with colleagues."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vitessce_url = \"http://vitessce.io/?url=data:,\" + quote_plus(json.dumps(config_dict))\n",
- "import webbrowser\n",
- "webbrowser.open(vitessce_url)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.8.0"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/data_export_s3.mo.py b/docs/notebooks/data_export_s3.mo.py
new file mode 100644
index 00000000..189f3fc4
--- /dev/null
+++ b/docs/notebooks/data_export_s3.mo.py
@@ -0,0 +1,225 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Data Preparation Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Export data to AWS S3
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 1. Import dependencies
+
+ We need to import the classes and functions that we will be using from the corresponding packages.
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ import os
+ import boto3
+ import json
+ from urllib.parse import quote_plus
+ from os.path import join, isfile, isdir
+ from urllib.request import urlretrieve
+ from anndata import read_h5ad
+ import scanpy as sc
+
+ from vitessce import (
+ VitessceWidget,
+ VitessceConfig,
+ Component as cm,
+ CoordinationType as ct,
+ AnnDataWrapper,
+ )
+ from vitessce.data_utils import (
+ optimize_adata,
+ VAR_CHUNK_SIZE,
+ )
+ return (
+ AnnDataWrapper,
+ VAR_CHUNK_SIZE,
+ VitessceConfig,
+ boto3,
+ cm,
+ isdir,
+ isfile,
+ join,
+ json,
+ optimize_adata,
+ os,
+ quote_plus,
+ read_h5ad,
+ urlretrieve,
+ )
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 2. Download and process data
+
+ For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17.
+ """
+ )
+ return
+
+
+@app.cell
+def _(isfile, join, os, read_h5ad, urlretrieve):
+ adata_filepath = join("data", "habib17.processed.h5ad")
+ if not isfile(adata_filepath):
+ os.makedirs("data", exist_ok=True)
+ urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)
+
+ adata = read_h5ad(adata_filepath)
+ top_dispersion = adata.var["dispersions_norm"][
+ sorted(
+ range(len(adata.var["dispersions_norm"])),
+ key=lambda k: adata.var["dispersions_norm"][k],
+ )[-51:][0]
+ ]
+ adata.var["top_highly_variable"] = (
+ adata.var["dispersions_norm"] > top_dispersion
+ )
+ return (adata,)
+
+
+@app.cell
+def _(VAR_CHUNK_SIZE, adata, isdir, join, optimize_adata):
+ zarr_filepath = join('data', 'habib17.processed.zarr')
+ if not isdir(zarr_filepath):
+ adata_1 = optimize_adata(adata, obs_cols=['CellType'], obsm_keys=['X_umap'], var_cols=['top_highly_variable'], optimize_X=True)
+ adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])
+ return (zarr_filepath,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 3. Create the Vitessce configuration
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ Set up the configuration by adding the views and datasets of interest.
+ """
+ )
+ return
+
+
+@app.cell
+def _(AnnDataWrapper, VitessceConfig, cm, zarr_filepath):
+ vc = VitessceConfig(schema_version="1.0.15", name='Habib et al', description='COVID-19 Healthy Donor Brain')
+ dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(
+ adata_path=zarr_filepath,
+ obs_embedding_paths=["obsm/X_umap"],
+ obs_embedding_names=["UMAP"],
+ obs_set_paths=["obs/CellType"],
+ obs_set_names=["Cell Type"],
+ obs_feature_matrix_path="X",
+ feature_filter_path="var/top_highly_variable"
+ ))
+ scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping="UMAP")
+ cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)
+ genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)
+ heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)
+ vc.layout((scatterplot | (cell_sets / genes)) / heatmap);
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 4. Create a `boto3` resource with S3 credentials
+ """
+ )
+ return
+
+
+@app.cell
+def _(boto3, os):
+ s3 = boto3.resource(
+ service_name='s3',
+ aws_access_key_id=os.environ['VITESSCE_S3_ACCESS_KEY_ID'],
+ aws_secret_access_key=os.environ['VITESSCE_S3_SECRET_ACCESS_KEY'],
+ )
+ return (s3,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 5. Upload files to S3
+
+ The `.export(to='S3')` method on the view config instance will upload all data objects to the specified bucket. Then, the processed view config will be returned as a `dict`, with the file URLs filled in, pointing to the S3 bucket files. For more information about configuring the S3 bucket so that files are accessible over the internet, visit the "Hosting Data" page of our core documentation site.
+ """
+ )
+ return
+
+
+@app.cell
+def _(s3, vc):
+ config_dict = vc.export(to='S3', s3=s3, bucket_name='vitessce-export-examples', prefix='test')
+ return (config_dict,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 6. View on vitessce.io
+
+ The returned view config dict can be converted to a URL, and can be used to share the interactive visualizations with colleagues.
+ """
+ )
+ return
+
+
+@app.cell
+def _(config_dict, json, quote_plus):
+ vitessce_url = "http://vitessce.io/?url=data:," + quote_plus(json.dumps(config_dict))
+ import webbrowser
+ webbrowser.open(vitessce_url)
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/page_mode_comparative.ipynb b/docs/notebooks/page_mode_comparative.ipynb
deleted file mode 100644
index 49607f86..00000000
--- a/docs/notebooks/page_mode_comparative.ipynb
+++ /dev/null
@@ -1,490 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Visualization of ComparativeData object"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Configure Vitessce"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from oxc_py import transform\n",
- "from vitessce import VitessceConfig, hconcat, vconcat"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Configure the data and views"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "# Reference: https://github.com/vitessce/vitessce/blob/main/examples/configs/src/view-configs/kpmp-premiere.js"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "base_url = 'https://storage.googleapis.com/vitessce-demo-data/kpmp-jan-2025/kpmp_premiere_20250330.adata.zarr'"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.17\", name='Lake et al.')\n",
- "\n",
- "dataset = vc.add_dataset('lake_et_al').add_file(\n",
- " file_type='comparisonMetadata.anndata.zarr',\n",
- " url=base_url,\n",
- " options={\n",
- " \"path\": 'uns/comparison_metadata',\n",
- " },\n",
- " coordination_values={\n",
- " \"obsType\": 'cell',\n",
- " \"sampleType\": 'sample',\n",
- " },\n",
- ").add_file(\n",
- " file_type='comparativeFeatureStats.anndata.zarr',\n",
- " url=base_url,\n",
- " options= {\n",
- " \"metadataPath\": 'uns/comparison_metadata',\n",
- " \"indexColumn\": 'names',\n",
- " \"pValueColumn\": 'pvals_adj',\n",
- " \"foldChangeColumn\": 'logfoldchanges',\n",
- " \"pValueAdjusted\": True,\n",
- " \"foldChangeTransformation\": 'log2',\n",
- " },\n",
- " coordination_values={\n",
- " \"obsType\": 'cell',\n",
- " \"sampleType\": 'sample',\n",
- " \"featureType\": 'gene',\n",
- " },\n",
- ").add_file(\n",
- " file_type= 'comparativeObsSetStats.anndata.zarr',\n",
- " url= base_url,\n",
- " options= {\n",
- " \"metadataPath\": 'uns/comparison_metadata',\n",
- " \"indexColumn\": 'Cell Type',\n",
- " \"interceptExpectedSampleColumn\": 'Expected Sample_intercept',\n",
- " \"effectExpectedSampleColumn\": 'Expected Sample_effect',\n",
- " \"foldChangeColumn\": 'log2-fold change',\n",
- " \"foldChangeTransformation\": 'log2',\n",
- " \"isCredibleEffectColumn\": 'is_credible_effect',\n",
- " },\n",
- " coordination_values= {\n",
- " \"obsType\": 'cell',\n",
- " \"sampleType\": 'sample',\n",
- " },\n",
- ").add_file(\n",
- " file_type='comparativeFeatureSetStats.anndata.zarr',\n",
- " url=base_url,\n",
- " options= {\n",
- " \"metadataPath\": 'uns/comparison_metadata',\n",
- " \"indexColumn\": 'pathway_name',\n",
- " \"termColumn\": 'pathway_term',\n",
- " \"pValueColumn\": 'pvals_adj',\n",
- " \"pValueAdjusted\": True,\n",
- " \"analysisType\": 'pertpy_hypergeometric',\n",
- " \"featureSetLibrary\": 'Reactome_2022',\n",
- " },\n",
- " coordination_values= {\n",
- " \"obsType\": 'cell',\n",
- " \"featureType\": 'gene',\n",
- " \"sampleType\": 'sample',\n",
- " },\n",
- ").add_file(\n",
- " file_type='anndata.zarr',\n",
- " url=base_url,\n",
- " coordination_values={\n",
- " \"obsType\": 'cell',\n",
- " \"featureType\": 'gene',\n",
- " \"featureValueType\": 'expression',\n",
- " \"sampleType\": 'sample',\n",
- " },\n",
- " options={\n",
- " \"obsFeatureMatrix\": {\n",
- " \"path\": 'layers/pearson_residuals',\n",
- " },\n",
- " \"obsEmbedding\": [\n",
- " {\n",
- " \"path\": 'obsm/X_densmap',\n",
- " \"embeddingType\": 'densMAP',\n",
- " },\n",
- " ],\n",
- " \"obsSets\": [\n",
- " {\n",
- " \"name\": 'Cell Type',\n",
- " \"path\": 'obs/cell_type',\n",
- " },\n",
- " {\n",
- " \"name\": 'Subclass L1',\n",
- " \"path\": 'obs/subclass_l1',\n",
- " },\n",
- " {\n",
- " \"name\": 'Subclass L2',\n",
- " \"path\": 'obs/subclass_l2',\n",
- " },\n",
- " {\n",
- " \"name\": 'Donor ID',\n",
- " \"path\": 'obs/donor_id',\n",
- " },\n",
- " ],\n",
- " \"sampleEdges\": {\n",
- " \"path\": 'obs/SampleID',\n",
- " },\n",
- " },\n",
- ").add_file(\n",
- " file_type='sampleSets.anndata.zarr',\n",
- " url=f\"{base_url}/uns/__all__.samples\",\n",
- " options={\n",
- " \"sampleSets\": [\n",
- " {\n",
- " \"name\": 'Disease Type',\n",
- " \"path\": 'diseasetype',\n",
- " },\n",
- " {\n",
- " \"name\": 'Adjudicated Category',\n",
- " \"path\": 'AdjudicatedCategory',\n",
- " },\n",
- " {\n",
- " \"name\": 'Enrollment Category',\n",
- " \"path\": 'EnrollmentCategory',\n",
- " },\n",
- " ],\n",
- " },\n",
- " coordination_values= {\n",
- " \"sampleType\": 'sample',\n",
- " },\n",
- ")\n",
- "\n",
- "biomarkerSelect = vc.add_view('biomarkerSelect', dataset=dataset, uid='biomarker-select')\n",
- "comparativeHeading = vc.add_view('comparativeHeading', dataset=dataset, uid='comparative-heading')\n",
- "dualScatterplot = vc.add_view('dualScatterplot', dataset=dataset, uid='scatterplot')\n",
- "obsSets = vc.add_view('obsSets', dataset=dataset, uid='cell-sets')\n",
- "sampleSets = vc.add_view('sampleSetPairManager', dataset=dataset, uid='sample-sets')\n",
- "obsSetSizes = vc.add_view('obsSetSizes', dataset=dataset)\n",
- "featureList = vc.add_view('featureList', dataset=dataset)\n",
- "violinPlots = vc.add_view('obsSetFeatureValueDistribution', dataset=dataset, uid='violin-plot')\n",
- "dotPlot = vc.add_view('dotPlot', dataset=dataset, uid='dot-plot')\n",
- "treemap = vc.add_view('treemap', dataset=dataset, uid='treemap')\n",
- "volcanoPlot = vc.add_view('volcanoPlot', dataset=dataset, uid='volcano-plot')\n",
- "volcanoPlotTable = vc.add_view('featureStatsTable', dataset=dataset, uid='volcano-plot-table')\n",
- "obsSetCompositionBarPlot = vc.add_view('obsSetCompositionBarPlot', dataset=dataset, uid='sccoda-plot')\n",
- "featureSetEnrichmentBarPlot = vc.add_view('featureSetEnrichmentBarPlot', dataset=dataset, uid='pathways-plot')\n",
- "\n",
- "[sampleSetScope_caseControl] = vc.add_coordination('sampleSetSelection')\n",
- "sampleSetScope_caseControl.set_value([['Disease Type', 'CKD'], ['Disease Type', 'Reference']])\n",
- "\n",
- "[featureSelectionScope] = vc.add_coordination('featureSelection')\n",
- "featureSelectionScope.set_value(['UMOD', 'NPHS2'])\n",
- "\n",
- "vc.link_views_by_dict([dualScatterplot], {\n",
- " \"embeddingType\": 'densMAP',\n",
- " \"embeddingContoursVisible\": True,\n",
- " \"embeddingPointsVisible\": False,\n",
- " \"embeddingObsSetLabelsVisible\": True,\n",
- "}, meta=False);\n",
- "\n",
- "\n",
- "vc.link_views([biomarkerSelect, dualScatterplot, obsSets, obsSetSizes, featureList, violinPlots, dotPlot, treemap, volcanoPlot, volcanoPlotTable, comparativeHeading, obsSetCompositionBarPlot, featureSetEnrichmentBarPlot, sampleSets], ['sampleType'], ['sample'])\n",
- "\n",
- "vc.link_views_by_dict([biomarkerSelect, dualScatterplot, obsSets, obsSetSizes, featureList, violinPlots, dotPlot, treemap, volcanoPlot, volcanoPlotTable, comparativeHeading, obsSetCompositionBarPlot, featureSetEnrichmentBarPlot, sampleSets], {\n",
- " \"sampleSetSelection\": sampleSetScope_caseControl,\n",
- " \"featureSelection\": featureSelectionScope,\n",
- "}, meta=False)\n",
- "\n",
- "vc.link_views_by_dict([dualScatterplot, violinPlots, featureList, dotPlot], {\n",
- " # \"featureSelection\": ['UMOD', 'NPHS2'], // , 'ENSG00000074803', 'ENSG00000164825'],\n",
- " \"obsColorEncoding\": 'geneSelection',\n",
- " \"featureValueColormap\": 'jet',\n",
- " \"featureValueColormapRange\": [0, 0.25],\n",
- " \"featureAggregationStrategy\": None,\n",
- "}, meta=False)\n",
- "\n",
- "vc.layout(hconcat(\n",
- " vconcat(dualScatterplot, biomarkerSelect, comparativeHeading, obsSets, obsSetSizes, featureList),\n",
- " vconcat(treemap, featureSetEnrichmentBarPlot, violinPlots, dotPlot, obsSetCompositionBarPlot, sampleSets),\n",
- " volcanoPlotTable,\n",
- "));"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "tags": []
- },
- "source": [
- "## Define the page layout"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "PAGE_ESM = transform(\"\"\"\n",
- "import clsx from \"https://unpkg.com/clsx@1.1.1/dist/clsx.m.js\";\n",
- "\n",
- "function createPage(utilsForPages) {\n",
- " const {\n",
- " React,\n",
- " usePageModeView,\n",
- " } = utilsForPages;\n",
- " function PageComponent(props) {\n",
- " const BiomarkerSelect = usePageModeView('biomarker-select');\n",
- " const ComparativeHeading = usePageModeView('comparative-heading');\n",
- " const CellSets = usePageModeView('cell-sets');\n",
- " const SampleSets = usePageModeView('sample-sets');\n",
- " const DualScatterplot = usePageModeView('scatterplot');\n",
- " const ViolinPlot = usePageModeView('violin-plot');\n",
- " const DotPlot = usePageModeView('dot-plot');\n",
- " const Treemap = usePageModeView('treemap');\n",
- " const VolcanoPlot = usePageModeView('volcano-plot');\n",
- " const VolcanoPlotTable = usePageModeView('volcano-plot-table');\n",
- " const SccodaPlot = usePageModeView('sccoda-plot');\n",
- " const PathwaysPlot = usePageModeView('pathways-plot');\n",
- "\n",
- " \n",
- " return (\n",
- " <>\n",
- " \n",
- "
\n",
- "
\n",
- "
Comparative visualization of single-cell atlas data \n",
- " \n",
- " \n",
- "
\n",
- "\n",
- " \n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "
\n",
- "
This view contains a treemap visualization to communicate cell type composition in each of the selected sample groups.
\n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "
\n",
- "
\n",
- "
This view displays the results of a cell type composition analysis performed using the ScCODA algorithm (Büttner et al. 2021). Cell types with significantly different composition between the selected sample groups are displayed opaque while not-signficant results are displayed with transparent bars. The single outlined bar denotes the automatically-selected reference cell type.
\n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "
\n",
- "
\n",
- "
This view displays differential expression test results, performed using the rank_genes_groups function from Scanpy (Wolf et al. 2018) with method "wilcoxon". The arrows on the bottom left and bottom right denote the direction of the effect. Click a point in the plot to select the corresponding gene. Note that differential expression tests have been run for each cell type separately, so the each gene can appear multiple times (once per cell type). If there are too many points on the plot, cell types can be selected to filter the points.
\n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "
\n",
- "
\n",
- "
This view displays differential expression test results in tabular form. Click a row in the table to select the corresponding gene.
\n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "
\n",
- "
\n",
- "
This view displays gene set enrichment test results based on the differential expression results. Gene set enrichment tests have been performed using Reactome 2022 pathway gene sets from BlitzGSEA (Lachmann et al. 2022) via the hypergeometric function of Pertpy (Heumos et al. 2024).
\n",
- "
\n",
- "
\n",
- "
\n",
- "
\n",
- "
\n",
- "
This view contains contour scatterplots which display the results of a density-preserving dimensionality reduction (Narayan et al. 2021). Contour opacities correspond to the shown percentile thresholds.
\n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "
\n",
- "
\n",
- "
This dot plot view displays gene expression values per cell type and sample group for the selected biomarkers.
\n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "
\n",
- "
\n",
- "
This violin plot view displays gene expression values per cell type and sample group for the selected biomarker.
\n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- " {/*
Neighborhood-level representations \n",
- "
TODO \n",
- "
Segmented instance-level representations \n",
- "
TODO \n",
- "
Image-level representations \n",
- "
TODO \n",
- "
Participant-level representations \n",
- "
TODO */}\n",
- "
\n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "\n",
- "
\n",
- " >\n",
- " );\n",
- " }\n",
- " return PageComponent;\n",
- "}\n",
- "export default { createPage };\n",
- "\"\"\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Render page as widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget(page_esm=PAGE_ESM, page_mode=True, height=4700, prevent_scroll=False)\n",
- "vw"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.14"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/page_mode_comparative.mo.py b/docs/notebooks/page_mode_comparative.mo.py
new file mode 100644
index 00000000..0f350132
--- /dev/null
+++ b/docs/notebooks/page_mode_comparative.mo.py
@@ -0,0 +1,461 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Visualization of ComparativeData object
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Configure Vitessce
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ from oxc_py import transform
+ from vitessce import VitessceConfig, hconcat, vconcat
+ return VitessceConfig, hconcat, transform, vconcat
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Configure the data and views
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ # Reference: https://github.com/vitessce/vitessce/blob/main/examples/configs/src/view-configs/kpmp-premiere.js
+ return
+
+
+@app.cell
+def _():
+ base_url = 'https://storage.googleapis.com/vitessce-demo-data/kpmp-jan-2025/kpmp_premiere_20250330.adata.zarr'
+ return (base_url,)
+
+
+@app.cell
+def _(VitessceConfig, base_url, hconcat, vconcat):
+ vc = VitessceConfig(schema_version="1.0.17", name='Lake et al.')
+
+ dataset = vc.add_dataset('lake_et_al').add_file(
+ file_type='comparisonMetadata.anndata.zarr',
+ url=base_url,
+ options={
+ "path": 'uns/comparison_metadata',
+ },
+ coordination_values={
+ "obsType": 'cell',
+ "sampleType": 'sample',
+ },
+ ).add_file(
+ file_type='comparativeFeatureStats.anndata.zarr',
+ url=base_url,
+ options= {
+ "metadataPath": 'uns/comparison_metadata',
+ "indexColumn": 'names',
+ "pValueColumn": 'pvals_adj',
+ "foldChangeColumn": 'logfoldchanges',
+ "pValueAdjusted": True,
+ "foldChangeTransformation": 'log2',
+ },
+ coordination_values={
+ "obsType": 'cell',
+ "sampleType": 'sample',
+ "featureType": 'gene',
+ },
+ ).add_file(
+ file_type= 'comparativeObsSetStats.anndata.zarr',
+ url= base_url,
+ options= {
+ "metadataPath": 'uns/comparison_metadata',
+ "indexColumn": 'Cell Type',
+ "interceptExpectedSampleColumn": 'Expected Sample_intercept',
+ "effectExpectedSampleColumn": 'Expected Sample_effect',
+ "foldChangeColumn": 'log2-fold change',
+ "foldChangeTransformation": 'log2',
+ "isCredibleEffectColumn": 'is_credible_effect',
+ },
+ coordination_values= {
+ "obsType": 'cell',
+ "sampleType": 'sample',
+ },
+ ).add_file(
+ file_type='comparativeFeatureSetStats.anndata.zarr',
+ url=base_url,
+ options= {
+ "metadataPath": 'uns/comparison_metadata',
+ "indexColumn": 'pathway_name',
+ "termColumn": 'pathway_term',
+ "pValueColumn": 'pvals_adj',
+ "pValueAdjusted": True,
+ "analysisType": 'pertpy_hypergeometric',
+ "featureSetLibrary": 'Reactome_2022',
+ },
+ coordination_values= {
+ "obsType": 'cell',
+ "featureType": 'gene',
+ "sampleType": 'sample',
+ },
+ ).add_file(
+ file_type='anndata.zarr',
+ url=base_url,
+ coordination_values={
+ "obsType": 'cell',
+ "featureType": 'gene',
+ "featureValueType": 'expression',
+ "sampleType": 'sample',
+ },
+ options={
+ "obsFeatureMatrix": {
+ "path": 'layers/pearson_residuals',
+ },
+ "obsEmbedding": [
+ {
+ "path": 'obsm/X_densmap',
+ "embeddingType": 'densMAP',
+ },
+ ],
+ "obsSets": [
+ {
+ "name": 'Cell Type',
+ "path": 'obs/cell_type',
+ },
+ {
+ "name": 'Subclass L1',
+ "path": 'obs/subclass_l1',
+ },
+ {
+ "name": 'Subclass L2',
+ "path": 'obs/subclass_l2',
+ },
+ {
+ "name": 'Donor ID',
+ "path": 'obs/donor_id',
+ },
+ ],
+ "sampleEdges": {
+ "path": 'obs/SampleID',
+ },
+ },
+ ).add_file(
+ file_type='sampleSets.anndata.zarr',
+ url=f"{base_url}/uns/__all__.samples",
+ options={
+ "sampleSets": [
+ {
+ "name": 'Disease Type',
+ "path": 'diseasetype',
+ },
+ {
+ "name": 'Adjudicated Category',
+ "path": 'AdjudicatedCategory',
+ },
+ {
+ "name": 'Enrollment Category',
+ "path": 'EnrollmentCategory',
+ },
+ ],
+ },
+ coordination_values= {
+ "sampleType": 'sample',
+ },
+ )
+
+ biomarkerSelect = vc.add_view('biomarkerSelect', dataset=dataset, uid='biomarker-select')
+ comparativeHeading = vc.add_view('comparativeHeading', dataset=dataset, uid='comparative-heading')
+ dualScatterplot = vc.add_view('dualScatterplot', dataset=dataset, uid='scatterplot')
+ obsSets = vc.add_view('obsSets', dataset=dataset, uid='cell-sets')
+ sampleSets = vc.add_view('sampleSetPairManager', dataset=dataset, uid='sample-sets')
+ obsSetSizes = vc.add_view('obsSetSizes', dataset=dataset)
+ featureList = vc.add_view('featureList', dataset=dataset)
+ violinPlots = vc.add_view('obsSetFeatureValueDistribution', dataset=dataset, uid='violin-plot')
+ dotPlot = vc.add_view('dotPlot', dataset=dataset, uid='dot-plot')
+ treemap = vc.add_view('treemap', dataset=dataset, uid='treemap')
+ volcanoPlot = vc.add_view('volcanoPlot', dataset=dataset, uid='volcano-plot')
+ volcanoPlotTable = vc.add_view('featureStatsTable', dataset=dataset, uid='volcano-plot-table')
+ obsSetCompositionBarPlot = vc.add_view('obsSetCompositionBarPlot', dataset=dataset, uid='sccoda-plot')
+ featureSetEnrichmentBarPlot = vc.add_view('featureSetEnrichmentBarPlot', dataset=dataset, uid='pathways-plot')
+
+ [sampleSetScope_caseControl] = vc.add_coordination('sampleSetSelection')
+ sampleSetScope_caseControl.set_value([['Disease Type', 'CKD'], ['Disease Type', 'Reference']])
+
+ [featureSelectionScope] = vc.add_coordination('featureSelection')
+ featureSelectionScope.set_value(['UMOD', 'NPHS2'])
+
+ vc.link_views_by_dict([dualScatterplot], {
+ "embeddingType": 'densMAP',
+ "embeddingContoursVisible": True,
+ "embeddingPointsVisible": False,
+ "embeddingObsSetLabelsVisible": True,
+ }, meta=False);
+
+
+ vc.link_views([biomarkerSelect, dualScatterplot, obsSets, obsSetSizes, featureList, violinPlots, dotPlot, treemap, volcanoPlot, volcanoPlotTable, comparativeHeading, obsSetCompositionBarPlot, featureSetEnrichmentBarPlot, sampleSets], ['sampleType'], ['sample'])
+
+ vc.link_views_by_dict([biomarkerSelect, dualScatterplot, obsSets, obsSetSizes, featureList, violinPlots, dotPlot, treemap, volcanoPlot, volcanoPlotTable, comparativeHeading, obsSetCompositionBarPlot, featureSetEnrichmentBarPlot, sampleSets], {
+ "sampleSetSelection": sampleSetScope_caseControl,
+ "featureSelection": featureSelectionScope,
+ }, meta=False)
+
+ vc.link_views_by_dict([dualScatterplot, violinPlots, featureList, dotPlot], {
+ # "featureSelection": ['UMOD', 'NPHS2'], // , 'ENSG00000074803', 'ENSG00000164825'],
+ "obsColorEncoding": 'geneSelection',
+ "featureValueColormap": 'jet',
+ "featureValueColormapRange": [0, 0.25],
+ "featureAggregationStrategy": None,
+ }, meta=False)
+
+ vc.layout(hconcat(
+ vconcat(dualScatterplot, biomarkerSelect, comparativeHeading, obsSets, obsSetSizes, featureList),
+ vconcat(treemap, featureSetEnrichmentBarPlot, violinPlots, dotPlot, obsSetCompositionBarPlot, sampleSets),
+ volcanoPlotTable,
+ ));
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Define the page layout
+ """
+ )
+ return
+
+
+@app.cell
+def _(transform):
+ PAGE_ESM = transform("""
+ import clsx from "https://unpkg.com/clsx@1.1.1/dist/clsx.m.js";
+
+ function createPage(utilsForPages) {
+ const {
+ React,
+ usePageModeView,
+ } = utilsForPages;
+ function PageComponent(props) {
+ const BiomarkerSelect = usePageModeView('biomarker-select');
+ const ComparativeHeading = usePageModeView('comparative-heading');
+ const CellSets = usePageModeView('cell-sets');
+ const SampleSets = usePageModeView('sample-sets');
+ const DualScatterplot = usePageModeView('scatterplot');
+ const ViolinPlot = usePageModeView('violin-plot');
+ const DotPlot = usePageModeView('dot-plot');
+ const Treemap = usePageModeView('treemap');
+ const VolcanoPlot = usePageModeView('volcano-plot');
+ const VolcanoPlotTable = usePageModeView('volcano-plot-table');
+ const SccodaPlot = usePageModeView('sccoda-plot');
+ const PathwaysPlot = usePageModeView('pathways-plot');
+
+
+ return (
+ <>
+
+
+
+
Comparative visualization of single-cell atlas data
+
+
+
+
+
+
+
+
+
+
+
+
This view contains a treemap visualization to communicate cell type composition in each of the selected sample groups.
+
+
+
+
+
+
+
+
This view displays the results of a cell type composition analysis performed using the ScCODA algorithm (Büttner et al. 2021). Cell types with significantly different composition between the selected sample groups are displayed opaque while not-signficant results are displayed with transparent bars. The single outlined bar denotes the automatically-selected reference cell type.
+
+
+
+
+
+
+
+
This view displays differential expression test results, performed using the rank_genes_groups function from Scanpy (Wolf et al. 2018) with method "wilcoxon". The arrows on the bottom left and bottom right denote the direction of the effect. Click a point in the plot to select the corresponding gene. Note that differential expression tests have been run for each cell type separately, so the each gene can appear multiple times (once per cell type). If there are too many points on the plot, cell types can be selected to filter the points.
+
+
+
+
+
+
+
+
This view displays differential expression test results in tabular form. Click a row in the table to select the corresponding gene.
+
+
+
+
+
+
+
+
This view displays gene set enrichment test results based on the differential expression results. Gene set enrichment tests have been performed using Reactome 2022 pathway gene sets from BlitzGSEA (Lachmann et al. 2022) via the hypergeometric function of Pertpy (Heumos et al. 2024).
+
+
+
+
+
+
This view contains contour scatterplots which display the results of a density-preserving dimensionality reduction (Narayan et al. 2021). Contour opacities correspond to the shown percentile thresholds.
+
+
+
+
+
+
+
+
This dot plot view displays gene expression values per cell type and sample group for the selected biomarkers.
+
+
+
+
+
+
+
+
This violin plot view displays gene expression values per cell type and sample group for the selected biomarker.
+
+
+
+
+
+ {/*
Neighborhood-level representations
+
TODO
+
Segmented instance-level representations
+
TODO
+
Image-level representations
+
TODO
+
Participant-level representations
+
TODO */}
+
+
+
+
+ >
+ );
+ }
+ return PageComponent;
+ }
+ export default { createPage };
+ """)
+ return (PAGE_ESM,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Render page as widget
+ """
+ )
+ return
+
+
+@app.cell
+def _(PAGE_ESM, vc):
+ vw = vc.widget(page_esm=PAGE_ESM, page_mode=True, height=4700, prevent_scroll=False)
+ vw
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/page_mode_example.ipynb b/docs/notebooks/page_mode_example.ipynb
deleted file mode 100644
index 031111c8..00000000
--- a/docs/notebooks/page_mode_example.ipynb
+++ /dev/null
@@ -1,197 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Page mode example"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Configure Vitessce"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " AnnDataWrapper,\n",
- " CsvWrapper,\n",
- ")\n",
- "from oxc_py import transform"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Configure the data and views"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "url = 'https://storage.googleapis.com/vitessce-demo-data/anndata-test/pbmc3k_processed.zarr'"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.17\", name='PBMC Reference')\n",
- "dataset = vc.add_dataset(name='PBMC 3k').add_object(\n",
- " AnnDataWrapper(\n",
- " adata_url=url,\n",
- " obs_set_paths=[\"obs/louvain\"],\n",
- " obs_set_names=[\"Louvain\"],\n",
- " obs_embedding_paths=[\"obsm/X_umap\", \"obsm/X_pca\"],\n",
- " obs_embedding_names=[\"UMAP\", \"PCA\"],\n",
- " obs_feature_matrix_path=\"X\"\n",
- " )\n",
- ")\n",
- "\n",
- "umap = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\", uid=\"scatterplot-umap\")\n",
- "pca = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"PCA\", uid=\"scatterplot-pca\")\n",
- "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset, uid=\"cell-sets\")\n",
- "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset, uid=\"gene-list\")\n",
- "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset, uid=\"heatmap\")\n",
- "\n",
- "vc.layout((umap / pca) | ((cell_sets | genes) / heatmap));"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "tags": []
- },
- "source": [
- "## Define the page layout"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "PAGE_ESM = transform(\"\"\"\n",
- "function createPage(utilsForPages) {\n",
- " const {\n",
- " React,\n",
- " usePageModeView,\n",
- " } = utilsForPages;\n",
- " function PageComponent(props) {\n",
- " const ScatterplotUmap = usePageModeView('scatterplot-umap');\n",
- " const ScatterplotPca = usePageModeView('scatterplot-pca');\n",
- " const CellSets = usePageModeView('cell-sets');\n",
- " const GeneList = usePageModeView('gene-list');\n",
- " const Heatmap = usePageModeView('heatmap');\n",
- " \n",
- " return (\n",
- " <>\n",
- " \n",
- " \n",
- "
\n",
- "
This is an arbitrary HTML element with custom CSS \n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "
Another HTML element \n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "
\n",
- " \n",
- " \n",
- "
\n",
- "
\n",
- "\n",
- " >\n",
- " );\n",
- " }\n",
- " return PageComponent;\n",
- "}\n",
- "export default { createPage };\n",
- "\"\"\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Render page as widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget(page_esm=PAGE_ESM, page_mode=True, height=1100)\n",
- "vw"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.14"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/page_mode_example.mo.py b/docs/notebooks/page_mode_example.mo.py
new file mode 100644
index 00000000..0f117780
--- /dev/null
+++ b/docs/notebooks/page_mode_example.mo.py
@@ -0,0 +1,185 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Page mode example
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Configure Vitessce
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ from vitessce import (
+ VitessceConfig,
+ Component as cm,
+ CoordinationType as ct,
+ AnnDataWrapper,
+ CsvWrapper,
+ )
+ from oxc_py import transform
+ return AnnDataWrapper, VitessceConfig, cm, transform
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Configure the data and views
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ url = 'https://storage.googleapis.com/vitessce-demo-data/anndata-test/pbmc3k_processed.zarr'
+ return (url,)
+
+
+@app.cell
+def _(AnnDataWrapper, VitessceConfig, cm, url):
+ vc = VitessceConfig(schema_version="1.0.17", name='PBMC Reference')
+ dataset = vc.add_dataset(name='PBMC 3k').add_object(
+ AnnDataWrapper(
+ adata_url=url,
+ obs_set_paths=["obs/louvain"],
+ obs_set_names=["Louvain"],
+ obs_embedding_paths=["obsm/X_umap", "obsm/X_pca"],
+ obs_embedding_names=["UMAP", "PCA"],
+ obs_feature_matrix_path="X"
+ )
+ )
+
+ umap = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping="UMAP", uid="scatterplot-umap")
+ pca = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping="PCA", uid="scatterplot-pca")
+ cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset, uid="cell-sets")
+ genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset, uid="gene-list")
+ heatmap = vc.add_view(cm.HEATMAP, dataset=dataset, uid="heatmap")
+
+ vc.layout((umap / pca) | ((cell_sets | genes) / heatmap));
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Define the page layout
+ """
+ )
+ return
+
+
+@app.cell
+def _(transform):
+ PAGE_ESM = transform("""
+ function createPage(utilsForPages) {
+ const {
+ React,
+ usePageModeView,
+ } = utilsForPages;
+ function PageComponent(props) {
+ const ScatterplotUmap = usePageModeView('scatterplot-umap');
+ const ScatterplotPca = usePageModeView('scatterplot-pca');
+ const CellSets = usePageModeView('cell-sets');
+ const GeneList = usePageModeView('gene-list');
+ const Heatmap = usePageModeView('heatmap');
+
+ return (
+ <>
+
+
+
+
This is an arbitrary HTML element with custom CSS
+
+
Another HTML element
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+ }
+ return PageComponent;
+ }
+ export default { createPage };
+ """)
+ return (PAGE_ESM,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Render page as widget
+ """
+ )
+ return
+
+
+@app.cell
+def _(PAGE_ESM, vc):
+ vw = vc.widget(page_esm=PAGE_ESM, page_mode=True, height=1100)
+ vw
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/spatial_data.ipynb b/docs/notebooks/spatial_data.ipynb
deleted file mode 100644
index 1a6eb831..00000000
--- a/docs/notebooks/spatial_data.ipynb
+++ /dev/null
@@ -1,164 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Visualization of a SpatialData object"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Import dependencies\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join, isfile, isdir\n",
- "from urllib.request import urlretrieve\n",
- "import zipfile\n",
- "\n",
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " ViewType as vt,\n",
- " CoordinationType as ct,\n",
- " CoordinationLevel as CL,\n",
- " SpatialDataWrapper,\n",
- " get_initial_coordination_scope_prefix\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "data_dir = \"data\"\n",
- "zip_filepath = join(data_dir, \"visium.spatialdata.zarr.zip\")\n",
- "spatialdata_filepath = join(data_dir, \"visium.spatialdata.zarr\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "if not isdir(spatialdata_filepath):\n",
- " if not isfile(zip_filepath):\n",
- " os.makedirs(data_dir, exist_ok=True)\n",
- " urlretrieve('https://s3.embl.de/spatialdata/spatialdata-sandbox/visium_associated_xenium_io.zip', zip_filepath)\n",
- " with zipfile.ZipFile(zip_filepath,\"r\") as zip_ref:\n",
- " zip_ref.extractall(data_dir)\n",
- " os.rename(join(data_dir, \"data.zarr\"), spatialdata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Configure Vitessce\n",
- "\n",
- "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(\n",
- " schema_version=\"1.0.18\",\n",
- " name='Visium SpatialData Demo (visium_associated_xenium_io)',\n",
- ")\n",
- "# Add data to the configuration:\n",
- "wrapper = SpatialDataWrapper(\n",
- " sdata_path=spatialdata_filepath,\n",
- " # The following paths are relative to the root of the SpatialData zarr store on-disk.\n",
- " image_path=\"images/CytAssist_FFPE_Human_Breast_Cancer_full_image\",\n",
- " table_path=\"tables/table\",\n",
- " obs_feature_matrix_path=\"tables/table/X\",\n",
- " obs_spots_path=\"shapes/CytAssist_FFPE_Human_Breast_Cancer\",\n",
- " region=\"CytAssist_FFPE_Human_Breast_Cancer\",\n",
- " coordinate_system=\"global\",\n",
- " coordination_values={\n",
- " # The following tells Vitessce to consider each observation as a \"spot\"\n",
- " \"obsType\": \"spot\",\n",
- " }\n",
- ")\n",
- "dataset = vc.add_dataset(name='Breast Cancer Visium').add_object(wrapper)\n",
- "\n",
- "# Add views (visualizations) to the configuration:\n",
- "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
- "feature_list = vc.add_view(vt.FEATURE_LIST, dataset=dataset)\n",
- "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " 'imageLayer': CL([{\n",
- " 'photometricInterpretation': 'RGB',\n",
- " }]),\n",
- "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
- "obs_sets = vc.add_view(vt.OBS_SETS, dataset=dataset)\n",
- "vc.link_views([spatial, layer_controller, feature_list, obs_sets], ['obsType'], [wrapper.obs_type_label])\n",
- "\n",
- "# Layout the views\n",
- "vc.layout(spatial | (feature_list / layer_controller / obs_sets));"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Render the widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.14"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/spatial_data.mo.py b/docs/notebooks/spatial_data.mo.py
new file mode 100644
index 00000000..7b0cc4bb
--- /dev/null
+++ b/docs/notebooks/spatial_data.mo.py
@@ -0,0 +1,181 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Visualization of a SpatialData object
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Import dependencies
+
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ import os
+ from os.path import join, isfile, isdir
+ from urllib.request import urlretrieve
+ import zipfile
+
+ from vitessce import (
+ VitessceConfig,
+ ViewType as vt,
+ CoordinationType as ct,
+ CoordinationLevel as CL,
+ SpatialDataWrapper,
+ get_initial_coordination_scope_prefix
+ )
+ return (
+ CL,
+ SpatialDataWrapper,
+ VitessceConfig,
+ get_initial_coordination_scope_prefix,
+ isdir,
+ isfile,
+ join,
+ os,
+ urlretrieve,
+ vt,
+ zipfile,
+ )
+
+
+@app.cell
+def _(join):
+ data_dir = "data"
+ zip_filepath = join(data_dir, "visium.spatialdata.zarr.zip")
+ spatialdata_filepath = join(data_dir, "visium.spatialdata.zarr")
+ return data_dir, spatialdata_filepath, zip_filepath
+
+
+@app.cell
+def _(
+ data_dir,
+ isdir,
+ isfile,
+ join,
+ os,
+ spatialdata_filepath,
+ urlretrieve,
+ zip_filepath,
+ zipfile,
+):
+ if not isdir(spatialdata_filepath):
+ if not isfile(zip_filepath):
+ os.makedirs(data_dir, exist_ok=True)
+ urlretrieve('https://s3.embl.de/spatialdata/spatialdata-sandbox/visium_associated_xenium_io.zip', zip_filepath)
+ with zipfile.ZipFile(zip_filepath,"r") as zip_ref:
+ zip_ref.extractall(data_dir)
+ os.rename(join(data_dir, "data.zarr"), spatialdata_filepath)
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Configure Vitessce
+
+ Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views.
+ """
+ )
+ return
+
+
+@app.cell
+def _(
+ CL,
+ SpatialDataWrapper,
+ VitessceConfig,
+ get_initial_coordination_scope_prefix,
+ spatialdata_filepath,
+ vt,
+):
+ vc = VitessceConfig(
+ schema_version="1.0.18",
+ name='Visium SpatialData Demo (visium_associated_xenium_io)',
+ )
+ # Add data to the configuration:
+ wrapper = SpatialDataWrapper(
+ sdata_path=spatialdata_filepath,
+ # The following paths are relative to the root of the SpatialData zarr store on-disk.
+ image_path="images/CytAssist_FFPE_Human_Breast_Cancer_full_image",
+ table_path="tables/table",
+ obs_feature_matrix_path="tables/table/X",
+ obs_spots_path="shapes/CytAssist_FFPE_Human_Breast_Cancer",
+ region="CytAssist_FFPE_Human_Breast_Cancer",
+ coordinate_system="global",
+ coordination_values={
+ # The following tells Vitessce to consider each observation as a "spot"
+ "obsType": "spot",
+ }
+ )
+ dataset = vc.add_dataset(name='Breast Cancer Visium').add_object(wrapper)
+
+ # Add views (visualizations) to the configuration:
+ spatial = vc.add_view("spatialBeta", dataset=dataset)
+ feature_list = vc.add_view(vt.FEATURE_LIST, dataset=dataset)
+ layer_controller = vc.add_view("layerControllerBeta", dataset=dataset)
+ vc.link_views_by_dict([spatial, layer_controller], {
+ 'imageLayer': CL([{
+ 'photometricInterpretation': 'RGB',
+ }]),
+ }, scope_prefix=get_initial_coordination_scope_prefix("A", "image"))
+ obs_sets = vc.add_view(vt.OBS_SETS, dataset=dataset)
+ vc.link_views([spatial, layer_controller, feature_list, obs_sets], ['obsType'], [wrapper.obs_type_label])
+
+ # Layout the views
+ vc.layout(spatial | (feature_list / layer_controller / obs_sets));
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### Render the widget
+ """
+ )
+ return
+
+
+@app.cell
+def _(vc):
+ vw = vc.widget()
+ vw
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/spatial_data_blobs.ipynb b/docs/notebooks/spatial_data_blobs.ipynb
deleted file mode 100644
index 717e9645..00000000
--- a/docs/notebooks/spatial_data_blobs.ipynb
+++ /dev/null
@@ -1,201 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Visualization of a SpatialData object, blobs example"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Import dependencies\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import spatialdata\n",
- "from os.path import join"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "sdata = spatialdata.datasets.blobs()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "spatialdata_filepath = join(\"data\", \"blobs.spatialdata.zarr\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "sdata.write(spatialdata_filepath, overwrite=True)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " ViewType as vt,\n",
- " CoordinationType as ct,\n",
- " CoordinationLevel as CL,\n",
- " SpatialDataWrapper,\n",
- " get_initial_coordination_scope_prefix\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Configure Vitessce\n",
- "\n",
- "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(\n",
- " schema_version=\"1.0.18\",\n",
- " name='Visium SpatialData Demo (blobs)',\n",
- ")\n",
- "# Add data to the configuration:\n",
- "wrapper = SpatialDataWrapper(\n",
- " sdata_store=spatialdata_filepath,\n",
- " # The following paths are relative to the root of the SpatialData zarr store on-disk.\n",
- " image_path=\"images/blobs_image\",\n",
- " obs_segmentations_path=\"labels/blobs_labels\",\n",
- " coordinate_system=\"global\",\n",
- " coordination_values={\n",
- " \"obsType\": \"blob\",\n",
- " \"fileUid\": \"my_unique_id\"\n",
- " }\n",
- ")\n",
- "dataset = vc.add_dataset(name='Blobs').add_object(wrapper)\n",
- "\n",
- "# Add views (visualizations) to the configuration:\n",
- "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
- "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
- "\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " 'imageLayer': CL([{\n",
- " \"fileUid\": \"my_unique_id\",\n",
- " 'photometricInterpretation': 'BlackIsZero',\n",
- " 'spatialLayerOpacity': 0.9,\n",
- " 'imageChannel': CL([\n",
- " {\n",
- " \"spatialTargetC\": 0,\n",
- " \"spatialChannelColor\": [255, 0, 0],\n",
- " \"spatialChannelOpacity\": 1.0\n",
- " },\n",
- " {\n",
- " \"spatialTargetC\": 1,\n",
- " \"spatialChannelColor\": [0, 255, 0],\n",
- " \"spatialChannelOpacity\": 1.0\n",
- " },\n",
- " {\n",
- " \"spatialTargetC\": 2,\n",
- " \"spatialChannelColor\": [0, 0, 255],\n",
- " \"spatialChannelOpacity\": 1.0\n",
- " }\n",
- " ])\n",
- " }]),\n",
- "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
- "\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " 'segmentationLayer': CL([{\n",
- " \"fileUid\": \"my_unique_id\",\n",
- " 'segmentationChannel': CL([{\n",
- " 'spatialChannelVisible': True,\n",
- " 'obsType': 'blob',\n",
- " }]),\n",
- " }]),\n",
- "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"obsSegmentations\"))\n",
- "\n",
- "# Layout the views\n",
- "vc.layout(spatial | layer_controller);"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Render the widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.14"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/spatial_data_blobs.mo.py b/docs/notebooks/spatial_data_blobs.mo.py
new file mode 100644
index 00000000..ff4d6b94
--- /dev/null
+++ b/docs/notebooks/spatial_data_blobs.mo.py
@@ -0,0 +1,187 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Visualization of a SpatialData object, blobs example
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Import dependencies
+
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ import spatialdata
+ from os.path import join
+ return join, spatialdata
+
+
+@app.cell
+def _(spatialdata):
+ sdata = spatialdata.datasets.blobs()
+ return (sdata,)
+
+
+@app.cell
+def _(join):
+ spatialdata_filepath = join("data", "blobs.spatialdata.zarr")
+ return (spatialdata_filepath,)
+
+
+@app.cell
+def _(sdata, spatialdata_filepath):
+ sdata.write(spatialdata_filepath, overwrite=True)
+ return
+
+
+@app.cell
+def _():
+ from vitessce import (
+ VitessceConfig,
+ ViewType as vt,
+ CoordinationType as ct,
+ CoordinationLevel as CL,
+ SpatialDataWrapper,
+ get_initial_coordination_scope_prefix
+ )
+ return (
+ CL,
+ SpatialDataWrapper,
+ VitessceConfig,
+ get_initial_coordination_scope_prefix,
+ )
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Configure Vitessce
+
+ Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views.
+ """
+ )
+ return
+
+
+@app.cell
+def _(
+ CL,
+ SpatialDataWrapper,
+ VitessceConfig,
+ get_initial_coordination_scope_prefix,
+ spatialdata_filepath,
+):
+ vc = VitessceConfig(
+ schema_version="1.0.18",
+ name='Visium SpatialData Demo (blobs)',
+ )
+ # Add data to the configuration:
+ wrapper = SpatialDataWrapper(
+ sdata_store=spatialdata_filepath,
+ # The following paths are relative to the root of the SpatialData zarr store on-disk.
+ image_path="images/blobs_image",
+ obs_segmentations_path="labels/blobs_labels",
+ coordinate_system="global",
+ coordination_values={
+ "obsType": "blob",
+ "fileUid": "my_unique_id"
+ }
+ )
+ dataset = vc.add_dataset(name='Blobs').add_object(wrapper)
+
+ # Add views (visualizations) to the configuration:
+ spatial = vc.add_view("spatialBeta", dataset=dataset)
+ layer_controller = vc.add_view("layerControllerBeta", dataset=dataset)
+
+ vc.link_views_by_dict([spatial, layer_controller], {
+ 'imageLayer': CL([{
+ "fileUid": "my_unique_id",
+ 'photometricInterpretation': 'BlackIsZero',
+ 'spatialLayerOpacity': 0.9,
+ 'imageChannel': CL([
+ {
+ "spatialTargetC": 0,
+ "spatialChannelColor": [255, 0, 0],
+ "spatialChannelOpacity": 1.0
+ },
+ {
+ "spatialTargetC": 1,
+ "spatialChannelColor": [0, 255, 0],
+ "spatialChannelOpacity": 1.0
+ },
+ {
+ "spatialTargetC": 2,
+ "spatialChannelColor": [0, 0, 255],
+ "spatialChannelOpacity": 1.0
+ }
+ ])
+ }]),
+ }, scope_prefix=get_initial_coordination_scope_prefix("A", "image"))
+
+ vc.link_views_by_dict([spatial, layer_controller], {
+ 'segmentationLayer': CL([{
+ "fileUid": "my_unique_id",
+ 'segmentationChannel': CL([{
+ 'spatialChannelVisible': True,
+ 'obsType': 'blob',
+ }]),
+ }]),
+ }, scope_prefix=get_initial_coordination_scope_prefix("A", "obsSegmentations"))
+
+ # Layout the views
+ vc.layout(spatial | layer_controller);
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### Render the widget
+ """
+ )
+ return
+
+
+@app.cell
+def _(vc):
+ vw = vc.widget()
+ vw
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/spatial_data_kpmp_vis.ipynb b/docs/notebooks/spatial_data_kpmp_vis.ipynb
deleted file mode 100644
index e10e51c5..00000000
--- a/docs/notebooks/spatial_data_kpmp_vis.ipynb
+++ /dev/null
@@ -1,477 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Import dependencies\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "# Reference: https://github.com/vitessce/vitessce/blob/main/examples/configs/src/view-configs/spatial-beta/kpmp.js"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " ViewType as vt,\n",
- " CoordinationType as ct,\n",
- " CoordinationLevel as CL,\n",
- " SpatialDataWrapper,\n",
- " AnnDataWrapper,\n",
- " ImageOmeTiffWrapper,\n",
- " ImageOmeZarrWrapper,\n",
- " ObsSegmentationsOmeZarrWrapper,\n",
- " get_initial_coordination_scope_prefix,\n",
- " hconcat,\n",
- " vconcat,\n",
- ")\n",
- "from os.path import join"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Configure Vitessce"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "sdata_url = \"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/sdata.zarr\""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "# Create a VitessceConfig instance.\n",
- "vc = VitessceConfig(schema_version=\"1.0.18\", name=\"SpatialData\")\n",
- "\n",
- "t_obstype = \"Tubule\"\n",
- "a_obstype = \"Artery\"\n",
- "ci_obstype = \"Cortical Interstitium\"\n",
- "gsg_obstype = \"G. S. Glomerulus\"\n",
- "ngsg_obstype = \"Non-G. S. Glomerulus\"\n",
- "ifta_obstype = \"Interstitial Fibrosis and Tubular Atrophy\"\n",
- "ptc_obstype = \"Peritubular Capillaries\"\n",
- "\n",
- "# Add a new dataset to the Vitessce configuration,\n",
- "# then add the wrapper class instance to this dataset.\n",
- "dataset = vc.add_dataset(name='KPMP').add_object(\n",
- " SpatialDataWrapper(\n",
- " sdata_url=sdata_url,\n",
- " image_path=\"images/image\",\n",
- " coordinate_system=\"global\",\n",
- " )\n",
- ").add_object(\n",
- " SpatialDataWrapper(\n",
- " sdata_url=sdata_url,\n",
- " table_path=\"tables/table_tubules\",\n",
- " obs_segmentations_path=\"labels/labels_tubules\",\n",
- " obs_feature_matrix_path=\"tables/table_tubules/X\",\n",
- " coordinate_system=\"global\",\n",
- " coordination_values={\n",
- " \"fileUid\": \"labels_tubules\",\n",
- " \"obsType\": t_obstype,\n",
- " \"featureType\": 'feature',\n",
- " \"featureValueType\": 'value',\n",
- " }\n",
- " )\n",
- ").add_object(\n",
- " SpatialDataWrapper(\n",
- " sdata_url=sdata_url,\n",
- " obs_segmentations_path=\"labels/labels_arteries_arterioles\",\n",
- " coordinate_system=\"global\",\n",
- " coordination_values={\n",
- " \"fileUid\": \"labels_arteries_arterioles\",\n",
- " \"obsType\": a_obstype,\n",
- " \"featureType\": 'feature',\n",
- " \"featureValueType\": 'value',\n",
- " }\n",
- " )\n",
- ").add_object(\n",
- " SpatialDataWrapper(\n",
- " sdata_url=sdata_url,\n",
- " table_path=\"tables/table_cortical_interstitia\",\n",
- " obs_segmentations_path=\"labels/labels_cortical_interstitia\",\n",
- " obs_feature_matrix_path=\"tables/table_cortical_interstitia/X\",\n",
- " coordinate_system=\"global\",\n",
- " coordination_values={\n",
- " \"fileUid\": \"labels_cortical_interstitia\",\n",
- " \"obsType\": ci_obstype,\n",
- " \"featureType\": 'feature',\n",
- " \"featureValueType\": 'value',\n",
- " }\n",
- " )\n",
- ").add_object(\n",
- " SpatialDataWrapper(\n",
- " sdata_url=sdata_url,\n",
- " table_path=\"tables/table_globally_sclerotic_glomeruli\",\n",
- " obs_segmentations_path=\"labels/labels_globally_sclerotic_glomeruli\",\n",
- " obs_feature_matrix_path=\"tables/table_globally_sclerotic_glomeruli/X\",\n",
- " coordinate_system=\"global\",\n",
- " coordination_values={\n",
- " \"fileUid\": \"labels_globally_sclerotic_glomeruli\",\n",
- " \"obsType\": gsg_obstype,\n",
- " \"featureType\": 'feature',\n",
- " \"featureValueType\": 'value',\n",
- " }\n",
- " )\n",
- ").add_object(\n",
- " SpatialDataWrapper(\n",
- " sdata_url=sdata_url,\n",
- " table_path=\"tables/table_non_globally_sclerotic_glomeruli\",\n",
- " obs_segmentations_path=\"labels/labels_non_globally_sclerotic_glomeruli\",\n",
- " obs_feature_matrix_path=\"tables/table_non_globally_sclerotic_glomeruli/X\",\n",
- " coordinate_system=\"global\",\n",
- " coordination_values={\n",
- " \"fileUid\": \"labels_non_globally_sclerotic_glomeruli\",\n",
- " \"obsType\": ngsg_obstype,\n",
- " \"featureType\": 'feature',\n",
- " \"featureValueType\": 'value',\n",
- " }\n",
- " )\n",
- ").add_object(\n",
- " SpatialDataWrapper(\n",
- " sdata_url=sdata_url,\n",
- " table_path=\"tables/table_interstitialfibrosis_and_tubular_atrophy\",\n",
- " obs_segmentations_path=\"labels/labels_interstitialfibrosis_and_tubular_atrophy\",\n",
- " coordinate_system=\"global\",\n",
- " coordination_values={\n",
- " \"fileUid\": \"labels_interstitialfibrosis_and_tubular_atrophy\",\n",
- " \"obsType\": ifta_obstype,\n",
- " \"featureType\": 'feature',\n",
- " \"featureValueType\": 'value',\n",
- " }\n",
- " )\n",
- ").add_object(\n",
- " SpatialDataWrapper(\n",
- " sdata_url=sdata_url,\n",
- " table_path=\"tables/table_peritubular_capillaries\",\n",
- " obs_segmentations_path=\"labels/labels_peritubular_capillaries\",\n",
- " obs_feature_matrix_path=\"tables/table_peritubular_capillaries/X\",\n",
- " obs_set_paths=[\n",
- " \"tables/table_peritubular_capillaries/obs/cortex_ifta_set\",\n",
- " \"tables/table_peritubular_capillaries/obs/cortex_set\",\n",
- " \"tables/table_peritubular_capillaries/obs/ifta_set\",\n",
- " [\"tables/table_peritubular_capillaries/obs/cortex_set\", \"tables/table_peritubular_capillaries/obs/ifta_set\"],\n",
- " ],\n",
- " obs_set_names=[\n",
- " \"Cortex and IFTA membership\",\n",
- " \"Cortex membership\",\n",
- " \"IFTA membership\",\n",
- " \"Cortex and IFTA hierarchy\",\n",
- " ],\n",
- " coordinate_system=\"global\",\n",
- " coordination_values={\n",
- " \"fileUid\": \"labels_peritubular_capillaries\",\n",
- " \"obsType\": ptc_obstype,\n",
- " \"featureType\": 'feature',\n",
- " \"featureValueType\": 'value',\n",
- " }\n",
- " )\n",
- ")\n",
- "\n",
- "# Add views (visualizations) to the configuration.\n",
- "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
- "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
- "# Tubules\n",
- "tubules_feature_list = vc.add_view(\"featureList\", dataset=dataset).set_props(title=\"Tubules\")\n",
- "tubules_histogram = vc.add_view(\"featureValueHistogram\", dataset=dataset)\n",
- "# Peritubular capillaries\n",
- "pt_feature_list = vc.add_view(\"featureList\", dataset=dataset).set_props(title=\"Peritubular Capillaries\")\n",
- "pt_histogram = vc.add_view(\"featureValueHistogram\", dataset=dataset)\n",
- "# GSG\n",
- "gsg_feature_list = vc.add_view(\"featureList\", dataset=dataset).set_props(title=\"Globally Sclerotic Glomeruli\")\n",
- "gsg_histogram = vc.add_view(\"featureValueHistogram\", dataset=dataset)\n",
- "# NGSG\n",
- "ngsg_feature_list = vc.add_view(\"featureList\", dataset=dataset).set_props(title=\"Non-Globally Sclerotic Glomeruli\")\n",
- "ngsg_histogram = vc.add_view(\"featureValueHistogram\", dataset=dataset)\n",
- "\n",
- "# Add obsSets, obsSetSizes, and violin plot views for PTC sets+areas/aspectRatio\n",
- "pt_sets = vc.add_view(\"obsSets\", dataset=dataset)\n",
- "pt_bar_plot = vc.add_view(\"obsSetSizes\", dataset=dataset)\n",
- "pt_violin_plot = vc.add_view(\"obsSetFeatureValueDistribution\", dataset=dataset).set_props(jitter=True)\n",
- "\n",
- "\n",
- "# Coordination of views.\n",
- "[ft_scope, fvt_scope] = vc.add_coordination(\"featureType\", \"featureValueType\")\n",
- "ft_scope.set_value(\"feature\")\n",
- "fvt_scope.set_value(\"value\")\n",
- "\n",
- "[t_ot_scope, t_fs_scope, t_oce_scope] = vc.add_coordination(\"obsType\", \"featureSelection\", \"obsColorEncoding\")\n",
- "t_ot_scope.set_value(t_obstype)\n",
- "t_oce_scope.set_value(\"spatialChannelColor\")\n",
- "\n",
- "[pt_ot_scope, pt_fs_scope, pt_oce_scope] = vc.add_coordination(\"obsType\", \"featureSelection\", \"obsColorEncoding\")\n",
- "pt_ot_scope.set_value(ptc_obstype)\n",
- "pt_fs_scope.set_value([\"Area\"])\n",
- "pt_oce_scope.set_value(\"cellSetSelection\")\n",
- "\n",
- "\n",
- "[gsg_ot_scope, gsg_fs_scope, gsg_oce_scope, gsg_fvcr_scope] = vc.add_coordination(\"obsType\", \"featureSelection\", \"obsColorEncoding\", \"featureValueColormapRange\")\n",
- "gsg_ot_scope.set_value(gsg_obstype)\n",
- "gsg_oce_scope.set_value(\"spatialChannelColor\")\n",
- "gsg_fvcr_scope.set_value([(3077 - 2333) / (29911 - 2333), 1.0])\n",
- "\n",
- "[ngsg_ot_scope, ngsg_fs_scope, ngsg_oce_scope, ngsg_fvcr_scope] = vc.add_coordination(\"obsType\", \"featureSelection\", \"obsColorEncoding\", \"featureValueColormapRange\")\n",
- "ngsg_ot_scope.set_value(ngsg_obstype)\n",
- "ngsg_oce_scope.set_value(\"spatialChannelColor\")\n",
- "ngsg_fvcr_scope.set_value([0.0, 1 - (59451 - 29911) / (59451 - 3077)])\n",
- "\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " \"imageLayer\": CL([{\n",
- " \"spatialLayerOpacity\": 0.1,\n",
- " \"photometricInterpretation\": \"RGB\",\n",
- " }]),\n",
- "}, meta=True, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
- "\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " \"segmentationLayer\": CL([\n",
- " {\n",
- " \"fileUid\": \"labels_tubules\",\n",
- " \"segmentationChannel\": CL([{\n",
- " \"spatialTargetC\": 0,\n",
- " \"obsType\": t_ot_scope,\n",
- " \"featureType\": ft_scope,\n",
- " \"featureValueType\": fvt_scope,\n",
- " \"featureSelection\": t_fs_scope,\n",
- " \"spatialChannelVisible\": False,\n",
- " \"spatialChannelColor\": [73, 155, 119],\n",
- " \"spatialChannelOpacity\": 0.5,\n",
- " \"obsColorEncoding\": t_oce_scope,\n",
- " \"featureValueColormapRange\": [0, 1],\n",
- " \"featureAggregationStrategy\": \"first\",\n",
- " \"spatialSegmentationFilled\": True,\n",
- " \"obsHighlight\": None,\n",
- " }]),\n",
- " },\n",
- " {\n",
- " \"fileUid\": \"labels_arteries_arterioles\",\n",
- " \"segmentationChannel\": CL([{\n",
- " \"spatialTargetC\": 0,\n",
- " \"obsType\": \"Artery\",\n",
- " \"featureType\": ft_scope,\n",
- " \"featureValueType\": fvt_scope,\n",
- " \"spatialChannelVisible\": False,\n",
- " \"spatialChannelColor\": [237, 226, 107],\n",
- " \"spatialChannelOpacity\": 0.5,\n",
- " \"obsColorEncoding\": \"spatialChannelColor\",\n",
- " \"featureValueColormapRange\": [0, 1],\n",
- " \"featureAggregationStrategy\": \"first\",\n",
- " \"spatialSegmentationFilled\": True,\n",
- " \"obsHighlight\": None,\n",
- " }]),\n",
- " },\n",
- " {\n",
- " \"fileUid\": \"labels_cortical_interstitia\",\n",
- " \"segmentationChannel\": CL([{\n",
- " \"spatialTargetC\": 0,\n",
- " \"obsType\": \"Cortical Interstitium\",\n",
- " \"featureType\": ft_scope,\n",
- " \"featureValueType\": fvt_scope,\n",
- " \"spatialChannelVisible\": False,\n",
- " \"spatialChannelColor\": [255, 255, 255],\n",
- " \"spatialChannelOpacity\": 0.5,\n",
- " \"obsColorEncoding\": \"spatialChannelColor\",\n",
- " \"featureValueColormapRange\": [0, 1],\n",
- " \"featureAggregationStrategy\": \"first\",\n",
- " \"spatialSegmentationFilled\": True,\n",
- " \"obsHighlight\": None,\n",
- " }]),\n",
- " },\n",
- " {\n",
- " \"fileUid\": \"labels_globally_sclerotic_glomeruli\",\n",
- " \"segmentationChannel\": CL([{\n",
- " \"spatialTargetC\": 0,\n",
- " \"obsType\": gsg_ot_scope,\n",
- " \"featureType\": ft_scope,\n",
- " \"featureValueType\": fvt_scope,\n",
- " \"featureSelection\": gsg_fs_scope,\n",
- " \"spatialChannelVisible\": False,\n",
- " \"spatialChannelColor\": [52, 113, 171],\n",
- " \"spatialChannelOpacity\": 0.5,\n",
- " \"obsColorEncoding\": gsg_oce_scope,\n",
- " \"featureValueColormapRange\": gsg_fvcr_scope,\n",
- " \"featureAggregationStrategy\": \"first\",\n",
- " \"spatialSegmentationFilled\": True,\n",
- " \"obsHighlight\": None,\n",
- " }]),\n",
- " },\n",
- " {\n",
- " \"fileUid\": \"labels_non_globally_sclerotic_glomeruli\",\n",
- " \"segmentationChannel\": CL([{\n",
- " \"spatialTargetC\": 0,\n",
- " \"obsType\": ngsg_ot_scope,\n",
- " \"featureType\": ft_scope,\n",
- " \"featureValueType\": fvt_scope,\n",
- " \"featureSelection\": ngsg_fs_scope,\n",
- " \"spatialChannelVisible\": False,\n",
- " \"spatialChannelColor\": [114, 179, 226],\n",
- " \"spatialChannelOpacity\": 0.5,\n",
- " \"obsColorEncoding\": ngsg_oce_scope,\n",
- " \"featureValueColormapRange\": ngsg_fvcr_scope,\n",
- " \"featureAggregationStrategy\": \"first\",\n",
- " \"spatialSegmentationFilled\": True,\n",
- " \"obsHighlight\": None,\n",
- " }]),\n",
- " },\n",
- " {\n",
- " \"fileUid\": \"labels_interstitialfibrosis_and_tubular_atrophy\",\n",
- " \"segmentationChannel\": CL([{\n",
- " \"spatialTargetC\": 0,\n",
- " \"obsType\": \"Interstitial Fibrosis and Tubular Atrophy\",\n",
- " \"featureType\": ft_scope,\n",
- " \"featureValueType\": fvt_scope,\n",
- " \"spatialChannelVisible\": True,\n",
- " \"spatialChannelColor\": [218, 161, 66],\n",
- " \"spatialChannelOpacity\": 1.0,\n",
- " \"obsColorEncoding\": \"spatialChannelColor\",\n",
- " \"featureValueColormapRange\": [0, 1],\n",
- " \"featureAggregationStrategy\": \"first\",\n",
- " \"spatialSegmentationFilled\": False,\n",
- " \"obsHighlight\": None,\n",
- " }]),\n",
- " },\n",
- " {\n",
- " \"fileUid\": \"labels_peritubular_capillaries\",\n",
- " \"segmentationChannel\": CL([{\n",
- " \"spatialTargetC\": 0,\n",
- " \"obsType\": pt_ot_scope,\n",
- " \"featureType\": ft_scope,\n",
- " \"featureValueType\": fvt_scope,\n",
- " \"featureSelection\": pt_fs_scope,\n",
- " \"spatialChannelVisible\": True,\n",
- " \"spatialChannelColor\": [197, 101, 47],\n",
- " \"spatialChannelOpacity\": 1.0,\n",
- " \"obsColorEncoding\": pt_oce_scope,\n",
- " \"featureValueColormapRange\": [0, 0.5],\n",
- " \"featureAggregationStrategy\": \"first\",\n",
- " \"spatialSegmentationFilled\": True,\n",
- " \"obsHighlight\": None,\n",
- " }]),\n",
- " }\n",
- " ]),\n",
- "}, meta=True, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"obsSegmentations\"))\n",
- "\n",
- "tubules_feature_list.use_coordination(t_ot_scope, ft_scope, fvt_scope, t_fs_scope, t_oce_scope)\n",
- "tubules_histogram.use_coordination(t_ot_scope, ft_scope, fvt_scope, t_fs_scope, t_oce_scope)\n",
- "\n",
- "pt_feature_list.use_coordination(pt_ot_scope, ft_scope, fvt_scope, pt_fs_scope, pt_oce_scope)\n",
- "pt_histogram.use_coordination(pt_ot_scope, ft_scope, fvt_scope, pt_fs_scope, pt_oce_scope)\n",
- "\n",
- "pt_sets.use_coordination(pt_ot_scope, ft_scope, fvt_scope, pt_fs_scope, pt_oce_scope)\n",
- "pt_bar_plot.use_coordination(pt_ot_scope, ft_scope, fvt_scope, pt_fs_scope, pt_oce_scope)\n",
- "pt_violin_plot.use_coordination(pt_ot_scope, ft_scope, fvt_scope, pt_fs_scope, pt_oce_scope)\n",
- "\n",
- "\n",
- "gsg_feature_list.use_coordination(gsg_ot_scope, ft_scope, fvt_scope, gsg_fs_scope, gsg_oce_scope, gsg_fvcr_scope)\n",
- "gsg_histogram.use_coordination(gsg_ot_scope, ft_scope, fvt_scope, gsg_fs_scope, gsg_oce_scope, gsg_fvcr_scope)\n",
- "\n",
- "ngsg_feature_list.use_coordination(ngsg_ot_scope, ft_scope, fvt_scope, ngsg_fs_scope, ngsg_oce_scope, ngsg_fvcr_scope)\n",
- "ngsg_histogram.use_coordination(ngsg_ot_scope, ft_scope, fvt_scope, ngsg_fs_scope, ngsg_oce_scope, ngsg_fvcr_scope)\n",
- "\n",
- "\n",
- "# Layout the views in a grid arrangement.\n",
- "vc.layout(vconcat(\n",
- " hconcat(spatial, layer_controller, split=[3, 1]),\n",
- " hconcat(\n",
- " (tubules_feature_list / tubules_histogram),\n",
- " (pt_feature_list / pt_histogram),\n",
- " (gsg_feature_list / gsg_histogram),\n",
- " (ngsg_feature_list / ngsg_histogram)\n",
- " ),\n",
- " hconcat(pt_sets, pt_bar_plot, pt_violin_plot)\n",
- "));"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget(height=1000)\n",
- "vw"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "#import json\n",
- "#print(json.dumps(vc.to_dict(), indent=2))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.14"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/spatial_data_kpmp_vis.mo.py b/docs/notebooks/spatial_data_kpmp_vis.mo.py
new file mode 100644
index 00000000..bc51784a
--- /dev/null
+++ b/docs/notebooks/spatial_data_kpmp_vis.mo.py
@@ -0,0 +1,450 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Import dependencies
+
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ # Reference: https://github.com/vitessce/vitessce/blob/main/examples/configs/src/view-configs/spatial-beta/kpmp.js
+ return
+
+
+@app.cell
+def _():
+ from vitessce import (
+ VitessceConfig,
+ ViewType as vt,
+ CoordinationType as ct,
+ CoordinationLevel as CL,
+ SpatialDataWrapper,
+ AnnDataWrapper,
+ ImageOmeTiffWrapper,
+ ImageOmeZarrWrapper,
+ ObsSegmentationsOmeZarrWrapper,
+ get_initial_coordination_scope_prefix,
+ hconcat,
+ vconcat,
+ )
+ from os.path import join
+ return (
+ CL,
+ SpatialDataWrapper,
+ VitessceConfig,
+ get_initial_coordination_scope_prefix,
+ hconcat,
+ vconcat,
+ )
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Configure Vitessce
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ sdata_url = "https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/sdata.zarr"
+ return (sdata_url,)
+
+
+@app.cell
+def _(
+ CL,
+ SpatialDataWrapper,
+ VitessceConfig,
+ get_initial_coordination_scope_prefix,
+ hconcat,
+ sdata_url,
+ vconcat,
+):
+ # Create a VitessceConfig instance.
+ vc = VitessceConfig(schema_version="1.0.18", name="SpatialData")
+
+ t_obstype = "Tubule"
+ a_obstype = "Artery"
+ ci_obstype = "Cortical Interstitium"
+ gsg_obstype = "G. S. Glomerulus"
+ ngsg_obstype = "Non-G. S. Glomerulus"
+ ifta_obstype = "Interstitial Fibrosis and Tubular Atrophy"
+ ptc_obstype = "Peritubular Capillaries"
+
+ # Add a new dataset to the Vitessce configuration,
+ # then add the wrapper class instance to this dataset.
+ dataset = vc.add_dataset(name='KPMP').add_object(
+ SpatialDataWrapper(
+ sdata_url=sdata_url,
+ image_path="images/image",
+ coordinate_system="global",
+ )
+ ).add_object(
+ SpatialDataWrapper(
+ sdata_url=sdata_url,
+ table_path="tables/table_tubules",
+ obs_segmentations_path="labels/labels_tubules",
+ obs_feature_matrix_path="tables/table_tubules/X",
+ coordinate_system="global",
+ coordination_values={
+ "fileUid": "labels_tubules",
+ "obsType": t_obstype,
+ "featureType": 'feature',
+ "featureValueType": 'value',
+ }
+ )
+ ).add_object(
+ SpatialDataWrapper(
+ sdata_url=sdata_url,
+ obs_segmentations_path="labels/labels_arteries_arterioles",
+ coordinate_system="global",
+ coordination_values={
+ "fileUid": "labels_arteries_arterioles",
+ "obsType": a_obstype,
+ "featureType": 'feature',
+ "featureValueType": 'value',
+ }
+ )
+ ).add_object(
+ SpatialDataWrapper(
+ sdata_url=sdata_url,
+ table_path="tables/table_cortical_interstitia",
+ obs_segmentations_path="labels/labels_cortical_interstitia",
+ obs_feature_matrix_path="tables/table_cortical_interstitia/X",
+ coordinate_system="global",
+ coordination_values={
+ "fileUid": "labels_cortical_interstitia",
+ "obsType": ci_obstype,
+ "featureType": 'feature',
+ "featureValueType": 'value',
+ }
+ )
+ ).add_object(
+ SpatialDataWrapper(
+ sdata_url=sdata_url,
+ table_path="tables/table_globally_sclerotic_glomeruli",
+ obs_segmentations_path="labels/labels_globally_sclerotic_glomeruli",
+ obs_feature_matrix_path="tables/table_globally_sclerotic_glomeruli/X",
+ coordinate_system="global",
+ coordination_values={
+ "fileUid": "labels_globally_sclerotic_glomeruli",
+ "obsType": gsg_obstype,
+ "featureType": 'feature',
+ "featureValueType": 'value',
+ }
+ )
+ ).add_object(
+ SpatialDataWrapper(
+ sdata_url=sdata_url,
+ table_path="tables/table_non_globally_sclerotic_glomeruli",
+ obs_segmentations_path="labels/labels_non_globally_sclerotic_glomeruli",
+ obs_feature_matrix_path="tables/table_non_globally_sclerotic_glomeruli/X",
+ coordinate_system="global",
+ coordination_values={
+ "fileUid": "labels_non_globally_sclerotic_glomeruli",
+ "obsType": ngsg_obstype,
+ "featureType": 'feature',
+ "featureValueType": 'value',
+ }
+ )
+ ).add_object(
+ SpatialDataWrapper(
+ sdata_url=sdata_url,
+ table_path="tables/table_interstitialfibrosis_and_tubular_atrophy",
+ obs_segmentations_path="labels/labels_interstitialfibrosis_and_tubular_atrophy",
+ coordinate_system="global",
+ coordination_values={
+ "fileUid": "labels_interstitialfibrosis_and_tubular_atrophy",
+ "obsType": ifta_obstype,
+ "featureType": 'feature',
+ "featureValueType": 'value',
+ }
+ )
+ ).add_object(
+ SpatialDataWrapper(
+ sdata_url=sdata_url,
+ table_path="tables/table_peritubular_capillaries",
+ obs_segmentations_path="labels/labels_peritubular_capillaries",
+ obs_feature_matrix_path="tables/table_peritubular_capillaries/X",
+ obs_set_paths=[
+ "tables/table_peritubular_capillaries/obs/cortex_ifta_set",
+ "tables/table_peritubular_capillaries/obs/cortex_set",
+ "tables/table_peritubular_capillaries/obs/ifta_set",
+ ["tables/table_peritubular_capillaries/obs/cortex_set", "tables/table_peritubular_capillaries/obs/ifta_set"],
+ ],
+ obs_set_names=[
+ "Cortex and IFTA membership",
+ "Cortex membership",
+ "IFTA membership",
+ "Cortex and IFTA hierarchy",
+ ],
+ coordinate_system="global",
+ coordination_values={
+ "fileUid": "labels_peritubular_capillaries",
+ "obsType": ptc_obstype,
+ "featureType": 'feature',
+ "featureValueType": 'value',
+ }
+ )
+ )
+
+ # Add views (visualizations) to the configuration.
+ spatial = vc.add_view("spatialBeta", dataset=dataset)
+ layer_controller = vc.add_view("layerControllerBeta", dataset=dataset)
+ # Tubules
+ tubules_feature_list = vc.add_view("featureList", dataset=dataset).set_props(title="Tubules")
+ tubules_histogram = vc.add_view("featureValueHistogram", dataset=dataset)
+ # Peritubular capillaries
+ pt_feature_list = vc.add_view("featureList", dataset=dataset).set_props(title="Peritubular Capillaries")
+ pt_histogram = vc.add_view("featureValueHistogram", dataset=dataset)
+ # GSG
+ gsg_feature_list = vc.add_view("featureList", dataset=dataset).set_props(title="Globally Sclerotic Glomeruli")
+ gsg_histogram = vc.add_view("featureValueHistogram", dataset=dataset)
+ # NGSG
+ ngsg_feature_list = vc.add_view("featureList", dataset=dataset).set_props(title="Non-Globally Sclerotic Glomeruli")
+ ngsg_histogram = vc.add_view("featureValueHistogram", dataset=dataset)
+
+ # Add obsSets, obsSetSizes, and violin plot views for PTC sets+areas/aspectRatio
+ pt_sets = vc.add_view("obsSets", dataset=dataset)
+ pt_bar_plot = vc.add_view("obsSetSizes", dataset=dataset)
+ pt_violin_plot = vc.add_view("obsSetFeatureValueDistribution", dataset=dataset).set_props(jitter=True)
+
+
+ # Coordination of views.
+ [ft_scope, fvt_scope] = vc.add_coordination("featureType", "featureValueType")
+ ft_scope.set_value("feature")
+ fvt_scope.set_value("value")
+
+ [t_ot_scope, t_fs_scope, t_oce_scope] = vc.add_coordination("obsType", "featureSelection", "obsColorEncoding")
+ t_ot_scope.set_value(t_obstype)
+ t_oce_scope.set_value("spatialChannelColor")
+
+ [pt_ot_scope, pt_fs_scope, pt_oce_scope] = vc.add_coordination("obsType", "featureSelection", "obsColorEncoding")
+ pt_ot_scope.set_value(ptc_obstype)
+ pt_fs_scope.set_value(["Area"])
+ pt_oce_scope.set_value("cellSetSelection")
+
+
+ [gsg_ot_scope, gsg_fs_scope, gsg_oce_scope, gsg_fvcr_scope] = vc.add_coordination("obsType", "featureSelection", "obsColorEncoding", "featureValueColormapRange")
+ gsg_ot_scope.set_value(gsg_obstype)
+ gsg_oce_scope.set_value("spatialChannelColor")
+ gsg_fvcr_scope.set_value([(3077 - 2333) / (29911 - 2333), 1.0])
+
+ [ngsg_ot_scope, ngsg_fs_scope, ngsg_oce_scope, ngsg_fvcr_scope] = vc.add_coordination("obsType", "featureSelection", "obsColorEncoding", "featureValueColormapRange")
+ ngsg_ot_scope.set_value(ngsg_obstype)
+ ngsg_oce_scope.set_value("spatialChannelColor")
+ ngsg_fvcr_scope.set_value([0.0, 1 - (59451 - 29911) / (59451 - 3077)])
+
+ vc.link_views_by_dict([spatial, layer_controller], {
+ "imageLayer": CL([{
+ "spatialLayerOpacity": 0.1,
+ "photometricInterpretation": "RGB",
+ }]),
+ }, meta=True, scope_prefix=get_initial_coordination_scope_prefix("A", "image"))
+
+ vc.link_views_by_dict([spatial, layer_controller], {
+ "segmentationLayer": CL([
+ {
+ "fileUid": "labels_tubules",
+ "segmentationChannel": CL([{
+ "spatialTargetC": 0,
+ "obsType": t_ot_scope,
+ "featureType": ft_scope,
+ "featureValueType": fvt_scope,
+ "featureSelection": t_fs_scope,
+ "spatialChannelVisible": False,
+ "spatialChannelColor": [73, 155, 119],
+ "spatialChannelOpacity": 0.5,
+ "obsColorEncoding": t_oce_scope,
+ "featureValueColormapRange": [0, 1],
+ "featureAggregationStrategy": "first",
+ "spatialSegmentationFilled": True,
+ "obsHighlight": None,
+ }]),
+ },
+ {
+ "fileUid": "labels_arteries_arterioles",
+ "segmentationChannel": CL([{
+ "spatialTargetC": 0,
+ "obsType": "Artery",
+ "featureType": ft_scope,
+ "featureValueType": fvt_scope,
+ "spatialChannelVisible": False,
+ "spatialChannelColor": [237, 226, 107],
+ "spatialChannelOpacity": 0.5,
+ "obsColorEncoding": "spatialChannelColor",
+ "featureValueColormapRange": [0, 1],
+ "featureAggregationStrategy": "first",
+ "spatialSegmentationFilled": True,
+ "obsHighlight": None,
+ }]),
+ },
+ {
+ "fileUid": "labels_cortical_interstitia",
+ "segmentationChannel": CL([{
+ "spatialTargetC": 0,
+ "obsType": "Cortical Interstitium",
+ "featureType": ft_scope,
+ "featureValueType": fvt_scope,
+ "spatialChannelVisible": False,
+ "spatialChannelColor": [255, 255, 255],
+ "spatialChannelOpacity": 0.5,
+ "obsColorEncoding": "spatialChannelColor",
+ "featureValueColormapRange": [0, 1],
+ "featureAggregationStrategy": "first",
+ "spatialSegmentationFilled": True,
+ "obsHighlight": None,
+ }]),
+ },
+ {
+ "fileUid": "labels_globally_sclerotic_glomeruli",
+ "segmentationChannel": CL([{
+ "spatialTargetC": 0,
+ "obsType": gsg_ot_scope,
+ "featureType": ft_scope,
+ "featureValueType": fvt_scope,
+ "featureSelection": gsg_fs_scope,
+ "spatialChannelVisible": False,
+ "spatialChannelColor": [52, 113, 171],
+ "spatialChannelOpacity": 0.5,
+ "obsColorEncoding": gsg_oce_scope,
+ "featureValueColormapRange": gsg_fvcr_scope,
+ "featureAggregationStrategy": "first",
+ "spatialSegmentationFilled": True,
+ "obsHighlight": None,
+ }]),
+ },
+ {
+ "fileUid": "labels_non_globally_sclerotic_glomeruli",
+ "segmentationChannel": CL([{
+ "spatialTargetC": 0,
+ "obsType": ngsg_ot_scope,
+ "featureType": ft_scope,
+ "featureValueType": fvt_scope,
+ "featureSelection": ngsg_fs_scope,
+ "spatialChannelVisible": False,
+ "spatialChannelColor": [114, 179, 226],
+ "spatialChannelOpacity": 0.5,
+ "obsColorEncoding": ngsg_oce_scope,
+ "featureValueColormapRange": ngsg_fvcr_scope,
+ "featureAggregationStrategy": "first",
+ "spatialSegmentationFilled": True,
+ "obsHighlight": None,
+ }]),
+ },
+ {
+ "fileUid": "labels_interstitialfibrosis_and_tubular_atrophy",
+ "segmentationChannel": CL([{
+ "spatialTargetC": 0,
+ "obsType": "Interstitial Fibrosis and Tubular Atrophy",
+ "featureType": ft_scope,
+ "featureValueType": fvt_scope,
+ "spatialChannelVisible": True,
+ "spatialChannelColor": [218, 161, 66],
+ "spatialChannelOpacity": 1.0,
+ "obsColorEncoding": "spatialChannelColor",
+ "featureValueColormapRange": [0, 1],
+ "featureAggregationStrategy": "first",
+ "spatialSegmentationFilled": False,
+ "obsHighlight": None,
+ }]),
+ },
+ {
+ "fileUid": "labels_peritubular_capillaries",
+ "segmentationChannel": CL([{
+ "spatialTargetC": 0,
+ "obsType": pt_ot_scope,
+ "featureType": ft_scope,
+ "featureValueType": fvt_scope,
+ "featureSelection": pt_fs_scope,
+ "spatialChannelVisible": True,
+ "spatialChannelColor": [197, 101, 47],
+ "spatialChannelOpacity": 1.0,
+ "obsColorEncoding": pt_oce_scope,
+ "featureValueColormapRange": [0, 0.5],
+ "featureAggregationStrategy": "first",
+ "spatialSegmentationFilled": True,
+ "obsHighlight": None,
+ }]),
+ }
+ ]),
+ }, meta=True, scope_prefix=get_initial_coordination_scope_prefix("A", "obsSegmentations"))
+
+ tubules_feature_list.use_coordination(t_ot_scope, ft_scope, fvt_scope, t_fs_scope, t_oce_scope)
+ tubules_histogram.use_coordination(t_ot_scope, ft_scope, fvt_scope, t_fs_scope, t_oce_scope)
+
+ pt_feature_list.use_coordination(pt_ot_scope, ft_scope, fvt_scope, pt_fs_scope, pt_oce_scope)
+ pt_histogram.use_coordination(pt_ot_scope, ft_scope, fvt_scope, pt_fs_scope, pt_oce_scope)
+
+ pt_sets.use_coordination(pt_ot_scope, ft_scope, fvt_scope, pt_fs_scope, pt_oce_scope)
+ pt_bar_plot.use_coordination(pt_ot_scope, ft_scope, fvt_scope, pt_fs_scope, pt_oce_scope)
+ pt_violin_plot.use_coordination(pt_ot_scope, ft_scope, fvt_scope, pt_fs_scope, pt_oce_scope)
+
+
+ gsg_feature_list.use_coordination(gsg_ot_scope, ft_scope, fvt_scope, gsg_fs_scope, gsg_oce_scope, gsg_fvcr_scope)
+ gsg_histogram.use_coordination(gsg_ot_scope, ft_scope, fvt_scope, gsg_fs_scope, gsg_oce_scope, gsg_fvcr_scope)
+
+ ngsg_feature_list.use_coordination(ngsg_ot_scope, ft_scope, fvt_scope, ngsg_fs_scope, ngsg_oce_scope, ngsg_fvcr_scope)
+ ngsg_histogram.use_coordination(ngsg_ot_scope, ft_scope, fvt_scope, ngsg_fs_scope, ngsg_oce_scope, ngsg_fvcr_scope)
+
+
+ # Layout the views in a grid arrangement.
+ vc.layout(vconcat(
+ hconcat(spatial, layer_controller, split=[3, 1]),
+ hconcat(
+ (tubules_feature_list / tubules_histogram),
+ (pt_feature_list / pt_histogram),
+ (gsg_feature_list / gsg_histogram),
+ (ngsg_feature_list / ngsg_histogram)
+ ),
+ hconcat(pt_sets, pt_bar_plot, pt_violin_plot)
+ ));
+ return (vc,)
+
+
+@app.cell
+def _(vc):
+ vw = vc.widget(height=1000)
+ vw
+ return
+
+
+@app.cell
+def _():
+ #import json
+ #print(json.dumps(vc.to_dict(), indent=2))
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/spatial_data_merfish.ipynb b/docs/notebooks/spatial_data_merfish.ipynb
deleted file mode 100644
index 11e8e9e0..00000000
--- a/docs/notebooks/spatial_data_merfish.ipynb
+++ /dev/null
@@ -1,208 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Visualization of a SpatialData object, blobs example"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Import dependencies\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "sdata_url = \"https://data-2.vitessce.io/data/moffitt/merfish_mouse_ileum.sdata.zarr\""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " ViewType as vt,\n",
- " CoordinationType as ct,\n",
- " CoordinationLevel as CL,\n",
- " SpatialDataWrapper,\n",
- " get_initial_coordination_scope_prefix\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Configure Vitessce\n",
- "\n",
- "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(\n",
- " schema_version=\"1.0.18\",\n",
- " name='SpatialData with MERFISH data',\n",
- ")\n",
- "# Add data to the configuration:\n",
- "\n",
- "dataset = vc.add_dataset(name='MERFISH').add_object(SpatialDataWrapper(\n",
- " sdata_url=sdata_url,\n",
- " # The following paths are relative to the root of the SpatialData zarr store on-disk.\n",
- " image_path=\"images/stains\",\n",
- " coordinate_system=\"global\",\n",
- " coordination_values={\n",
- " \"fileUid\": \"stains\"\n",
- " }\n",
- ")).add_object(SpatialDataWrapper(\n",
- " sdata_url=sdata_url,\n",
- " # The following paths are relative to the root of the SpatialData zarr store on-disk.\n",
- " obs_segmentations_path=\"labels/dapi_labels\",\n",
- " coordinate_system=\"global\",\n",
- " coordination_values={\n",
- " \"obsType\": \"nucleus\",\n",
- " \"fileUid\": \"dapi\"\n",
- " }\n",
- ")).add_object(SpatialDataWrapper(\n",
- " sdata_url=sdata_url,\n",
- " # The following paths are relative to the root of the SpatialData zarr store on-disk.\n",
- " obs_segmentations_path=\"labels/membrane_labels\",\n",
- " coordinate_system=\"global\",\n",
- " coordination_values={\n",
- " \"obsType\": \"cell\",\n",
- " \"fileUid\": \"membrane\"\n",
- " }\n",
- "))\n",
- "\n",
- "# Add views (visualizations) to the configuration:\n",
- "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
- "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
- "\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " 'imageLayer': CL([{\n",
- " \"fileUid\": \"stains\",\n",
- " 'photometricInterpretation': 'BlackIsZero',\n",
- " 'spatialLayerOpacity': 1.0,\n",
- " 'spatialLayerVisible': True,\n",
- " 'imageChannel': CL([\n",
- " {\n",
- " 'spatialChannelVisible': True,\n",
- " \"spatialTargetC\": 0, # DAPI, Nucleus\n",
- " \"spatialChannelColor\": [0, 0, 255],\n",
- " \"spatialChannelOpacity\": 1.0\n",
- " },\n",
- " {\n",
- " 'spatialChannelVisible': True,\n",
- " \"spatialTargetC\": 1, # Membrane, Cell\n",
- " \"spatialChannelColor\": [255, 255, 255],\n",
- " \"spatialChannelOpacity\": 1.0\n",
- " }\n",
- " ])\n",
- " }]),\n",
- "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
- "\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " 'segmentationLayer': CL([{\n",
- " \"fileUid\": \"membrane\",\n",
- " 'spatialLayerOpacity': 1.0,\n",
- " 'spatialLayerVisible': True,\n",
- " 'segmentationChannel': CL([{\n",
- " 'spatialChannelVisible': True,\n",
- " 'obsType': 'cell',\n",
- " \"spatialChannelColor\": [200, 200, 200],\n",
- " \"obsColorEncoding\": \"spatialChannelColor\",\n",
- " }]),\n",
- " }, {\n",
- " \"fileUid\": \"dapi\",\n",
- " 'spatialLayerOpacity': 1.0,\n",
- " 'spatialLayerVisible': True,\n",
- " 'segmentationChannel': CL([{\n",
- " 'spatialChannelVisible': True,\n",
- " 'obsType': 'nucleus',\n",
- " \"spatialChannelColor\": [255, 255, 255],\n",
- " \"obsColorEncoding\": \"spatialChannelColor\",\n",
- " }]),\n",
- " }]),\n",
- "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"obsSegmentations\"))\n",
- "\n",
- "# Layout the views\n",
- "vc.layout(spatial | layer_controller);"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Render the widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.14"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/spatial_data_merfish.mo.py b/docs/notebooks/spatial_data_merfish.mo.py
new file mode 100644
index 00000000..94081dec
--- /dev/null
+++ b/docs/notebooks/spatial_data_merfish.mo.py
@@ -0,0 +1,196 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Visualization of a SpatialData object, blobs example
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Import dependencies
+
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ sdata_url = "https://data-2.vitessce.io/data/moffitt/merfish_mouse_ileum.sdata.zarr"
+ return (sdata_url,)
+
+
+@app.cell
+def _():
+ from vitessce import (
+ VitessceConfig,
+ ViewType as vt,
+ CoordinationType as ct,
+ CoordinationLevel as CL,
+ SpatialDataWrapper,
+ get_initial_coordination_scope_prefix
+ )
+ return (
+ CL,
+ SpatialDataWrapper,
+ VitessceConfig,
+ get_initial_coordination_scope_prefix,
+ )
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Configure Vitessce
+
+ Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views.
+ """
+ )
+ return
+
+
+@app.cell
+def _(
+ CL,
+ SpatialDataWrapper,
+ VitessceConfig,
+ get_initial_coordination_scope_prefix,
+ sdata_url,
+):
+ vc = VitessceConfig(
+ schema_version="1.0.18",
+ name='SpatialData with MERFISH data',
+ )
+ # Add data to the configuration:
+
+ dataset = vc.add_dataset(name='MERFISH').add_object(SpatialDataWrapper(
+ sdata_url=sdata_url,
+ # The following paths are relative to the root of the SpatialData zarr store on-disk.
+ image_path="images/stains",
+ coordinate_system="global",
+ coordination_values={
+ "fileUid": "stains"
+ }
+ )).add_object(SpatialDataWrapper(
+ sdata_url=sdata_url,
+ # The following paths are relative to the root of the SpatialData zarr store on-disk.
+ obs_segmentations_path="labels/dapi_labels",
+ coordinate_system="global",
+ coordination_values={
+ "obsType": "nucleus",
+ "fileUid": "dapi"
+ }
+ )).add_object(SpatialDataWrapper(
+ sdata_url=sdata_url,
+ # The following paths are relative to the root of the SpatialData zarr store on-disk.
+ obs_segmentations_path="labels/membrane_labels",
+ coordinate_system="global",
+ coordination_values={
+ "obsType": "cell",
+ "fileUid": "membrane"
+ }
+ ))
+
+ # Add views (visualizations) to the configuration:
+ spatial = vc.add_view("spatialBeta", dataset=dataset)
+ layer_controller = vc.add_view("layerControllerBeta", dataset=dataset)
+
+ vc.link_views_by_dict([spatial, layer_controller], {
+ 'imageLayer': CL([{
+ "fileUid": "stains",
+ 'photometricInterpretation': 'BlackIsZero',
+ 'spatialLayerOpacity': 1.0,
+ 'spatialLayerVisible': True,
+ 'imageChannel': CL([
+ {
+ 'spatialChannelVisible': True,
+ "spatialTargetC": 0, # DAPI, Nucleus
+ "spatialChannelColor": [0, 0, 255],
+ "spatialChannelOpacity": 1.0
+ },
+ {
+ 'spatialChannelVisible': True,
+ "spatialTargetC": 1, # Membrane, Cell
+ "spatialChannelColor": [255, 255, 255],
+ "spatialChannelOpacity": 1.0
+ }
+ ])
+ }]),
+ }, scope_prefix=get_initial_coordination_scope_prefix("A", "image"))
+
+ vc.link_views_by_dict([spatial, layer_controller], {
+ 'segmentationLayer': CL([{
+ "fileUid": "membrane",
+ 'spatialLayerOpacity': 1.0,
+ 'spatialLayerVisible': True,
+ 'segmentationChannel': CL([{
+ 'spatialChannelVisible': True,
+ 'obsType': 'cell',
+ "spatialChannelColor": [200, 200, 200],
+ "obsColorEncoding": "spatialChannelColor",
+ }]),
+ }, {
+ "fileUid": "dapi",
+ 'spatialLayerOpacity': 1.0,
+ 'spatialLayerVisible': True,
+ 'segmentationChannel': CL([{
+ 'spatialChannelVisible': True,
+ 'obsType': 'nucleus',
+ "spatialChannelColor": [255, 255, 255],
+ "obsColorEncoding": "spatialChannelColor",
+ }]),
+ }]),
+ }, scope_prefix=get_initial_coordination_scope_prefix("A", "obsSegmentations"))
+
+ # Layout the views
+ vc.layout(spatial | layer_controller);
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### Render the widget
+ """
+ )
+ return
+
+
+@app.cell
+def _(vc):
+ vw = vc.widget()
+ vw
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/spatial_data_merfish_2.ipynb b/docs/notebooks/spatial_data_merfish_2.ipynb
deleted file mode 100644
index 74296a55..00000000
--- a/docs/notebooks/spatial_data_merfish_2.ipynb
+++ /dev/null
@@ -1,172 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Visualization of a SpatialData object"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Import dependencies\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join, isfile, isdir\n",
- "from urllib.request import urlretrieve\n",
- "import zipfile\n",
- "\n",
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " ViewType as vt,\n",
- " CoordinationType as ct,\n",
- " CoordinationLevel as CL,\n",
- " SpatialDataWrapper,\n",
- " get_initial_coordination_scope_prefix\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "data_dir = \"data\"\n",
- "zip_filepath = join(data_dir, \"merfish_2.spatialdata.zarr.zip\")\n",
- "spatialdata_filepath = join(data_dir, \"merfish_2.spatialdata.zarr\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "if not isdir(spatialdata_filepath):\n",
- " if not isfile(zip_filepath):\n",
- " os.makedirs(data_dir, exist_ok=True)\n",
- " urlretrieve('https://s3.embl.de/spatialdata/spatialdata-sandbox/merfish.zip', zip_filepath)\n",
- " with zipfile.ZipFile(zip_filepath,\"r\") as zip_ref:\n",
- " zip_ref.extractall(data_dir)\n",
- " os.rename(join(data_dir, \"data.zarr\"), spatialdata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Configure Vitessce\n",
- "\n",
- "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(\n",
- " schema_version=\"1.0.18\",\n",
- " name='MERFISH SpatialData Demo',\n",
- ")\n",
- "# Add data to the configuration:\n",
- "wrapper = SpatialDataWrapper(\n",
- " sdata_path=spatialdata_filepath,\n",
- " # The following paths are relative to the root of the SpatialData zarr store on-disk.\n",
- " image_path=\"images/rasterized\",\n",
- " table_path=\"tables/table\",\n",
- " obs_feature_matrix_path=\"tables/table/X\",\n",
- " obs_spots_path=\"shapes/cells\",\n",
- " coordinate_system=\"global\",\n",
- " coordination_values={\n",
- " # The following tells Vitessce to consider each observation as a \"spot\"\n",
- " \"obsType\": \"cell\",\n",
- " }\n",
- ")\n",
- "dataset = vc.add_dataset(name='MERFISH').add_object(wrapper)\n",
- "\n",
- "# Add views (visualizations) to the configuration:\n",
- "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
- "feature_list = vc.add_view(\"featureList\", dataset=dataset)\n",
- "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
- "obs_sets = vc.add_view(\"obsSets\", dataset=dataset)\n",
- "\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " 'spotLayer': CL([{\n",
- " 'obsType': 'cell',\n",
- " }]),\n",
- "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"obsSpots\"))\n",
- "\n",
- "vc.link_views([spatial, layer_controller, feature_list, obs_sets], ['obsType'], [wrapper.obs_type_label])\n",
- "\n",
- "# Layout the views\n",
- "vc.layout(spatial | (feature_list / layer_controller / obs_sets));"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Render the widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.14"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/spatial_data_merfish_2.mo.py b/docs/notebooks/spatial_data_merfish_2.mo.py
new file mode 100644
index 00000000..4c7781d4
--- /dev/null
+++ b/docs/notebooks/spatial_data_merfish_2.mo.py
@@ -0,0 +1,180 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Visualization of a SpatialData object
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Import dependencies
+
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ import os
+ from os.path import join, isfile, isdir
+ from urllib.request import urlretrieve
+ import zipfile
+
+ from vitessce import (
+ VitessceConfig,
+ ViewType as vt,
+ CoordinationType as ct,
+ CoordinationLevel as CL,
+ SpatialDataWrapper,
+ get_initial_coordination_scope_prefix
+ )
+ return (
+ CL,
+ SpatialDataWrapper,
+ VitessceConfig,
+ get_initial_coordination_scope_prefix,
+ isdir,
+ isfile,
+ join,
+ os,
+ urlretrieve,
+ zipfile,
+ )
+
+
+@app.cell
+def _(join):
+ data_dir = "data"
+ zip_filepath = join(data_dir, "merfish_2.spatialdata.zarr.zip")
+ spatialdata_filepath = join(data_dir, "merfish_2.spatialdata.zarr")
+ return data_dir, spatialdata_filepath, zip_filepath
+
+
+@app.cell
+def _(
+ data_dir,
+ isdir,
+ isfile,
+ join,
+ os,
+ spatialdata_filepath,
+ urlretrieve,
+ zip_filepath,
+ zipfile,
+):
+ if not isdir(spatialdata_filepath):
+ if not isfile(zip_filepath):
+ os.makedirs(data_dir, exist_ok=True)
+ urlretrieve('https://s3.embl.de/spatialdata/spatialdata-sandbox/merfish.zip', zip_filepath)
+ with zipfile.ZipFile(zip_filepath,"r") as zip_ref:
+ zip_ref.extractall(data_dir)
+ os.rename(join(data_dir, "data.zarr"), spatialdata_filepath)
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Configure Vitessce
+
+ Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views.
+ """
+ )
+ return
+
+
+@app.cell
+def _(
+ CL,
+ SpatialDataWrapper,
+ VitessceConfig,
+ get_initial_coordination_scope_prefix,
+ spatialdata_filepath,
+):
+ vc = VitessceConfig(
+ schema_version="1.0.18",
+ name='MERFISH SpatialData Demo',
+ )
+ # Add data to the configuration:
+ wrapper = SpatialDataWrapper(
+ sdata_path=spatialdata_filepath,
+ # The following paths are relative to the root of the SpatialData zarr store on-disk.
+ image_path="images/rasterized",
+ table_path="tables/table",
+ obs_feature_matrix_path="tables/table/X",
+ obs_spots_path="shapes/cells",
+ coordinate_system="global",
+ coordination_values={
+ # The following tells Vitessce to consider each observation as a "spot"
+ "obsType": "cell",
+ }
+ )
+ dataset = vc.add_dataset(name='MERFISH').add_object(wrapper)
+
+ # Add views (visualizations) to the configuration:
+ spatial = vc.add_view("spatialBeta", dataset=dataset)
+ feature_list = vc.add_view("featureList", dataset=dataset)
+ layer_controller = vc.add_view("layerControllerBeta", dataset=dataset)
+ obs_sets = vc.add_view("obsSets", dataset=dataset)
+
+ vc.link_views_by_dict([spatial, layer_controller], {
+ 'spotLayer': CL([{
+ 'obsType': 'cell',
+ }]),
+ }, scope_prefix=get_initial_coordination_scope_prefix("A", "obsSpots"))
+
+ vc.link_views([spatial, layer_controller, feature_list, obs_sets], ['obsType'], [wrapper.obs_type_label])
+
+ # Layout the views
+ vc.layout(spatial | (feature_list / layer_controller / obs_sets));
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### Render the widget
+ """
+ )
+ return
+
+
+@app.cell
+def _(vc):
+ vw = vc.widget()
+ vw
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/spatial_data_mouseliver.ipynb b/docs/notebooks/spatial_data_mouseliver.ipynb
deleted file mode 100644
index e1078c49..00000000
--- a/docs/notebooks/spatial_data_mouseliver.ipynb
+++ /dev/null
@@ -1,789 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "tags": []
- },
- "source": [
- "# Visualization of a SpatialData object and individual Spatial Elements, local data"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "This notebook explains how to create interactive visualizations of data that is accessible locally.\n",
- "\n",
- "\n",
- "We progress through different visualization tasks, first demonstrating how Vitessce facilitates integrated imaging and spatial single-cell visualizations, then demonstrating visualization of non-spatial and image-only datasets."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- ""
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Utility dependencies"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "First, we import utility dependencies which will be used to download the example dataset and manipulate file paths, zip files, and JSON files."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join, isfile, isdir\n",
- "from urllib.request import urlretrieve\n",
- "import zipfile\n",
- "import json"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Dependencies for Vitessce"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Here, we import classes and functions from the `vitessce` Python package.\n",
- "This package includes not only APIs for [visualization configuration](https://python-docs.vitessce.io/api_config.html) but also [helper functions](https://python-docs.vitessce.io/api_data.html#vitessce-data-utils) for basic data transformation tasks.\n",
- "To specify mappings between data fields and visualization properties, the package contains [classes](https://python-docs.vitessce.io/api_data.html#module-vitessce.wrappers) which wrap standard single-cell data structures stored in formats including [AnnData](https://doi.org/10.1101/2021.12.16.473007), [SpatialData](https://doi.org/10.1038/s41592-024-02212-x), [OME-TIFF](https://doi.org/10.1007/978-3-030-23937-4_1), and [OME-Zarr](https://doi.org/10.1038/s41592-021-01326-w):\n",
- "\n",
- "- [AnnDataWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.AnnDataWrapper)\n",
- "- [ImageOmeTiffWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ImageOmeTiffWrapper)\n",
- "- [ImageOmeZarrWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ImageOmeZarrWrapper)\n",
- "- [ObsSegmentationsOmeTiffWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ObsSegmentationsOmeTiffWrapper)\n",
- "- [ObsSegmentationsOmeZarrWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ObsSegmentationsOmeZarrWrapper)\n",
- "- [SpatialDataWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.SpatialDataWrapper)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " ViewType as vt,\n",
- " CoordinationType as ct,\n",
- " CoordinationLevel as CL,\n",
- " SpatialDataWrapper,\n",
- " AnnDataWrapper,\n",
- " ImageOmeTiffWrapper,\n",
- " ImageOmeZarrWrapper,\n",
- " ObsSegmentationsOmeZarrWrapper,\n",
- " get_initial_coordination_scope_prefix,\n",
- " hconcat,\n",
- " vconcat,\n",
- ")\n",
- "from vitessce.data_utils import (\n",
- " VAR_CHUNK_SIZE,\n",
- " generate_h5ad_ref_spec,\n",
- " multiplex_img_to_ome_tiff,\n",
- " multiplex_img_to_ome_zarr,\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Dependencies for data structures"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "In this blog post, we perform basic data transformation tasks to save individual elements of an integrated SpatialData object to separate files in AnnData, OME-TIFF, and OME-Zarr formats.\n",
- "To perform these data transformations, we import the following dependencies.\n",
- "In general, you will typically not need to import all of these dependencies, either because you are only working with data in one of these formats, or because the data you intend to visualize is already saved to a file or directory.\n",
- "\n",
- "Note: Dependencies such as `spatialdata` may need to be installed before they can be imported in the next code cell."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import numpy as np\n",
- "from spatialdata import read_zarr\n",
- "from anndata import AnnData\n",
- "from ome_zarr.writer import write_image\n",
- "import tifffile\n",
- "from generate_tiff_offsets import get_offsets"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Download example dataset"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "We download a mouse liver dataset which serves as a SpatialData [example dataset](https://github.com/scverse/spatialdata-notebooks/blob/main/notebooks/examples/transformations.ipynb).\n",
- "\n",
- "This dataset was generated by [Guilliams et al.](https://doi.org/10.1016/j.cell.2021.12.018) and processed using [SPArrOW](https://doi.org/10.1101/2024.07.04.601829) during the SpatialData [developer workshop](https://doi.org/10.37044/osf.io/8ck3e) in 2024."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "data_dir = \"data\"\n",
- "zip_filepath = join(data_dir, \"mouse_liver.spatialdata.zarr.zip\")\n",
- "spatialdata_filepath = join(data_dir, \"mouse_liver.spatialdata.zarr\")\n",
- "adata_zarr_filepath = join(data_dir, \"mouse_liver.anndata.zarr\")\n",
- "adata_h5ad_filepath = join(data_dir, \"mouse_liver.h5ad\")\n",
- "ref_spec_json_filepath = join(data_dir, \"mouse_liver.h5ad.ref.json\")\n",
- "ome_tiff_filepath = join(data_dir, \"mouse_liver.ome.tif\")\n",
- "offsets_json_filepath = join(data_dir, \"mouse_liver.ome.tif.offsets.json\")\n",
- "ome_zarr_filepath = join(data_dir, \"mouse_liver.ome.zarr\")\n",
- "labels_ome_zarr_filepath = join(data_dir, \"mouse_liver.labels.ome.zarr\")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "The following code uses Python's `urlretrieve` to download the SpatialData object as a zip file, then unzips the file using the `zipfile` module."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "if not isdir(spatialdata_filepath):\n",
- " if not isfile(zip_filepath):\n",
- " os.makedirs(data_dir, exist_ok=True)\n",
- " urlretrieve('https://s3.embl.de/spatialdata/spatialdata-sandbox/mouse_liver.zip', zip_filepath)\n",
- " with zipfile.ZipFile(zip_filepath,\"r\") as zip_ref:\n",
- " zip_ref.extractall(data_dir)\n",
- " os.rename(join(data_dir, \"data.zarr\"), spatialdata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "tags": []
- },
- "source": [
- "## Visualization of a SpatialData object"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "SpatialData objects are the most complex type of data structure we will work with in this blog post.\n",
- "SpatialData objects function as contains for multiple types of Spatial Elements:\n",
- "\n",
- "- Tables (each table is represented as an AnnData object)\n",
- "- Points (e.g., coordinates of transcripts from FISH-based experiments)\n",
- "- Shapes (vector-based shapes such as polygons and circles)\n",
- "- Labels (label images, i.e., segmentation bitmasks; each label image is stored using OME-Zarr)\n",
- "- Images (microscopy images; each image is stored using OME-Zarr)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Configure Vitessce\n",
- "\n",
- "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views.\n",
- "To visualize data stored in a SpatialData object, we use the `SpatialDataWrapper` class and specify the paths (relative to the root of the Zarr [directory store](https://zarr.readthedocs.io/en/v2.18.5/api/storage.html#zarr.storage.DirectoryStore)) to different spatial elements of interest."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "# Create a VitessceConfig instance.\n",
- "vc = VitessceConfig(schema_version=\"1.0.18\", name=\"SpatialData Demo\")\n",
- "\n",
- "# Instantiate the wrapper class, specifying data fields of interest.\n",
- "wrapper = SpatialDataWrapper(\n",
- " sdata_path=spatialdata_filepath,\n",
- " # The following paths are relative to the root of the SpatialData Zarr store on-disk.\n",
- " table_path=\"tables/table\",\n",
- " image_path=\"images/raw_image\",\n",
- " obs_segmentations_path=\"labels/segmentation_mask\",\n",
- " obs_feature_matrix_path=\"tables/table/X\",\n",
- " obs_set_paths=[\"tables/table/obs/annotation\"],\n",
- " obs_set_names=[\"Annotation\"],\n",
- " region=\"nucleus_boundaries\",\n",
- " coordinate_system=\"global\",\n",
- " coordination_values={\n",
- " \"obsType\": \"cell\" \n",
- " }\n",
- ")\n",
- "# Add a new dataset to the Vitessce configuration,\n",
- "# then add the wrapper class instance to this dataset.\n",
- "dataset = vc.add_dataset(name='Mouse Liver').add_object(wrapper)\n",
- "\n",
- "# Add views (visualizations) to the configuration.\n",
- "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
- "feature_list = vc.add_view(\"featureList\", dataset=dataset)\n",
- "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
- "obs_sets = vc.add_view(\"obsSets\", dataset=dataset)\n",
- "heatmap = vc.add_view(\"heatmap\", dataset=dataset)\n",
- "\n",
- "[obs_color_encoding_scope] = vc.add_coordination(\"obsColorEncoding\")\n",
- "obs_color_encoding_scope.set_value(\"cellSetSelection\")\n",
- "\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " \"imageLayer\": CL([{\n",
- " \"photometricInterpretation\": \"BlackIsZero\",\n",
- " \"imageChannel\": CL([{\n",
- " \"spatialTargetC\": 0,\n",
- " \"spatialChannelColor\": [255, 255, 255],\n",
- " \"spatialChannelWindow\": [0, 4000],\n",
- " }])\n",
- " }]),\n",
- "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
- "\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " \"segmentationLayer\": CL([{\n",
- " \"segmentationChannel\": CL([{\n",
- " \"obsColorEncoding\": obs_color_encoding_scope,\n",
- " }]),\n",
- " }]),\n",
- "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"obsSegmentations\"))\n",
- "\n",
- "vc.link_views([spatial, layer_controller, feature_list, obs_sets, heatmap], [\"obsType\"], [wrapper.obs_type_label])\n",
- "vc.link_views_by_dict([feature_list, obs_sets, heatmap], {\n",
- " \"obsColorEncoding\": obs_color_encoding_scope,\n",
- "}, meta=False)\n",
- "\n",
- "# Layout the views in a grid arrangement.\n",
- "vc.layout((spatial / heatmap) | (layer_controller / (feature_list | obs_sets)));"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Render the widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Extract AnnData object from SpatialData object"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "The above example demonstrates how to visualize a spatial 'omics dataset containing not only single-cell information (e.g., a cell-by-gene expression matrix, cell type annotations) but also an image and cell segmentations.\n",
- "To demonstrate how to use Vitessce to visualize data from a (non-spatial) single-cell experiment, we will extract this information from the SpatialData object and save it to a simpler [AnnData](https://anndata.readthedocs.io/) object (ignoring the imaging and spatially-resolved elements)."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "sdata = read_zarr(spatialdata_filepath)\n",
- "sdata"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "adata = sdata.tables['table']\n",
- "adata"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "As Zarr-formatted data can be easily visualized by Vitessce, we recommend saving the AnnData object to a Zarr store using the [write_zarr](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_zarr.html) method.\n",
- "Optionally, the shape of array chunks (for the AnnData `X` array) can be specified as a parameter, to optimize performance based on data access patterns.\n",
- "For example, a common pattern is to visualize data across all cells for one gene.\n",
- "To support such a pattern, the chunk shape can be specified as follows, `(total number of cells, small number of genes)`, resulting in tall-and-skinny array chunks."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "adata.write_zarr(adata_zarr_filepath, chunks=(adata.shape[0], VAR_CHUNK_SIZE))"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Alternatively, your AnnData object may already be stored using the H5AD (HDF5-based) format.\n",
- "To demonstrate this scenario, we save the object using the [write_h5ad](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_h5ad.html) method."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "adata.write_h5ad(adata_h5ad_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "To read H5AD-formatted data, Vitessce requires an accompanying JSON [references specification](https://fsspec.github.io/kerchunk/spec.html) file, which can be constructed using the `generate_h5ad_ref_spec` utility function."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "ref_dict = generate_h5ad_ref_spec(adata_h5ad_filepath)\n",
- "with open(ref_spec_json_filepath, \"w\") as f:\n",
- " json.dump(ref_dict, f)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Visualization of an AnnData object"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Zarr-based AnnData"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.18\", name=\"AnnData (zarr)\")\n",
- "# Add data.\n",
- "wrapper = AnnDataWrapper(\n",
- " adata_path=adata_zarr_filepath,\n",
- " obs_feature_matrix_path=\"X\",\n",
- " obs_set_paths=[\"obs/annotation\"],\n",
- " obs_set_names=[\"Annotation\"],\n",
- " coordination_values={\n",
- " \"obsType\": \"cell\" \n",
- " }\n",
- ")\n",
- "dataset = vc.add_dataset(name='Mouse Liver').add_object(wrapper)\n",
- "\n",
- "# Add views.\n",
- "heatmap = vc.add_view(vt.HEATMAP, dataset=dataset)\n",
- "feature_list = vc.add_view(vt.FEATURE_LIST, dataset=dataset)\n",
- "obs_sets = vc.add_view(vt.OBS_SETS, dataset=dataset)\n",
- "violin_plots = vc.add_view(\"obsSetFeatureValueDistribution\", dataset=dataset)\n",
- "\n",
- "vc.link_views([heatmap, feature_list, obs_sets], ['obsType', 'featureValueColormapRange'], ['cell', [0, 0.01]])\n",
- "\n",
- "# Layout the views.\n",
- "vc.layout((heatmap / violin_plots) | (feature_list / obs_sets));"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc.widget()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### H5AD-based AnnData"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.18\", name=\"AnnData (h5ad)\")\n",
- "# Add data.\n",
- "wrapper = AnnDataWrapper(\n",
- " adata_path=adata_h5ad_filepath,\n",
- " ref_path=ref_spec_json_filepath,\n",
- " obs_feature_matrix_path=\"X\",\n",
- " obs_set_paths=[\"obs/annotation\"],\n",
- " obs_set_names=[\"Annotation\"],\n",
- " coordination_values={\n",
- " \"obsType\": \"cell\" \n",
- " }\n",
- ")\n",
- "dataset = vc.add_dataset(name='Mouse Liver').add_object(wrapper)\n",
- "\n",
- "# Add views.\n",
- "heatmap = vc.add_view(vt.HEATMAP, dataset=dataset)\n",
- "feature_list = vc.add_view(vt.FEATURE_LIST, dataset=dataset)\n",
- "obs_sets = vc.add_view(vt.OBS_SETS, dataset=dataset)\n",
- "violin_plots = vc.add_view(\"obsSetFeatureValueDistribution\", dataset=dataset)\n",
- "\n",
- "vc.link_views([heatmap, feature_list, obs_sets], ['obsType', 'featureValueColormapRange'], ['cell', [0, 0.01]])\n",
- "\n",
- "# Layout the views.\n",
- "vc.layout((heatmap / violin_plots) | (feature_list / obs_sets));"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc.widget()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Extract image from SpatialData object"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "In contrast to extraction of the non-spatial data from the SpatialData object, we can extract the imaging (and segmentation/label image) data and save it to a dedicated bioimaging file format."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "img_arr = sdata.images['raw_image'].to_numpy()\n",
- "labels_arr = sdata.labels['segmentation_mask'].to_numpy()\n",
- "labels_arr = labels_arr[np.newaxis, :]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Save image to OME-Zarr"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "For small images, the data can be saved to OME-Zarr or OME-TIFF format using [utility functions](https://python-docs.vitessce.io/api_data.html#vitessce-data-utils) from the Vitessce package.\n",
- "Larger images require generation of an [image pyramid](https://en.wikipedia.org/wiki/Pyramid_(image_processing)), which can be performed using tools from the OME ecosystem such as [bioformats2raw](https://github.com/glencoesoftware/bioformats2raw) and [raw2ometiff](https://github.com/glencoesoftware/raw2ometiff)."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "multiplex_img_to_ome_zarr(img_arr, [\"Channel 0\"], ome_zarr_filepath)\n",
- "multiplex_img_to_ome_zarr(labels_arr, [\"cell\"], labels_ome_zarr_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Save image and segmentations to OME-TIFF"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "To efficiently visualize OME-TIFF data using Vitessce, a JSON-based offsets file can be constructed using [generate-tiff-offsets](https://github.com/hms-dbmi/generate-tiff-offsets).\n",
- "This JSON file contains byte offsets into different partitions of the TIFF file, effectively resulting in an \"indexed TIFF\" which is described by [Manz et al. 2022](https://doi.org/10.1038/s41592-022-01482-7)."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "multiplex_img_to_ome_tiff(img_arr, [\"Channel 0\"], ome_tiff_filepath)\n",
- "offsets = get_offsets(ome_tiff_filepath)\n",
- "with open(offsets_json_filepath, \"w\") as f:\n",
- " json.dump(offsets, f)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Visualization of an image file"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### OME-Zarr image"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.18\", name=\"Image (ome-zarr)\")\n",
- "\n",
- "# Add data.\n",
- "img_wrapper = ImageOmeZarrWrapper(\n",
- " img_path=ome_zarr_filepath,\n",
- " coordination_values={\n",
- " \"fileUid\": \"image\",\n",
- " }\n",
- ")\n",
- "segmentations_wrapper = ObsSegmentationsOmeZarrWrapper(\n",
- " img_path=labels_ome_zarr_filepath,\n",
- " coordination_values={\n",
- " \"fileUid\": \"segmentations\",\n",
- " }\n",
- ")\n",
- "# Here, we chain .add_object calls to add both the image and segmentation\n",
- "# wrapper instances to the same dataset.\n",
- "dataset = vc.add_dataset(name='Mouse Liver').add_object(img_wrapper).add_object(segmentations_wrapper)\n",
- "\n",
- "# Add views.\n",
- "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
- "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
- "\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " 'imageLayer': CL([{\n",
- " # In case there are multiple image files in our dataset,\n",
- " # we use fileUid to specify which file we intend to visualize\n",
- " # in this image layer.\n",
- " 'fileUid': 'image',\n",
- " 'photometricInterpretation': 'BlackIsZero',\n",
- " 'imageChannel': CL([{\n",
- " 'spatialTargetC': 0,\n",
- " 'spatialChannelColor': [255, 255, 255],\n",
- " 'spatialChannelWindow': [0, 4000],\n",
- " }])\n",
- " }]),\n",
- "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
- "\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " 'segmentationLayer': CL([{\n",
- " # In case there are multiple segmentation files in our dataset,\n",
- " # we use fileUid to specify which file we intend to visualize\n",
- " # in this segmentation layer.\n",
- " 'fileUid': 'segmentations',\n",
- " 'segmentationChannel': CL([{\n",
- " 'obsColorEncoding': 'spatialChannelColor',\n",
- " 'spatialChannelColor': [0, 255, 0],\n",
- " 'spatialChannelOpacity': 0.75,\n",
- " 'spatialSegmentationFilled': False,\n",
- " 'spatialSegmentationStrokeWidth': 0.25,\n",
- " }]),\n",
- " }]),\n",
- "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"obsSegmentations\"))\n",
- "\n",
- "vc.link_views([spatial, layer_controller, feature_list, obs_sets], ['obsType'], ['cell'])\n",
- "\n",
- "# Layout the views.\n",
- "vc.layout(hconcat(spatial, layer_controller, split=(2, 1)));"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### OME-TIFF image"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.18\", name=\"Image and segmentations (ome-tiff)\")\n",
- "# Add data.\n",
- "wrapper = ImageOmeTiffWrapper(\n",
- " img_path=ome_tiff_filepath,\n",
- " offsets_path=offsets_json_filepath\n",
- ")\n",
- "dataset = vc.add_dataset(name='Mouse Liver').add_object(wrapper)\n",
- "\n",
- "# Add views.\n",
- "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
- "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
- "\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " 'imageLayer': CL([{\n",
- " 'photometricInterpretation': 'BlackIsZero',\n",
- " 'imageChannel': CL([{\n",
- " 'spatialTargetC': 0,\n",
- " 'spatialChannelColor': [255, 255, 255],\n",
- " 'spatialChannelWindow': [0, 4000],\n",
- " }])\n",
- " }]),\n",
- "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
- "\n",
- "# Layout the views.\n",
- "vc.layout(hconcat(spatial, layer_controller, split=(2, 1)));"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc.widget()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Data location options\n",
- "\n",
- "Vitessce can visualize data [not only stored](https://python-docs.vitessce.io/data_options.html) locally (referenced using local file or directory paths) but also stored remotely (referenced using absolute URL paths).\n",
- "Depending on whether the Python kernel running the Jupyter process is running locally versus remotely (e.g., on a cluster or cloud platform such as Google Colab), certain data locations may be challenging to access from the machine running the Jupyter notebook frontend (i.e., the machine on which the web browser used to view the notebook is installed).\n",
- "\n",
- "To provide data via one of these alternative mechanisms, use parameters with the following suffices when instantiating the data wrapper classes.\n",
- "\n",
- "- `_path`: Local file or directory\n",
- "- `_url`: Remote file or directory\n",
- "- `_store`: Zarr-store-accessible (for zarr-based formats)\n",
- "- `_artifact`: Lamin artifact\n",
- "\n",
- "For example, `adata_path` can be exchanged for one of the following options.\n",
- "\n",
- "```diff\n",
- "AnnDataWrapper(\n",
- "- adata_path=\"./mouse_liver.spatialdata.zarr\",\n",
- "+ adata_url=\"https://example.com/mouse_liver.spatialdata.zarr\", # Absolute URL\n",
- "+ adata_store=\"./mouse_liver.spatialdata.zarr\", # String interpreted as root of DirectoryStore\n",
- "+ adata_store=zarr.DirectoryStore(\"./mouse_liver.spatialdata.zarr\"), # Instance of zarr.storage\n",
- "+ adata_artifact=adata_zarr_artifact, # Instance of ln.Artifact\n",
- " ...\n",
- "```\n",
- "\n",
- "Note that the `_store` options are only available for Zarr-based formats, such as AnnDataWrapper, SpatialDataWrapper, and ImageOmeZarrWrapper.\n",
- "Further, when multiple files are required, such as both `adata_path` and `ref_path` (for the JSON reference specification file accompanying an H5AD file) or `img_path` and `offsets_path`, multiple parameter suffices may need to be changed."
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.14"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/spatial_data_mouseliver.mo.py b/docs/notebooks/spatial_data_mouseliver.mo.py
new file mode 100644
index 00000000..f5e690cf
--- /dev/null
+++ b/docs/notebooks/spatial_data_mouseliver.mo.py
@@ -0,0 +1,754 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Visualization of a SpatialData object and individual Spatial Elements, local data
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ This notebook explains how to create interactive visualizations of data that is accessible locally.
+
+
+ We progress through different visualization tasks, first demonstrating how Vitessce facilitates integrated imaging and spatial single-cell visualizations, then demonstrating visualization of non-spatial and image-only datasets.
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Utility dependencies
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ First, we import utility dependencies which will be used to download the example dataset and manipulate file paths, zip files, and JSON files.
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ import os
+ from os.path import join, isfile, isdir
+ from urllib.request import urlretrieve
+ import zipfile
+ import json
+ return isdir, isfile, join, json, os, urlretrieve, zipfile
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Dependencies for Vitessce
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ Here, we import classes and functions from the `vitessce` Python package.
+ This package includes not only APIs for [visualization configuration](https://python-docs.vitessce.io/api_config.html) but also [helper functions](https://python-docs.vitessce.io/api_data.html#vitessce-data-utils) for basic data transformation tasks.
+ To specify mappings between data fields and visualization properties, the package contains [classes](https://python-docs.vitessce.io/api_data.html#module-vitessce.wrappers) which wrap standard single-cell data structures stored in formats including [AnnData](https://doi.org/10.1101/2021.12.16.473007), [SpatialData](https://doi.org/10.1038/s41592-024-02212-x), [OME-TIFF](https://doi.org/10.1007/978-3-030-23937-4_1), and [OME-Zarr](https://doi.org/10.1038/s41592-021-01326-w):
+
+ - [AnnDataWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.AnnDataWrapper)
+ - [ImageOmeTiffWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ImageOmeTiffWrapper)
+ - [ImageOmeZarrWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ImageOmeZarrWrapper)
+ - [ObsSegmentationsOmeTiffWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ObsSegmentationsOmeTiffWrapper)
+ - [ObsSegmentationsOmeZarrWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ObsSegmentationsOmeZarrWrapper)
+ - [SpatialDataWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.SpatialDataWrapper)
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ from vitessce import (
+ VitessceConfig,
+ ViewType as vt,
+ CoordinationType as ct,
+ CoordinationLevel as CL,
+ SpatialDataWrapper,
+ AnnDataWrapper,
+ ImageOmeTiffWrapper,
+ ImageOmeZarrWrapper,
+ ObsSegmentationsOmeZarrWrapper,
+ get_initial_coordination_scope_prefix,
+ hconcat,
+ vconcat,
+ )
+ from vitessce.data_utils import (
+ VAR_CHUNK_SIZE,
+ generate_h5ad_ref_spec,
+ multiplex_img_to_ome_tiff,
+ multiplex_img_to_ome_zarr,
+ )
+ return (
+ AnnDataWrapper,
+ CL,
+ ImageOmeTiffWrapper,
+ ImageOmeZarrWrapper,
+ ObsSegmentationsOmeZarrWrapper,
+ SpatialDataWrapper,
+ VAR_CHUNK_SIZE,
+ VitessceConfig,
+ generate_h5ad_ref_spec,
+ get_initial_coordination_scope_prefix,
+ hconcat,
+ multiplex_img_to_ome_tiff,
+ multiplex_img_to_ome_zarr,
+ vt,
+ )
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Dependencies for data structures
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ In this blog post, we perform basic data transformation tasks to save individual elements of an integrated SpatialData object to separate files in AnnData, OME-TIFF, and OME-Zarr formats.
+ To perform these data transformations, we import the following dependencies.
+ In general, you will typically not need to import all of these dependencies, either because you are only working with data in one of these formats, or because the data you intend to visualize is already saved to a file or directory.
+
+ Note: Dependencies such as `spatialdata` may need to be installed before they can be imported in the next code cell.
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ import numpy as np
+ from spatialdata import read_zarr
+ from anndata import AnnData
+ from ome_zarr.writer import write_image
+ import tifffile
+ from generate_tiff_offsets import get_offsets
+ return get_offsets, np, read_zarr
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Download example dataset
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ We download a mouse liver dataset which serves as a SpatialData [example dataset](https://github.com/scverse/spatialdata-notebooks/blob/main/notebooks/examples/transformations.ipynb).
+
+ This dataset was generated by [Guilliams et al.](https://doi.org/10.1016/j.cell.2021.12.018) and processed using [SPArrOW](https://doi.org/10.1101/2024.07.04.601829) during the SpatialData [developer workshop](https://doi.org/10.37044/osf.io/8ck3e) in 2024.
+ """
+ )
+ return
+
+
+@app.cell
+def _(join):
+ data_dir = "data"
+ zip_filepath = join(data_dir, "mouse_liver.spatialdata.zarr.zip")
+ spatialdata_filepath = join(data_dir, "mouse_liver.spatialdata.zarr")
+ adata_zarr_filepath = join(data_dir, "mouse_liver.anndata.zarr")
+ adata_h5ad_filepath = join(data_dir, "mouse_liver.h5ad")
+ ref_spec_json_filepath = join(data_dir, "mouse_liver.h5ad.ref.json")
+ ome_tiff_filepath = join(data_dir, "mouse_liver.ome.tif")
+ offsets_json_filepath = join(data_dir, "mouse_liver.ome.tif.offsets.json")
+ ome_zarr_filepath = join(data_dir, "mouse_liver.ome.zarr")
+ labels_ome_zarr_filepath = join(data_dir, "mouse_liver.labels.ome.zarr")
+ return (
+ adata_h5ad_filepath,
+ adata_zarr_filepath,
+ data_dir,
+ labels_ome_zarr_filepath,
+ offsets_json_filepath,
+ ome_tiff_filepath,
+ ome_zarr_filepath,
+ ref_spec_json_filepath,
+ spatialdata_filepath,
+ zip_filepath,
+ )
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ The following code uses Python's `urlretrieve` to download the SpatialData object as a zip file, then unzips the file using the `zipfile` module.
+ """
+ )
+ return
+
+
+@app.cell
+def _(
+ data_dir,
+ isdir,
+ isfile,
+ join,
+ os,
+ spatialdata_filepath,
+ urlretrieve,
+ zip_filepath,
+ zipfile,
+):
+ if not isdir(spatialdata_filepath):
+ if not isfile(zip_filepath):
+ os.makedirs(data_dir, exist_ok=True)
+ urlretrieve('https://s3.embl.de/spatialdata/spatialdata-sandbox/mouse_liver.zip', zip_filepath)
+ with zipfile.ZipFile(zip_filepath,"r") as zip_ref:
+ zip_ref.extractall(data_dir)
+ os.rename(join(data_dir, "data.zarr"), spatialdata_filepath)
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Visualization of a SpatialData object
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ SpatialData objects are the most complex type of data structure we will work with in this blog post.
+ SpatialData objects function as contains for multiple types of Spatial Elements:
+
+ - Tables (each table is represented as an AnnData object)
+ - Points (e.g., coordinates of transcripts from FISH-based experiments)
+ - Shapes (vector-based shapes such as polygons and circles)
+ - Labels (label images, i.e., segmentation bitmasks; each label image is stored using OME-Zarr)
+ - Images (microscopy images; each image is stored using OME-Zarr)
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Configure Vitessce
+
+ Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views.
+ To visualize data stored in a SpatialData object, we use the `SpatialDataWrapper` class and specify the paths (relative to the root of the Zarr [directory store](https://zarr.readthedocs.io/en/v2.18.5/api/storage.html#zarr.storage.DirectoryStore)) to different spatial elements of interest.
+ """
+ )
+ return
+
+
+@app.cell
+def _(
+ CL,
+ SpatialDataWrapper,
+ VitessceConfig,
+ get_initial_coordination_scope_prefix,
+ spatialdata_filepath,
+):
+ vc = VitessceConfig(schema_version='1.0.18', name='SpatialData Demo')
+ _wrapper = SpatialDataWrapper(sdata_path=spatialdata_filepath, table_path='tables/table', image_path='images/raw_image', obs_segmentations_path='labels/segmentation_mask', obs_feature_matrix_path='tables/table/X', obs_set_paths=['tables/table/obs/annotation'], obs_set_names=['Annotation'], region='nucleus_boundaries', coordinate_system='global', coordination_values={'obsType': 'cell'})
+ _dataset = vc.add_dataset(name='Mouse Liver').add_object(_wrapper)
+ _spatial = vc.add_view('spatialBeta', dataset=_dataset)
+ feature_list = vc.add_view('featureList', dataset=_dataset)
+ _layer_controller = vc.add_view('layerControllerBeta', dataset=_dataset)
+ obs_sets = vc.add_view('obsSets', dataset=_dataset)
+ _heatmap = vc.add_view('heatmap', dataset=_dataset)
+ [obs_color_encoding_scope] = vc.add_coordination('obsColorEncoding')
+ obs_color_encoding_scope.set_value('cellSetSelection')
+ vc.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))
+ vc.link_views_by_dict([_spatial, _layer_controller], {'segmentationLayer': CL([{'segmentationChannel': CL([{'obsColorEncoding': obs_color_encoding_scope}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'obsSegmentations'))
+ vc.link_views([_spatial, _layer_controller, feature_list, obs_sets, _heatmap], ['obsType'], [_wrapper.obs_type_label])
+ vc.link_views_by_dict([feature_list, obs_sets, _heatmap], {'obsColorEncoding': obs_color_encoding_scope}, meta=False)
+ vc.layout(_spatial / _heatmap | _layer_controller / (feature_list | obs_sets))
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### Render the widget
+ """
+ )
+ return
+
+
+@app.cell
+def _(vc):
+ _vw = vc.widget()
+ _vw
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Extract AnnData object from SpatialData object
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ The above example demonstrates how to visualize a spatial 'omics dataset containing not only single-cell information (e.g., a cell-by-gene expression matrix, cell type annotations) but also an image and cell segmentations.
+ To demonstrate how to use Vitessce to visualize data from a (non-spatial) single-cell experiment, we will extract this information from the SpatialData object and save it to a simpler [AnnData](https://anndata.readthedocs.io/) object (ignoring the imaging and spatially-resolved elements).
+ """
+ )
+ return
+
+
+@app.cell
+def _(read_zarr, spatialdata_filepath):
+ sdata = read_zarr(spatialdata_filepath)
+ sdata
+ return (sdata,)
+
+
+@app.cell
+def _(sdata):
+ adata = sdata.tables['table']
+ adata
+ return (adata,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ As Zarr-formatted data can be easily visualized by Vitessce, we recommend saving the AnnData object to a Zarr store using the [write_zarr](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_zarr.html) method.
+ Optionally, the shape of array chunks (for the AnnData `X` array) can be specified as a parameter, to optimize performance based on data access patterns.
+ For example, a common pattern is to visualize data across all cells for one gene.
+ To support such a pattern, the chunk shape can be specified as follows, `(total number of cells, small number of genes)`, resulting in tall-and-skinny array chunks.
+ """
+ )
+ return
+
+
+@app.cell
+def _(VAR_CHUNK_SIZE, adata, adata_zarr_filepath):
+ adata.write_zarr(adata_zarr_filepath, chunks=(adata.shape[0], VAR_CHUNK_SIZE))
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ Alternatively, your AnnData object may already be stored using the H5AD (HDF5-based) format.
+ To demonstrate this scenario, we save the object using the [write_h5ad](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_h5ad.html) method.
+ """
+ )
+ return
+
+
+@app.cell
+def _(adata, adata_h5ad_filepath):
+ adata.write_h5ad(adata_h5ad_filepath)
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ To read H5AD-formatted data, Vitessce requires an accompanying JSON [references specification](https://fsspec.github.io/kerchunk/spec.html) file, which can be constructed using the `generate_h5ad_ref_spec` utility function.
+ """
+ )
+ return
+
+
+@app.cell
+def _(
+ adata_h5ad_filepath,
+ generate_h5ad_ref_spec,
+ json,
+ ref_spec_json_filepath,
+):
+ ref_dict = generate_h5ad_ref_spec(adata_h5ad_filepath)
+ with open(ref_spec_json_filepath, 'w') as _f:
+ json.dump(ref_dict, _f)
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Visualization of an AnnData object
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### Zarr-based AnnData
+ """
+ )
+ return
+
+
+@app.cell
+def _(AnnDataWrapper, VitessceConfig, adata_zarr_filepath, vt):
+ vc_1 = VitessceConfig(schema_version='1.0.18', name='AnnData (zarr)')
+ _wrapper = AnnDataWrapper(adata_path=adata_zarr_filepath, obs_feature_matrix_path='X', obs_set_paths=['obs/annotation'], obs_set_names=['Annotation'], coordination_values={'obsType': 'cell'})
+ _dataset = vc_1.add_dataset(name='Mouse Liver').add_object(_wrapper)
+ _heatmap = vc_1.add_view(vt.HEATMAP, dataset=_dataset)
+ feature_list_1 = vc_1.add_view(vt.FEATURE_LIST, dataset=_dataset)
+ obs_sets_1 = vc_1.add_view(vt.OBS_SETS, dataset=_dataset)
+ _violin_plots = vc_1.add_view('obsSetFeatureValueDistribution', dataset=_dataset)
+ vc_1.link_views([_heatmap, feature_list_1, obs_sets_1], ['obsType', 'featureValueColormapRange'], ['cell', [0, 0.01]])
+ vc_1.layout(_heatmap / _violin_plots | feature_list_1 / obs_sets_1)
+ return (vc_1,)
+
+
+@app.cell
+def _(vc_1):
+ vc_1.widget()
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### H5AD-based AnnData
+ """
+ )
+ return
+
+
+@app.cell
+def _(
+ AnnDataWrapper,
+ VitessceConfig,
+ adata_h5ad_filepath,
+ ref_spec_json_filepath,
+ vt,
+):
+ vc_2 = VitessceConfig(schema_version='1.0.18', name='AnnData (h5ad)')
+ _wrapper = AnnDataWrapper(adata_path=adata_h5ad_filepath, ref_path=ref_spec_json_filepath, obs_feature_matrix_path='X', obs_set_paths=['obs/annotation'], obs_set_names=['Annotation'], coordination_values={'obsType': 'cell'})
+ _dataset = vc_2.add_dataset(name='Mouse Liver').add_object(_wrapper)
+ _heatmap = vc_2.add_view(vt.HEATMAP, dataset=_dataset)
+ feature_list_2 = vc_2.add_view(vt.FEATURE_LIST, dataset=_dataset)
+ obs_sets_2 = vc_2.add_view(vt.OBS_SETS, dataset=_dataset)
+ _violin_plots = vc_2.add_view('obsSetFeatureValueDistribution', dataset=_dataset)
+ vc_2.link_views([_heatmap, feature_list_2, obs_sets_2], ['obsType', 'featureValueColormapRange'], ['cell', [0, 0.01]])
+ vc_2.layout(_heatmap / _violin_plots | feature_list_2 / obs_sets_2)
+ return feature_list_2, obs_sets_2, vc_2
+
+
+@app.cell
+def _(vc_2):
+ vc_2.widget()
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Extract image from SpatialData object
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ In contrast to extraction of the non-spatial data from the SpatialData object, we can extract the imaging (and segmentation/label image) data and save it to a dedicated bioimaging file format.
+ """
+ )
+ return
+
+
+@app.cell
+def _(np, sdata):
+ img_arr = sdata.images['raw_image'].to_numpy()
+ labels_arr = sdata.labels['segmentation_mask'].to_numpy()
+ labels_arr = labels_arr[np.newaxis, :]
+ return img_arr, labels_arr
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### Save image to OME-Zarr
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ For small images, the data can be saved to OME-Zarr or OME-TIFF format using [utility functions](https://python-docs.vitessce.io/api_data.html#vitessce-data-utils) from the Vitessce package.
+ Larger images require generation of an [image pyramid](https://en.wikipedia.org/wiki/Pyramid_(image_processing)), which can be performed using tools from the OME ecosystem such as [bioformats2raw](https://github.com/glencoesoftware/bioformats2raw) and [raw2ometiff](https://github.com/glencoesoftware/raw2ometiff).
+ """
+ )
+ return
+
+
+@app.cell
+def _(
+ img_arr,
+ labels_arr,
+ labels_ome_zarr_filepath,
+ multiplex_img_to_ome_zarr,
+ ome_zarr_filepath,
+):
+ multiplex_img_to_ome_zarr(img_arr, ["Channel 0"], ome_zarr_filepath)
+ multiplex_img_to_ome_zarr(labels_arr, ["cell"], labels_ome_zarr_filepath)
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### Save image and segmentations to OME-TIFF
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ To efficiently visualize OME-TIFF data using Vitessce, a JSON-based offsets file can be constructed using [generate-tiff-offsets](https://github.com/hms-dbmi/generate-tiff-offsets).
+ This JSON file contains byte offsets into different partitions of the TIFF file, effectively resulting in an "indexed TIFF" which is described by [Manz et al. 2022](https://doi.org/10.1038/s41592-022-01482-7).
+ """
+ )
+ return
+
+
+@app.cell
+def _(
+ get_offsets,
+ img_arr,
+ json,
+ multiplex_img_to_ome_tiff,
+ offsets_json_filepath,
+ ome_tiff_filepath,
+):
+ multiplex_img_to_ome_tiff(img_arr, ['Channel 0'], ome_tiff_filepath)
+ offsets = get_offsets(ome_tiff_filepath)
+ with open(offsets_json_filepath, 'w') as _f:
+ json.dump(offsets, _f)
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Visualization of an image file
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### OME-Zarr image
+ """
+ )
+ return
+
+
+@app.cell
+def _(
+ CL,
+ ImageOmeZarrWrapper,
+ ObsSegmentationsOmeZarrWrapper,
+ VitessceConfig,
+ feature_list_2,
+ get_initial_coordination_scope_prefix,
+ hconcat,
+ labels_ome_zarr_filepath,
+ obs_sets_2,
+ ome_zarr_filepath,
+):
+ vc_3 = VitessceConfig(schema_version='1.0.18', name='Image (ome-zarr)')
+ img_wrapper = ImageOmeZarrWrapper(img_path=ome_zarr_filepath, coordination_values={'fileUid': 'image'})
+ segmentations_wrapper = ObsSegmentationsOmeZarrWrapper(img_path=labels_ome_zarr_filepath, coordination_values={'fileUid': 'segmentations'})
+ _dataset = vc_3.add_dataset(name='Mouse Liver').add_object(img_wrapper).add_object(segmentations_wrapper)
+ _spatial = vc_3.add_view('spatialBeta', dataset=_dataset)
+ _layer_controller = vc_3.add_view('layerControllerBeta', dataset=_dataset)
+ vc_3.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'fileUid': 'image', 'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))
+ vc_3.link_views_by_dict([_spatial, _layer_controller], {'segmentationLayer': CL([{'fileUid': 'segmentations', 'segmentationChannel': CL([{'obsColorEncoding': 'spatialChannelColor', 'spatialChannelColor': [0, 255, 0], 'spatialChannelOpacity': 0.75, 'spatialSegmentationFilled': False, 'spatialSegmentationStrokeWidth': 0.25}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'obsSegmentations'))
+ vc_3.link_views([_spatial, _layer_controller, feature_list_2, obs_sets_2], ['obsType'], ['cell'])
+ vc_3.layout(hconcat(_spatial, _layer_controller, split=(2, 1)))
+ return (vc_3,)
+
+
+@app.cell
+def _(vc_3):
+ _vw = vc_3.widget()
+ _vw
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### OME-TIFF image
+ """
+ )
+ return
+
+
+@app.cell
+def _(
+ CL,
+ ImageOmeTiffWrapper,
+ VitessceConfig,
+ get_initial_coordination_scope_prefix,
+ hconcat,
+ offsets_json_filepath,
+ ome_tiff_filepath,
+):
+ vc_4 = VitessceConfig(schema_version='1.0.18', name='Image and segmentations (ome-tiff)')
+ _wrapper = ImageOmeTiffWrapper(img_path=ome_tiff_filepath, offsets_path=offsets_json_filepath)
+ _dataset = vc_4.add_dataset(name='Mouse Liver').add_object(_wrapper)
+ _spatial = vc_4.add_view('spatialBeta', dataset=_dataset)
+ _layer_controller = vc_4.add_view('layerControllerBeta', dataset=_dataset)
+ vc_4.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))
+ vc_4.layout(hconcat(_spatial, _layer_controller, split=(2, 1)))
+ return (vc_4,)
+
+
+@app.cell
+def _(vc_4):
+ vc_4.widget()
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Data location options
+
+ Vitessce can visualize data [not only stored](https://python-docs.vitessce.io/data_options.html) locally (referenced using local file or directory paths) but also stored remotely (referenced using absolute URL paths).
+ Depending on whether the Python kernel running the Jupyter process is running locally versus remotely (e.g., on a cluster or cloud platform such as Google Colab), certain data locations may be challenging to access from the machine running the Jupyter notebook frontend (i.e., the machine on which the web browser used to view the notebook is installed).
+
+ To provide data via one of these alternative mechanisms, use parameters with the following suffices when instantiating the data wrapper classes.
+
+ - `_path`: Local file or directory
+ - `_url`: Remote file or directory
+ - `_store`: Zarr-store-accessible (for zarr-based formats)
+ - `_artifact`: Lamin artifact
+
+ For example, `adata_path` can be exchanged for one of the following options.
+
+ ```diff
+ AnnDataWrapper(
+ - adata_path="./mouse_liver.spatialdata.zarr",
+ + adata_url="https://example.com/mouse_liver.spatialdata.zarr", # Absolute URL
+ + adata_store="./mouse_liver.spatialdata.zarr", # String interpreted as root of DirectoryStore
+ + adata_store=zarr.DirectoryStore("./mouse_liver.spatialdata.zarr"), # Instance of zarr.storage
+ + adata_artifact=adata_zarr_artifact, # Instance of ln.Artifact
+ ...
+ ```
+
+ Note that the `_store` options are only available for Zarr-based formats, such as AnnDataWrapper, SpatialDataWrapper, and ImageOmeZarrWrapper.
+ Further, when multiple files are required, such as both `adata_path` and `ref_path` (for the JSON reference specification file accompanying an H5AD file) or `img_path` and `offsets_path`, multiple parameter suffices may need to be changed.
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/spatial_data_mouseliver_remote.ipynb b/docs/notebooks/spatial_data_mouseliver_remote.ipynb
deleted file mode 100644
index d8bdb0dd..00000000
--- a/docs/notebooks/spatial_data_mouseliver_remote.ipynb
+++ /dev/null
@@ -1,627 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden",
- "tags": []
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "tags": []
- },
- "source": [
- "# Visualization of a SpatialData object and individual Spatial Elements, remote data"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "This notebook explains how to create interactive visualizations of data that are accessible remotely.\n",
- "\n",
- "\n",
- "We progress through different visualization tasks, first demonstrating how Vitessce facilitates integrated imaging and spatial single-cell visualizations, then demonstrating visualization of non-spatial and image-only datasets."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- ""
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Utility dependencies"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "First, we import utility dependencies which will be used to download the example dataset and manipulate file paths, zip files, and JSON files."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join, isfile, isdir\n",
- "from urllib.request import urlretrieve\n",
- "import zipfile\n",
- "import json"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Dependencies for Vitessce"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Here, we import classes and functions from the `vitessce` Python package.\n",
- "This package includes not only APIs for [visualization configuration](https://python-docs.vitessce.io/api_config.html) but also [helper functions](https://python-docs.vitessce.io/api_data.html#vitessce-data-utils) for basic data transformation tasks.\n",
- "To specify mappings between data fields and visualization properties, the package contains [classes](https://python-docs.vitessce.io/api_data.html#module-vitessce.wrappers) which wrap standard single-cell data structures stored in formats including [AnnData](https://doi.org/10.1101/2021.12.16.473007), [SpatialData](https://doi.org/10.1038/s41592-024-02212-x), [OME-TIFF](https://doi.org/10.1007/978-3-030-23937-4_1), and [OME-Zarr](https://doi.org/10.1038/s41592-021-01326-w):\n",
- "\n",
- "- [AnnDataWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.AnnDataWrapper)\n",
- "- [ImageOmeTiffWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ImageOmeTiffWrapper)\n",
- "- [ImageOmeZarrWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ImageOmeZarrWrapper)\n",
- "- [ObsSegmentationsOmeTiffWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ObsSegmentationsOmeTiffWrapper)\n",
- "- [ObsSegmentationsOmeZarrWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ObsSegmentationsOmeZarrWrapper)\n",
- "- [SpatialDataWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.SpatialDataWrapper)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " ViewType as vt,\n",
- " CoordinationType as ct,\n",
- " CoordinationLevel as CL,\n",
- " SpatialDataWrapper,\n",
- " AnnDataWrapper,\n",
- " ImageOmeTiffWrapper,\n",
- " ImageOmeZarrWrapper,\n",
- " ObsSegmentationsOmeZarrWrapper,\n",
- " get_initial_coordination_scope_prefix,\n",
- " hconcat,\n",
- " vconcat,\n",
- ")\n",
- "from vitessce.data_utils import (\n",
- " VAR_CHUNK_SIZE,\n",
- " generate_h5ad_ref_spec,\n",
- " multiplex_img_to_ome_tiff,\n",
- " multiplex_img_to_ome_zarr,\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "In this blog post, we perform basic data transformation tasks to save individual elements of an integrated SpatialData object to separate files in AnnData, OME-TIFF, and OME-Zarr formats.\n",
- "To perform these data transformations, we import the following dependencies.\n",
- "In general, you will typically not need to import all of these dependencies, either because you are only working with data in one of these formats, or because the data you intend to visualize is already saved to a file or directory."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Download example dataset"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "We download a mouse liver dataset which serves as a SpatialData [example dataset](https://github.com/scverse/spatialdata-notebooks/blob/main/notebooks/examples/transformations.ipynb).\n",
- "\n",
- "This dataset was generated by [Guilliams et al.](https://doi.org/10.1016/j.cell.2021.12.018) and processed using [SPArrOW](https://doi.org/10.1101/2024.07.04.601829) during the SpatialData [developer workshop](https://doi.org/10.37044/osf.io/8ck3e) in 2024."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "base_url = \"https://storage.googleapis.com/vitessce-demo-data/spatialdata-may-2025\""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "zip_filepath = f\"{base_url}/mouse_liver.spatialdata.zarr.zip\"\n",
- "spatialdata_filepath = f\"{base_url}/mouse_liver.spatialdata.zarr\"\n",
- "adata_zarr_filepath = f\"{base_url}/mouse_liver.anndata.zarr\"\n",
- "adata_h5ad_filepath = f\"{base_url}/mouse_liver.h5ad\"\n",
- "ref_spec_json_filepath = f\"{base_url}/mouse_liver.h5ad.ref.json\"\n",
- "ome_tiff_filepath = f\"{base_url}/mouse_liver.ome.tif\"\n",
- "offsets_json_filepath = f\"{base_url}/mouse_liver.ome.tif.offsets.json\"\n",
- "ome_zarr_filepath = f\"{base_url}/mouse_liver.ome.zarr\"\n",
- "labels_ome_zarr_filepath = f\"{base_url}/mouse_liver.labels.ome.zarr\""
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "tags": []
- },
- "source": [
- "## Visualization of a SpatialData object"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "SpatialData objects are the most complex type of data structure we will work with in this blog post.\n",
- "SpatialData objects function as contains for multiple types of Spatial Elements:\n",
- "\n",
- "- Tables (each table is represented as an AnnData object)\n",
- "- Points (e.g., coordinates of transcripts from FISH-based experiments)\n",
- "- Shapes (vector-based shapes such as polygons and circles)\n",
- "- Labels (label images, i.e., segmentation bitmasks; each label image is stored using OME-Zarr)\n",
- "- Images (microscopy images; each image is stored using OME-Zarr)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Configure Vitessce\n",
- "\n",
- "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views.\n",
- "To visualize data stored in a SpatialData object, we use the `SpatialDataWrapper` class and specify the paths (relative to the root of the Zarr [directory store](https://zarr.readthedocs.io/en/v2.18.5/api/storage.html#zarr.storage.DirectoryStore)) to different spatial elements of interest."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "# Create a VitessceConfig instance.\n",
- "vc = VitessceConfig(schema_version=\"1.0.18\", name=\"SpatialData Demo\")\n",
- "\n",
- "# Instantiate the wrapper class, specifying data fields of interest.\n",
- "wrapper = SpatialDataWrapper(\n",
- " sdata_url=spatialdata_filepath,\n",
- " # The following paths are relative to the root of the SpatialData Zarr store on-disk.\n",
- " table_path=\"tables/table\",\n",
- " image_path=\"images/raw_image\",\n",
- " obs_segmentations_path=\"labels/segmentation_mask\",\n",
- " obs_feature_matrix_path=\"tables/table/X\",\n",
- " obs_set_paths=[\"tables/table/obs/annotation\"],\n",
- " obs_set_names=[\"Annotation\"],\n",
- " region=\"nucleus_boundaries\",\n",
- " coordinate_system=\"global\",\n",
- " coordination_values={\n",
- " \"obsType\": \"cell\" \n",
- " }\n",
- ")\n",
- "# Add a new dataset to the Vitessce configuration,\n",
- "# then add the wrapper class instance to this dataset.\n",
- "dataset = vc.add_dataset(name='Mouse Liver').add_object(wrapper)\n",
- "\n",
- "# Add views (visualizations) to the configuration.\n",
- "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
- "feature_list = vc.add_view(\"featureList\", dataset=dataset)\n",
- "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
- "obs_sets = vc.add_view(\"obsSets\", dataset=dataset)\n",
- "heatmap = vc.add_view(\"heatmap\", dataset=dataset)\n",
- "\n",
- "[obs_color_encoding_scope] = vc.add_coordination(\"obsColorEncoding\")\n",
- "obs_color_encoding_scope.set_value(\"cellSetSelection\")\n",
- "\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " \"imageLayer\": CL([{\n",
- " \"photometricInterpretation\": \"BlackIsZero\",\n",
- " \"imageChannel\": CL([{\n",
- " \"spatialTargetC\": 0,\n",
- " \"spatialChannelColor\": [255, 255, 255],\n",
- " \"spatialChannelWindow\": [0, 4000],\n",
- " }])\n",
- " }]),\n",
- "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
- "\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " \"segmentationLayer\": CL([{\n",
- " \"segmentationChannel\": CL([{\n",
- " \"obsColorEncoding\": obs_color_encoding_scope,\n",
- " }]),\n",
- " }]),\n",
- "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"obsSegmentations\"))\n",
- "\n",
- "vc.link_views([spatial, layer_controller, feature_list, obs_sets, heatmap], [\"obsType\"], [wrapper.obs_type_label])\n",
- "vc.link_views_by_dict([feature_list, obs_sets, heatmap], {\n",
- " \"obsColorEncoding\": obs_color_encoding_scope,\n",
- "}, meta=False)\n",
- "\n",
- "# Layout the views in a grid arrangement.\n",
- "vc.layout((spatial / heatmap) | (layer_controller / (feature_list | obs_sets)));"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Render the widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Extract AnnData object from SpatialData object"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "The above example demonstrates how to visualize a spatial 'omics dataset containing not only single-cell information (e.g., a cell-by-gene expression matrix, cell type annotations) but also an image and cell segmentations.\n",
- "To demonstrate how to use Vitessce to visualize data from a (non-spatial) single-cell experiment, we will extract this information from the SpatialData object and save it to a simpler [AnnData](https://anndata.readthedocs.io/) object (ignoring the imaging and spatially-resolved elements)."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "As Zarr-formatted data can be easily visualized by Vitessce, we recommend saving the AnnData object to a Zarr store using the [write_zarr](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_zarr.html) method.\n",
- "Optionally, the shape of array chunks (for the AnnData `X` array) can be specified as a parameter, to optimize performance based on data access patterns.\n",
- "For example, a common pattern is to visualize data across all cells for one gene.\n",
- "To support such a pattern, the chunk shape can be specified as follows, `(total number of cells, small number of genes)`, resulting in tall-and-skinny array chunks."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Alternatively, your AnnData object may already be stored using the H5AD (HDF5-based) format.\n",
- "To demonstrate this scenario, we save the object using the [write_h5ad](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_h5ad.html) method."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "To read H5AD-formatted data, Vitessce requires an accompanying JSON [references specification](https://fsspec.github.io/kerchunk/spec.html) file, which can be constructed using the `generate_h5ad_ref_spec` utility function."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Visualization of an AnnData object"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Zarr-based AnnData"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.18\", name=\"AnnData (zarr)\")\n",
- "# Add data.\n",
- "wrapper = AnnDataWrapper(\n",
- " adata_url=adata_zarr_filepath,\n",
- " obs_feature_matrix_path=\"X\",\n",
- " obs_set_paths=[\"obs/annotation\"],\n",
- " obs_set_names=[\"Annotation\"],\n",
- " coordination_values={\n",
- " \"obsType\": \"cell\" \n",
- " }\n",
- ")\n",
- "dataset = vc.add_dataset(name='Mouse Liver').add_object(wrapper)\n",
- "\n",
- "# Add views.\n",
- "heatmap = vc.add_view(vt.HEATMAP, dataset=dataset)\n",
- "feature_list = vc.add_view(vt.FEATURE_LIST, dataset=dataset)\n",
- "obs_sets = vc.add_view(vt.OBS_SETS, dataset=dataset)\n",
- "violin_plots = vc.add_view(\"obsSetFeatureValueDistribution\", dataset=dataset)\n",
- "\n",
- "vc.link_views([heatmap, feature_list, obs_sets], ['obsType', 'featureValueColormapRange'], ['cell', [0, 0.01]])\n",
- "\n",
- "# Layout the views.\n",
- "vc.layout((heatmap / violin_plots) | (feature_list / obs_sets));"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc.widget()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### H5AD-based AnnData"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.18\", name=\"AnnData (h5ad)\")\n",
- "# Add data.\n",
- "wrapper = AnnDataWrapper(\n",
- " adata_url=adata_h5ad_filepath,\n",
- " ref_url=ref_spec_json_filepath,\n",
- " obs_feature_matrix_path=\"X\",\n",
- " obs_set_paths=[\"obs/annotation\"],\n",
- " obs_set_names=[\"Annotation\"],\n",
- " coordination_values={\n",
- " \"obsType\": \"cell\" \n",
- " }\n",
- ")\n",
- "dataset = vc.add_dataset(name='Mouse Liver').add_object(wrapper)\n",
- "\n",
- "# Add views.\n",
- "heatmap = vc.add_view(vt.HEATMAP, dataset=dataset)\n",
- "feature_list = vc.add_view(vt.FEATURE_LIST, dataset=dataset)\n",
- "obs_sets = vc.add_view(vt.OBS_SETS, dataset=dataset)\n",
- "violin_plots = vc.add_view(\"obsSetFeatureValueDistribution\", dataset=dataset)\n",
- "\n",
- "vc.link_views([heatmap, feature_list, obs_sets], ['obsType', 'featureValueColormapRange'], ['cell', [0, 0.01]])\n",
- "\n",
- "# Layout the views.\n",
- "vc.layout((heatmap / violin_plots) | (feature_list / obs_sets));"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc.widget()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Visualization of an image file"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### OME-Zarr image"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.18\", name=\"Image (ome-zarr)\")\n",
- "\n",
- "# Add data.\n",
- "img_wrapper = ImageOmeZarrWrapper(\n",
- " img_url=ome_zarr_filepath,\n",
- " coordination_values={\n",
- " \"fileUid\": \"image\",\n",
- " }\n",
- ")\n",
- "segmentations_wrapper = ObsSegmentationsOmeZarrWrapper(\n",
- " img_url=labels_ome_zarr_filepath,\n",
- " coordination_values={\n",
- " \"fileUid\": \"segmentations\",\n",
- " }\n",
- ")\n",
- "# Here, we chain .add_object calls to add both the image and segmentation\n",
- "# wrapper instances to the same dataset.\n",
- "dataset = vc.add_dataset(name='Mouse Liver').add_object(img_wrapper).add_object(segmentations_wrapper)\n",
- "\n",
- "# Add views.\n",
- "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
- "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
- "\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " 'imageLayer': CL([{\n",
- " # In case there are multiple image files in our dataset,\n",
- " # we use fileUid to specify which file we intend to visualize\n",
- " # in this image layer.\n",
- " 'fileUid': 'image',\n",
- " 'photometricInterpretation': 'BlackIsZero',\n",
- " 'imageChannel': CL([{\n",
- " 'spatialTargetC': 0,\n",
- " 'spatialChannelColor': [255, 255, 255],\n",
- " 'spatialChannelWindow': [0, 4000],\n",
- " }])\n",
- " }]),\n",
- "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
- "\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " 'segmentationLayer': CL([{\n",
- " # In case there are multiple segmentation files in our dataset,\n",
- " # we use fileUid to specify which file we intend to visualize\n",
- " # in this segmentation layer.\n",
- " 'fileUid': 'segmentations',\n",
- " 'segmentationChannel': CL([{\n",
- " 'obsColorEncoding': 'spatialChannelColor',\n",
- " 'spatialChannelColor': [0, 255, 0],\n",
- " 'spatialChannelOpacity': 0.75,\n",
- " 'spatialSegmentationFilled': False,\n",
- " 'spatialSegmentationStrokeWidth': 0.25,\n",
- " }]),\n",
- " }]),\n",
- "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"obsSegmentations\"))\n",
- "\n",
- "vc.link_views([spatial, layer_controller, feature_list, obs_sets], ['obsType'], ['cell'])\n",
- "\n",
- "# Layout the views.\n",
- "vc.layout(hconcat(spatial, layer_controller, split=(2, 1)));"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### OME-TIFF image"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.18\", name=\"Image and segmentations (ome-tiff)\")\n",
- "# Add data.\n",
- "wrapper = ImageOmeTiffWrapper(\n",
- " img_url=ome_tiff_filepath,\n",
- " offsets_url=offsets_json_filepath\n",
- ")\n",
- "dataset = vc.add_dataset(name='Mouse Liver').add_object(wrapper)\n",
- "\n",
- "# Add views.\n",
- "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
- "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
- "\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " 'imageLayer': CL([{\n",
- " 'photometricInterpretation': 'BlackIsZero',\n",
- " 'imageChannel': CL([{\n",
- " 'spatialTargetC': 0,\n",
- " 'spatialChannelColor': [255, 255, 255],\n",
- " 'spatialChannelWindow': [0, 4000],\n",
- " }])\n",
- " }]),\n",
- "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
- "\n",
- "# Layout the views.\n",
- "vc.layout(hconcat(spatial, layer_controller, split=(2, 1)));"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc.widget()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Data location options\n",
- "\n",
- "Vitessce can visualize data [not only stored](https://python-docs.vitessce.io/data_options.html) locally (referenced using local file or directory paths) but also stored remotely (referenced using absolute URL paths).\n",
- "Depending on whether the Python kernel running the Jupyter process is running locally versus remotely (e.g., on a cluster or cloud platform such as Google Colab), certain data locations may be challenging to access from the machine running the Jupyter notebook frontend (i.e., the machine on which the web browser used to view the notebook is installed).\n",
- "\n",
- "To provide data via one of these alternative mechanisms, use parameters with the following suffices when instantiating the data wrapper classes.\n",
- "\n",
- "- `_path`: Local file or directory\n",
- "- `_url`: Remote file or directory\n",
- "- `_store`: Zarr-store-accessible (for zarr-based formats)\n",
- "- `_artifact`: Lamin artifact\n",
- "\n",
- "For example, `adata_path` can be exchanged for one of the following options.\n",
- "\n",
- "```diff\n",
- "AnnDataWrapper(\n",
- "- adata_path=\"./mouse_liver.spatialdata.zarr\",\n",
- "+ adata_url=\"https://example.com/mouse_liver.spatialdata.zarr\", # Absolute URL\n",
- "+ adata_store=\"./mouse_liver.spatialdata.zarr\", # String interpreted as root of DirectoryStore\n",
- "+ adata_store=zarr.DirectoryStore(\"./mouse_liver.spatialdata.zarr\"), # Instance of zarr.storage\n",
- "+ adata_artifact=adata_zarr_artifact, # Instance of ln.Artifact\n",
- " ...\n",
- "```\n",
- "\n",
- "Note that the `_store` options are only available for Zarr-based formats, such as AnnDataWrapper, SpatialDataWrapper, and ImageOmeZarrWrapper.\n",
- "Further, when multiple files are required, such as both `adata_path` and `ref_path` (for the JSON reference specification file accompanying an H5AD file) or `img_path` and `offsets_path`, multiple parameter suffices may need to be changed."
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.14"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/spatial_data_mouseliver_remote.mo.py b/docs/notebooks/spatial_data_mouseliver_remote.mo.py
new file mode 100644
index 00000000..69119bc8
--- /dev/null
+++ b/docs/notebooks/spatial_data_mouseliver_remote.mo.py
@@ -0,0 +1,560 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Visualization of a SpatialData object and individual Spatial Elements, remote data
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ This notebook explains how to create interactive visualizations of data that are accessible remotely.
+
+
+ We progress through different visualization tasks, first demonstrating how Vitessce facilitates integrated imaging and spatial single-cell visualizations, then demonstrating visualization of non-spatial and image-only datasets.
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Utility dependencies
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ First, we import utility dependencies which will be used to download the example dataset and manipulate file paths, zip files, and JSON files.
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ import os
+ from os.path import join, isfile, isdir
+ from urllib.request import urlretrieve
+ import zipfile
+ import json
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Dependencies for Vitessce
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ Here, we import classes and functions from the `vitessce` Python package.
+ This package includes not only APIs for [visualization configuration](https://python-docs.vitessce.io/api_config.html) but also [helper functions](https://python-docs.vitessce.io/api_data.html#vitessce-data-utils) for basic data transformation tasks.
+ To specify mappings between data fields and visualization properties, the package contains [classes](https://python-docs.vitessce.io/api_data.html#module-vitessce.wrappers) which wrap standard single-cell data structures stored in formats including [AnnData](https://doi.org/10.1101/2021.12.16.473007), [SpatialData](https://doi.org/10.1038/s41592-024-02212-x), [OME-TIFF](https://doi.org/10.1007/978-3-030-23937-4_1), and [OME-Zarr](https://doi.org/10.1038/s41592-021-01326-w):
+
+ - [AnnDataWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.AnnDataWrapper)
+ - [ImageOmeTiffWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ImageOmeTiffWrapper)
+ - [ImageOmeZarrWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ImageOmeZarrWrapper)
+ - [ObsSegmentationsOmeTiffWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ObsSegmentationsOmeTiffWrapper)
+ - [ObsSegmentationsOmeZarrWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ObsSegmentationsOmeZarrWrapper)
+ - [SpatialDataWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.SpatialDataWrapper)
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ from vitessce import (
+ VitessceConfig,
+ ViewType as vt,
+ CoordinationType as ct,
+ CoordinationLevel as CL,
+ SpatialDataWrapper,
+ AnnDataWrapper,
+ ImageOmeTiffWrapper,
+ ImageOmeZarrWrapper,
+ ObsSegmentationsOmeZarrWrapper,
+ get_initial_coordination_scope_prefix,
+ hconcat,
+ vconcat,
+ )
+ from vitessce.data_utils import (
+ VAR_CHUNK_SIZE,
+ generate_h5ad_ref_spec,
+ multiplex_img_to_ome_tiff,
+ multiplex_img_to_ome_zarr,
+ )
+ return (
+ AnnDataWrapper,
+ CL,
+ ImageOmeTiffWrapper,
+ ImageOmeZarrWrapper,
+ ObsSegmentationsOmeZarrWrapper,
+ SpatialDataWrapper,
+ VitessceConfig,
+ get_initial_coordination_scope_prefix,
+ hconcat,
+ vt,
+ )
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ In this blog post, we perform basic data transformation tasks to save individual elements of an integrated SpatialData object to separate files in AnnData, OME-TIFF, and OME-Zarr formats.
+ To perform these data transformations, we import the following dependencies.
+ In general, you will typically not need to import all of these dependencies, either because you are only working with data in one of these formats, or because the data you intend to visualize is already saved to a file or directory.
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Download example dataset
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ We download a mouse liver dataset which serves as a SpatialData [example dataset](https://github.com/scverse/spatialdata-notebooks/blob/main/notebooks/examples/transformations.ipynb).
+
+ This dataset was generated by [Guilliams et al.](https://doi.org/10.1016/j.cell.2021.12.018) and processed using [SPArrOW](https://doi.org/10.1101/2024.07.04.601829) during the SpatialData [developer workshop](https://doi.org/10.37044/osf.io/8ck3e) in 2024.
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ base_url = "https://storage.googleapis.com/vitessce-demo-data/spatialdata-may-2025"
+ return (base_url,)
+
+
+@app.cell
+def _(base_url):
+ zip_filepath = f"{base_url}/mouse_liver.spatialdata.zarr.zip"
+ spatialdata_filepath = f"{base_url}/mouse_liver.spatialdata.zarr"
+ adata_zarr_filepath = f"{base_url}/mouse_liver.anndata.zarr"
+ adata_h5ad_filepath = f"{base_url}/mouse_liver.h5ad"
+ ref_spec_json_filepath = f"{base_url}/mouse_liver.h5ad.ref.json"
+ ome_tiff_filepath = f"{base_url}/mouse_liver.ome.tif"
+ offsets_json_filepath = f"{base_url}/mouse_liver.ome.tif.offsets.json"
+ ome_zarr_filepath = f"{base_url}/mouse_liver.ome.zarr"
+ labels_ome_zarr_filepath = f"{base_url}/mouse_liver.labels.ome.zarr"
+ return (
+ adata_h5ad_filepath,
+ adata_zarr_filepath,
+ labels_ome_zarr_filepath,
+ offsets_json_filepath,
+ ome_tiff_filepath,
+ ome_zarr_filepath,
+ ref_spec_json_filepath,
+ spatialdata_filepath,
+ )
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Visualization of a SpatialData object
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ SpatialData objects are the most complex type of data structure we will work with in this blog post.
+ SpatialData objects function as contains for multiple types of Spatial Elements:
+
+ - Tables (each table is represented as an AnnData object)
+ - Points (e.g., coordinates of transcripts from FISH-based experiments)
+ - Shapes (vector-based shapes such as polygons and circles)
+ - Labels (label images, i.e., segmentation bitmasks; each label image is stored using OME-Zarr)
+ - Images (microscopy images; each image is stored using OME-Zarr)
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Configure Vitessce
+
+ Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views.
+ To visualize data stored in a SpatialData object, we use the `SpatialDataWrapper` class and specify the paths (relative to the root of the Zarr [directory store](https://zarr.readthedocs.io/en/v2.18.5/api/storage.html#zarr.storage.DirectoryStore)) to different spatial elements of interest.
+ """
+ )
+ return
+
+
+@app.cell
+def _(
+ CL,
+ SpatialDataWrapper,
+ VitessceConfig,
+ get_initial_coordination_scope_prefix,
+ spatialdata_filepath,
+):
+ vc = VitessceConfig(schema_version='1.0.18', name='SpatialData Demo')
+ _wrapper = SpatialDataWrapper(sdata_url=spatialdata_filepath, table_path='tables/table', image_path='images/raw_image', obs_segmentations_path='labels/segmentation_mask', obs_feature_matrix_path='tables/table/X', obs_set_paths=['tables/table/obs/annotation'], obs_set_names=['Annotation'], region='nucleus_boundaries', coordinate_system='global', coordination_values={'obsType': 'cell'})
+ _dataset = vc.add_dataset(name='Mouse Liver').add_object(_wrapper)
+ _spatial = vc.add_view('spatialBeta', dataset=_dataset)
+ feature_list = vc.add_view('featureList', dataset=_dataset)
+ _layer_controller = vc.add_view('layerControllerBeta', dataset=_dataset)
+ obs_sets = vc.add_view('obsSets', dataset=_dataset)
+ _heatmap = vc.add_view('heatmap', dataset=_dataset)
+ [obs_color_encoding_scope] = vc.add_coordination('obsColorEncoding')
+ obs_color_encoding_scope.set_value('cellSetSelection')
+ vc.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))
+ vc.link_views_by_dict([_spatial, _layer_controller], {'segmentationLayer': CL([{'segmentationChannel': CL([{'obsColorEncoding': obs_color_encoding_scope}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'obsSegmentations'))
+ vc.link_views([_spatial, _layer_controller, feature_list, obs_sets, _heatmap], ['obsType'], [_wrapper.obs_type_label])
+ vc.link_views_by_dict([feature_list, obs_sets, _heatmap], {'obsColorEncoding': obs_color_encoding_scope}, meta=False)
+ vc.layout(_spatial / _heatmap | _layer_controller / (feature_list | obs_sets))
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### Render the widget
+ """
+ )
+ return
+
+
+@app.cell
+def _(vc):
+ _vw = vc.widget()
+ _vw
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Extract AnnData object from SpatialData object
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ The above example demonstrates how to visualize a spatial 'omics dataset containing not only single-cell information (e.g., a cell-by-gene expression matrix, cell type annotations) but also an image and cell segmentations.
+ To demonstrate how to use Vitessce to visualize data from a (non-spatial) single-cell experiment, we will extract this information from the SpatialData object and save it to a simpler [AnnData](https://anndata.readthedocs.io/) object (ignoring the imaging and spatially-resolved elements).
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ As Zarr-formatted data can be easily visualized by Vitessce, we recommend saving the AnnData object to a Zarr store using the [write_zarr](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_zarr.html) method.
+ Optionally, the shape of array chunks (for the AnnData `X` array) can be specified as a parameter, to optimize performance based on data access patterns.
+ For example, a common pattern is to visualize data across all cells for one gene.
+ To support such a pattern, the chunk shape can be specified as follows, `(total number of cells, small number of genes)`, resulting in tall-and-skinny array chunks.
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ Alternatively, your AnnData object may already be stored using the H5AD (HDF5-based) format.
+ To demonstrate this scenario, we save the object using the [write_h5ad](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_h5ad.html) method.
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ To read H5AD-formatted data, Vitessce requires an accompanying JSON [references specification](https://fsspec.github.io/kerchunk/spec.html) file, which can be constructed using the `generate_h5ad_ref_spec` utility function.
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Visualization of an AnnData object
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### Zarr-based AnnData
+ """
+ )
+ return
+
+
+@app.cell
+def _(AnnDataWrapper, VitessceConfig, adata_zarr_filepath, vt):
+ vc_1 = VitessceConfig(schema_version='1.0.18', name='AnnData (zarr)')
+ _wrapper = AnnDataWrapper(adata_url=adata_zarr_filepath, obs_feature_matrix_path='X', obs_set_paths=['obs/annotation'], obs_set_names=['Annotation'], coordination_values={'obsType': 'cell'})
+ _dataset = vc_1.add_dataset(name='Mouse Liver').add_object(_wrapper)
+ _heatmap = vc_1.add_view(vt.HEATMAP, dataset=_dataset)
+ feature_list_1 = vc_1.add_view(vt.FEATURE_LIST, dataset=_dataset)
+ obs_sets_1 = vc_1.add_view(vt.OBS_SETS, dataset=_dataset)
+ _violin_plots = vc_1.add_view('obsSetFeatureValueDistribution', dataset=_dataset)
+ vc_1.link_views([_heatmap, feature_list_1, obs_sets_1], ['obsType', 'featureValueColormapRange'], ['cell', [0, 0.01]])
+ vc_1.layout(_heatmap / _violin_plots | feature_list_1 / obs_sets_1)
+ return (vc_1,)
+
+
+@app.cell
+def _(vc_1):
+ vc_1.widget()
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### H5AD-based AnnData
+ """
+ )
+ return
+
+
+@app.cell
+def _(
+ AnnDataWrapper,
+ VitessceConfig,
+ adata_h5ad_filepath,
+ ref_spec_json_filepath,
+ vt,
+):
+ vc_2 = VitessceConfig(schema_version='1.0.18', name='AnnData (h5ad)')
+ _wrapper = AnnDataWrapper(adata_url=adata_h5ad_filepath, ref_url=ref_spec_json_filepath, obs_feature_matrix_path='X', obs_set_paths=['obs/annotation'], obs_set_names=['Annotation'], coordination_values={'obsType': 'cell'})
+ _dataset = vc_2.add_dataset(name='Mouse Liver').add_object(_wrapper)
+ _heatmap = vc_2.add_view(vt.HEATMAP, dataset=_dataset)
+ feature_list_2 = vc_2.add_view(vt.FEATURE_LIST, dataset=_dataset)
+ obs_sets_2 = vc_2.add_view(vt.OBS_SETS, dataset=_dataset)
+ _violin_plots = vc_2.add_view('obsSetFeatureValueDistribution', dataset=_dataset)
+ vc_2.link_views([_heatmap, feature_list_2, obs_sets_2], ['obsType', 'featureValueColormapRange'], ['cell', [0, 0.01]])
+ vc_2.layout(_heatmap / _violin_plots | feature_list_2 / obs_sets_2)
+ return feature_list_2, obs_sets_2, vc_2
+
+
+@app.cell
+def _(vc_2):
+ vc_2.widget()
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Visualization of an image file
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### OME-Zarr image
+ """
+ )
+ return
+
+
+@app.cell
+def _(
+ CL,
+ ImageOmeZarrWrapper,
+ ObsSegmentationsOmeZarrWrapper,
+ VitessceConfig,
+ feature_list_2,
+ get_initial_coordination_scope_prefix,
+ hconcat,
+ labels_ome_zarr_filepath,
+ obs_sets_2,
+ ome_zarr_filepath,
+):
+ vc_3 = VitessceConfig(schema_version='1.0.18', name='Image (ome-zarr)')
+ img_wrapper = ImageOmeZarrWrapper(img_url=ome_zarr_filepath, coordination_values={'fileUid': 'image'})
+ segmentations_wrapper = ObsSegmentationsOmeZarrWrapper(img_url=labels_ome_zarr_filepath, coordination_values={'fileUid': 'segmentations'})
+ _dataset = vc_3.add_dataset(name='Mouse Liver').add_object(img_wrapper).add_object(segmentations_wrapper)
+ _spatial = vc_3.add_view('spatialBeta', dataset=_dataset)
+ _layer_controller = vc_3.add_view('layerControllerBeta', dataset=_dataset)
+ vc_3.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'fileUid': 'image', 'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))
+ vc_3.link_views_by_dict([_spatial, _layer_controller], {'segmentationLayer': CL([{'fileUid': 'segmentations', 'segmentationChannel': CL([{'obsColorEncoding': 'spatialChannelColor', 'spatialChannelColor': [0, 255, 0], 'spatialChannelOpacity': 0.75, 'spatialSegmentationFilled': False, 'spatialSegmentationStrokeWidth': 0.25}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'obsSegmentations'))
+ vc_3.link_views([_spatial, _layer_controller, feature_list_2, obs_sets_2], ['obsType'], ['cell'])
+ vc_3.layout(hconcat(_spatial, _layer_controller, split=(2, 1)))
+ return (vc_3,)
+
+
+@app.cell
+def _(vc_3):
+ _vw = vc_3.widget()
+ _vw
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### OME-TIFF image
+ """
+ )
+ return
+
+
+@app.cell
+def _(
+ CL,
+ ImageOmeTiffWrapper,
+ VitessceConfig,
+ get_initial_coordination_scope_prefix,
+ hconcat,
+ offsets_json_filepath,
+ ome_tiff_filepath,
+):
+ vc_4 = VitessceConfig(schema_version='1.0.18', name='Image and segmentations (ome-tiff)')
+ _wrapper = ImageOmeTiffWrapper(img_url=ome_tiff_filepath, offsets_url=offsets_json_filepath)
+ _dataset = vc_4.add_dataset(name='Mouse Liver').add_object(_wrapper)
+ _spatial = vc_4.add_view('spatialBeta', dataset=_dataset)
+ _layer_controller = vc_4.add_view('layerControllerBeta', dataset=_dataset)
+ vc_4.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))
+ vc_4.layout(hconcat(_spatial, _layer_controller, split=(2, 1)))
+ return (vc_4,)
+
+
+@app.cell
+def _(vc_4):
+ vc_4.widget()
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Data location options
+
+ Vitessce can visualize data [not only stored](https://python-docs.vitessce.io/data_options.html) locally (referenced using local file or directory paths) but also stored remotely (referenced using absolute URL paths).
+ Depending on whether the Python kernel running the Jupyter process is running locally versus remotely (e.g., on a cluster or cloud platform such as Google Colab), certain data locations may be challenging to access from the machine running the Jupyter notebook frontend (i.e., the machine on which the web browser used to view the notebook is installed).
+
+ To provide data via one of these alternative mechanisms, use parameters with the following suffices when instantiating the data wrapper classes.
+
+ - `_path`: Local file or directory
+ - `_url`: Remote file or directory
+ - `_store`: Zarr-store-accessible (for zarr-based formats)
+ - `_artifact`: Lamin artifact
+
+ For example, `adata_path` can be exchanged for one of the following options.
+
+ ```diff
+ AnnDataWrapper(
+ - adata_path="./mouse_liver.spatialdata.zarr",
+ + adata_url="https://example.com/mouse_liver.spatialdata.zarr", # Absolute URL
+ + adata_store="./mouse_liver.spatialdata.zarr", # String interpreted as root of DirectoryStore
+ + adata_store=zarr.DirectoryStore("./mouse_liver.spatialdata.zarr"), # Instance of zarr.storage
+ + adata_artifact=adata_zarr_artifact, # Instance of ln.Artifact
+ ...
+ ```
+
+ Note that the `_store` options are only available for Zarr-based formats, such as AnnDataWrapper, SpatialDataWrapper, and ImageOmeZarrWrapper.
+ Further, when multiple files are required, such as both `adata_path` and `ref_path` (for the JSON reference specification file accompanying an H5AD file) or `img_path` and `offsets_path`, multiple parameter suffices may need to be changed.
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/spatial_data_visium_hd.ipynb b/docs/notebooks/spatial_data_visium_hd.ipynb
deleted file mode 100644
index 0ca3257e..00000000
--- a/docs/notebooks/spatial_data_visium_hd.ipynb
+++ /dev/null
@@ -1,247 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Visualization of a SpatialData object"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Import dependencies\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join, isfile, isdir\n",
- "from urllib.request import urlretrieve\n",
- "import zipfile\n",
- "\n",
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " ViewType as vt,\n",
- " CoordinationType as ct,\n",
- " CoordinationLevel as CL,\n",
- " SpatialDataWrapper,\n",
- " get_initial_coordination_scope_prefix\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "data_dir = \"data\"\n",
- "zip_filepath = join(data_dir, \"visium_hd_3.0.0_io.zip\")\n",
- "spatialdata_filepath = join(data_dir, \"visium_hd_3.0.0.spatialdata.zarr\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "if not isdir(spatialdata_filepath):\n",
- " if not isfile(zip_filepath):\n",
- " os.makedirs(data_dir, exist_ok=True)\n",
- " urlretrieve('https://s3.embl.de/spatialdata/spatialdata-sandbox/visium_hd_3.0.0_io.zip', zip_filepath)\n",
- " with zipfile.ZipFile(zip_filepath,\"r\") as zip_ref:\n",
- " zip_ref.extractall(data_dir)\n",
- " os.rename(join(data_dir, \"data.zarr\"), spatialdata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Rasterize bins\n",
- "Reference: https://spatialdata.scverse.org/en/stable/tutorials/notebooks/notebooks/examples/technology_visium_hd.html#performant-on-the-fly-data-rasterization"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from spatialdata import (\n",
- " read_zarr,\n",
- " rasterize_bins,\n",
- " rasterize_bins_link_table_to_labels\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "sdata = read_zarr(spatialdata_filepath)\n",
- "sdata"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "for bin_size in [\"016\", \"008\", \"002\"]:\n",
- " # rasterize_bins() requires a compresed sparse column (csc) matrix\n",
- " sdata.tables[f\"square_{bin_size}um\"].X = sdata.tables[f\"square_{bin_size}um\"].X.tocsc()\n",
- " rasterized = rasterize_bins(\n",
- " sdata,\n",
- " f\"Visium_HD_Mouse_Small_Intestine_square_{bin_size}um\",\n",
- " f\"square_{bin_size}um\",\n",
- " \"array_col\",\n",
- " \"array_row\",\n",
- " # We want to rasterize to a Labels element, rather than an Image element.\n",
- " return_region_as_labels=True\n",
- " )\n",
- " sdata[f\"rasterized_{bin_size}um\"] = rasterized\n",
- " rasterize_bins_link_table_to_labels(\n",
- " sdata,\n",
- " table_name=f\"square_{bin_size}um\",\n",
- " rasterized_labels_name=f\"rasterized_{bin_size}um\",\n",
- " )\n",
- " sdata.write_element(f\"rasterized_{bin_size}um\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "sdata"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Configure Vitessce\n",
- "\n",
- "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(\n",
- " schema_version=\"1.0.18\",\n",
- " name='Visium HD SpatialData Demo',\n",
- ")\n",
- "# Add data to the configuration:\n",
- "wrapper = SpatialDataWrapper(\n",
- " sdata_path=spatialdata_filepath,\n",
- " # The following paths are relative to the root of the SpatialData zarr store on-disk.\n",
- " image_path=\"images/Visium_HD_Mouse_Small_Intestine_full_image\",\n",
- " table_path=\"tables/square_016um\",\n",
- " obs_feature_matrix_path=\"tables/square_016um/X\",\n",
- " obs_segmentations_path=\"labels/rasterized_016um\",\n",
- " #region=\"CytAssist_FFPE_Human_Breast_Cancer\",\n",
- " coordinate_system=\"Visium_HD_Mouse_Small_Intestine\",\n",
- " coordination_values={\n",
- " # The following tells Vitessce to consider each observation as a \"bin\"\n",
- " \"obsType\": \"bin\",\n",
- " }\n",
- ")\n",
- "dataset = vc.add_dataset(name='Visium HD').add_object(wrapper)\n",
- "\n",
- "# Add views (visualizations) to the configuration:\n",
- "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
- "feature_list = vc.add_view(\"featureList\", dataset=dataset)\n",
- "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " 'imageLayer': CL([{\n",
- " 'photometricInterpretation': 'RGB',\n",
- " }]),\n",
- "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " 'segmentationLayer': CL([{\n",
- " 'segmentationChannel': CL([{\n",
- " 'spatialChannelOpacity': 0.5,\n",
- " 'obsColorEncoding': 'geneSelection',\n",
- " 'featureValueColormapRange': [0, 0.5],\n",
- " }])\n",
- " }]),\n",
- "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"obsSegmentations\"))\n",
- "obs_sets = vc.add_view(vt.OBS_SETS, dataset=dataset)\n",
- "vc.link_views([spatial, layer_controller, feature_list, obs_sets], ['obsType', 'featureSelection'], [wrapper.obs_type_label, ['AA986860']])\n",
- "\n",
- "# Layout the views\n",
- "vc.layout(spatial | (feature_list / layer_controller / obs_sets));"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### Render the widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.14"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/spatial_data_visium_hd.mo.py b/docs/notebooks/spatial_data_visium_hd.mo.py
new file mode 100644
index 00000000..86bf1b76
--- /dev/null
+++ b/docs/notebooks/spatial_data_visium_hd.mo.py
@@ -0,0 +1,248 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Visualization of a SpatialData object
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Import dependencies
+
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ import os
+ from os.path import join, isfile, isdir
+ from urllib.request import urlretrieve
+ import zipfile
+
+ from vitessce import (
+ VitessceConfig,
+ ViewType as vt,
+ CoordinationType as ct,
+ CoordinationLevel as CL,
+ SpatialDataWrapper,
+ get_initial_coordination_scope_prefix
+ )
+ return (
+ CL,
+ SpatialDataWrapper,
+ VitessceConfig,
+ get_initial_coordination_scope_prefix,
+ isdir,
+ isfile,
+ join,
+ os,
+ urlretrieve,
+ vt,
+ zipfile,
+ )
+
+
+@app.cell
+def _(join):
+ data_dir = "data"
+ zip_filepath = join(data_dir, "visium_hd_3.0.0_io.zip")
+ spatialdata_filepath = join(data_dir, "visium_hd_3.0.0.spatialdata.zarr")
+ return data_dir, spatialdata_filepath, zip_filepath
+
+
+@app.cell
+def _(
+ data_dir,
+ isdir,
+ isfile,
+ join,
+ os,
+ spatialdata_filepath,
+ urlretrieve,
+ zip_filepath,
+ zipfile,
+):
+ if not isdir(spatialdata_filepath):
+ if not isfile(zip_filepath):
+ os.makedirs(data_dir, exist_ok=True)
+ urlretrieve('https://s3.embl.de/spatialdata/spatialdata-sandbox/visium_hd_3.0.0_io.zip', zip_filepath)
+ with zipfile.ZipFile(zip_filepath,"r") as zip_ref:
+ zip_ref.extractall(data_dir)
+ os.rename(join(data_dir, "data.zarr"), spatialdata_filepath)
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Rasterize bins
+ Reference: https://spatialdata.scverse.org/en/stable/tutorials/notebooks/notebooks/examples/technology_visium_hd.html#performant-on-the-fly-data-rasterization
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ from spatialdata import (
+ read_zarr,
+ rasterize_bins,
+ rasterize_bins_link_table_to_labels
+ )
+ return rasterize_bins, rasterize_bins_link_table_to_labels, read_zarr
+
+
+@app.cell
+def _(read_zarr, spatialdata_filepath):
+ sdata = read_zarr(spatialdata_filepath)
+ sdata
+ return (sdata,)
+
+
+@app.cell
+def _(rasterize_bins, rasterize_bins_link_table_to_labels, sdata):
+ for bin_size in ["016", "008", "002"]:
+ # rasterize_bins() requires a compresed sparse column (csc) matrix
+ sdata.tables[f"square_{bin_size}um"].X = sdata.tables[f"square_{bin_size}um"].X.tocsc()
+ rasterized = rasterize_bins(
+ sdata,
+ f"Visium_HD_Mouse_Small_Intestine_square_{bin_size}um",
+ f"square_{bin_size}um",
+ "array_col",
+ "array_row",
+ # We want to rasterize to a Labels element, rather than an Image element.
+ return_region_as_labels=True
+ )
+ sdata[f"rasterized_{bin_size}um"] = rasterized
+ rasterize_bins_link_table_to_labels(
+ sdata,
+ table_name=f"square_{bin_size}um",
+ rasterized_labels_name=f"rasterized_{bin_size}um",
+ )
+ sdata.write_element(f"rasterized_{bin_size}um")
+ return
+
+
+@app.cell
+def _(sdata):
+ sdata
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Configure Vitessce
+
+ Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views.
+ """
+ )
+ return
+
+
+@app.cell
+def _(
+ CL,
+ SpatialDataWrapper,
+ VitessceConfig,
+ get_initial_coordination_scope_prefix,
+ spatialdata_filepath,
+ vt,
+):
+ vc = VitessceConfig(
+ schema_version="1.0.18",
+ name='Visium HD SpatialData Demo',
+ )
+ # Add data to the configuration:
+ wrapper = SpatialDataWrapper(
+ sdata_path=spatialdata_filepath,
+ # The following paths are relative to the root of the SpatialData zarr store on-disk.
+ image_path="images/Visium_HD_Mouse_Small_Intestine_full_image",
+ table_path="tables/square_016um",
+ obs_feature_matrix_path="tables/square_016um/X",
+ obs_segmentations_path="labels/rasterized_016um",
+ #region="CytAssist_FFPE_Human_Breast_Cancer",
+ coordinate_system="Visium_HD_Mouse_Small_Intestine",
+ coordination_values={
+ # The following tells Vitessce to consider each observation as a "bin"
+ "obsType": "bin",
+ }
+ )
+ dataset = vc.add_dataset(name='Visium HD').add_object(wrapper)
+
+ # Add views (visualizations) to the configuration:
+ spatial = vc.add_view("spatialBeta", dataset=dataset)
+ feature_list = vc.add_view("featureList", dataset=dataset)
+ layer_controller = vc.add_view("layerControllerBeta", dataset=dataset)
+ vc.link_views_by_dict([spatial, layer_controller], {
+ 'imageLayer': CL([{
+ 'photometricInterpretation': 'RGB',
+ }]),
+ }, scope_prefix=get_initial_coordination_scope_prefix("A", "image"))
+ vc.link_views_by_dict([spatial, layer_controller], {
+ 'segmentationLayer': CL([{
+ 'segmentationChannel': CL([{
+ 'spatialChannelOpacity': 0.5,
+ 'obsColorEncoding': 'geneSelection',
+ 'featureValueColormapRange': [0, 0.5],
+ }])
+ }]),
+ }, scope_prefix=get_initial_coordination_scope_prefix("A", "obsSegmentations"))
+ obs_sets = vc.add_view(vt.OBS_SETS, dataset=dataset)
+ vc.link_views([spatial, layer_controller, feature_list, obs_sets], ['obsType', 'featureSelection'], [wrapper.obs_type_label, ['AA986860']])
+
+ # Layout the views
+ vc.layout(spatial | (feature_list / layer_controller / obs_sets));
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### Render the widget
+ """
+ )
+ return
+
+
+@app.cell
+def _(vc):
+ vw = vc.widget()
+ vw
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/web_app_brain.ipynb b/docs/notebooks/web_app_brain.ipynb
deleted file mode 100644
index bd3d6eb0..00000000
--- a/docs/notebooks/web_app_brain.ipynb
+++ /dev/null
@@ -1,253 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Web App Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Visualization of single-cell RNA seq data using vitessce.io"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 1. Import dependencies\n",
- "\n",
- "We need to import the classes and functions that we will be using from the corresponding packages."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join\n",
- "from urllib.request import urlretrieve\n",
- "from anndata import read_h5ad\n",
- "import scanpy as sc\n",
- "\n",
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " AnnDataWrapper,\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 2. Download the data\n",
- "\n",
- "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "os.makedirs(\"data\", exist_ok=True)\n",
- "adata_filepath = join(\"data\", \"habib17.processed.h5ad\")\n",
- "urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 3. Load the data\n",
- "\n",
- "Note: this function may print a `FutureWarning`"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "adata = read_h5ad(adata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 3.1. Preprocess the Data For Visualization\n",
- "\n",
- "This dataset contains 25,587 genes. In order to visualize it efficiently, we convert it to CSC sparse format so that we can make fast requests for gene data. We also prepare to visualize the top 50 highly variable genes for the heatmap as ranked by dispersion norm, although one may use any boolean array filter for the heatmap."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "top_dispersion = adata.var[\"dispersions_norm\"][\n",
- " sorted(\n",
- " range(len(adata.var[\"dispersions_norm\"])),\n",
- " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
- " )[-51:][0]\n",
- "]\n",
- "adata.var[\"top_highly_variable\"] = (\n",
- " adata.var[\"dispersions_norm\"] > top_dispersion\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 4. Create the Vitessce widget configuration\n",
- "\n",
- "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### 4.1. Instantiate a `VitessceConfig` object\n",
- "\n",
- "Use the `VitessceConfig(name, description)` constructor to create an instance."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', description='COVID-19 Healthy Donor Brain')"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### 4.2. Add a dataset to the `VitessceConfig` instance\n",
- "\n",
- "In Vitessce, a dataset is a container for one file per data type. The `.add_dataset(name)` method on the `vc` instance sets up and returns a new dataset instance.\n",
- "\n",
- "Then, we can call the dataset's `.add_object(wrapper_object)` method to attach a \"data wrapper\" instance to our new dataset. For example, the `AnnDataWrapper` class knows how to convert AnnData objects to the corresponding Vitessce data types.\n",
- "\n",
- "Dataset wrapper classes may require additional parameters to resolve ambiguities. For instance, `AnnData` objects may store multiple clusterings or cell type annotation columns in the `adata.obs` dataframe. We can use the parameter `cell_set_obs_cols` to tell Vitessce which columns of the `obs` dataframe correspond to cell sets."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
- " adata,\n",
- " obs_embedding_paths=[\"obsm/X_umap\"],\n",
- " obs_embedding_names=[\"UMAP\"],\n",
- " obs_set_paths=[\"obs/CellType\"],\n",
- " obs_set_names=[\"Cell Type\"],\n",
- " obs_feature_matrix_path=\"X\",\n",
- " feature_filter_path=\"var/top_highly_variable\"\n",
- " )\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### 4.3. Add visualizations to the `VitessceConfig` instance\n",
- "\n",
- "Now that we have added a dataset, we can configure visualizations. The `.add_view(dataset, component_type)` method adds a view (i.e. visualization or controller component) to the configuration.\n",
- "\n",
- "The `Component` enum class (which we have imported as `cm` here) can be used to fill in the `component_type` parameter.\n",
- "\n",
- "For convenience, the `SCATTERPLOT` component type takes the extra `mapping` keyword argument, which specifies which embedding should be used for mapping cells to (x,y) points on the plot."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
- "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
- "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
- "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### 4.4. Define the visualization layout\n",
- "\n",
- "The `vc.layout(view_concat)` method allows us to specify how our views will be arranged in the layout grid in the widget. The `|` and `/` characters are magic syntax for `hconcat(v1, v2)` and `vconcat(v1, v2)`, respectively."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc.layout((scatterplot | cell_sets) / (heatmap | genes));"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 5. Launch the web application\n",
- "\n",
- "The `vc.web_app()` method serves the processed data locally and opens a web browser to `http://vitessce.io/?url={config_as_json}`"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc.web_app()"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.14"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/web_app_brain.mo.py b/docs/notebooks/web_app_brain.mo.py
new file mode 100644
index 00000000..13860962
--- /dev/null
+++ b/docs/notebooks/web_app_brain.mo.py
@@ -0,0 +1,249 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Web App Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Visualization of single-cell RNA seq data using vitessce.io
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 1. Import dependencies
+
+ We need to import the classes and functions that we will be using from the corresponding packages.
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ import os
+ from os.path import join
+ from urllib.request import urlretrieve
+ from anndata import read_h5ad
+ import scanpy as sc
+
+ from vitessce import (
+ VitessceConfig,
+ Component as cm,
+ CoordinationType as ct,
+ AnnDataWrapper,
+ )
+ return AnnDataWrapper, VitessceConfig, cm, join, os, read_h5ad, urlretrieve
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 2. Download the data
+
+ For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17.
+ """
+ )
+ return
+
+
+@app.cell
+def _(join, os, urlretrieve):
+ os.makedirs("data", exist_ok=True)
+ adata_filepath = join("data", "habib17.processed.h5ad")
+ urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)
+ return (adata_filepath,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 3. Load the data
+
+ Note: this function may print a `FutureWarning`
+ """
+ )
+ return
+
+
+@app.cell
+def _(adata_filepath, read_h5ad):
+ adata = read_h5ad(adata_filepath)
+ return (adata,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 3.1. Preprocess the Data For Visualization
+
+ This dataset contains 25,587 genes. In order to visualize it efficiently, we convert it to CSC sparse format so that we can make fast requests for gene data. We also prepare to visualize the top 50 highly variable genes for the heatmap as ranked by dispersion norm, although one may use any boolean array filter for the heatmap.
+ """
+ )
+ return
+
+
+@app.cell
+def _(adata):
+ top_dispersion = adata.var["dispersions_norm"][
+ sorted(
+ range(len(adata.var["dispersions_norm"])),
+ key=lambda k: adata.var["dispersions_norm"][k],
+ )[-51:][0]
+ ]
+ adata.var["top_highly_variable"] = (
+ adata.var["dispersions_norm"] > top_dispersion
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 4. Create the Vitessce widget configuration
+
+ Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views.
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### 4.1. Instantiate a `VitessceConfig` object
+
+ Use the `VitessceConfig(name, description)` constructor to create an instance.
+ """
+ )
+ return
+
+
+@app.cell
+def _(VitessceConfig):
+ vc = VitessceConfig(schema_version="1.0.15", name='Habib et al', description='COVID-19 Healthy Donor Brain')
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### 4.2. Add a dataset to the `VitessceConfig` instance
+
+ In Vitessce, a dataset is a container for one file per data type. The `.add_dataset(name)` method on the `vc` instance sets up and returns a new dataset instance.
+
+ Then, we can call the dataset's `.add_object(wrapper_object)` method to attach a "data wrapper" instance to our new dataset. For example, the `AnnDataWrapper` class knows how to convert AnnData objects to the corresponding Vitessce data types.
+
+ Dataset wrapper classes may require additional parameters to resolve ambiguities. For instance, `AnnData` objects may store multiple clusterings or cell type annotation columns in the `adata.obs` dataframe. We can use the parameter `cell_set_obs_cols` to tell Vitessce which columns of the `obs` dataframe correspond to cell sets.
+ """
+ )
+ return
+
+
+@app.cell
+def _(AnnDataWrapper, adata, vc):
+ dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(
+ adata,
+ obs_embedding_paths=["obsm/X_umap"],
+ obs_embedding_names=["UMAP"],
+ obs_set_paths=["obs/CellType"],
+ obs_set_names=["Cell Type"],
+ obs_feature_matrix_path="X",
+ feature_filter_path="var/top_highly_variable"
+ )
+ )
+ return (dataset,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### 4.3. Add visualizations to the `VitessceConfig` instance
+
+ Now that we have added a dataset, we can configure visualizations. The `.add_view(dataset, component_type)` method adds a view (i.e. visualization or controller component) to the configuration.
+
+ The `Component` enum class (which we have imported as `cm` here) can be used to fill in the `component_type` parameter.
+
+ For convenience, the `SCATTERPLOT` component type takes the extra `mapping` keyword argument, which specifies which embedding should be used for mapping cells to (x,y) points on the plot.
+ """
+ )
+ return
+
+
+@app.cell
+def _(cm, dataset, vc):
+ scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping="UMAP")
+ cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)
+ genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)
+ heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)
+ return cell_sets, genes, heatmap, scatterplot
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### 4.4. Define the visualization layout
+
+ The `vc.layout(view_concat)` method allows us to specify how our views will be arranged in the layout grid in the widget. The `|` and `/` characters are magic syntax for `hconcat(v1, v2)` and `vconcat(v1, v2)`, respectively.
+ """
+ )
+ return
+
+
+@app.cell
+def _(cell_sets, genes, heatmap, scatterplot, vc):
+ vc.layout((scatterplot | cell_sets) / (heatmap | genes));
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 5. Launch the web application
+
+ The `vc.web_app()` method serves the processed data locally and opens a web browser to `http://vitessce.io/?url={config_as_json}`
+ """
+ )
+ return
+
+
+@app.cell
+def _(vc):
+ vc.web_app()
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/widget_anndata_with_image.ipynb b/docs/notebooks/widget_anndata_with_image.ipynb
deleted file mode 100644
index f76d87f9..00000000
--- a/docs/notebooks/widget_anndata_with_image.ipynb
+++ /dev/null
@@ -1,130 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Visualization of AnnData object containing an image in `uns`"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Note: This approach to storing images within AnnData objects is no longer recommended now that [SpatialData](https://spatialdata.scverse.org/en/stable/) has been introduced."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import scanpy as sc\n",
- "import numpy as np\n",
- "from vitessce.data_utils import rgb_img_to_ome_zarr, VAR_CHUNK_SIZE\n",
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " AnnDataWrapper,\n",
- " ImageOmeZarrWrapper,\n",
- ")\n",
- "from os.path import join"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "output_img = join(\"data\", \"V1_Human_Lymph_Node.ome.zarr\")\n",
- "output_adata = join(\"data\", \"V1_Human_Lymph_Node.anndata.zarr\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "adata = sc.datasets.visium_sge(sample_id=\"V1_Human_Lymph_Node\", include_hires_tiff=True)\n",
- "\n",
- "# Write img_arr to OME-Zarr.\n",
- "# Need to convert images from interleaved to non-interleaved (color axis should be first).\n",
- "img_hires = adata.uns['spatial']['V1_Human_Lymph_Node']['images']['hires']\n",
- "img_arr = np.transpose(img_hires, (2, 0, 1))\n",
- "# Convert values from [0, 1] to [0, 255].\n",
- "img_arr *= 255.0\n",
- "\n",
- "# First, save the image to an OME-Zarr image format\n",
- "rgb_img_to_ome_zarr(img_arr, output_img, axes=\"cyx\", chunks=(1, 256, 256), img_name=\"Image\")\n",
- "# Second, save the AnnData object to Zarr format\n",
- "adata.write_zarr(output_adata, chunks=[adata.shape[0], VAR_CHUNK_SIZE])"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.17\", name=\"AnnData with image\")\n",
- "dataset = vc.add_dataset(\"My dataset\").add_object(\n",
- " AnnDataWrapper(\n",
- " adata_path=output_adata,\n",
- " \n",
- " )\n",
- ").add_object(\n",
- " ImageOmeZarrWrapper(\n",
- " img_path=output_img,\n",
- " )\n",
- ")\n",
- "\n",
- "spatial_view = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
- "lc_view = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
- "\n",
- "vc.layout(spatial_view | lc_view);"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.14"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/widget_anndata_with_image.mo.py b/docs/notebooks/widget_anndata_with_image.mo.py
new file mode 100644
index 00000000..c02776e3
--- /dev/null
+++ b/docs/notebooks/widget_anndata_with_image.mo.py
@@ -0,0 +1,126 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Visualization of AnnData object containing an image in `uns`
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ Note: This approach to storing images within AnnData objects is no longer recommended now that [SpatialData](https://spatialdata.scverse.org/en/stable/) has been introduced.
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ import scanpy as sc
+ import numpy as np
+ from vitessce.data_utils import rgb_img_to_ome_zarr, VAR_CHUNK_SIZE
+ from vitessce import (
+ VitessceConfig,
+ AnnDataWrapper,
+ ImageOmeZarrWrapper,
+ )
+ from os.path import join
+ return (
+ AnnDataWrapper,
+ ImageOmeZarrWrapper,
+ VAR_CHUNK_SIZE,
+ VitessceConfig,
+ join,
+ np,
+ rgb_img_to_ome_zarr,
+ sc,
+ )
+
+
+@app.cell
+def _(join):
+ output_img = join("data", "V1_Human_Lymph_Node.ome.zarr")
+ output_adata = join("data", "V1_Human_Lymph_Node.anndata.zarr")
+ return output_adata, output_img
+
+
+@app.cell
+def _(VAR_CHUNK_SIZE, np, output_adata, output_img, rgb_img_to_ome_zarr, sc):
+ adata = sc.datasets.visium_sge(sample_id="V1_Human_Lymph_Node", include_hires_tiff=True)
+
+ # Write img_arr to OME-Zarr.
+ # Need to convert images from interleaved to non-interleaved (color axis should be first).
+ img_hires = adata.uns['spatial']['V1_Human_Lymph_Node']['images']['hires']
+ img_arr = np.transpose(img_hires, (2, 0, 1))
+ # Convert values from [0, 1] to [0, 255].
+ img_arr *= 255.0
+
+ # First, save the image to an OME-Zarr image format
+ rgb_img_to_ome_zarr(img_arr, output_img, axes="cyx", chunks=(1, 256, 256), img_name="Image")
+ # Second, save the AnnData object to Zarr format
+ adata.write_zarr(output_adata, chunks=[adata.shape[0], VAR_CHUNK_SIZE])
+ return
+
+
+@app.cell
+def _(
+ AnnDataWrapper,
+ ImageOmeZarrWrapper,
+ VitessceConfig,
+ output_adata,
+ output_img,
+):
+ vc = VitessceConfig(schema_version="1.0.17", name="AnnData with image")
+ dataset = vc.add_dataset("My dataset").add_object(
+ AnnDataWrapper(
+ adata_path=output_adata,
+
+ )
+ ).add_object(
+ ImageOmeZarrWrapper(
+ img_path=output_img,
+ )
+ )
+
+ spatial_view = vc.add_view("spatialBeta", dataset=dataset)
+ lc_view = vc.add_view("layerControllerBeta", dataset=dataset)
+
+ vc.layout(spatial_view | lc_view);
+ return (vc,)
+
+
+@app.cell
+def _(vc):
+ vw = vc.widget()
+ vw
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/widget_brain.ipynb b/docs/notebooks/widget_brain.ipynb
deleted file mode 100644
index 759bd928..00000000
--- a/docs/notebooks/widget_brain.ipynb
+++ /dev/null
@@ -1,295 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Visualization of single-cell RNA seq data"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 1. Import dependencies\n",
- "\n",
- "We need to import the classes and functions that we will be using from the corresponding packages."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join, isfile, isdir\n",
- "from urllib.request import urlretrieve\n",
- "from anndata import read_h5ad\n",
- "import scanpy as sc\n",
- "\n",
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " AnnDataWrapper,\n",
- ")\n",
- "from vitessce.data_utils import (\n",
- " optimize_adata,\n",
- " VAR_CHUNK_SIZE,\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 2. Download the data\n",
- "\n",
- "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "adata_filepath = join(\"data\", \"habib17.processed.h5ad\")\n",
- "if not isfile(adata_filepath):\n",
- " os.makedirs(\"data\", exist_ok=True)\n",
- " urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 3. Load the data\n",
- "\n",
- "Note: this function may print a `FutureWarning`"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "adata = read_h5ad(adata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "tags": []
- },
- "source": [
- "## 3.1. Preprocess the Data For Visualization\n",
- "\n",
- "This dataset contains 25,587 genes. We prepare to visualize the top 50 highly variable genes for the heatmap as ranked by dispersion norm, although one may use any boolean array filter for the heatmap."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "top_dispersion = adata.var[\"dispersions_norm\"][\n",
- " sorted(\n",
- " range(len(adata.var[\"dispersions_norm\"])),\n",
- " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
- " )[-51:][0]\n",
- "]\n",
- "adata.var[\"top_highly_variable\"] = (\n",
- " adata.var[\"dispersions_norm\"] > top_dispersion\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 3.2 Save the Data to Zarr store\n",
- "\n",
- "We want to convert the original `h5ad` file to a [Zarr](https://zarr.readthedocs.io/en/stable/) store, which Vitessce is able to load. We can use the `optimize_adata` function to ensure that all arrays and dataframe columns that we intend to use in our visualization are in the optimal format to be loaded by Vitessce. This function will cast arrays to numerical data types that take up less space (as long as the values allow). Note: unused arrays and columns (i.e., not specified in any of the parameters to `optimize_adata`) will not be copied into the new AnnData object."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "zarr_filepath = join(\"data\", \"habib17.processed.zarr\")\n",
- "if not isdir(zarr_filepath):\n",
- " adata = optimize_adata(\n",
- " adata,\n",
- " obs_cols=[\"CellType\"],\n",
- " obsm_keys=[\"X_umap\"],\n",
- " optimize_X=True,\n",
- " var_cols=[\"top_highly_variable\"],\n",
- " )\n",
- " adata.write_zarr(zarr_filepath, chunks=[adata.shape[0], VAR_CHUNK_SIZE])"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 4. Create the Vitessce widget configuration\n",
- "\n",
- "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### 4.1. Instantiate a `VitessceConfig` object\n",
- "\n",
- "Use the `VitessceConfig` constructor to create an instance."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', description='COVID-19 Healthy Donor Brain')"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### 4.2. Add a dataset to the `VitessceConfig` instance\n",
- "\n",
- "In Vitessce, a dataset is a container for one file per data type. The `.add_dataset(name)` method on the `vc` instance sets up and returns a new dataset instance.\n",
- "\n",
- "Then, we can call the dataset's `.add_object(wrapper_object)` method to attach a \"data wrapper\" instance to our new dataset. For example, the `AnnDataWrapper` helps to configure AnnData Zarr stores for use in the Vitessce configuration.\n",
- "\n",
- "Dataset wrapper classes may require additional parameters to resolve ambiguities. For instance, `AnnData` objects may store multiple clusterings or cell type annotation columns in the `adata.obs` dataframe. We can use the parameter `obs_set_paths` to tell Vitessce that certain columns of the `obs` dataframe correspond to cell type annotations or cell clusterings."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
- " adata_path=zarr_filepath,\n",
- " obs_embedding_paths=[\"obsm/X_umap\"],\n",
- " obs_embedding_names=[\"UMAP\"],\n",
- " obs_set_paths=[\"obs/CellType\"],\n",
- " obs_set_names=[\"Cell Type\"],\n",
- " obs_feature_matrix_path=\"X\",\n",
- " initial_feature_filter_path=\"var/top_highly_variable\"\n",
- " )\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### 4.3. Add visualizations to the `VitessceConfig` instance\n",
- "\n",
- "Now that we have added a dataset, we can configure visualizations. The `.add_view` method adds a view (i.e. visualization or controller component) to the configuration.\n",
- "\n",
- "The `Component` enum class (which we have imported as `cm` here) can be used to fill in the `component_type` parameter.\n",
- "\n",
- "For convenience, the `SCATTERPLOT` component type takes the extra `mapping` keyword argument, which specifies which embedding should be used for mapping cells to (x,y) points on the plot."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
- "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
- "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
- "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### 4.4. Define the visualization layout\n",
- "\n",
- "The `vc.layout(view_concat)` method allows us to specify how our views will be arranged in the layout grid in the widget. The `|` and `/` characters are magic syntax for `hconcat(v1, v2)` and `vconcat(v1, v2)`, respectively."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc.layout((scatterplot | cell_sets) / (heatmap | genes));"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 5. Create the widget\n",
- "\n",
- "The `vc.widget()` method returns the configured widget instance."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.8.0"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/widget_brain.mo.py b/docs/notebooks/widget_brain.mo.py
new file mode 100644
index 00000000..0d7e6ffd
--- /dev/null
+++ b/docs/notebooks/widget_brain.mo.py
@@ -0,0 +1,288 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Visualization of single-cell RNA seq data
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 1. Import dependencies
+
+ We need to import the classes and functions that we will be using from the corresponding packages.
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ import os
+ from os.path import join, isfile, isdir
+ from urllib.request import urlretrieve
+ from anndata import read_h5ad
+ import scanpy as sc
+
+ from vitessce import (
+ VitessceConfig,
+ Component as cm,
+ CoordinationType as ct,
+ AnnDataWrapper,
+ )
+ from vitessce.data_utils import (
+ optimize_adata,
+ VAR_CHUNK_SIZE,
+ )
+ return (
+ AnnDataWrapper,
+ VAR_CHUNK_SIZE,
+ VitessceConfig,
+ cm,
+ isdir,
+ isfile,
+ join,
+ optimize_adata,
+ os,
+ read_h5ad,
+ urlretrieve,
+ )
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 2. Download the data
+
+ For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17.
+ """
+ )
+ return
+
+
+@app.cell
+def _(isfile, join, os, urlretrieve):
+ adata_filepath = join("data", "habib17.processed.h5ad")
+ if not isfile(adata_filepath):
+ os.makedirs("data", exist_ok=True)
+ urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)
+ return (adata_filepath,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 3. Load the data
+
+ Note: this function may print a `FutureWarning`
+ """
+ )
+ return
+
+
+@app.cell
+def _(adata_filepath, read_h5ad):
+ adata = read_h5ad(adata_filepath)
+ return (adata,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 3.1. Preprocess the Data For Visualization
+
+ This dataset contains 25,587 genes. We prepare to visualize the top 50 highly variable genes for the heatmap as ranked by dispersion norm, although one may use any boolean array filter for the heatmap.
+ """
+ )
+ return
+
+
+@app.cell
+def _(adata):
+ top_dispersion = adata.var["dispersions_norm"][
+ sorted(
+ range(len(adata.var["dispersions_norm"])),
+ key=lambda k: adata.var["dispersions_norm"][k],
+ )[-51:][0]
+ ]
+ adata.var["top_highly_variable"] = (
+ adata.var["dispersions_norm"] > top_dispersion
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 3.2 Save the Data to Zarr store
+
+ We want to convert the original `h5ad` file to a [Zarr](https://zarr.readthedocs.io/en/stable/) store, which Vitessce is able to load. We can use the `optimize_adata` function to ensure that all arrays and dataframe columns that we intend to use in our visualization are in the optimal format to be loaded by Vitessce. This function will cast arrays to numerical data types that take up less space (as long as the values allow). Note: unused arrays and columns (i.e., not specified in any of the parameters to `optimize_adata`) will not be copied into the new AnnData object.
+ """
+ )
+ return
+
+
+@app.cell
+def _(VAR_CHUNK_SIZE, adata, isdir, join, optimize_adata):
+ zarr_filepath = join('data', 'habib17.processed.zarr')
+ if not isdir(zarr_filepath):
+ adata_1 = optimize_adata(adata, obs_cols=['CellType'], obsm_keys=['X_umap'], optimize_X=True, var_cols=['top_highly_variable'])
+ adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])
+ return (zarr_filepath,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 4. Create the Vitessce widget configuration
+
+ Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views.
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### 4.1. Instantiate a `VitessceConfig` object
+
+ Use the `VitessceConfig` constructor to create an instance.
+ """
+ )
+ return
+
+
+@app.cell
+def _(VitessceConfig):
+ vc = VitessceConfig(schema_version="1.0.15", name='Habib et al', description='COVID-19 Healthy Donor Brain')
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### 4.2. Add a dataset to the `VitessceConfig` instance
+
+ In Vitessce, a dataset is a container for one file per data type. The `.add_dataset(name)` method on the `vc` instance sets up and returns a new dataset instance.
+
+ Then, we can call the dataset's `.add_object(wrapper_object)` method to attach a "data wrapper" instance to our new dataset. For example, the `AnnDataWrapper` helps to configure AnnData Zarr stores for use in the Vitessce configuration.
+
+ Dataset wrapper classes may require additional parameters to resolve ambiguities. For instance, `AnnData` objects may store multiple clusterings or cell type annotation columns in the `adata.obs` dataframe. We can use the parameter `obs_set_paths` to tell Vitessce that certain columns of the `obs` dataframe correspond to cell type annotations or cell clusterings.
+ """
+ )
+ return
+
+
+@app.cell
+def _(AnnDataWrapper, vc, zarr_filepath):
+ dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(
+ adata_path=zarr_filepath,
+ obs_embedding_paths=["obsm/X_umap"],
+ obs_embedding_names=["UMAP"],
+ obs_set_paths=["obs/CellType"],
+ obs_set_names=["Cell Type"],
+ obs_feature_matrix_path="X",
+ initial_feature_filter_path="var/top_highly_variable"
+ )
+ )
+ return (dataset,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### 4.3. Add visualizations to the `VitessceConfig` instance
+
+ Now that we have added a dataset, we can configure visualizations. The `.add_view` method adds a view (i.e. visualization or controller component) to the configuration.
+
+ The `Component` enum class (which we have imported as `cm` here) can be used to fill in the `component_type` parameter.
+
+ For convenience, the `SCATTERPLOT` component type takes the extra `mapping` keyword argument, which specifies which embedding should be used for mapping cells to (x,y) points on the plot.
+ """
+ )
+ return
+
+
+@app.cell
+def _(cm, dataset, vc):
+ scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping="UMAP")
+ cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)
+ genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)
+ heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)
+ return cell_sets, genes, heatmap, scatterplot
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### 4.4. Define the visualization layout
+
+ The `vc.layout(view_concat)` method allows us to specify how our views will be arranged in the layout grid in the widget. The `|` and `/` characters are magic syntax for `hconcat(v1, v2)` and `vconcat(v1, v2)`, respectively.
+ """
+ )
+ return
+
+
+@app.cell
+def _(cell_sets, genes, heatmap, scatterplot, vc):
+ vc.layout((scatterplot | cell_sets) / (heatmap | genes));
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 5. Create the widget
+
+ The `vc.widget()` method returns the configured widget instance.
+ """
+ )
+ return
+
+
+@app.cell
+def _(vc):
+ vw = vc.widget()
+ vw
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/widget_brain_h5ad.ipynb b/docs/notebooks/widget_brain_h5ad.ipynb
deleted file mode 100644
index 66183ceb..00000000
--- a/docs/notebooks/widget_brain_h5ad.ipynb
+++ /dev/null
@@ -1,170 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Visualization of single-cell RNA seq data from H5AD file"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join, isfile, isdir\n",
- "from urllib.request import urlretrieve\n",
- "from anndata import read_h5ad\n",
- "import scanpy as sc\n",
- "import json\n",
- "\n",
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " AnnDataWrapper,\n",
- ")\n",
- "from vitessce.data_utils import (\n",
- " generate_h5ad_ref_spec\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 0. Download data"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "h5_url = \"https://datasets.cellxgene.cziscience.com/84df8fa1-ab53-43c9-a439-95dcb9148265.h5ad\""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "adata_filepath = join(\"data\", \"84df8fa1-ab53-43c9-a439-95dcb9148265.h5ad\")\n",
- "if not isfile(adata_filepath):\n",
- " os.makedirs(\"data\", exist_ok=True)\n",
- " urlretrieve(h5_url, adata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 1. Create a Reference Spec JSON file for the H5AD file\n",
- "\n",
- "In order for Vitessce to load H5AD files, we also need to provide a corresponding [Reference Spec](https://fsspec.github.io/kerchunk/spec.html) JSON file which contains mappings between AnnData object keys and the byte offsets at which those AnnData object values begin within the H5AD file binary contents."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "json_filepath = join(\"data\", \"84df8fa1-ab53-43c9-a439-95dcb9148265.h5ad.reference.json\")\n",
- "if not isfile(json_filepath):\n",
- " ref_dict = generate_h5ad_ref_spec(h5_url)\n",
- " with open(json_filepath, \"w\") as f:\n",
- " json.dump(ref_dict, f)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "tags": []
- },
- "source": [
- "## 2. Create the Vitessce widget configuration\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.17\", name='Nakshatri et al', description='snRNA-seq analyses of breast tissues of healthy women of diverse genetic ancestry')\n",
- "\n",
- "dataset = vc.add_dataset(name='84df8fa1').add_object(AnnDataWrapper(\n",
- " adata_path=adata_filepath,\n",
- " ref_path=json_filepath, # We specify paths to both the H5AD and JSON files\n",
- " obs_embedding_paths=[\"obsm/X_wnn.umap\"],\n",
- " obs_embedding_names=[\"UMAP\"],\n",
- " obs_set_paths=[\"obs/cell_type\"],\n",
- " obs_set_names=[\"Cell Type\"],\n",
- " obs_feature_matrix_path=\"X\",\n",
- " )\n",
- ")\n",
- "\n",
- "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
- "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
- "cell_set_sizes = vc.add_view(cm.OBS_SET_SIZES, dataset=dataset)\n",
- "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
- "\n",
- "vc.layout((scatterplot | cell_sets) / (cell_set_sizes | genes));"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "tags": []
- },
- "source": [
- "## 3. Create the widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.14"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/widget_brain_h5ad.mo.py b/docs/notebooks/widget_brain_h5ad.mo.py
new file mode 100644
index 00000000..6386f489
--- /dev/null
+++ b/docs/notebooks/widget_brain_h5ad.mo.py
@@ -0,0 +1,164 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Visualization of single-cell RNA seq data from H5AD file
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ import os
+ from os.path import join, isfile, isdir
+ from urllib.request import urlretrieve
+ from anndata import read_h5ad
+ import scanpy as sc
+ import json
+
+ from vitessce import (
+ VitessceConfig,
+ Component as cm,
+ CoordinationType as ct,
+ AnnDataWrapper,
+ )
+ from vitessce.data_utils import (
+ generate_h5ad_ref_spec
+ )
+ return (
+ AnnDataWrapper,
+ VitessceConfig,
+ cm,
+ generate_h5ad_ref_spec,
+ isfile,
+ join,
+ json,
+ os,
+ urlretrieve,
+ )
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 0. Download data
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ h5_url = "https://datasets.cellxgene.cziscience.com/84df8fa1-ab53-43c9-a439-95dcb9148265.h5ad"
+ return (h5_url,)
+
+
+@app.cell
+def _(h5_url, isfile, join, os, urlretrieve):
+ adata_filepath = join("data", "84df8fa1-ab53-43c9-a439-95dcb9148265.h5ad")
+ if not isfile(adata_filepath):
+ os.makedirs("data", exist_ok=True)
+ urlretrieve(h5_url, adata_filepath)
+ return (adata_filepath,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 1. Create a Reference Spec JSON file for the H5AD file
+
+ In order for Vitessce to load H5AD files, we also need to provide a corresponding [Reference Spec](https://fsspec.github.io/kerchunk/spec.html) JSON file which contains mappings between AnnData object keys and the byte offsets at which those AnnData object values begin within the H5AD file binary contents.
+ """
+ )
+ return
+
+
+@app.cell
+def _(generate_h5ad_ref_spec, h5_url, isfile, join, json):
+ json_filepath = join("data", "84df8fa1-ab53-43c9-a439-95dcb9148265.h5ad.reference.json")
+ if not isfile(json_filepath):
+ ref_dict = generate_h5ad_ref_spec(h5_url)
+ with open(json_filepath, "w") as f:
+ json.dump(ref_dict, f)
+ return (json_filepath,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 2. Create the Vitessce widget configuration
+
+ """
+ )
+ return
+
+
+@app.cell
+def _(AnnDataWrapper, VitessceConfig, adata_filepath, cm, json_filepath):
+ vc = VitessceConfig(schema_version="1.0.17", name='Nakshatri et al', description='snRNA-seq analyses of breast tissues of healthy women of diverse genetic ancestry')
+
+ dataset = vc.add_dataset(name='84df8fa1').add_object(AnnDataWrapper(
+ adata_path=adata_filepath,
+ ref_path=json_filepath, # We specify paths to both the H5AD and JSON files
+ obs_embedding_paths=["obsm/X_wnn.umap"],
+ obs_embedding_names=["UMAP"],
+ obs_set_paths=["obs/cell_type"],
+ obs_set_names=["Cell Type"],
+ obs_feature_matrix_path="X",
+ )
+ )
+
+ scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping="UMAP")
+ cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)
+ cell_set_sizes = vc.add_view(cm.OBS_SET_SIZES, dataset=dataset)
+ genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)
+
+ vc.layout((scatterplot | cell_sets) / (cell_set_sizes | genes));
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 3. Create the widget
+ """
+ )
+ return
+
+
+@app.cell
+def _(vc):
+ vw = vc.widget()
+ vw
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/widget_brain_with_base_dir.ipynb b/docs/notebooks/widget_brain_with_base_dir.ipynb
deleted file mode 100644
index 41da8211..00000000
--- a/docs/notebooks/widget_brain_with_base_dir.ipynb
+++ /dev/null
@@ -1,329 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Configure relative to a base_dir"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 1. Import dependencies\n",
- "\n",
- "We need to import the classes and functions that we will be using from the corresponding packages."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join, isfile, isdir\n",
- "from urllib.request import urlretrieve\n",
- "from anndata import read_h5ad\n",
- "\n",
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " AnnDataWrapper,\n",
- " BASE_URL_PLACEHOLDER,\n",
- ")\n",
- "from vitessce.data_utils import (\n",
- " optimize_adata,\n",
- " VAR_CHUNK_SIZE,\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 2. Define a `base_dir`\n",
- "\n",
- "We will define a `base_dir` inside which our data will live. We will provide this to `VitessceConfig` in order to construct a configuration that contains URL paths relative to this directory."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "BASE_DIR = \"data\""
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 3. Download the data\n",
- "\n",
- "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "adata_relative_filepath = \"habib17.processed.h5ad\" # Relative to BASE_DIR\n",
- "adata_filepath = join(BASE_DIR, adata_relative_filepath)\n",
- "if not isfile(adata_filepath):\n",
- " os.makedirs(BASE_DIR, exist_ok=True)\n",
- " urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 4. Load the data\n",
- "\n",
- "Note: this function may print a `FutureWarning`"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "adata = read_h5ad(adata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "tags": []
- },
- "source": [
- "## 4.1. Preprocess the Data For Visualization\n",
- "\n",
- "This dataset contains 25,587 genes. We prepare to visualize the top 50 highly variable genes for the heatmap as ranked by dispersion norm, although one may use any boolean array filter for the heatmap."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "top_dispersion = adata.var[\"dispersions_norm\"][\n",
- " sorted(\n",
- " range(len(adata.var[\"dispersions_norm\"])),\n",
- " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
- " )[-51:][0]\n",
- "]\n",
- "adata.var[\"top_highly_variable\"] = (\n",
- " adata.var[\"dispersions_norm\"] > top_dispersion\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 4.2 Save the Data to Zarr store\n",
- "\n",
- "We want to convert the original `h5ad` file to a [Zarr](https://zarr.readthedocs.io/en/stable/) store, which Vitessce is able to load. We can use the `optimize_adata` function to ensure that all arrays and dataframe columns that we intend to use in our visualization are in the optimal format to be loaded by Vitessce. This function will cast arrays to numerical data types that take up less space (as long as the values allow). Note: unused arrays and columns (i.e., not specified in any of the parameters to `optimize_adata`) will not be copied into the new AnnData object."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "zarr_relative_filepath = \"habib17.processed.zarr\" # Relative to BASE_DIR\n",
- "zarr_filepath = join(BASE_DIR, zarr_relative_filepath)\n",
- "if not isdir(zarr_filepath):\n",
- " adata = optimize_adata(\n",
- " adata,\n",
- " obs_cols=[\"CellType\"],\n",
- " obsm_keys=[\"X_umap\"],\n",
- " optimize_X=True,\n",
- " var_cols=[\"top_highly_variable\"],\n",
- " )\n",
- " adata.write_zarr(zarr_filepath, chunks=[adata.shape[0], VAR_CHUNK_SIZE])"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 5. Create the Vitessce widget configuration\n",
- "\n",
- "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### 5.1. Instantiate a `VitessceConfig` object\n",
- "\n",
- "Use the `VitessceConfig` constructor to create an instance. In this case, we want to construct our configuration using local data that is relative to a particular directory, so we provide the `base_dir` parameter.\n",
- "\n",
- "Note: This `base_dir` parameter is optional. When it is omitted, local data paths are assumed to be relative to the current working directory."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', base_dir=BASE_DIR)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### 5.2. Add a dataset to the `VitessceConfig` instance\n",
- "\n",
- "In Vitessce, a dataset is a container for one file per data type. The `.add_dataset(name)` method on the `vc` instance sets up and returns a new dataset instance.\n",
- "\n",
- "Then, we can call the dataset's `.add_object(wrapper_object)` method to attach a \"data wrapper\" instance to our new dataset. For example, the `AnnDataWrapper` helps to configure AnnData Zarr stores for use in the Vitessce configuration.\n",
- "\n",
- "Dataset wrapper classes may require additional parameters to resolve ambiguities. For instance, `AnnData` objects may store multiple clusterings or cell type annotation columns in the `adata.obs` dataframe. We can use the parameter `obs_set_paths` to tell Vitessce that certain columns of the `obs` dataframe correspond to cell type annotations or cell clusterings."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
- " adata_path=zarr_relative_filepath, # Relative to BASE_DIR (because we specified base_dir in the VitessceConfig constructor)\n",
- " obs_embedding_paths=[\"obsm/X_umap\"],\n",
- " obs_embedding_names=[\"UMAP\"],\n",
- " obs_set_paths=[\"obs/CellType\"],\n",
- " obs_set_names=[\"Cell Type\"],\n",
- " obs_feature_matrix_path=\"X\",\n",
- " initial_feature_filter_path=\"var/top_highly_variable\"\n",
- " )\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### 5.3. Add visualizations to the `VitessceConfig` instance\n",
- "\n",
- "Now that we have added a dataset, we can configure visualizations. The `.add_view` method adds a view (i.e. visualization or controller component) to the configuration.\n",
- "\n",
- "The `Component` enum class (which we have imported as `cm` here) can be used to fill in the `component_type` parameter.\n",
- "\n",
- "For convenience, the `SCATTERPLOT` component type takes the extra `mapping` keyword argument, which specifies which embedding should be used for mapping cells to (x,y) points on the plot."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
- "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
- "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
- "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### 5.4. Define the visualization layout\n",
- "\n",
- "The `vc.layout(view_concat)` method allows us to specify how our views will be arranged in the layout grid in the widget. The `|` and `/` characters are magic syntax for `hconcat(v1, v2)` and `vconcat(v1, v2)`, respectively."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc.layout((scatterplot | cell_sets) / (heatmap | genes));"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 6. Create the widget\n",
- "\n",
- "The `vc.widget()` method returns the configured widget instance."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 7. Check the URLs in the configuration\n",
- "\n",
- "We can check that the data URLs in the configuration respected the specified `base_dir`."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "config_dict = vc.to_dict(base_url=BASE_URL_PLACEHOLDER)\n",
- "config_dict"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.14"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/widget_brain_with_base_dir.mo.py b/docs/notebooks/widget_brain_with_base_dir.mo.py
new file mode 100644
index 00000000..deae6013
--- /dev/null
+++ b/docs/notebooks/widget_brain_with_base_dir.mo.py
@@ -0,0 +1,330 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Configure relative to a base_dir
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 1. Import dependencies
+
+ We need to import the classes and functions that we will be using from the corresponding packages.
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ import os
+ from os.path import join, isfile, isdir
+ from urllib.request import urlretrieve
+ from anndata import read_h5ad
+
+ from vitessce import (
+ VitessceConfig,
+ Component as cm,
+ CoordinationType as ct,
+ AnnDataWrapper,
+ BASE_URL_PLACEHOLDER,
+ )
+ from vitessce.data_utils import (
+ optimize_adata,
+ VAR_CHUNK_SIZE,
+ )
+ return (
+ AnnDataWrapper,
+ BASE_URL_PLACEHOLDER,
+ VAR_CHUNK_SIZE,
+ VitessceConfig,
+ cm,
+ isdir,
+ isfile,
+ join,
+ optimize_adata,
+ os,
+ read_h5ad,
+ urlretrieve,
+ )
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 2. Define a `base_dir`
+
+ We will define a `base_dir` inside which our data will live. We will provide this to `VitessceConfig` in order to construct a configuration that contains URL paths relative to this directory.
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ BASE_DIR = "data"
+ return (BASE_DIR,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 3. Download the data
+
+ For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17.
+ """
+ )
+ return
+
+
+@app.cell
+def _(BASE_DIR, isfile, join, os, urlretrieve):
+ adata_relative_filepath = "habib17.processed.h5ad" # Relative to BASE_DIR
+ adata_filepath = join(BASE_DIR, adata_relative_filepath)
+ if not isfile(adata_filepath):
+ os.makedirs(BASE_DIR, exist_ok=True)
+ urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)
+ return (adata_filepath,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 4. Load the data
+
+ Note: this function may print a `FutureWarning`
+ """
+ )
+ return
+
+
+@app.cell
+def _(adata_filepath, read_h5ad):
+ adata = read_h5ad(adata_filepath)
+ return (adata,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 4.1. Preprocess the Data For Visualization
+
+ This dataset contains 25,587 genes. We prepare to visualize the top 50 highly variable genes for the heatmap as ranked by dispersion norm, although one may use any boolean array filter for the heatmap.
+ """
+ )
+ return
+
+
+@app.cell
+def _(adata):
+ top_dispersion = adata.var["dispersions_norm"][
+ sorted(
+ range(len(adata.var["dispersions_norm"])),
+ key=lambda k: adata.var["dispersions_norm"][k],
+ )[-51:][0]
+ ]
+ adata.var["top_highly_variable"] = (
+ adata.var["dispersions_norm"] > top_dispersion
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 4.2 Save the Data to Zarr store
+
+ We want to convert the original `h5ad` file to a [Zarr](https://zarr.readthedocs.io/en/stable/) store, which Vitessce is able to load. We can use the `optimize_adata` function to ensure that all arrays and dataframe columns that we intend to use in our visualization are in the optimal format to be loaded by Vitessce. This function will cast arrays to numerical data types that take up less space (as long as the values allow). Note: unused arrays and columns (i.e., not specified in any of the parameters to `optimize_adata`) will not be copied into the new AnnData object.
+ """
+ )
+ return
+
+
+@app.cell
+def _(BASE_DIR, VAR_CHUNK_SIZE, adata, isdir, join, optimize_adata):
+ zarr_relative_filepath = 'habib17.processed.zarr'
+ zarr_filepath = join(BASE_DIR, zarr_relative_filepath)
+ if not isdir(zarr_filepath):
+ adata_1 = optimize_adata(adata, obs_cols=['CellType'], obsm_keys=['X_umap'], optimize_X=True, var_cols=['top_highly_variable'])
+ adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])
+ return (zarr_relative_filepath,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 5. Create the Vitessce widget configuration
+
+ Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views.
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### 5.1. Instantiate a `VitessceConfig` object
+
+ Use the `VitessceConfig` constructor to create an instance. In this case, we want to construct our configuration using local data that is relative to a particular directory, so we provide the `base_dir` parameter.
+
+ Note: This `base_dir` parameter is optional. When it is omitted, local data paths are assumed to be relative to the current working directory.
+ """
+ )
+ return
+
+
+@app.cell
+def _(BASE_DIR, VitessceConfig):
+ vc = VitessceConfig(schema_version="1.0.15", name='Habib et al', base_dir=BASE_DIR)
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### 5.2. Add a dataset to the `VitessceConfig` instance
+
+ In Vitessce, a dataset is a container for one file per data type. The `.add_dataset(name)` method on the `vc` instance sets up and returns a new dataset instance.
+
+ Then, we can call the dataset's `.add_object(wrapper_object)` method to attach a "data wrapper" instance to our new dataset. For example, the `AnnDataWrapper` helps to configure AnnData Zarr stores for use in the Vitessce configuration.
+
+ Dataset wrapper classes may require additional parameters to resolve ambiguities. For instance, `AnnData` objects may store multiple clusterings or cell type annotation columns in the `adata.obs` dataframe. We can use the parameter `obs_set_paths` to tell Vitessce that certain columns of the `obs` dataframe correspond to cell type annotations or cell clusterings.
+ """
+ )
+ return
+
+
+@app.cell
+def _(AnnDataWrapper, vc, zarr_relative_filepath):
+ dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(
+ adata_path=zarr_relative_filepath, # Relative to BASE_DIR (because we specified base_dir in the VitessceConfig constructor)
+ obs_embedding_paths=["obsm/X_umap"],
+ obs_embedding_names=["UMAP"],
+ obs_set_paths=["obs/CellType"],
+ obs_set_names=["Cell Type"],
+ obs_feature_matrix_path="X",
+ initial_feature_filter_path="var/top_highly_variable"
+ )
+ )
+ return (dataset,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### 5.3. Add visualizations to the `VitessceConfig` instance
+
+ Now that we have added a dataset, we can configure visualizations. The `.add_view` method adds a view (i.e. visualization or controller component) to the configuration.
+
+ The `Component` enum class (which we have imported as `cm` here) can be used to fill in the `component_type` parameter.
+
+ For convenience, the `SCATTERPLOT` component type takes the extra `mapping` keyword argument, which specifies which embedding should be used for mapping cells to (x,y) points on the plot.
+ """
+ )
+ return
+
+
+@app.cell
+def _(cm, dataset, vc):
+ scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping="UMAP")
+ cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)
+ genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)
+ heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)
+ return cell_sets, genes, heatmap, scatterplot
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ### 5.4. Define the visualization layout
+
+ The `vc.layout(view_concat)` method allows us to specify how our views will be arranged in the layout grid in the widget. The `|` and `/` characters are magic syntax for `hconcat(v1, v2)` and `vconcat(v1, v2)`, respectively.
+ """
+ )
+ return
+
+
+@app.cell
+def _(cell_sets, genes, heatmap, scatterplot, vc):
+ vc.layout((scatterplot | cell_sets) / (heatmap | genes));
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 6. Create the widget
+
+ The `vc.widget()` method returns the configured widget instance.
+ """
+ )
+ return
+
+
+@app.cell
+def _(vc):
+ vw = vc.widget()
+ vw
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 7. Check the URLs in the configuration
+
+ We can check that the data URLs in the configuration respected the specified `base_dir`.
+ """
+ )
+ return
+
+
+@app.cell
+def _(BASE_URL_PLACEHOLDER, vc):
+ config_dict = vc.to_dict(base_url=BASE_URL_PLACEHOLDER)
+ config_dict
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/widget_brain_with_quality_metric.ipynb b/docs/notebooks/widget_brain_with_quality_metric.ipynb
deleted file mode 100644
index c273c72b..00000000
--- a/docs/notebooks/widget_brain_with_quality_metric.ipynb
+++ /dev/null
@@ -1,251 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Visualization of single-cell RNA seq data"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 1. Import dependencies\n",
- "\n",
- "We need to import the classes and functions that we will be using from the corresponding packages."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join, isfile, isdir\n",
- "from urllib.request import urlretrieve\n",
- "from anndata import read_h5ad\n",
- "import scanpy as sc\n",
- "\n",
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " AnnDataWrapper,\n",
- ")\n",
- "from vitessce.data_utils import (\n",
- " optimize_adata,\n",
- " VAR_CHUNK_SIZE,\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 2. Download the data\n",
- "\n",
- "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "adata_filepath = join(\"data\", \"habib17.processed.h5ad\")\n",
- "if not isfile(adata_filepath):\n",
- " os.makedirs(\"data\", exist_ok=True)\n",
- " urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 3. Load the data\n",
- "\n",
- "Note: this function may print a `FutureWarning`"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "adata = read_h5ad(adata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "tags": []
- },
- "source": [
- "## 3.1. Preprocess the Data For Visualization\n",
- "\n",
- "This dataset contains 25,587 genes. We prepare to visualize the top 50 highly variable genes for the heatmap as ranked by dispersion norm, although one may use any boolean array filter for the heatmap."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "top_dispersion = adata.var[\"dispersions_norm\"][\n",
- " sorted(\n",
- " range(len(adata.var[\"dispersions_norm\"])),\n",
- " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
- " )[-51:][0]\n",
- "]\n",
- "adata.var[\"top_highly_variable\"] = (\n",
- " adata.var[\"dispersions_norm\"] > top_dispersion\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 3.2 Save the Data to Zarr store\n",
- "\n",
- "We want to convert the original `h5ad` file to a [Zarr](https://zarr.readthedocs.io/en/stable/) store, which Vitessce is able to load. We can use the `optimize_adata` function to ensure that all arrays and dataframe columns that we intend to use in our visualization are in the optimal format to be loaded by Vitessce. This function will cast arrays to numerical data types that take up less space (as long as the values allow). Note: unused arrays and columns (i.e., not specified in any of the parameters to `optimize_adata`) will not be copied into the new AnnData object."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "zarr_filepath = join(\"data\", \"habib17.h5ad.zarr\")\n",
- "if not isdir(zarr_filepath):\n",
- " adata.write_zarr(zarr_filepath, chunks=[adata.shape[0], VAR_CHUNK_SIZE])"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(\n",
- " schema_version=\"1.0.17\",\n",
- " name='Habib et al',\n",
- " description='COVID-19 Healthy Donor Brain'\n",
- ")\n",
- "\n",
- "# Add data.\n",
- "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
- " adata_path=zarr_filepath,\n",
- " obs_embedding_paths=[\"obsm/X_umap\"],\n",
- " obs_embedding_names=[\"UMAP\"],\n",
- " obs_set_paths=[\"obs/CellType\"],\n",
- " obs_set_names=[\"Cell Type\"],\n",
- " obs_feature_matrix_path=\"X\",\n",
- " initial_feature_filter_path=\"var/top_highly_variable\",\n",
- " coordination_values={\n",
- " \"obsType\": 'cell',\n",
- " \"featureType\": 'gene',\n",
- " \"featureValueType\": 'expression',\n",
- " },\n",
- ")).add_object(AnnDataWrapper(\n",
- " adata_path=zarr_filepath,\n",
- " obs_feature_column_paths=[\"obs/percent_mito\"],\n",
- " coordination_values={\n",
- " \"obsType\": 'cell',\n",
- " \"featureType\": 'qualityMetric',\n",
- " \"featureValueType\": 'value',\n",
- " }\n",
- "))\n",
- "\n",
- "# Add views.\n",
- "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
- "scatterplot_2 = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
- "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
- "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
- "histogram = vc.add_view(cm.FEATURE_VALUE_HISTOGRAM, dataset=dataset)\n",
- "\n",
- "# Link views.\n",
- "\n",
- "# Color one of the two scatterplots by the percent_mito quality metric.\n",
- "# Also use this quality metric for the histogram values.\n",
- "vc.link_views_by_dict([histogram, scatterplot_2], {\n",
- " \"obsType\": 'cell',\n",
- " \"featureType\": 'qualityMetric',\n",
- " \"featureValueType\": 'value',\n",
- " \"featureSelection\": [\"percent_mito\"],\n",
- " \"obsColorEncoding\": \"geneSelection\",\n",
- "}, meta=False)\n",
- "\n",
- "# Synchronize the zooming and panning of the two scatterplots\n",
- "vc.link_views_by_dict([scatterplot, scatterplot_2], {\n",
- " \"embeddingZoom\": None,\n",
- " \"embeddingTargetX\": None,\n",
- " \"embeddingTargetY\": None,\n",
- "}, meta=False)\n",
- "\n",
- "# Define the layout.\n",
- "vc.layout((scatterplot | (cell_sets / genes)) / (scatterplot_2 | histogram));"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 5. Create the widget\n"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.14"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/widget_brain_with_quality_metric.mo.py b/docs/notebooks/widget_brain_with_quality_metric.mo.py
new file mode 100644
index 00000000..5b3dfae1
--- /dev/null
+++ b/docs/notebooks/widget_brain_with_quality_metric.mo.py
@@ -0,0 +1,244 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Visualization of single-cell RNA seq data
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 1. Import dependencies
+
+ We need to import the classes and functions that we will be using from the corresponding packages.
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ import os
+ from os.path import join, isfile, isdir
+ from urllib.request import urlretrieve
+ from anndata import read_h5ad
+ import scanpy as sc
+
+ from vitessce import (
+ VitessceConfig,
+ Component as cm,
+ CoordinationType as ct,
+ AnnDataWrapper,
+ )
+ from vitessce.data_utils import (
+ optimize_adata,
+ VAR_CHUNK_SIZE,
+ )
+ return (
+ AnnDataWrapper,
+ VAR_CHUNK_SIZE,
+ VitessceConfig,
+ cm,
+ isdir,
+ isfile,
+ join,
+ os,
+ read_h5ad,
+ urlretrieve,
+ )
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 2. Download the data
+
+ For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17.
+ """
+ )
+ return
+
+
+@app.cell
+def _(isfile, join, os, urlretrieve):
+ adata_filepath = join("data", "habib17.processed.h5ad")
+ if not isfile(adata_filepath):
+ os.makedirs("data", exist_ok=True)
+ urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)
+ return (adata_filepath,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 3. Load the data
+
+ Note: this function may print a `FutureWarning`
+ """
+ )
+ return
+
+
+@app.cell
+def _(adata_filepath, read_h5ad):
+ adata = read_h5ad(adata_filepath)
+ return (adata,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 3.1. Preprocess the Data For Visualization
+
+ This dataset contains 25,587 genes. We prepare to visualize the top 50 highly variable genes for the heatmap as ranked by dispersion norm, although one may use any boolean array filter for the heatmap.
+ """
+ )
+ return
+
+
+@app.cell
+def _(adata):
+ top_dispersion = adata.var["dispersions_norm"][
+ sorted(
+ range(len(adata.var["dispersions_norm"])),
+ key=lambda k: adata.var["dispersions_norm"][k],
+ )[-51:][0]
+ ]
+ adata.var["top_highly_variable"] = (
+ adata.var["dispersions_norm"] > top_dispersion
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 3.2 Save the Data to Zarr store
+
+ We want to convert the original `h5ad` file to a [Zarr](https://zarr.readthedocs.io/en/stable/) store, which Vitessce is able to load. We can use the `optimize_adata` function to ensure that all arrays and dataframe columns that we intend to use in our visualization are in the optimal format to be loaded by Vitessce. This function will cast arrays to numerical data types that take up less space (as long as the values allow). Note: unused arrays and columns (i.e., not specified in any of the parameters to `optimize_adata`) will not be copied into the new AnnData object.
+ """
+ )
+ return
+
+
+@app.cell
+def _(VAR_CHUNK_SIZE, adata, isdir, join):
+ zarr_filepath = join("data", "habib17.h5ad.zarr")
+ if not isdir(zarr_filepath):
+ adata.write_zarr(zarr_filepath, chunks=[adata.shape[0], VAR_CHUNK_SIZE])
+ return (zarr_filepath,)
+
+
+@app.cell
+def _(AnnDataWrapper, VitessceConfig, cm, zarr_filepath):
+ vc = VitessceConfig(
+ schema_version="1.0.17",
+ name='Habib et al',
+ description='COVID-19 Healthy Donor Brain'
+ )
+
+ # Add data.
+ dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(
+ adata_path=zarr_filepath,
+ obs_embedding_paths=["obsm/X_umap"],
+ obs_embedding_names=["UMAP"],
+ obs_set_paths=["obs/CellType"],
+ obs_set_names=["Cell Type"],
+ obs_feature_matrix_path="X",
+ initial_feature_filter_path="var/top_highly_variable",
+ coordination_values={
+ "obsType": 'cell',
+ "featureType": 'gene',
+ "featureValueType": 'expression',
+ },
+ )).add_object(AnnDataWrapper(
+ adata_path=zarr_filepath,
+ obs_feature_column_paths=["obs/percent_mito"],
+ coordination_values={
+ "obsType": 'cell',
+ "featureType": 'qualityMetric',
+ "featureValueType": 'value',
+ }
+ ))
+
+ # Add views.
+ scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping="UMAP")
+ scatterplot_2 = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping="UMAP")
+ cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)
+ genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)
+ histogram = vc.add_view(cm.FEATURE_VALUE_HISTOGRAM, dataset=dataset)
+
+ # Link views.
+
+ # Color one of the two scatterplots by the percent_mito quality metric.
+ # Also use this quality metric for the histogram values.
+ vc.link_views_by_dict([histogram, scatterplot_2], {
+ "obsType": 'cell',
+ "featureType": 'qualityMetric',
+ "featureValueType": 'value',
+ "featureSelection": ["percent_mito"],
+ "obsColorEncoding": "geneSelection",
+ }, meta=False)
+
+ # Synchronize the zooming and panning of the two scatterplots
+ vc.link_views_by_dict([scatterplot, scatterplot_2], {
+ "embeddingZoom": None,
+ "embeddingTargetX": None,
+ "embeddingTargetY": None,
+ }, meta=False)
+
+ # Define the layout.
+ vc.layout((scatterplot | (cell_sets / genes)) / (scatterplot_2 | histogram));
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 5. Create the widget
+
+ """
+ )
+ return
+
+
+@app.cell
+def _(vc):
+ vw = vc.widget()
+ vw
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/widget_from_dict.ipynb b/docs/notebooks/widget_from_dict.ipynb
deleted file mode 100644
index 868c8497..00000000
--- a/docs/notebooks/widget_from_dict.ipynb
+++ /dev/null
@@ -1,108 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Using an existing view config dict"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 1. Import dependencies\n",
- "\n",
- "We need to import the `VitessceConfig` class."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import VitessceConfig"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 2. Import config of interest as a dict\n",
- "\n",
- "The Vitessce config at its lowest level is a JSON object or a Python `dict` that specifies a layout for the Vitessce components will be rendered in the widget. These components may be scatterplots, spatial plots, heatmaps, or control components. The config also describes the datasets and files that will be visualized.\n",
- "\n",
- "The `vitessce` package provides helper functions and classes to simplify the process of defining Vitessce configs. Those functions are demonstrated in the other notebooks. The helper functions are intended to make visualization of local datasets easy. However, in this case, we are importing a config that has been pre-defined in the file `example_configs.py`, in which the dataset being visualized is stored remotely in AWS S3 (rather than locally)."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from example_configs import dries as dries_config"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 3. Create the Vitessce widget\n",
- "\n",
- "Create the widget by creating a new config instance using the `VitessceConfig.from_dict` static method, then calling the config's `.widget()` method.\n",
- "\n",
- "Render the widget by placing the widget variable on its own line at the end of the notebook cell."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig.from_dict(dries_config)\n",
- "vw = vc.widget()\n",
- "vw"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.8.0"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/widget_from_dict.mo.py b/docs/notebooks/widget_from_dict.mo.py
new file mode 100644
index 00000000..a55c97e1
--- /dev/null
+++ b/docs/notebooks/widget_from_dict.mo.py
@@ -0,0 +1,94 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Using an existing view config dict
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 1. Import dependencies
+
+ We need to import the `VitessceConfig` class.
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ from vitessce import VitessceConfig
+ return (VitessceConfig,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 2. Import config of interest as a dict
+
+ The Vitessce config at its lowest level is a JSON object or a Python `dict` that specifies a layout for the Vitessce components will be rendered in the widget. These components may be scatterplots, spatial plots, heatmaps, or control components. The config also describes the datasets and files that will be visualized.
+
+ The `vitessce` package provides helper functions and classes to simplify the process of defining Vitessce configs. Those functions are demonstrated in the other notebooks. The helper functions are intended to make visualization of local datasets easy. However, in this case, we are importing a config that has been pre-defined in the file `example_configs.py`, in which the dataset being visualized is stored remotely in AWS S3 (rather than locally).
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ from example_configs import dries as dries_config
+ return (dries_config,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 3. Create the Vitessce widget
+
+ Create the widget by creating a new config instance using the `VitessceConfig.from_dict` static method, then calling the config's `.widget()` method.
+
+ Render the widget by placing the widget variable on its own line at the end of the notebook cell.
+ """
+ )
+ return
+
+
+@app.cell
+def _(VitessceConfig, dries_config):
+ vc = VitessceConfig.from_dict(dries_config)
+ vw = vc.widget()
+ vw
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/widget_genomic_profiles.ipynb b/docs/notebooks/widget_genomic_profiles.ipynb
deleted file mode 100644
index 1794598c..00000000
--- a/docs/notebooks/widget_genomic_profiles.ipynb
+++ /dev/null
@@ -1,220 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Visualization of genomic profiles"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 1. Import dependencies\n",
- "\n",
- "We need to import the classes and functions that we will be using from the corresponding packages."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " ViewType as vt,\n",
- " CoordinationType as ct,\n",
- " AnnDataWrapper,\n",
- " MultivecZarrWrapper,\n",
- ")\n",
- "from vitessce.data_utils import (\n",
- " adata_to_multivec_zarr,\n",
- ")\n",
- "from os.path import join\n",
- "from scipy.io import mmread\n",
- "import pandas as pd\n",
- "import numpy as np\n",
- "from anndata import AnnData"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 2. Load the data\n",
- "\n",
- "In this step, we load the raw data that has been downloaded from the HuBMAP portal https://portal.hubmapconsortium.org/browse/dataset/210d118a14c8624b6bb9610a9062656e"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "mtx = mmread(join('data', 'snapatac', 'filtered_cell_by_bin.mtx')).toarray()\n",
- "barcodes_df = pd.read_csv(join('data', 'snapatac', 'barcodes.txt'), header=None)\n",
- "bins_df = pd.read_csv(join('data', 'snapatac', 'bins.txt'), header=None, names=[\"interval\"])\n",
- "clusters_df = pd.read_csv(join('data', 'snapatac', 'umap_coords_clusters.csv'), index_col=0)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 3. Convert the data to Vitessce-compatible formats\n",
- "\n",
- "Vitessce can load AnnData objects saved to Zarr formats efficiently."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "# The genome assembly is GRCh38 but the chromosome names in the bin names do not start with the \"chr\" prefix.\n",
- "# This is incompatible with the chromosome names from `negspy`, so we need to append the prefix.\n",
- "bins_df[\"interval\"] = bins_df[\"interval\"].apply(lambda x: \"chr\" + x)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "obs = clusters_df[[\"cluster\"]]\n",
- "obs[\"cluster\"] = obs[\"cluster\"].astype(str)\n",
- "obsm = { \"X_umap\": clusters_df[[\"umap.1\", \"umap.2\"]].values }\n",
- "adata = AnnData(X=mtx, obs=obs, var=bins_df, obsm=obsm)\n",
- "adata"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "multivec_zarr_path = join(\"data\", \"HBM485.TBWH.322.multivec.zarr\")\n",
- "adata_zarr_path = join(\"data\", \"HBM485.TBWH.322.adata.zarr\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "# Sort cluster IDs\n",
- "cluster_ids = obs[\"cluster\"].unique().tolist()\n",
- "cluster_ids.sort(key=int)\n",
- "# Save genomic profiles to multivec-zarr format.\n",
- "adata_to_multivec_zarr(adata, multivec_zarr_path, obs_set_col=\"cluster\", obs_set_name=\"Cluster\", obs_set_vals=cluster_ids)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "# Save anndata object to AnnData-Zarr format.\n",
- "adata.write_zarr(adata_zarr_path)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "tags": []
- },
- "source": [
- "## 4. Make a Vitessce configuration\n",
- "\n",
- "We need to tell Vitessce about the data that we want to load and the visualization components that we want to include in the widget.\n",
- "For this dataset, we want to add the `GENOMIC_PROFILES` component, which renders genome browser tracks with [HiGlass](http://higlass.io)."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='HuBMAP snATAC-seq')\n",
- "dataset = vc.add_dataset(name='HBM485.TBWH.322').add_object(MultivecZarrWrapper(\n",
- " zarr_path=multivec_zarr_path\n",
- ")).add_object(AnnDataWrapper(\n",
- " adata_path=adata_zarr_path,\n",
- " obs_embedding_paths=[\"obsm/X_umap\"],\n",
- " obs_embedding_names=[\"UMAP\"],\n",
- " obs_set_paths=[\"obs/cluster\"],\n",
- " obs_set_names=[\"Cluster\"],\n",
- "))\n",
- "\n",
- "genomic_profiles = vc.add_view(vt.GENOMIC_PROFILES, dataset=dataset)\n",
- "scatter = vc.add_view(vt.SCATTERPLOT, dataset=dataset, mapping = \"UMAP\")\n",
- "cell_sets = vc.add_view(vt.OBS_SETS, dataset=dataset)\n",
- "\n",
- "vc.layout(genomic_profiles / (scatter | cell_sets));"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 5. Create the widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget(height=800)\n",
- "vw"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.7.4"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/widget_genomic_profiles.mo.py b/docs/notebooks/widget_genomic_profiles.mo.py
new file mode 100644
index 00000000..592bf698
--- /dev/null
+++ b/docs/notebooks/widget_genomic_profiles.mo.py
@@ -0,0 +1,209 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Visualization of genomic profiles
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 1. Import dependencies
+
+ We need to import the classes and functions that we will be using from the corresponding packages.
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ from vitessce import (
+ VitessceConfig,
+ ViewType as vt,
+ CoordinationType as ct,
+ AnnDataWrapper,
+ MultivecZarrWrapper,
+ )
+ from vitessce.data_utils import (
+ adata_to_multivec_zarr,
+ )
+ from os.path import join
+ from scipy.io import mmread
+ import pandas as pd
+ import numpy as np
+ from anndata import AnnData
+ return (
+ AnnData,
+ AnnDataWrapper,
+ MultivecZarrWrapper,
+ VitessceConfig,
+ adata_to_multivec_zarr,
+ join,
+ mmread,
+ pd,
+ vt,
+ )
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 2. Load the data
+
+ In this step, we load the raw data that has been downloaded from the HuBMAP portal https://portal.hubmapconsortium.org/browse/dataset/210d118a14c8624b6bb9610a9062656e
+ """
+ )
+ return
+
+
+@app.cell
+def _(join, mmread, pd):
+ mtx = mmread(join('data', 'snapatac', 'filtered_cell_by_bin.mtx')).toarray()
+ barcodes_df = pd.read_csv(join('data', 'snapatac', 'barcodes.txt'), header=None)
+ bins_df = pd.read_csv(join('data', 'snapatac', 'bins.txt'), header=None, names=["interval"])
+ clusters_df = pd.read_csv(join('data', 'snapatac', 'umap_coords_clusters.csv'), index_col=0)
+ return bins_df, clusters_df, mtx
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 3. Convert the data to Vitessce-compatible formats
+
+ Vitessce can load AnnData objects saved to Zarr formats efficiently.
+ """
+ )
+ return
+
+
+@app.cell
+def _(bins_df):
+ # The genome assembly is GRCh38 but the chromosome names in the bin names do not start with the "chr" prefix.
+ # This is incompatible with the chromosome names from `negspy`, so we need to append the prefix.
+ bins_df["interval"] = bins_df["interval"].apply(lambda x: "chr" + x)
+ return
+
+
+@app.cell
+def _(AnnData, bins_df, clusters_df, mtx):
+ obs = clusters_df[["cluster"]]
+ obs["cluster"] = obs["cluster"].astype(str)
+ obsm = { "X_umap": clusters_df[["umap.1", "umap.2"]].values }
+ adata = AnnData(X=mtx, obs=obs, var=bins_df, obsm=obsm)
+ adata
+ return adata, obs
+
+
+@app.cell
+def _(join):
+ multivec_zarr_path = join("data", "HBM485.TBWH.322.multivec.zarr")
+ adata_zarr_path = join("data", "HBM485.TBWH.322.adata.zarr")
+ return adata_zarr_path, multivec_zarr_path
+
+
+@app.cell
+def _(adata, adata_to_multivec_zarr, multivec_zarr_path, obs):
+ # Sort cluster IDs
+ cluster_ids = obs["cluster"].unique().tolist()
+ cluster_ids.sort(key=int)
+ # Save genomic profiles to multivec-zarr format.
+ adata_to_multivec_zarr(adata, multivec_zarr_path, obs_set_col="cluster", obs_set_name="Cluster", obs_set_vals=cluster_ids)
+ return
+
+
+@app.cell
+def _(adata, adata_zarr_path):
+ # Save anndata object to AnnData-Zarr format.
+ adata.write_zarr(adata_zarr_path)
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 4. Make a Vitessce configuration
+
+ We need to tell Vitessce about the data that we want to load and the visualization components that we want to include in the widget.
+ For this dataset, we want to add the `GENOMIC_PROFILES` component, which renders genome browser tracks with [HiGlass](http://higlass.io).
+ """
+ )
+ return
+
+
+@app.cell
+def _(
+ AnnDataWrapper,
+ MultivecZarrWrapper,
+ VitessceConfig,
+ adata_zarr_path,
+ multivec_zarr_path,
+ vt,
+):
+ vc = VitessceConfig(schema_version="1.0.15", name='HuBMAP snATAC-seq')
+ dataset = vc.add_dataset(name='HBM485.TBWH.322').add_object(MultivecZarrWrapper(
+ zarr_path=multivec_zarr_path
+ )).add_object(AnnDataWrapper(
+ adata_path=adata_zarr_path,
+ obs_embedding_paths=["obsm/X_umap"],
+ obs_embedding_names=["UMAP"],
+ obs_set_paths=["obs/cluster"],
+ obs_set_names=["Cluster"],
+ ))
+
+ genomic_profiles = vc.add_view(vt.GENOMIC_PROFILES, dataset=dataset)
+ scatter = vc.add_view(vt.SCATTERPLOT, dataset=dataset, mapping = "UMAP")
+ cell_sets = vc.add_view(vt.OBS_SETS, dataset=dataset)
+
+ vc.layout(genomic_profiles / (scatter | cell_sets));
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 5. Create the widget
+ """
+ )
+ return
+
+
+@app.cell
+def _(vc):
+ vw = vc.widget(height=800)
+ vw
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/widget_imaging.ipynb b/docs/notebooks/widget_imaging.ipynb
deleted file mode 100644
index 9eed449f..00000000
--- a/docs/notebooks/widget_imaging.ipynb
+++ /dev/null
@@ -1,114 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Visualization of Multi-Modal Imaging Data\n",
- "We visualize IMS, PAS, and AF imaging data overlaid from the Spraggins Lab of the Biomolecular Multimodal Imaging Center (BIOMC) at Vanderbilt University, uploaded to the HuBMAP data portal."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " OmeTiffWrapper,\n",
- " MultiImageWrapper,\n",
- ")\n",
- "from os.path import join"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 1. Configure Vitessce\n",
- "Set up the images from the three different assays, with the `use_physical_size_scaling` set to `True` so that the IMS image scales to the other images based on their physical sizes."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='Spraggins Multi-Modal', description='PAS + IMS + AF From https://portal.hubmapconsortium.org/browse/collection/6a6efd0c1a2681dc7d2faab8e4ab0bca')\n",
- "dataset = vc.add_dataset(name='Spraggins').add_object(\n",
- " MultiImageWrapper(\n",
- " image_wrappers=[\n",
- " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/f4188a148e4c759092d19369d310883b/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-PAS_images/VAN0006-LK-2-85-PAS_registered.ome.tif?token=', name='PAS'),\n",
- " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/2130d5f91ce61d7157a42c0497b06de8/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-AF_preIMS_images/VAN0006-LK-2-85-AF_preIMS_registered.ome.tif?token=', name='AF'),\n",
- " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/be503a021ed910c0918842e318e6efa2/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_PosMode_multilayer.ome.tif?token=', name='IMS Pos Mode'),\n",
- " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/ca886a630b2038997a4cfbbf4abfd283/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_NegMode_multilayer.ome.tif?token=', name='IMS Neg Mode')\n",
- " ],\n",
- " use_physical_size_scaling=True,\n",
- " )\n",
- ")\n",
- "spatial = vc.add_view(cm.SPATIAL, dataset=dataset)\n",
- "status = vc.add_view(cm.STATUS, dataset=dataset)\n",
- "lc = vc.add_view(cm.LAYER_CONTROLLER, dataset=dataset).set_props(disableChannelsIfRgbDetected=True)\n",
- "vc.layout(spatial | (lc / status));"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 2. Create the Vitessce widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.8.0"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/widget_imaging.mo.py b/docs/notebooks/widget_imaging.mo.py
new file mode 100644
index 00000000..ea18dd11
--- /dev/null
+++ b/docs/notebooks/widget_imaging.mo.py
@@ -0,0 +1,97 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Visualization of Multi-Modal Imaging Data
+ We visualize IMS, PAS, and AF imaging data overlaid from the Spraggins Lab of the Biomolecular Multimodal Imaging Center (BIOMC) at Vanderbilt University, uploaded to the HuBMAP data portal.
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ from vitessce import (
+ VitessceConfig,
+ Component as cm,
+ CoordinationType as ct,
+ OmeTiffWrapper,
+ MultiImageWrapper,
+ )
+ from os.path import join
+ return MultiImageWrapper, OmeTiffWrapper, VitessceConfig, cm
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 1. Configure Vitessce
+ Set up the images from the three different assays, with the `use_physical_size_scaling` set to `True` so that the IMS image scales to the other images based on their physical sizes.
+ """
+ )
+ return
+
+
+@app.cell
+def _(MultiImageWrapper, OmeTiffWrapper, VitessceConfig, cm):
+ vc = VitessceConfig(schema_version="1.0.15", name='Spraggins Multi-Modal', description='PAS + IMS + AF From https://portal.hubmapconsortium.org/browse/collection/6a6efd0c1a2681dc7d2faab8e4ab0bca')
+ dataset = vc.add_dataset(name='Spraggins').add_object(
+ MultiImageWrapper(
+ image_wrappers=[
+ OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/f4188a148e4c759092d19369d310883b/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-PAS_images/VAN0006-LK-2-85-PAS_registered.ome.tif?token=', name='PAS'),
+ OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/2130d5f91ce61d7157a42c0497b06de8/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-AF_preIMS_images/VAN0006-LK-2-85-AF_preIMS_registered.ome.tif?token=', name='AF'),
+ OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/be503a021ed910c0918842e318e6efa2/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_PosMode_multilayer.ome.tif?token=', name='IMS Pos Mode'),
+ OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/ca886a630b2038997a4cfbbf4abfd283/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_NegMode_multilayer.ome.tif?token=', name='IMS Neg Mode')
+ ],
+ use_physical_size_scaling=True,
+ )
+ )
+ spatial = vc.add_view(cm.SPATIAL, dataset=dataset)
+ status = vc.add_view(cm.STATUS, dataset=dataset)
+ lc = vc.add_view(cm.LAYER_CONTROLLER, dataset=dataset).set_props(disableChannelsIfRgbDetected=True)
+ vc.layout(spatial | (lc / status));
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 2. Create the Vitessce widget
+ """
+ )
+ return
+
+
+@app.cell
+def _(vc):
+ vw = vc.widget()
+ vw
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/widget_imaging_beta.ipynb b/docs/notebooks/widget_imaging_beta.ipynb
deleted file mode 100644
index e0f78c5b..00000000
--- a/docs/notebooks/widget_imaging_beta.ipynb
+++ /dev/null
@@ -1,168 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Visualization of Multi-Modal Imaging Data\n",
- "We visualize IMS, PAS, and AF imaging data overlaid from the Spraggins Lab of the Biomolecular Multimodal Imaging Center (BIOMC) at Vanderbilt University, uploaded to the HuBMAP data portal."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " OmeTiffWrapper,\n",
- " MultiImageWrapper,\n",
- " CoordinationLevel as CL,\n",
- ")\n",
- "from os.path import join"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 1. Configure Vitessce\n",
- "Set up the images from the three different assays, with the `use_physical_size_scaling` set to `True` so that the IMS image scales to the other images based on their physical sizes."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.16\", name='Spraggins Multi-Modal', description='PAS + IMS + AF From https://portal.hubmapconsortium.org/browse/collection/6a6efd0c1a2681dc7d2faab8e4ab0bca')\n",
- "dataset = vc.add_dataset(name='Spraggins').add_file(\n",
- " url='https://assets.hubmapconsortium.org/f4188a148e4c759092d19369d310883b/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-PAS_images/VAN0006-LK-2-85-PAS_registered.ome.tif?token=',\n",
- " file_type=\"image.ome-tiff\",\n",
- " coordination_values={\n",
- " \"fileUid\": \"PAS\",\n",
- " },\n",
- ")\n",
- "\n",
- "imageScopes = vc.add_coordination_by_dict({\n",
- " \"imageLayer\": CL([\n",
- " {\n",
- " \"fileUid\": 'PAS',\n",
- " \"spatialLayerOpacity\": 1,\n",
- " \"spatialLayerVisible\": True,\n",
- " \"photometricInterpretation\": 'RGB',\n",
- " \"imageChannel\": CL([\n",
- " {\n",
- " \"spatialTargetC\": 0,\n",
- " \"spatialChannelColor\": [255, 0, 0],\n",
- " \"spatialChannelVisible\": True,\n",
- " \"spatialChannelOpacity\": 1.0,\n",
- " \"spatialChannelWindow\": [0, 255],\n",
- " },\n",
- " {\n",
- " \"spatialTargetC\": 1,\n",
- " \"spatialChannelColor\": [0, 255, 0],\n",
- " \"spatialChannelVisible\": True,\n",
- " \"spatialChannelOpacity\": 1.0,\n",
- " \"spatialChannelWindow\": [0, 255],\n",
- " },\n",
- " {\n",
- " \"spatialTargetC\": 2,\n",
- " \"spatialChannelColor\": [0, 0, 255],\n",
- " \"spatialChannelVisible\": True,\n",
- " \"spatialChannelOpacity\": 1.0,\n",
- " \"spatialChannelWindow\": [0, 255],\n",
- " },\n",
- " ]),\n",
- " }\n",
- " ])\n",
- "})\n",
- "\n",
- "metaCoordinationScope = vc.add_meta_coordination()\n",
- "metaCoordinationScope.use_coordination_by_dict(imageScopes)\n",
- "\n",
- "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
- "lc = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
- "\n",
- "spatial.use_meta_coordination(metaCoordinationScope)\n",
- "lc.use_meta_coordination(metaCoordinationScope)\n",
- "\n",
- "vc.layout(spatial | lc);"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 2. Create the Vitessce widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {},
- "outputs": [
- {
- "data": {
- "application/vnd.jupyter.widget-view+json": {
- "model_id": "a5efa92286df4ad58cf94cfb3d12b703",
- "version_major": 2,
- "version_minor": 0
- },
- "text/plain": [
- "VitessceWidget(config={'version': '1.0.16', 'name': 'Spraggins Multi-Modal', 'description': 'PAS + IMS + AF Fr…"
- ]
- },
- "execution_count": 3,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "vw = vc.widget(custom_js_url='http://localhost:8000/packages/main/prod/dist/index.min.js')\n",
- "vw"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.9.0"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/widget_imaging_beta.mo.py b/docs/notebooks/widget_imaging_beta.mo.py
new file mode 100644
index 00000000..4fde5426
--- /dev/null
+++ b/docs/notebooks/widget_imaging_beta.mo.py
@@ -0,0 +1,135 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Visualization of Multi-Modal Imaging Data
+ We visualize IMS, PAS, and AF imaging data overlaid from the Spraggins Lab of the Biomolecular Multimodal Imaging Center (BIOMC) at Vanderbilt University, uploaded to the HuBMAP data portal.
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ from vitessce import (
+ VitessceConfig,
+ Component as cm,
+ CoordinationType as ct,
+ OmeTiffWrapper,
+ MultiImageWrapper,
+ CoordinationLevel as CL,
+ )
+ from os.path import join
+ return CL, VitessceConfig
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 1. Configure Vitessce
+ Set up the images from the three different assays, with the `use_physical_size_scaling` set to `True` so that the IMS image scales to the other images based on their physical sizes.
+ """
+ )
+ return
+
+
+@app.cell
+def _(CL, VitessceConfig):
+ vc = VitessceConfig(schema_version="1.0.16", name='Spraggins Multi-Modal', description='PAS + IMS + AF From https://portal.hubmapconsortium.org/browse/collection/6a6efd0c1a2681dc7d2faab8e4ab0bca')
+ dataset = vc.add_dataset(name='Spraggins').add_file(
+ url='https://assets.hubmapconsortium.org/f4188a148e4c759092d19369d310883b/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-PAS_images/VAN0006-LK-2-85-PAS_registered.ome.tif?token=',
+ file_type="image.ome-tiff",
+ coordination_values={
+ "fileUid": "PAS",
+ },
+ )
+
+ imageScopes = vc.add_coordination_by_dict({
+ "imageLayer": CL([
+ {
+ "fileUid": 'PAS',
+ "spatialLayerOpacity": 1,
+ "spatialLayerVisible": True,
+ "photometricInterpretation": 'RGB',
+ "imageChannel": CL([
+ {
+ "spatialTargetC": 0,
+ "spatialChannelColor": [255, 0, 0],
+ "spatialChannelVisible": True,
+ "spatialChannelOpacity": 1.0,
+ "spatialChannelWindow": [0, 255],
+ },
+ {
+ "spatialTargetC": 1,
+ "spatialChannelColor": [0, 255, 0],
+ "spatialChannelVisible": True,
+ "spatialChannelOpacity": 1.0,
+ "spatialChannelWindow": [0, 255],
+ },
+ {
+ "spatialTargetC": 2,
+ "spatialChannelColor": [0, 0, 255],
+ "spatialChannelVisible": True,
+ "spatialChannelOpacity": 1.0,
+ "spatialChannelWindow": [0, 255],
+ },
+ ]),
+ }
+ ])
+ })
+
+ metaCoordinationScope = vc.add_meta_coordination()
+ metaCoordinationScope.use_coordination_by_dict(imageScopes)
+
+ spatial = vc.add_view("spatialBeta", dataset=dataset)
+ lc = vc.add_view("layerControllerBeta", dataset=dataset)
+
+ spatial.use_meta_coordination(metaCoordinationScope)
+ lc.use_meta_coordination(metaCoordinationScope)
+
+ vc.layout(spatial | lc);
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 2. Create the Vitessce widget
+ """
+ )
+ return
+
+
+@app.cell
+def _(vc):
+ vw = vc.widget(custom_js_url='http://localhost:8000/packages/main/prod/dist/index.min.js')
+ vw
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/widget_imaging_segmentation.ipynb b/docs/notebooks/widget_imaging_segmentation.ipynb
deleted file mode 100644
index 7177e4d8..00000000
--- a/docs/notebooks/widget_imaging_segmentation.ipynb
+++ /dev/null
@@ -1,118 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Visualization of Segmentation Bitmask\n",
- "We visualize raw imaging data + a segmentation bitmask the [MCMicro piplene](https://mcmicro.org/) - see https://www.biorxiv.org/content/10.1101/2021.03.15.435473v1.full and specifically [Figure S1](https://www.google.com/url?q=https://www.biorxiv.org/content/10.1101/2021.03.15.435473v1.full%23F3&sa=D&source=editors&ust=1623173627976000&usg=AOvVaw3JkzCxYyE86q8jxfNCgShh)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " OmeTiffWrapper,\n",
- " MultiImageWrapper,\n",
- ")\n",
- "from os.path import join"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 1. Configure Vitessce\n",
- "Set up the two images, already pyramidal from the [bioformats2raw + raw2ometiff pipeline](https://github.com/hms-dbmi/viv/tree/master/tutorial), labeling the segmentation \"on top\" as the bitmask and the other as simply the image data. "
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='MCMicro Bitmask Visualization', description='Segmentation + Data of Exemplar 001')\n",
- "dataset = vc.add_dataset(name='MCMicro').add_object(\n",
- " MultiImageWrapper(\n",
- " image_wrappers=[\n",
- " OmeTiffWrapper(img_url='https://vitessce-demo-data.storage.googleapis.com/exemplar-001/exemplar-001.pyramid.ome.tif', name='Image'),\n",
- " OmeTiffWrapper(img_url='https://vitessce-demo-data.storage.googleapis.com/exemplar-001/cellMask.pyramid.ome.tif', name='Mask', is_bitmask=True),\n",
- " ]\n",
- " )\n",
- ")\n",
- "spatial = vc.add_view(cm.SPATIAL, dataset=dataset)\n",
- "status = vc.add_view(cm.STATUS, dataset=dataset)\n",
- "lc = vc.add_view(cm.LAYER_CONTROLLER, dataset=dataset)\n",
- "vc.layout(spatial | (lc / status));"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 2. Create the Vitessce widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.8.0"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/widget_imaging_segmentation.mo.py b/docs/notebooks/widget_imaging_segmentation.mo.py
new file mode 100644
index 00000000..532bb71c
--- /dev/null
+++ b/docs/notebooks/widget_imaging_segmentation.mo.py
@@ -0,0 +1,94 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Visualization of Segmentation Bitmask
+ We visualize raw imaging data + a segmentation bitmask the [MCMicro piplene](https://mcmicro.org/) - see https://www.biorxiv.org/content/10.1101/2021.03.15.435473v1.full and specifically [Figure S1](https://www.google.com/url?q=https://www.biorxiv.org/content/10.1101/2021.03.15.435473v1.full%23F3&sa=D&source=editors&ust=1623173627976000&usg=AOvVaw3JkzCxYyE86q8jxfNCgShh)
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ from vitessce import (
+ VitessceConfig,
+ Component as cm,
+ CoordinationType as ct,
+ OmeTiffWrapper,
+ MultiImageWrapper,
+ )
+ from os.path import join
+ return MultiImageWrapper, OmeTiffWrapper, VitessceConfig, cm
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 1. Configure Vitessce
+ Set up the two images, already pyramidal from the [bioformats2raw + raw2ometiff pipeline](https://github.com/hms-dbmi/viv/tree/master/tutorial), labeling the segmentation "on top" as the bitmask and the other as simply the image data.
+ """
+ )
+ return
+
+
+@app.cell
+def _(MultiImageWrapper, OmeTiffWrapper, VitessceConfig, cm):
+ vc = VitessceConfig(schema_version="1.0.15", name='MCMicro Bitmask Visualization', description='Segmentation + Data of Exemplar 001')
+ dataset = vc.add_dataset(name='MCMicro').add_object(
+ MultiImageWrapper(
+ image_wrappers=[
+ OmeTiffWrapper(img_url='https://vitessce-demo-data.storage.googleapis.com/exemplar-001/exemplar-001.pyramid.ome.tif', name='Image'),
+ OmeTiffWrapper(img_url='https://vitessce-demo-data.storage.googleapis.com/exemplar-001/cellMask.pyramid.ome.tif', name='Mask', is_bitmask=True),
+ ]
+ )
+ )
+ spatial = vc.add_view(cm.SPATIAL, dataset=dataset)
+ status = vc.add_view(cm.STATUS, dataset=dataset)
+ lc = vc.add_view(cm.LAYER_CONTROLLER, dataset=dataset)
+ vc.layout(spatial | (lc / status));
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 2. Create the Vitessce widget
+ """
+ )
+ return
+
+
+@app.cell
+def _(vc):
+ vw = vc.widget()
+ vw
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/widget_loom.ipynb b/docs/notebooks/widget_loom.ipynb
deleted file mode 100644
index 0c4f958b..00000000
--- a/docs/notebooks/widget_loom.ipynb
+++ /dev/null
@@ -1,219 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Visualization of a Loom file"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 1. Import dependencies"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join, isfile, isdir\n",
- "from urllib.request import urlretrieve\n",
- "from anndata import read_loom\n",
- "import numpy as np\n",
- "\n",
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " AnnDataWrapper,\n",
- ")\n",
- "from vitessce.data_utils import (\n",
- " optimize_adata,\n",
- " to_diamond,\n",
- " VAR_CHUNK_SIZE,\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 2. Download data\n",
- "\n",
- "Download `osmFISH_SScortex_mouse_all_cells.loom` from http://loom.linnarssonlab.org/."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "loom_filepath = join(\"data\", \"osmFISH_SScortex_mouse_all_cells.loom\")\n",
- "if not isfile(loom_filepath):\n",
- " os.makedirs(\"data\", exist_ok=True)\n",
- " urlretrieve('http://loom.linnarssonlab.org/clone/osmFISH/osmFISH_SScortex_mouse_all_cells.loom', loom_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 3. Open Loom file with AnnData's read_loom"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "adata = read_loom(loom_filepath, obsm_names={\"tSNE\": [\"_tSNE_1\", \"_tSNE_2\"], \"spatial\": [\"X\", \"Y\"]})"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Generate pseudo-segmentations as diamond-shaped polygons centered on the spatial coordinate of each cell, and store in `adata.obsm[\"segmentations\"]`"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "num_cells = adata.obs.shape[0]\n",
- "adata.obsm[\"segmentations\"] = np.zeros((num_cells, 4, 2))\n",
- "radius = 100\n",
- "for i in range(num_cells):\n",
- " adata.obsm[\"segmentations\"][i, :, :] = to_diamond(adata.obsm['spatial'][i, 0], adata.obsm['spatial'][i, 1], radius)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Save the AnnData object to a Zarr store:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "zarr_filepath = join(\"data\", \"osmFISH_SScortex_mouse_all_cells.zarr\")\n",
- "if not isdir(zarr_filepath) or True:\n",
- " adata = optimize_adata(\n",
- " adata,\n",
- " obs_cols=[\"ClusterName\"],\n",
- " obsm_keys=[\"tSNE\", \"spatial\", \"segmentations\"],\n",
- " optimize_X=True,\n",
- " )\n",
- " adata.write_zarr(zarr_filepath, chunks=[adata.shape[0], VAR_CHUNK_SIZE])"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 4. Configure Vitessce\n",
- "\n",
- "Create a Vitessce view config."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='Loom Example', description='osmFISH dataset of the mouse cortex including all cells')\n",
- "w = AnnDataWrapper(adata_path=zarr_filepath, obs_set_paths=[\"obs/ClusterName\"], obs_set_names=[\"Clusters\"], obs_locations_path=\"obsm/spatial\", obs_segmentations_path=\"obsm/segmentations\", obs_embedding_paths=[\"obsm/tSNE\"])\n",
- "dataset = vc.add_dataset(name='SScortex').add_object(w)\n",
- "\n",
- "tsne = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"tSNE\")\n",
- "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
- "spatial = vc.add_view(cm.SPATIAL, dataset=dataset)\n",
- "\n",
- "spatial_segmentation_layer_value = {\n",
- " \"opacity\": 1,\n",
- " \"radius\": 0,\n",
- " \"visible\": True,\n",
- " \"stroked\": False\n",
- "}\n",
- "\n",
- "vc.link_views([spatial], [ct.SPATIAL_ZOOM, ct.SPATIAL_TARGET_X, ct.SPATIAL_TARGET_Y, ct.SPATIAL_SEGMENTATION_LAYER], [-6.43, 10417.69, 24885.55, spatial_segmentation_layer_value])\n",
- "vc.layout(spatial | (tsne / cell_sets));"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 5. Render the widget"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "A widget can be created with the `.widget()` method on the config instance."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.8.0"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/widget_loom.mo.py b/docs/notebooks/widget_loom.mo.py
new file mode 100644
index 00000000..eb879421
--- /dev/null
+++ b/docs/notebooks/widget_loom.mo.py
@@ -0,0 +1,218 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Visualization of a Loom file
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 1. Import dependencies
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ import os
+ from os.path import join, isfile, isdir
+ from urllib.request import urlretrieve
+ from anndata import read_loom
+ import numpy as np
+
+ from vitessce import (
+ VitessceConfig,
+ Component as cm,
+ CoordinationType as ct,
+ AnnDataWrapper,
+ )
+ from vitessce.data_utils import (
+ optimize_adata,
+ to_diamond,
+ VAR_CHUNK_SIZE,
+ )
+ return (
+ AnnDataWrapper,
+ VAR_CHUNK_SIZE,
+ VitessceConfig,
+ cm,
+ ct,
+ isdir,
+ isfile,
+ join,
+ np,
+ optimize_adata,
+ os,
+ read_loom,
+ to_diamond,
+ urlretrieve,
+ )
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 2. Download data
+
+ Download `osmFISH_SScortex_mouse_all_cells.loom` from http://loom.linnarssonlab.org/.
+ """
+ )
+ return
+
+
+@app.cell
+def _(isfile, join, os, urlretrieve):
+ loom_filepath = join("data", "osmFISH_SScortex_mouse_all_cells.loom")
+ if not isfile(loom_filepath):
+ os.makedirs("data", exist_ok=True)
+ urlretrieve('http://loom.linnarssonlab.org/clone/osmFISH/osmFISH_SScortex_mouse_all_cells.loom', loom_filepath)
+ return (loom_filepath,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 3. Open Loom file with AnnData's read_loom
+ """
+ )
+ return
+
+
+@app.cell
+def _(loom_filepath, read_loom):
+ adata = read_loom(loom_filepath, obsm_names={"tSNE": ["_tSNE_1", "_tSNE_2"], "spatial": ["X", "Y"]})
+ return (adata,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ Generate pseudo-segmentations as diamond-shaped polygons centered on the spatial coordinate of each cell, and store in `adata.obsm["segmentations"]`
+ """
+ )
+ return
+
+
+@app.cell
+def _(adata, np, to_diamond):
+ num_cells = adata.obs.shape[0]
+ adata.obsm["segmentations"] = np.zeros((num_cells, 4, 2))
+ radius = 100
+ for i in range(num_cells):
+ adata.obsm["segmentations"][i, :, :] = to_diamond(adata.obsm['spatial'][i, 0], adata.obsm['spatial'][i, 1], radius)
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ Save the AnnData object to a Zarr store:
+ """
+ )
+ return
+
+
+@app.cell
+def _(VAR_CHUNK_SIZE, adata, isdir, join, optimize_adata):
+ zarr_filepath = join('data', 'osmFISH_SScortex_mouse_all_cells.zarr')
+ if not isdir(zarr_filepath) or True:
+ adata_1 = optimize_adata(adata, obs_cols=['ClusterName'], obsm_keys=['tSNE', 'spatial', 'segmentations'], optimize_X=True)
+ adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])
+ return (zarr_filepath,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 4. Configure Vitessce
+
+ Create a Vitessce view config.
+ """
+ )
+ return
+
+
+@app.cell
+def _(AnnDataWrapper, VitessceConfig, cm, ct, zarr_filepath):
+ vc = VitessceConfig(schema_version="1.0.15", name='Loom Example', description='osmFISH dataset of the mouse cortex including all cells')
+ w = AnnDataWrapper(adata_path=zarr_filepath, obs_set_paths=["obs/ClusterName"], obs_set_names=["Clusters"], obs_locations_path="obsm/spatial", obs_segmentations_path="obsm/segmentations", obs_embedding_paths=["obsm/tSNE"])
+ dataset = vc.add_dataset(name='SScortex').add_object(w)
+
+ tsne = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping="tSNE")
+ cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)
+ spatial = vc.add_view(cm.SPATIAL, dataset=dataset)
+
+ spatial_segmentation_layer_value = {
+ "opacity": 1,
+ "radius": 0,
+ "visible": True,
+ "stroked": False
+ }
+
+ vc.link_views([spatial], [ct.SPATIAL_ZOOM, ct.SPATIAL_TARGET_X, ct.SPATIAL_TARGET_Y, ct.SPATIAL_SEGMENTATION_LAYER], [-6.43, 10417.69, 24885.55, spatial_segmentation_layer_value])
+ vc.layout(spatial | (tsne / cell_sets));
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 5. Render the widget
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ A widget can be created with the `.widget()` method on the config instance.
+ """
+ )
+ return
+
+
+@app.cell
+def _(vc):
+ vw = vc.widget()
+ vw
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/widget_modify_config.ipynb b/docs/notebooks/widget_modify_config.ipynb
deleted file mode 100644
index 97355f6d..00000000
--- a/docs/notebooks/widget_modify_config.ipynb
+++ /dev/null
@@ -1,1153 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "dI4N5oh0cYc1",
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Programmatic modification of widget configuration"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "id": "KnWYWhnMcYc2"
- },
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " OmeTiffWrapper,\n",
- " MultiImageWrapper,\n",
- " CoordinationLevel as CL,\n",
- " ObsSegmentationsOmeTiffWrapper,\n",
- " ImageOmeTiffWrapper,\n",
- " get_initial_coordination_scope_prefix,\n",
- ")\n",
- "import random"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "id": "qqiLSqvqcYc3"
- },
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.16\")\n",
- "dataset = vc.add_dataset(name='Spraggins').add_object(\n",
- " ImageOmeTiffWrapper(\n",
- " img_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2_bf.ome.tif\",\n",
- " offsets_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2_bf.offsets.json\"\n",
- " )\n",
- ").add_object(\n",
- " ObsSegmentationsOmeTiffWrapper(\n",
- " img_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2.ome.tif\",\n",
- " offsets_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2.offsets.json\",\n",
- " obs_types_from_channel_names=True\n",
- " )\n",
- ")\n",
- "\n",
- "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
- "lc = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
- "\n",
- "vc.link_views_by_dict([spatial, lc], {\n",
- " \"imageLayer\": CL([\n",
- " {\n",
- " \"photometricInterpretation\": \"RGB\"\n",
- " }\n",
- " ]),\n",
- "}, meta=True, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
- "\n",
- "vc.layout(spatial | lc);"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 617,
- "referenced_widgets": [
- "a6e72904c7cd4521bb486f69ac9cb6c7",
- "800201ad9e7942fbbb6b0a195ef6ec6a"
- ]
- },
- "id": "wRXsCajecYc3",
- "outputId": "726b6ad0-5f3f-4b31-922f-a96336e688f2"
- },
- "outputs": [],
- "source": [
- "vw = vc.widget(remount_on_uid_change=False)\n",
- "vw"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "colab": {
- "base_uri": "https://localhost:8080/"
- },
- "id": "H43CtKancu6-",
- "outputId": "00d1a53e-75fe-4fe8-c5a7-33c175fddbc4"
- },
- "outputs": [],
- "source": [
- "# Inspect the current configuration value.\n",
- "# This is a dict in the JSON-based format https://vitessce.io/docs/view-config-json/\n",
- "vw.config"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "id": "kU1rj0EPcYc3"
- },
- "outputs": [],
- "source": [
- "# Programatically set a different zoom level and toggle the visibility/color of different segmentation layers:\n",
- "vw.config = {\n",
- " **vw.config,\n",
- " # Need to provide a fresh \"uid\" value.\n",
- " # This will tell Vitessce that the contents should be diff-ed against the previous config.\n",
- " \"uid\": f\"new_config_{random.random()}\",\n",
- " \"coordinationSpace\": {\n",
- " # Information about the coordination space can be found at https://vitessce.io/docs/coordination-types/\n",
- " **vw.config[\"coordinationSpace\"],\n",
- " \"spatialZoom\": {\n",
- " **vw.config[\"coordinationSpace\"][\"spatialZoom\"],\n",
- " \"A\": -8\n",
- " },\n",
- " \"spatialChannelVisible\": {\n",
- " **vw.config[\"coordinationSpace\"][\"spatialChannelVisible\"],\n",
- " \"init_A_obsSegmentations_0\": True,\n",
- " \"init_A_obsSegmentations_1\": False,\n",
- " \"init_A_obsSegmentations_2\": False,\n",
- " \"init_A_obsSegmentations_3\": False\n",
- " },\n",
- " \"spatialChannelColor\": {\n",
- " **vw.config[\"coordinationSpace\"][\"spatialChannelColor\"],\n",
- " \"init_A_obsSegmentations_0\": [255, 0, 0],\n",
- " }\n",
- " }\n",
- "}"
- ]
- }
- ],
- "metadata": {
- "colab": {
- "provenance": []
- },
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.14"
- },
- "widgets": {
- "application/vnd.jupyter.widget-state+json": {
- "800201ad9e7942fbbb6b0a195ef6ec6a": {
- "model_module": "@jupyter-widgets/base",
- "model_module_version": "1.2.0",
- "model_name": "LayoutModel",
- "state": {
- "_model_module": "@jupyter-widgets/base",
- "_model_module_version": "1.2.0",
- "_model_name": "LayoutModel",
- "_view_count": null,
- "_view_module": "@jupyter-widgets/base",
- "_view_module_version": "1.2.0",
- "_view_name": "LayoutView",
- "align_content": null,
- "align_items": null,
- "align_self": null,
- "border": null,
- "bottom": null,
- "display": null,
- "flex": null,
- "flex_flow": null,
- "grid_area": null,
- "grid_auto_columns": null,
- "grid_auto_flow": null,
- "grid_auto_rows": null,
- "grid_column": null,
- "grid_gap": null,
- "grid_row": null,
- "grid_template_areas": null,
- "grid_template_columns": null,
- "grid_template_rows": null,
- "height": null,
- "justify_content": null,
- "justify_items": null,
- "left": null,
- "margin": null,
- "max_height": null,
- "max_width": null,
- "min_height": null,
- "min_width": null,
- "object_fit": null,
- "object_position": null,
- "order": null,
- "overflow": null,
- "overflow_x": null,
- "overflow_y": null,
- "padding": null,
- "right": null,
- "top": null,
- "visibility": null,
- "width": null
- }
- },
- "a6e72904c7cd4521bb486f69ac9cb6c7": {
- "model_module": "anywidget",
- "model_module_version": "~0.9.*",
- "model_name": "AnyModel",
- "state": {
- "_anywidget_id": "vitessce.widget.VitessceWidget",
- "_dom_classes": [],
- "_esm": "\nimport { importWithMap } from 'https://unpkg.com/dynamic-importmap@0.1.0';\nconst importMap = {\n imports: {\n \"react\": \"https://esm.sh/react@18.2.0?dev\",\n \"react-dom\": \"https://esm.sh/react-dom@18.2.0?dev\",\n \"react-dom/client\": \"https://esm.sh/react-dom@18.2.0/client?dev\",\n },\n};\n\nconst React = await importWithMap(\"react\", importMap);\nconst { createRoot } = await importWithMap(\"react-dom/client\", importMap);\n\nconst e = React.createElement;\n\nconst prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;\n\n// The jupyter server may be running through a proxy,\n// which means that the client needs to prepend the part of the URL before /proxy/8000 such as\n// https://hub.gke2.mybinder.org/user/vitessce-vitessce-python-swi31vcv/proxy/8000/A/0/cells\nfunction prependBaseUrl(config, proxy, hasHostName) {\n if(!proxy || hasHostName) {\n return config;\n }\n const { origin } = new URL(window.location.href);\n let baseUrl;\n const jupyterLabConfigEl = document.getElementById('jupyter-config-data');\n\n if (jupyterLabConfigEl) {\n // This is jupyter lab\n baseUrl = JSON.parse(jupyterLabConfigEl.textContent || '').baseUrl;\n } else {\n // This is jupyter notebook\n baseUrl = document.getElementsByTagName('body')[0].getAttribute('data-base-url');\n }\n return {\n ...config,\n datasets: config.datasets.map(d => ({\n ...d,\n files: d.files.map(f => ({\n ...f,\n url: `${origin}${baseUrl}${f.url}`,\n })),\n })),\n };\n}\n\nasync function render(view) {\n const cssUid = view.model.get('uid');\n const jsDevMode = view.model.get('js_dev_mode');\n const jsPackageVersion = view.model.get('js_package_version');\n const customJsUrl = view.model.get('custom_js_url');\n const pluginEsmArr = view.model.get('plugin_esm');\n const remountOnUidChange = view.model.get('remount_on_uid_change');\n const storeUrls = view.model.get('store_urls');\n const invokeTimeout = view.model.get('invoke_timeout');\n\n const pkgName = (jsDevMode ? \"@vitessce/dev\" : \"vitessce\");\n\n importMap.imports[\"vitessce\"] = (customJsUrl.length > 0\n ? customJsUrl\n : `https://unpkg.com/${pkgName}@${jsPackageVersion}`\n );\n\n const {\n Vitessce,\n PluginFileType,\n PluginViewType,\n PluginCoordinationType,\n PluginJointFileType,\n z,\n useCoordination,\n useGridItemSize,\n // TODO: names and function signatures are subject to change for the following functions\n // Reference: https://github.com/keller-mark/use-coordination/issues/37#issuecomment-1946226827\n useComplexCoordination,\n useMultiCoordinationScopesNonNull,\n useMultiCoordinationScopesSecondaryNonNull,\n useComplexCoordinationSecondary,\n useCoordinationScopes,\n useCoordinationScopesBy,\n } = await importWithMap(\"vitessce\", importMap);\n\n let pluginViewTypes = [];\n let pluginCoordinationTypes = [];\n let pluginFileTypes = [];\n let pluginJointFileTypes = [];\n\n const stores = Object.fromEntries(\n storeUrls.map(storeUrl => ([\n storeUrl,\n {\n async get(key) {\n const [data, buffers] = await view.experimental.invoke(\"_zarr_get\", [storeUrl, key], {\n signal: AbortSignal.timeout(invokeTimeout),\n });\n if (!data.success) return undefined;\n\n if (key.includes(\"spatialdata_attrs\") && key.endsWith(\"0\") && !ArrayBuffer.isView(buffers[0].buffer)) {\n // For some reason, the Zarrita.js UnicodeStringArray does not seem to work with\n // ArrayBuffers (throws a TypeError), so here we convert to Uint8Array if needed.\n // This error is occurring specifically for the arr.getChunk call within the AnnDataSource._loadString function.\n // TODO: figure out a more long-term solution.\n return new Uint8Array(buffers[0].buffer);\n }\n\n return buffers[0].buffer;\n },\n }\n ])),\n );\n\n function invokePluginCommand(commandName, commandParams, commandBuffers) {\n return view.experimental.invoke(\"_plugin_command\", [commandName, commandParams], {\n signal: AbortSignal.timeout(invokeTimeout),\n ...(commandBuffers ? { buffers: commandBuffers } : {}),\n });\n }\n\n for (const pluginEsm of pluginEsmArr) {\n try {\n const pluginEsmUrl = URL.createObjectURL(new Blob([pluginEsm], { type: \"text/javascript\" }));\n const pluginModule = (await import(pluginEsmUrl)).default;\n URL.revokeObjectURL(pluginEsmUrl);\n\n const pluginsObj = await pluginModule.createPlugins({\n React,\n PluginFileType,\n PluginViewType,\n PluginCoordinationType,\n PluginJointFileType,\n z,\n invokeCommand: invokePluginCommand,\n useCoordination,\n useGridItemSize,\n useComplexCoordination,\n useMultiCoordinationScopesNonNull,\n useMultiCoordinationScopesSecondaryNonNull,\n useComplexCoordinationSecondary,\n useCoordinationScopes,\n useCoordinationScopesBy,\n });\n if(Array.isArray(pluginsObj.pluginViewTypes)) {\n pluginViewTypes = [...pluginViewTypes, ...pluginsObj.pluginViewTypes];\n }\n if(Array.isArray(pluginsObj.pluginCoordinationTypes)) {\n pluginCoordinationTypes = [...pluginCoordinationTypes, ...pluginsObj.pluginCoordinationTypes];\n }\n if(Array.isArray(pluginsObj.pluginFileTypes)) {\n pluginFileTypes = [...pluginFileTypes, ...pluginsObj.pluginFileTypes];\n }\n if(Array.isArray(pluginsObj.pluginJointFileTypes)) {\n pluginJointFileTypes = [...pluginJointFileTypes, ...pluginsObj.pluginJointFileTypes];\n }\n } catch(e) {\n console.error(e);\n }\n }\n\n function VitessceWidget(props) {\n const { model } = props;\n\n const [config, setConfig] = React.useState(prependBaseUrl(model.get('config'), model.get('proxy'), model.get('has_host_name')));\n const [validateConfig, setValidateConfig] = React.useState(true);\n const height = model.get('height');\n const theme = model.get('theme') === 'auto' ? (prefersDark ? 'dark' : 'light') : model.get('theme');\n\n const divRef = React.useRef();\n\n React.useEffect(() => {\n if(!divRef.current) {\n return () => {};\n }\n\n function handleMouseEnter() {\n const jpn = divRef.current.closest('.jp-Notebook');\n if(jpn) {\n jpn.style.overflow = \"hidden\";\n }\n }\n function handleMouseLeave(event) {\n if(event.relatedTarget === null || (event.relatedTarget && event.relatedTarget.closest('.jp-Notebook')?.length)) return;\n const jpn = divRef.current.closest('.jp-Notebook');\n if(jpn) {\n jpn.style.overflow = \"auto\";\n }\n }\n divRef.current.addEventListener(\"mouseenter\", handleMouseEnter);\n divRef.current.addEventListener(\"mouseleave\", handleMouseLeave);\n\n return () => {\n if(divRef.current) {\n divRef.current.removeEventListener(\"mouseenter\", handleMouseEnter);\n divRef.current.removeEventListener(\"mouseleave\", handleMouseLeave);\n }\n };\n }, [divRef]);\n\n // Config changed on JS side (from within ),\n // send updated config to Python side.\n const onConfigChange = React.useCallback((config) => {\n model.set('config', config);\n setValidateConfig(false);\n model.save_changes();\n }, [model]);\n\n // Config changed on Python side,\n // pass to component to it is updated on JS side.\n React.useEffect(() => {\n model.on('change:config', () => {\n const newConfig = prependBaseUrl(model.get('config'), model.get('proxy'), model.get('has_host_name'));\n\n // Force a re-render and re-validation by setting a new config.uid value.\n // TODO: make this conditional on a parameter from Python.\n //newConfig.uid = `random-${Math.random()}`;\n //console.log('newConfig', newConfig);\n setConfig(newConfig);\n });\n }, []);\n\n const vitessceProps = {\n height, theme, config, onConfigChange, validateConfig,\n pluginViewTypes, pluginCoordinationTypes, pluginFileTypes, pluginJointFileTypes,\n remountOnUidChange, stores,\n };\n\n return e('div', { ref: divRef, style: { height: height + 'px' } },\n e(React.Suspense, { fallback: e('div', {}, 'Loading...') },\n e(React.StrictMode, {},\n e(Vitessce, vitessceProps)\n ),\n ),\n );\n }\n\n const root = createRoot(view.el);\n root.render(e(VitessceWidget, { model: view.model }));\n\n return () => {\n // Re-enable scrolling.\n const jpn = view.el.closest('.jp-Notebook');\n if(jpn) {\n jpn.style.overflow = \"auto\";\n }\n\n // Clean up React and DOM state.\n root.unmount();\n if(view._isFromDisplay) {\n view.el.remove();\n }\n };\n}\nexport default { render };\n",
- "_model_module": "anywidget",
- "_model_module_version": "~0.9.*",
- "_model_name": "AnyModel",
- "_view_count": null,
- "_view_module": "anywidget",
- "_view_module_version": "~0.9.*",
- "_view_name": "AnyView",
- "config": {
- "coordinationSpace": {
- "additionalObsSets": {
- "A": null
- },
- "dataset": {
- "A": "A",
- "init_A_image_0": "init_A_image_0",
- "init_A_obsSegmentations_0": "init_A_obsSegmentations_0"
- },
- "featureHighlight": {
- "A": null
- },
- "featureSelection": {
- "A": null
- },
- "featureType": {
- "A": "gene"
- },
- "featureValueColormap": {
- "A": "plasma"
- },
- "featureValueColormapRange": {
- "A": [
- 0,
- 1
- ]
- },
- "featureValueType": {
- "A": "expression"
- },
- "fileUid": {
- "A": null,
- "init_A_image_0": null,
- "init_A_obsSegmentations_0": null
- },
- "imageChannel": {
- "A": null,
- "init_A_image_0": "__dummy__",
- "init_A_image_1": "__dummy__",
- "init_A_image_2": "__dummy__"
- },
- "imageLayer": {
- "A": null,
- "init_A_image_0": "__dummy__"
- },
- "legendVisible": {
- "A": true
- },
- "metaCoordinationScopes": {
- "init_A_image_0": {
- "imageLayer": [
- "init_A_image_0"
- ],
- "spatialImageLayer": "init_A_image_0",
- "spatialTargetT": "init_A_image_0",
- "spatialTargetZ": "init_A_image_0"
- },
- "init_A_obsSegmentations_0": {
- "segmentationLayer": [
- "init_A_obsSegmentations_0"
- ],
- "spatialSegmentationLayer": "init_A_obsSegmentations_0",
- "spatialTargetT": "init_A_obsSegmentations_0",
- "spatialTargetZ": "init_A_obsSegmentations_0"
- }
- },
- "metaCoordinationScopesBy": {
- "init_A_image_0": {
- "imageChannel": {
- "spatialChannelColor": {
- "init_A_image_0": "init_A_image_0",
- "init_A_image_1": "init_A_image_1",
- "init_A_image_2": "init_A_image_2"
- },
- "spatialChannelOpacity": {
- "init_A_image_0": "init_A_image_0",
- "init_A_image_1": "init_A_image_1",
- "init_A_image_2": "init_A_image_2"
- },
- "spatialChannelVisible": {
- "init_A_image_0": "init_A_image_0",
- "init_A_image_1": "init_A_image_1",
- "init_A_image_2": "init_A_image_2"
- },
- "spatialChannelWindow": {
- "init_A_image_0": "init_A_image_0",
- "init_A_image_1": "init_A_image_1",
- "init_A_image_2": "init_A_image_2"
- },
- "spatialTargetC": {
- "init_A_image_0": "init_A_image_0",
- "init_A_image_1": "init_A_image_1",
- "init_A_image_2": "init_A_image_2"
- }
- },
- "imageLayer": {
- "fileUid": {
- "init_A_image_0": "init_A_image_0"
- },
- "imageChannel": {
- "init_A_image_0": [
- "init_A_image_0",
- "init_A_image_1",
- "init_A_image_2"
- ]
- },
- "photometricInterpretation": {
- "init_A_image_0": "init_A_image_0"
- },
- "spatialLayerOpacity": {
- "init_A_image_0": "init_A_image_0"
- },
- "spatialLayerVisible": {
- "init_A_image_0": "init_A_image_0"
- },
- "spatialTargetResolution": {
- "init_A_image_0": "init_A_image_0"
- },
- "volumetricRenderingAlgorithm": {
- "init_A_image_0": "init_A_image_0"
- }
- }
- },
- "init_A_obsSegmentations_0": {
- "segmentationChannel": {
- "obsColorEncoding": {
- "init_A_obsSegmentations_0": "init_A_obsSegmentations_0",
- "init_A_obsSegmentations_1": "init_A_obsSegmentations_1",
- "init_A_obsSegmentations_2": "init_A_obsSegmentations_2",
- "init_A_obsSegmentations_3": "init_A_obsSegmentations_3",
- "init_A_obsSegmentations_4": "init_A_obsSegmentations_4"
- },
- "obsHighlight": {
- "init_A_obsSegmentations_0": "init_A_obsSegmentations_0",
- "init_A_obsSegmentations_1": "init_A_obsSegmentations_1",
- "init_A_obsSegmentations_2": "init_A_obsSegmentations_2",
- "init_A_obsSegmentations_3": "init_A_obsSegmentations_3",
- "init_A_obsSegmentations_4": "init_A_obsSegmentations_4"
- },
- "obsType": {
- "init_A_obsSegmentations_0": "init_A_obsSegmentations_0",
- "init_A_obsSegmentations_1": "init_A_obsSegmentations_1",
- "init_A_obsSegmentations_2": "init_A_obsSegmentations_2",
- "init_A_obsSegmentations_3": "init_A_obsSegmentations_3",
- "init_A_obsSegmentations_4": "init_A_obsSegmentations_4"
- },
- "spatialChannelColor": {
- "init_A_obsSegmentations_0": "init_A_obsSegmentations_0",
- "init_A_obsSegmentations_1": "init_A_obsSegmentations_1",
- "init_A_obsSegmentations_2": "init_A_obsSegmentations_2",
- "init_A_obsSegmentations_3": "init_A_obsSegmentations_3",
- "init_A_obsSegmentations_4": "init_A_obsSegmentations_4"
- },
- "spatialChannelOpacity": {
- "init_A_obsSegmentations_0": "init_A_obsSegmentations_0",
- "init_A_obsSegmentations_1": "init_A_obsSegmentations_1",
- "init_A_obsSegmentations_2": "init_A_obsSegmentations_2",
- "init_A_obsSegmentations_3": "init_A_obsSegmentations_3",
- "init_A_obsSegmentations_4": "init_A_obsSegmentations_4"
- },
- "spatialChannelVisible": {
- "init_A_obsSegmentations_0": "init_A_obsSegmentations_0",
- "init_A_obsSegmentations_1": "init_A_obsSegmentations_1",
- "init_A_obsSegmentations_2": "init_A_obsSegmentations_2",
- "init_A_obsSegmentations_3": "init_A_obsSegmentations_3",
- "init_A_obsSegmentations_4": "init_A_obsSegmentations_4"
- },
- "spatialChannelWindow": {
- "init_A_obsSegmentations_0": "init_A_obsSegmentations_0",
- "init_A_obsSegmentations_1": "init_A_obsSegmentations_1",
- "init_A_obsSegmentations_2": "init_A_obsSegmentations_2",
- "init_A_obsSegmentations_3": "init_A_obsSegmentations_3",
- "init_A_obsSegmentations_4": "init_A_obsSegmentations_4"
- },
- "spatialSegmentationFilled": {
- "init_A_obsSegmentations_0": "init_A_obsSegmentations_0",
- "init_A_obsSegmentations_1": "init_A_obsSegmentations_1",
- "init_A_obsSegmentations_2": "init_A_obsSegmentations_2",
- "init_A_obsSegmentations_3": "init_A_obsSegmentations_3",
- "init_A_obsSegmentations_4": "init_A_obsSegmentations_4"
- },
- "spatialSegmentationStrokeWidth": {
- "init_A_obsSegmentations_0": "init_A_obsSegmentations_0",
- "init_A_obsSegmentations_1": "init_A_obsSegmentations_1",
- "init_A_obsSegmentations_2": "init_A_obsSegmentations_2",
- "init_A_obsSegmentations_3": "init_A_obsSegmentations_3",
- "init_A_obsSegmentations_4": "init_A_obsSegmentations_4"
- },
- "spatialTargetC": {
- "init_A_obsSegmentations_0": "init_A_obsSegmentations_0",
- "init_A_obsSegmentations_1": "init_A_obsSegmentations_1",
- "init_A_obsSegmentations_2": "init_A_obsSegmentations_2",
- "init_A_obsSegmentations_3": "init_A_obsSegmentations_3",
- "init_A_obsSegmentations_4": "init_A_obsSegmentations_4"
- }
- },
- "segmentationLayer": {
- "fileUid": {
- "init_A_obsSegmentations_0": "init_A_obsSegmentations_0"
- },
- "segmentationChannel": {
- "init_A_obsSegmentations_0": [
- "init_A_obsSegmentations_0",
- "init_A_obsSegmentations_1",
- "init_A_obsSegmentations_2",
- "init_A_obsSegmentations_3",
- "init_A_obsSegmentations_4"
- ]
- },
- "spatialLayerOpacity": {
- "init_A_obsSegmentations_0": "init_A_obsSegmentations_0"
- },
- "spatialLayerVisible": {
- "init_A_obsSegmentations_0": "init_A_obsSegmentations_0"
- }
- }
- }
- },
- "moleculeHighlight": {
- "A": null
- },
- "obsColorEncoding": {
- "A": "cellSetSelection",
- "init_A_obsSegmentations_0": "spatialChannelColor",
- "init_A_obsSegmentations_1": "spatialChannelColor",
- "init_A_obsSegmentations_2": "spatialChannelColor",
- "init_A_obsSegmentations_3": "spatialChannelColor",
- "init_A_obsSegmentations_4": "spatialChannelColor"
- },
- "obsFilter": {
- "A": null
- },
- "obsHighlight": {
- "A": null,
- "init_A_obsSegmentations_0": null,
- "init_A_obsSegmentations_1": null,
- "init_A_obsSegmentations_2": null,
- "init_A_obsSegmentations_3": null,
- "init_A_obsSegmentations_4": null
- },
- "obsLabelsType": {
- "A": null
- },
- "obsSetColor": {
- "A": null
- },
- "obsSetHighlight": {
- "A": null
- },
- "obsSetSelection": {
- "A": null
- },
- "obsType": {
- "A": "cell",
- "init_A_obsSegmentations_0": "Channel 0",
- "init_A_obsSegmentations_1": "Channel 1",
- "init_A_obsSegmentations_2": "Channel 2",
- "init_A_obsSegmentations_3": "Channel 3",
- "init_A_obsSegmentations_4": "Channel 4"
- },
- "photometricInterpretation": {
- "A": null,
- "init_A_image_0": "RGB"
- },
- "pixelHighlight": {
- "A": null
- },
- "pointLayer": {
- "A": null
- },
- "segmentationChannel": {
- "A": null,
- "init_A_obsSegmentations_0": "__dummy__",
- "init_A_obsSegmentations_1": "__dummy__",
- "init_A_obsSegmentations_2": "__dummy__",
- "init_A_obsSegmentations_3": "__dummy__",
- "init_A_obsSegmentations_4": "__dummy__"
- },
- "segmentationLayer": {
- "A": null,
- "init_A_obsSegmentations_0": "__dummy__"
- },
- "spatialAxisFixed": {
- "A": false
- },
- "spatialChannelColor": {
- "A": [
- 255,
- 255,
- 255
- ],
- "init_A_image_0": [
- 255,
- 255,
- 255
- ],
- "init_A_image_1": [
- 255,
- 255,
- 255
- ],
- "init_A_image_2": [
- 255,
- 255,
- 255
- ],
- "init_A_obsSegmentations_0": [
- 255,
- 0,
- 0
- ],
- "init_A_obsSegmentations_1": [
- 0,
- 255,
- 0
- ],
- "init_A_obsSegmentations_2": [
- 255,
- 0,
- 255
- ],
- "init_A_obsSegmentations_3": [
- 255,
- 255,
- 0
- ],
- "init_A_obsSegmentations_4": [
- 0,
- 0,
- 0
- ]
- },
- "spatialChannelLabelSize": {
- "A": 14
- },
- "spatialChannelLabelsOrientation": {
- "A": "vertical"
- },
- "spatialChannelLabelsVisible": {
- "A": true
- },
- "spatialChannelOpacity": {
- "A": 1,
- "init_A_image_0": 1,
- "init_A_image_1": 1,
- "init_A_image_2": 1,
- "init_A_obsSegmentations_0": 1,
- "init_A_obsSegmentations_1": 1,
- "init_A_obsSegmentations_2": 1,
- "init_A_obsSegmentations_3": 1,
- "init_A_obsSegmentations_4": 1
- },
- "spatialChannelVisible": {
- "A": true,
- "init_A_image_0": true,
- "init_A_image_1": true,
- "init_A_image_2": true,
- "init_A_obsSegmentations_0": true,
- "init_A_obsSegmentations_1": false,
- "init_A_obsSegmentations_2": false,
- "init_A_obsSegmentations_3": false,
- "init_A_obsSegmentations_4": true
- },
- "spatialChannelWindow": {
- "A": null,
- "init_A_image_0": null,
- "init_A_image_1": null,
- "init_A_image_2": null,
- "init_A_obsSegmentations_0": null,
- "init_A_obsSegmentations_1": null,
- "init_A_obsSegmentations_2": null,
- "init_A_obsSegmentations_3": null,
- "init_A_obsSegmentations_4": null
- },
- "spatialImageLayer": {
- "init_A_image_0": [
- {
- "channels": [
- {
- "color": [
- 255,
- 0,
- 0
- ],
- "selection": {
- "c": 0,
- "t": 0,
- "z": 0
- },
- "slider": [
- 0,
- 255
- ],
- "visible": true
- },
- {
- "color": [
- 0,
- 255,
- 0
- ],
- "selection": {
- "c": 1,
- "t": 0,
- "z": 0
- },
- "slider": [
- 0,
- 255
- ],
- "visible": true
- },
- {
- "color": [
- 0,
- 0,
- 255
- ],
- "selection": {
- "c": 2,
- "t": 0,
- "z": 0
- },
- "slider": [
- 0,
- 255
- ],
- "visible": true
- }
- ],
- "colormap": null,
- "domainType": "Min/Max",
- "index": 0,
- "modelMatrix": [
- 1,
- 0,
- 0,
- 0,
- 0,
- 1,
- 0,
- 0,
- 0,
- 0,
- 1,
- 0,
- 0,
- 0,
- 0,
- 1
- ],
- "opacity": 1,
- "renderingMode": "Additive",
- "transparentColor": null,
- "type": "raster",
- "use3d": false,
- "visible": true
- }
- ]
- },
- "spatialLayerColor": {
- "A": null
- },
- "spatialLayerColormap": {
- "A": null
- },
- "spatialLayerModelMatrix": {
- "A": null
- },
- "spatialLayerOpacity": {
- "A": 1,
- "init_A_image_0": 1,
- "init_A_obsSegmentations_0": 1
- },
- "spatialLayerTransparentColor": {
- "A": null
- },
- "spatialLayerVisible": {
- "A": true,
- "init_A_image_0": true,
- "init_A_obsSegmentations_0": true
- },
- "spatialNeighborhoodLayer": {
- "A": null
- },
- "spatialOrbitAxis": {
- "A": "Y"
- },
- "spatialPointLayer": {
- "A": null
- },
- "spatialRenderingMode": {
- "A": "2D"
- },
- "spatialRotation": {
- "A": 0
- },
- "spatialRotationOrbit": {
- "A": 0
- },
- "spatialRotationX": {
- "A": 0
- },
- "spatialRotationY": {
- "A": 0
- },
- "spatialRotationZ": {
- "A": 0
- },
- "spatialSegmentationFilled": {
- "A": true,
- "init_A_obsSegmentations_0": true,
- "init_A_obsSegmentations_1": true,
- "init_A_obsSegmentations_2": true,
- "init_A_obsSegmentations_3": true,
- "init_A_obsSegmentations_4": true
- },
- "spatialSegmentationLayer": {
- "init_A_obsSegmentations_0": [
- {
- "channels": [
- {
- "color": [
- 0,
- 0,
- 255
- ],
- "selection": {
- "c": 0,
- "t": 0,
- "z": 0
- },
- "slider": [
- 1,
- 1
- ],
- "visible": true
- },
- {
- "color": [
- 0,
- 255,
- 0
- ],
- "selection": {
- "c": 1,
- "t": 0,
- "z": 0
- },
- "slider": [
- 1,
- 41
- ],
- "visible": true
- },
- {
- "color": [
- 255,
- 0,
- 255
- ],
- "selection": {
- "c": 2,
- "t": 0,
- "z": 0
- },
- "slider": [
- 1,
- 19
- ],
- "visible": true
- },
- {
- "color": [
- 255,
- 255,
- 0
- ],
- "selection": {
- "c": 3,
- "t": 0,
- "z": 0
- },
- "slider": [
- 5,
- 3318
- ],
- "visible": true
- }
- ],
- "colormap": null,
- "domainType": "Min/Max",
- "index": 0,
- "modelMatrix": [
- 1,
- 0,
- 0,
- 0,
- 0,
- 1,
- 0,
- 0,
- 0,
- 0,
- 1,
- 0,
- 0,
- 0,
- 0,
- 1
- ],
- "opacity": 1,
- "renderingMode": "Additive",
- "transparentColor": null,
- "type": "bitmask",
- "use3d": false,
- "visible": true
- }
- ]
- },
- "spatialSegmentationStrokeWidth": {
- "A": 1,
- "init_A_obsSegmentations_0": 1,
- "init_A_obsSegmentations_1": 1,
- "init_A_obsSegmentations_2": 1,
- "init_A_obsSegmentations_3": 1,
- "init_A_obsSegmentations_4": 1
- },
- "spatialSliceX": {
- "A": null
- },
- "spatialSliceY": {
- "A": null
- },
- "spatialSliceZ": {
- "A": null
- },
- "spatialSpotFilled": {
- "A": true
- },
- "spatialSpotRadius": {
- "A": 25
- },
- "spatialSpotStrokeWidth": {
- "A": 1
- },
- "spatialTargetC": {
- "A": null,
- "init_A_image_0": 0,
- "init_A_image_1": 1,
- "init_A_image_2": 2,
- "init_A_obsSegmentations_0": 0,
- "init_A_obsSegmentations_1": 1,
- "init_A_obsSegmentations_2": 2,
- "init_A_obsSegmentations_3": 3,
- "init_A_obsSegmentations_4": 4
- },
- "spatialTargetResolution": {
- "A": 0,
- "init_A_image_0": null
- },
- "spatialTargetT": {
- "A": null,
- "init_A_image_0": 0,
- "init_A_obsSegmentations_0": 0
- },
- "spatialTargetX": {
- "A": 22069.348625952447
- },
- "spatialTargetY": {
- "A": -26851.066191111484
- },
- "spatialTargetZ": {
- "A": null,
- "B": null,
- "init_A_image_0": 0,
- "init_A_obsSegmentations_0": 0
- },
- "spatialZoom": {
- "A": -4.912917349031568
- },
- "spotLayer": {
- "A": null
- },
- "tooltipCrosshairsVisible": {
- "A": true
- },
- "tooltipsVisible": {
- "A": true
- },
- "volumetricRenderingAlgorithm": {
- "A": "additive",
- "init_A_image_0": "maximumIntensityProjection"
- }
- },
- "datasets": [
- {
- "files": [
- {
- "fileType": "image.ome-tiff",
- "options": {
- "offsetsUrl": "https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2_bf.offsets.json"
- },
- "url": "https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2_bf.ome.tif"
- },
- {
- "fileType": "obsSegmentations.ome-tiff",
- "options": {
- "obsTypesFromChannelNames": true,
- "offsetsUrl": "https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2.offsets.json"
- },
- "url": "https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2.ome.tif"
- }
- ],
- "name": "Spraggins",
- "uid": "A"
- }
- ],
- "description": "",
- "initStrategy": "auto",
- "layout": [
- {
- "component": "spatialBeta",
- "coordinationScopes": {
- "additionalObsSets": "A",
- "dataset": "A",
- "featureHighlight": "A",
- "featureSelection": "A",
- "featureType": "A",
- "featureValueColormap": "A",
- "featureValueColormapRange": "A",
- "featureValueType": "A",
- "fileUid": "A",
- "imageChannel": "A",
- "imageLayer": "A",
- "legendVisible": "A",
- "metaCoordinationScopes": [
- "init_A_image_0",
- "init_A_obsSegmentations_0",
- "init_A_image_0"
- ],
- "metaCoordinationScopesBy": [
- "init_A_image_0",
- "init_A_obsSegmentations_0",
- "init_A_image_0"
- ],
- "moleculeHighlight": "A",
- "obsColorEncoding": "A",
- "obsFilter": "A",
- "obsHighlight": "A",
- "obsLabelsType": "A",
- "obsSetColor": "A",
- "obsSetHighlight": "A",
- "obsSetSelection": "A",
- "obsType": "A",
- "pixelHighlight": "A",
- "pointLayer": "A",
- "segmentationChannel": "A",
- "segmentationLayer": "A",
- "spatialAxisFixed": "A",
- "spatialChannelColor": "A",
- "spatialChannelLabelSize": "A",
- "spatialChannelLabelsOrientation": "A",
- "spatialChannelLabelsVisible": "A",
- "spatialChannelOpacity": "A",
- "spatialChannelVisible": "A",
- "spatialChannelWindow": "A",
- "spatialLayerColor": "A",
- "spatialLayerColormap": "A",
- "spatialLayerModelMatrix": "A",
- "spatialLayerOpacity": "A",
- "spatialLayerTransparentColor": "A",
- "spatialLayerVisible": "A",
- "spatialNeighborhoodLayer": "A",
- "spatialOrbitAxis": "A",
- "spatialPointLayer": "A",
- "spatialRenderingMode": "A",
- "spatialRotation": "A",
- "spatialRotationOrbit": "A",
- "spatialRotationX": "A",
- "spatialRotationY": "A",
- "spatialRotationZ": "A",
- "spatialSegmentationFilled": "A",
- "spatialSegmentationStrokeWidth": "A",
- "spatialSliceX": "A",
- "spatialSliceY": "A",
- "spatialSliceZ": "A",
- "spatialSpotFilled": "A",
- "spatialSpotRadius": "A",
- "spatialSpotStrokeWidth": "A",
- "spatialTargetC": "A",
- "spatialTargetResolution": "A",
- "spatialTargetT": "A",
- "spatialTargetX": "A",
- "spatialTargetY": "A",
- "spatialTargetZ": "A",
- "spatialZoom": "A",
- "spotLayer": "A",
- "tooltipCrosshairsVisible": "A",
- "tooltipsVisible": "A",
- "volumetricRenderingAlgorithm": "A"
- },
- "h": 12,
- "uid": "A",
- "w": 6,
- "x": 0,
- "y": 0
- },
- {
- "component": "layerControllerBeta",
- "coordinationScopes": {
- "dataset": "A",
- "featureSelection": "A",
- "featureType": "A",
- "featureValueColormap": "A",
- "featureValueColormapRange": "A",
- "featureValueType": "A",
- "fileUid": "A",
- "imageChannel": "A",
- "imageLayer": "A",
- "legendVisible": "A",
- "metaCoordinationScopes": [
- "init_A_image_0",
- "init_A_obsSegmentations_0",
- "init_A_image_0"
- ],
- "metaCoordinationScopesBy": [
- "init_A_image_0",
- "init_A_obsSegmentations_0",
- "init_A_image_0"
- ],
- "obsColorEncoding": "A",
- "obsType": "A",
- "photometricInterpretation": "A",
- "pointLayer": "A",
- "segmentationChannel": "A",
- "segmentationLayer": "A",
- "spatialChannelColor": "A",
- "spatialChannelLabelSize": "A",
- "spatialChannelLabelsOrientation": "A",
- "spatialChannelLabelsVisible": "A",
- "spatialChannelOpacity": "A",
- "spatialChannelVisible": "A",
- "spatialChannelWindow": "A",
- "spatialLayerColor": "A",
- "spatialLayerColormap": "A",
- "spatialLayerModelMatrix": "A",
- "spatialLayerOpacity": "A",
- "spatialLayerTransparentColor": "A",
- "spatialLayerVisible": "A",
- "spatialNeighborhoodLayer": "A",
- "spatialOrbitAxis": "A",
- "spatialPointLayer": "A",
- "spatialRenderingMode": "A",
- "spatialRotationOrbit": "A",
- "spatialRotationX": "A",
- "spatialRotationY": "A",
- "spatialRotationZ": "A",
- "spatialSegmentationFilled": "A",
- "spatialSegmentationStrokeWidth": "A",
- "spatialSliceX": "A",
- "spatialSliceY": "A",
- "spatialSliceZ": "A",
- "spatialSpotFilled": "A",
- "spatialSpotRadius": "A",
- "spatialSpotStrokeWidth": "A",
- "spatialTargetC": "A",
- "spatialTargetResolution": "A",
- "spatialTargetT": "A",
- "spatialTargetX": "A",
- "spatialTargetY": "A",
- "spatialTargetZ": "A",
- "spatialZoom": "A",
- "spotLayer": "A",
- "tooltipCrosshairsVisible": "A",
- "tooltipsVisible": "A",
- "volumetricRenderingAlgorithm": "A"
- },
- "h": 12,
- "uid": "B",
- "w": 6,
- "x": 6,
- "y": 0
- }
- ],
- "name": "",
- "uid": "new_config_0.9674035035199323",
- "version": "1.0.17"
- },
- "custom_js_url": "",
- "has_host_name": false,
- "height": 600,
- "invoke_timeout": 30000,
- "js_dev_mode": false,
- "js_package_version": "3.5.4",
- "layout": "IPY_MODEL_800201ad9e7942fbbb6b0a195ef6ec6a",
- "plugin_esm": [],
- "proxy": false,
- "remount_on_uid_change": false,
- "store_urls": [],
- "theme": "auto",
- "uid": "68fc"
- }
- }
- }
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/widget_modify_config.mo.py b/docs/notebooks/widget_modify_config.mo.py
new file mode 100644
index 00000000..915d2938
--- /dev/null
+++ b/docs/notebooks/widget_modify_config.mo.py
@@ -0,0 +1,141 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Programmatic modification of widget configuration
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ from vitessce import (
+ VitessceConfig,
+ Component as cm,
+ CoordinationType as ct,
+ OmeTiffWrapper,
+ MultiImageWrapper,
+ CoordinationLevel as CL,
+ ObsSegmentationsOmeTiffWrapper,
+ ImageOmeTiffWrapper,
+ get_initial_coordination_scope_prefix,
+ )
+ import random
+ return (
+ CL,
+ ImageOmeTiffWrapper,
+ ObsSegmentationsOmeTiffWrapper,
+ VitessceConfig,
+ get_initial_coordination_scope_prefix,
+ random,
+ )
+
+
+@app.cell
+def _(
+ CL,
+ ImageOmeTiffWrapper,
+ ObsSegmentationsOmeTiffWrapper,
+ VitessceConfig,
+ get_initial_coordination_scope_prefix,
+):
+ vc = VitessceConfig(schema_version="1.0.16")
+ dataset = vc.add_dataset(name='Spraggins').add_object(
+ ImageOmeTiffWrapper(
+ img_url="https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2_bf.ome.tif",
+ offsets_url="https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2_bf.offsets.json"
+ )
+ ).add_object(
+ ObsSegmentationsOmeTiffWrapper(
+ img_url="https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2.ome.tif",
+ offsets_url="https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2.offsets.json",
+ obs_types_from_channel_names=True
+ )
+ )
+
+ spatial = vc.add_view("spatialBeta", dataset=dataset)
+ lc = vc.add_view("layerControllerBeta", dataset=dataset)
+
+ vc.link_views_by_dict([spatial, lc], {
+ "imageLayer": CL([
+ {
+ "photometricInterpretation": "RGB"
+ }
+ ]),
+ }, meta=True, scope_prefix=get_initial_coordination_scope_prefix("A", "image"))
+
+ vc.layout(spatial | lc);
+ return (vc,)
+
+
+@app.cell
+def _(vc):
+ vw = vc.widget(remount_on_uid_change=False)
+ vw
+ return (vw,)
+
+
+@app.cell
+def _(vw):
+ # Inspect the current configuration value.
+ # This is a dict in the JSON-based format https://vitessce.io/docs/view-config-json/
+ vw.config
+ return
+
+
+@app.cell
+def _(random, vw):
+ # Programatically set a different zoom level and toggle the visibility/color of different segmentation layers:
+ vw.config = {
+ **vw.config,
+ # Need to provide a fresh "uid" value.
+ # This will tell Vitessce that the contents should be diff-ed against the previous config.
+ "uid": f"new_config_{random.random()}",
+ "coordinationSpace": {
+ # Information about the coordination space can be found at https://vitessce.io/docs/coordination-types/
+ **vw.config["coordinationSpace"],
+ "spatialZoom": {
+ **vw.config["coordinationSpace"]["spatialZoom"],
+ "A": -8
+ },
+ "spatialChannelVisible": {
+ **vw.config["coordinationSpace"]["spatialChannelVisible"],
+ "init_A_obsSegmentations_0": True,
+ "init_A_obsSegmentations_1": False,
+ "init_A_obsSegmentations_2": False,
+ "init_A_obsSegmentations_3": False
+ },
+ "spatialChannelColor": {
+ **vw.config["coordinationSpace"]["spatialChannelColor"],
+ "init_A_obsSegmentations_0": [255, 0, 0],
+ }
+ }
+ }
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/widget_neuroglancer.ipynb b/docs/notebooks/widget_neuroglancer.ipynb
deleted file mode 100644
index 43f1d933..00000000
--- a/docs/notebooks/widget_neuroglancer.ipynb
+++ /dev/null
@@ -1,239 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Example usage of Neuroglancer view"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " ImageOmeTiffWrapper,\n",
- " CsvWrapper,\n",
- " hconcat,\n",
- " vconcat,\n",
- " get_initial_coordination_scope_prefix,\n",
- " CoordinationLevel as CL\n",
- ")\n",
- "from os.path import join"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 1. Configure Vitessce"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.17\")\n",
- "dataset = vc.add_dataset(name='Meshes').add_object(\n",
- " ImageOmeTiffWrapper(\n",
- " img_url='https://lsp-public-data.s3.amazonaws.com/yapp-2023-3d-melanoma/Dataset1-LSP13626-invasive-margin.ome.tiff',\n",
- " offsets_url='https://lsp-public-data.s3.amazonaws.com/yapp-2023-3d-melanoma/Dataset1-LSP13626-invasive-margin.offsets.json',\n",
- " coordination_values={\n",
- " \"fileUid\": 'melanoma',\n",
- " },\n",
- " )\n",
- ").add_object(\n",
- " CsvWrapper(\n",
- " data_type=\"obsEmbedding\",\n",
- " csv_url='https://storage.googleapis.com/vitessce-demo-data/neuroglancer-march-2025/melanoma_with_embedding_filtered_ids.csv',\n",
- " options= {\n",
- " \"obsIndex\": 'id',\n",
- " \"obsEmbedding\": ['tSNE1', 'tSNE2'],\n",
- " },\n",
- " coordination_values= {\n",
- " \"obsType\": 'cell',\n",
- " \"embeddingType\": 'TSNE',\n",
- " },\n",
- " )\n",
- ").add_object(\n",
- " CsvWrapper(\n",
- " data_type=\"obsSets\",\n",
- " csv_url='https://storage.googleapis.com/vitessce-demo-data/neuroglancer-march-2025/melanoma_with_embedding_filtered_ids.csv',\n",
- " coordination_values={\n",
- " \"obsType\": 'cell',\n",
- " },\n",
- " options= {\n",
- " \"obsIndex\": 'id',\n",
- " \"obsSets\": [\n",
- " {\n",
- " \"name\": 'Clusters',\n",
- " \"column\": 'cluster',\n",
- " },\n",
- " ],\n",
- " },\n",
- " )\n",
- ")\n",
- "spatialThreeView = vc.add_view('spatialBeta', dataset=dataset);\n",
- "lcView = vc.add_view('layerControllerBeta', dataset=dataset);\n",
- "obsSets = vc.add_view('obsSets', dataset=dataset);\n",
- "scatterView = vc.add_view('scatterplot', dataset=dataset, mapping=\"TSNE\");\n",
- "# Configuration via props.viewerState is temporary and subject to change.\n",
- "neuroglancerView = vc.add_view('neuroglancer', dataset=dataset).set_props(viewerState={\n",
- " \"dimensions\": {\n",
- " \"x\": [\n",
- " 1e-9,\n",
- " \"m\"\n",
- " ],\n",
- " \"y\": [\n",
- " 1e-9,\n",
- " \"m\"\n",
- " ],\n",
- " \"z\": [\n",
- " 1e-9,\n",
- " \"m\"\n",
- " ]\n",
- " },\n",
- " \"position\": [\n",
- " 49.5,\n",
- " 1000.5,\n",
- " 5209.5\n",
- " ],\n",
- " \"crossSectionScale\": 1,\n",
- " \"projectionOrientation\": [\n",
- " -0.636204183101654,\n",
- " -0.5028395652770996,\n",
- " 0.5443811416625977,\n",
- " 0.2145828753709793\n",
- " ],\n",
- " \"projectionScale\": 1024,\n",
- " \"layers\": [\n",
- " {\n",
- " \"type\": \"segmentation\",\n",
- " \"source\": \"precomputed://https://vitessce-data-v2.s3.us-east-1.amazonaws.com/data/sorger/invasive_meshes\",\n",
- " \"segments\": [\n",
- " \"5\"\n",
- " ],\n",
- " \"segmentColors\": {\n",
- " \"5\": \"red\"\n",
- " },\n",
- " \"name\": \"segmentation\"\n",
- " }\n",
- " ],\n",
- " \"showSlices\": False,\n",
- " \"layout\": \"3d\"\n",
- "});\n",
- "\n",
- "vc.link_views([scatterView], ['embeddingObsRadiusMode', 'embeddingObsRadius'], ['manual', 4]);\n",
- "\n",
- "# Sync the zoom/rotation/pan states\n",
- "vc.link_views_by_dict([spatialThreeView, lcView, neuroglancerView], {\n",
- " \"spatialRenderingMode\": '3D',\n",
- " \"spatialZoom\": 0,\n",
- " \"spatialTargetT\": 0,\n",
- " \"spatialTargetX\": 0,\n",
- " \"spatialTargetY\": 0,\n",
- " \"spatialTargetZ\": 0,\n",
- " \"spatialRotationX\": 0,\n",
- " \"spatialRotationY\": 0,\n",
- "}, meta=False);\n",
- "\n",
- "# Initialize the image properties\n",
- "vc.link_views_by_dict([spatialThreeView, lcView], {\n",
- " \"imageLayer\": CL([\n",
- " {\n",
- " \"fileUid\": 'melanoma',\n",
- " \"spatialLayerOpacity\": 1,\n",
- " \"spatialTargetResolution\": None,\n",
- " \"imageChannel\": CL([\n",
- " {\n",
- " \"spatialTargetC\": 0,\n",
- " \"spatialChannelColor\": [255, 0, 0],\n",
- " \"spatialChannelVisible\": True,\n",
- " \"spatialChannelOpacity\": 1.0,\n",
- " },\n",
- " ]),\n",
- " },\n",
- " ]),\n",
- "}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'));\n",
- "\n",
- "\n",
- "vc.layout(hconcat(neuroglancerView, spatialThreeView, vconcat(lcView, obsSets, scatterView)));"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 2. Create the Vitessce widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.14"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/widget_neuroglancer.mo.py b/docs/notebooks/widget_neuroglancer.mo.py
new file mode 100644
index 00000000..08a5083e
--- /dev/null
+++ b/docs/notebooks/widget_neuroglancer.mo.py
@@ -0,0 +1,224 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Example usage of Neuroglancer view
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ from vitessce import (
+ VitessceConfig,
+ Component as cm,
+ CoordinationType as ct,
+ ImageOmeTiffWrapper,
+ CsvWrapper,
+ hconcat,
+ vconcat,
+ get_initial_coordination_scope_prefix,
+ CoordinationLevel as CL
+ )
+ from os.path import join
+ return (
+ CL,
+ CsvWrapper,
+ ImageOmeTiffWrapper,
+ VitessceConfig,
+ get_initial_coordination_scope_prefix,
+ hconcat,
+ vconcat,
+ )
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 1. Configure Vitessce
+ """
+ )
+ return
+
+
+@app.cell
+def _(
+ CL,
+ CsvWrapper,
+ ImageOmeTiffWrapper,
+ VitessceConfig,
+ get_initial_coordination_scope_prefix,
+ hconcat,
+ vconcat,
+):
+ vc = VitessceConfig(schema_version="1.0.17")
+ dataset = vc.add_dataset(name='Meshes').add_object(
+ ImageOmeTiffWrapper(
+ img_url='https://lsp-public-data.s3.amazonaws.com/yapp-2023-3d-melanoma/Dataset1-LSP13626-invasive-margin.ome.tiff',
+ offsets_url='https://lsp-public-data.s3.amazonaws.com/yapp-2023-3d-melanoma/Dataset1-LSP13626-invasive-margin.offsets.json',
+ coordination_values={
+ "fileUid": 'melanoma',
+ },
+ )
+ ).add_object(
+ CsvWrapper(
+ data_type="obsEmbedding",
+ csv_url='https://storage.googleapis.com/vitessce-demo-data/neuroglancer-march-2025/melanoma_with_embedding_filtered_ids.csv',
+ options= {
+ "obsIndex": 'id',
+ "obsEmbedding": ['tSNE1', 'tSNE2'],
+ },
+ coordination_values= {
+ "obsType": 'cell',
+ "embeddingType": 'TSNE',
+ },
+ )
+ ).add_object(
+ CsvWrapper(
+ data_type="obsSets",
+ csv_url='https://storage.googleapis.com/vitessce-demo-data/neuroglancer-march-2025/melanoma_with_embedding_filtered_ids.csv',
+ coordination_values={
+ "obsType": 'cell',
+ },
+ options= {
+ "obsIndex": 'id',
+ "obsSets": [
+ {
+ "name": 'Clusters',
+ "column": 'cluster',
+ },
+ ],
+ },
+ )
+ )
+ spatialThreeView = vc.add_view('spatialBeta', dataset=dataset);
+ lcView = vc.add_view('layerControllerBeta', dataset=dataset);
+ obsSets = vc.add_view('obsSets', dataset=dataset);
+ scatterView = vc.add_view('scatterplot', dataset=dataset, mapping="TSNE");
+ # Configuration via props.viewerState is temporary and subject to change.
+ neuroglancerView = vc.add_view('neuroglancer', dataset=dataset).set_props(viewerState={
+ "dimensions": {
+ "x": [
+ 1e-9,
+ "m"
+ ],
+ "y": [
+ 1e-9,
+ "m"
+ ],
+ "z": [
+ 1e-9,
+ "m"
+ ]
+ },
+ "position": [
+ 49.5,
+ 1000.5,
+ 5209.5
+ ],
+ "crossSectionScale": 1,
+ "projectionOrientation": [
+ -0.636204183101654,
+ -0.5028395652770996,
+ 0.5443811416625977,
+ 0.2145828753709793
+ ],
+ "projectionScale": 1024,
+ "layers": [
+ {
+ "type": "segmentation",
+ "source": "precomputed://https://vitessce-data-v2.s3.us-east-1.amazonaws.com/data/sorger/invasive_meshes",
+ "segments": [
+ "5"
+ ],
+ "segmentColors": {
+ "5": "red"
+ },
+ "name": "segmentation"
+ }
+ ],
+ "showSlices": False,
+ "layout": "3d"
+ });
+
+ vc.link_views([scatterView], ['embeddingObsRadiusMode', 'embeddingObsRadius'], ['manual', 4]);
+
+ # Sync the zoom/rotation/pan states
+ vc.link_views_by_dict([spatialThreeView, lcView, neuroglancerView], {
+ "spatialRenderingMode": '3D',
+ "spatialZoom": 0,
+ "spatialTargetT": 0,
+ "spatialTargetX": 0,
+ "spatialTargetY": 0,
+ "spatialTargetZ": 0,
+ "spatialRotationX": 0,
+ "spatialRotationY": 0,
+ }, meta=False);
+
+ # Initialize the image properties
+ vc.link_views_by_dict([spatialThreeView, lcView], {
+ "imageLayer": CL([
+ {
+ "fileUid": 'melanoma',
+ "spatialLayerOpacity": 1,
+ "spatialTargetResolution": None,
+ "imageChannel": CL([
+ {
+ "spatialTargetC": 0,
+ "spatialChannelColor": [255, 0, 0],
+ "spatialChannelVisible": True,
+ "spatialChannelOpacity": 1.0,
+ },
+ ]),
+ },
+ ]),
+ }, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'));
+
+
+ vc.layout(hconcat(neuroglancerView, spatialThreeView, vconcat(lcView, obsSets, scatterView)));
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 2. Create the Vitessce widget
+ """
+ )
+ return
+
+
+@app.cell
+def _(vc):
+ vw = vc.widget()
+ vw
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/widget_on_colab.ipynb b/docs/notebooks/widget_on_colab.ipynb
deleted file mode 100644
index 309ff7e5..00000000
--- a/docs/notebooks/widget_on_colab.ipynb
+++ /dev/null
@@ -1,137 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Setup for Google Colab"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## Install the package"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "!pip install vitessce[all]"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Visualization of Multi-Modal Imaging Data\n",
- "We visualize IMS, PAS, and AF imaging data overlaid from the Spraggins Lab of the Biomolecular Multimodal Imaging Center (BIOMC) at Vanderbilt University, uploaded to the HuBMAP data portal."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " OmeTiffWrapper,\n",
- " MultiImageWrapper,\n",
- ")\n",
- "from os.path import join"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 1. Configure Vitessce\n",
- "Set up the images from the three different assays, with the `use_physical_size_scaling` set to `True` so that the IMS image scales to the other images based on their physical sizes."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='Spraggins Multi-Modal', description='PAS + IMS + AF From https://portal.hubmapconsortium.org/browse/collection/6a6efd0c1a2681dc7d2faab8e4ab0bca')\n",
- "dataset = vc.add_dataset(name='Spraggins').add_object(\n",
- " MultiImageWrapper(\n",
- " image_wrappers=[\n",
- " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/f4188a148e4c759092d19369d310883b/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-PAS_images/VAN0006-LK-2-85-PAS_registered.ome.tif?token=', name='PAS'),\n",
- " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/2130d5f91ce61d7157a42c0497b06de8/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-AF_preIMS_images/VAN0006-LK-2-85-AF_preIMS_registered.ome.tif?token=', name='AF'),\n",
- " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/be503a021ed910c0918842e318e6efa2/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_PosMode_multilayer.ome.tif?token=', name='IMS Pos Mode'),\n",
- " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/ca886a630b2038997a4cfbbf4abfd283/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_NegMode_multilayer.ome.tif?token=', name='IMS Neg Mode')\n",
- " ],\n",
- " use_physical_size_scaling=True,\n",
- " )\n",
- ")\n",
- "spatial = vc.add_view(cm.SPATIAL, dataset=dataset)\n",
- "status = vc.add_view(cm.STATUS, dataset=dataset)\n",
- "lc = vc.add_view(cm.LAYER_CONTROLLER, dataset=dataset).set_props(disableChannelsIfRgbDetected=True)\n",
- "vc.layout(spatial | (lc / status));"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 2. Create the Vitessce widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.8.0"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/widget_on_colab.mo.py b/docs/notebooks/widget_on_colab.mo.py
new file mode 100644
index 00000000..b2be2ad3
--- /dev/null
+++ b/docs/notebooks/widget_on_colab.mo.py
@@ -0,0 +1,125 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Setup for Google Colab
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## Install the package
+ """
+ )
+ return
+
+
+app._unparsable_cell(
+ r"""
+ !pip install vitessce[all]
+ """,
+ name="_"
+)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Visualization of Multi-Modal Imaging Data
+ We visualize IMS, PAS, and AF imaging data overlaid from the Spraggins Lab of the Biomolecular Multimodal Imaging Center (BIOMC) at Vanderbilt University, uploaded to the HuBMAP data portal.
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ from vitessce import (
+ VitessceConfig,
+ Component as cm,
+ CoordinationType as ct,
+ OmeTiffWrapper,
+ MultiImageWrapper,
+ )
+ from os.path import join
+ return MultiImageWrapper, OmeTiffWrapper, VitessceConfig, cm
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 1. Configure Vitessce
+ Set up the images from the three different assays, with the `use_physical_size_scaling` set to `True` so that the IMS image scales to the other images based on their physical sizes.
+ """
+ )
+ return
+
+
+@app.cell
+def _(MultiImageWrapper, OmeTiffWrapper, VitessceConfig, cm):
+ vc = VitessceConfig(schema_version="1.0.15", name='Spraggins Multi-Modal', description='PAS + IMS + AF From https://portal.hubmapconsortium.org/browse/collection/6a6efd0c1a2681dc7d2faab8e4ab0bca')
+ dataset = vc.add_dataset(name='Spraggins').add_object(
+ MultiImageWrapper(
+ image_wrappers=[
+ OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/f4188a148e4c759092d19369d310883b/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-PAS_images/VAN0006-LK-2-85-PAS_registered.ome.tif?token=', name='PAS'),
+ OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/2130d5f91ce61d7157a42c0497b06de8/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-AF_preIMS_images/VAN0006-LK-2-85-AF_preIMS_registered.ome.tif?token=', name='AF'),
+ OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/be503a021ed910c0918842e318e6efa2/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_PosMode_multilayer.ome.tif?token=', name='IMS Pos Mode'),
+ OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/ca886a630b2038997a4cfbbf4abfd283/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_NegMode_multilayer.ome.tif?token=', name='IMS Neg Mode')
+ ],
+ use_physical_size_scaling=True,
+ )
+ )
+ spatial = vc.add_view(cm.SPATIAL, dataset=dataset)
+ status = vc.add_view(cm.STATUS, dataset=dataset)
+ lc = vc.add_view(cm.LAYER_CONTROLLER, dataset=dataset).set_props(disableChannelsIfRgbDetected=True)
+ vc.layout(spatial | (lc / status));
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 2. Create the Vitessce widget
+ """
+ )
+ return
+
+
+@app.cell
+def _(vc):
+ vw = vc.widget()
+ vw
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/widget_pbmc.ipynb b/docs/notebooks/widget_pbmc.ipynb
deleted file mode 100644
index 284546aa..00000000
--- a/docs/notebooks/widget_pbmc.ipynb
+++ /dev/null
@@ -1,204 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Visualization of 3k PBMC reference"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 1. Import dependencies\n",
- "\n",
- "We need to import the classes and functions that we will be using from the corresponding packages."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join, isfile, isdir\n",
- "from urllib.request import urlretrieve\n",
- "from anndata import read_h5ad\n",
- "import scanpy as sc\n",
- "\n",
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " AnnDataWrapper,\n",
- ")\n",
- "from vitessce.data_utils import (\n",
- " optimize_adata,\n",
- " VAR_CHUNK_SIZE,\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 2. Download the dataset\n",
- "\n",
- "Download `pbmc3k_final.h5ad` from https://seurat.nygenome.org/pbmc3k_final.h5ad"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "adata_filepath = join(\"data\", \"pbmc3k_final.h5ad\")\n",
- "if not isfile(adata_filepath):\n",
- " os.makedirs(\"data\", exist_ok=True)\n",
- " urlretrieve('https://seurat.nygenome.org/pbmc3k_final.h5ad', adata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 3. Load the dataset\n",
- "\n",
- "Load the dataset using AnnData's `read_h5ad` function."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "adata = read_h5ad(adata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 3.1 Save the AnnData object to Zarr"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "zarr_filepath = join(\"data\", \"pbmc3k_final.zarr\")\n",
- "if not isdir(zarr_filepath):\n",
- " adata = optimize_adata(\n",
- " adata,\n",
- " obs_cols=[\"leiden\"],\n",
- " obsm_keys=[\"X_umap\", \"X_pca\"],\n",
- " optimize_X=True,\n",
- " )\n",
- " adata.write_zarr(zarr_filepath, chunks=[adata.shape[0], VAR_CHUNK_SIZE])"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 4. Create a Vitessce view config\n",
- "\n",
- "Define the data and views you would like to include in the widget.\n",
- "\n",
- "For more details about how to configure data depending on where the files are located relative to the notebook execution, see https://python-docs.vitessce.io/data_options.html."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='PBMC Reference')\n",
- "dataset = vc.add_dataset(name='PBMC 3k').add_object(AnnDataWrapper(\n",
- " adata_store=zarr_filepath,\n",
- " obs_set_paths=[\"obs/leiden\"],\n",
- " obs_set_names=[\"Leiden\"],\n",
- " obs_embedding_paths=[\"obsm/X_umap\", \"obsm/X_pca\"],\n",
- " obs_embedding_names=[\"UMAP\", \"PCA\"],\n",
- " obs_feature_matrix_path=\"X\"\n",
- "))\n",
- "\n",
- "umap = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
- "pca = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"PCA\")\n",
- "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
- "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
- "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)\n",
- "\n",
- "vc.layout((umap / pca) | ((cell_sets | genes) / heatmap));"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 5. Create the Vitessce widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.9.0"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/widget_pbmc.mo.py b/docs/notebooks/widget_pbmc.mo.py
new file mode 100644
index 00000000..14bee94e
--- /dev/null
+++ b/docs/notebooks/widget_pbmc.mo.py
@@ -0,0 +1,190 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Visualization of 3k PBMC reference
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 1. Import dependencies
+
+ We need to import the classes and functions that we will be using from the corresponding packages.
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ import os
+ from os.path import join, isfile, isdir
+ from urllib.request import urlretrieve
+ from anndata import read_h5ad
+ import scanpy as sc
+
+ from vitessce import (
+ VitessceConfig,
+ Component as cm,
+ CoordinationType as ct,
+ AnnDataWrapper,
+ )
+ from vitessce.data_utils import (
+ optimize_adata,
+ VAR_CHUNK_SIZE,
+ )
+ return (
+ AnnDataWrapper,
+ VAR_CHUNK_SIZE,
+ VitessceConfig,
+ cm,
+ isdir,
+ isfile,
+ join,
+ optimize_adata,
+ os,
+ read_h5ad,
+ urlretrieve,
+ )
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 2. Download the dataset
+
+ Download `pbmc3k_final.h5ad` from https://seurat.nygenome.org/pbmc3k_final.h5ad
+ """
+ )
+ return
+
+
+@app.cell
+def _(isfile, join, os, urlretrieve):
+ adata_filepath = join("data", "pbmc3k_final.h5ad")
+ if not isfile(adata_filepath):
+ os.makedirs("data", exist_ok=True)
+ urlretrieve('https://seurat.nygenome.org/pbmc3k_final.h5ad', adata_filepath)
+ return (adata_filepath,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 3. Load the dataset
+
+ Load the dataset using AnnData's `read_h5ad` function.
+ """
+ )
+ return
+
+
+@app.cell
+def _(adata_filepath, read_h5ad):
+ adata = read_h5ad(adata_filepath)
+ return (adata,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 3.1 Save the AnnData object to Zarr
+ """
+ )
+ return
+
+
+@app.cell
+def _(VAR_CHUNK_SIZE, adata, isdir, join, optimize_adata):
+ zarr_filepath = join('data', 'pbmc3k_final.zarr')
+ if not isdir(zarr_filepath):
+ adata_1 = optimize_adata(adata, obs_cols=['leiden'], obsm_keys=['X_umap', 'X_pca'], optimize_X=True)
+ adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])
+ return (zarr_filepath,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 4. Create a Vitessce view config
+
+ Define the data and views you would like to include in the widget.
+
+ For more details about how to configure data depending on where the files are located relative to the notebook execution, see https://python-docs.vitessce.io/data_options.html.
+ """
+ )
+ return
+
+
+@app.cell
+def _(AnnDataWrapper, VitessceConfig, cm, zarr_filepath):
+ vc = VitessceConfig(schema_version="1.0.15", name='PBMC Reference')
+ dataset = vc.add_dataset(name='PBMC 3k').add_object(AnnDataWrapper(
+ adata_store=zarr_filepath,
+ obs_set_paths=["obs/leiden"],
+ obs_set_names=["Leiden"],
+ obs_embedding_paths=["obsm/X_umap", "obsm/X_pca"],
+ obs_embedding_names=["UMAP", "PCA"],
+ obs_feature_matrix_path="X"
+ ))
+
+ umap = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping="UMAP")
+ pca = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping="PCA")
+ cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)
+ genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)
+ heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)
+
+ vc.layout((umap / pca) | ((cell_sets | genes) / heatmap));
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 5. Create the Vitessce widget
+ """
+ )
+ return
+
+
+@app.cell
+def _(vc):
+ vw = vc.widget()
+ vw
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/widget_pbmc_remote.ipynb b/docs/notebooks/widget_pbmc_remote.ipynb
deleted file mode 100644
index 5b9101c8..00000000
--- a/docs/notebooks/widget_pbmc_remote.ipynb
+++ /dev/null
@@ -1,139 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Visualization of 3k PBMC reference from Remote Zarr Store"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 1. Import dependencies\n",
- "\n",
- "We need to import the classes and functions that we will be using from the corresponding packages."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join\n",
- "from urllib.request import urlretrieve\n",
- "from anndata import read_h5ad\n",
- "import scanpy as sc\n",
- "\n",
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " AnnDataWrapper,\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 2. Set the URL for the Remote Dataset\n",
- "\n",
- "For this example, we already have uploaded the `pbmc3k` dataset as a zarr store from the [scanpy docs](https://scanpy.readthedocs.io/en/stable/api/scanpy.datasets.pbmc3k.html) to the cloud."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "url = 'https://storage.googleapis.com/vitessce-demo-data/anndata-test/pbmc3k_processed.zarr/'"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 3. Create a Vitessce view config\n",
- "\n",
- "Define the data and views you would like to include in the widget."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='PBMC Reference')\n",
- "dataset = vc.add_dataset(name='PBMC 3k').add_object(AnnDataWrapper(adata_url=url, obs_set_paths=[\"obs/louvain\"], obs_set_names=[\"Louvain\"], obs_embedding_paths=[\"obsm/X_umap\", \"obsm/X_pca\"], obs_embedding_names=[\"UMAP\", \"PCA\"], obs_feature_matrix_path=\"X\"))\n",
- "\n",
- "umap = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
- "pca = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"PCA\")\n",
- "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
- "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
- "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)\n",
- "\n",
- "vc.layout((umap / pca) | ((cell_sets | genes) / heatmap));"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 4. Create the Vitessce widget"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "A widget can be created with the `.widget()` method on the config instance. Here, the `proxy=True` parameter allows this widget to be used in a cloud notebook environment, such as Binder."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.14"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/widget_pbmc_remote.mo.py b/docs/notebooks/widget_pbmc_remote.mo.py
new file mode 100644
index 00000000..fbe9da5a
--- /dev/null
+++ b/docs/notebooks/widget_pbmc_remote.mo.py
@@ -0,0 +1,135 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Visualization of 3k PBMC reference from Remote Zarr Store
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 1. Import dependencies
+
+ We need to import the classes and functions that we will be using from the corresponding packages.
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ import os
+ from os.path import join
+ from urllib.request import urlretrieve
+ from anndata import read_h5ad
+ import scanpy as sc
+
+ from vitessce import (
+ VitessceConfig,
+ Component as cm,
+ CoordinationType as ct,
+ AnnDataWrapper,
+ )
+ return AnnDataWrapper, VitessceConfig, cm
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 2. Set the URL for the Remote Dataset
+
+ For this example, we already have uploaded the `pbmc3k` dataset as a zarr store from the [scanpy docs](https://scanpy.readthedocs.io/en/stable/api/scanpy.datasets.pbmc3k.html) to the cloud.
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ url = 'https://storage.googleapis.com/vitessce-demo-data/anndata-test/pbmc3k_processed.zarr/'
+ return (url,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 3. Create a Vitessce view config
+
+ Define the data and views you would like to include in the widget.
+ """
+ )
+ return
+
+
+@app.cell
+def _(AnnDataWrapper, VitessceConfig, cm, url):
+ vc = VitessceConfig(schema_version="1.0.15", name='PBMC Reference')
+ dataset = vc.add_dataset(name='PBMC 3k').add_object(AnnDataWrapper(adata_url=url, obs_set_paths=["obs/louvain"], obs_set_names=["Louvain"], obs_embedding_paths=["obsm/X_umap", "obsm/X_pca"], obs_embedding_names=["UMAP", "PCA"], obs_feature_matrix_path="X"))
+
+ umap = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping="UMAP")
+ pca = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping="PCA")
+ cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)
+ genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)
+ heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)
+
+ vc.layout((umap / pca) | ((cell_sets | genes) / heatmap));
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 4. Create the Vitessce widget
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ A widget can be created with the `.widget()` method on the config instance. Here, the `proxy=True` parameter allows this widget to be used in a cloud notebook environment, such as Binder.
+ """
+ )
+ return
+
+
+@app.cell
+def _(vc):
+ vw = vc.widget()
+ vw
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/widget_plugin_custom.ipynb b/docs/notebooks/widget_plugin_custom.ipynb
deleted file mode 100644
index c8b19f85..00000000
--- a/docs/notebooks/widget_plugin_custom.ipynb
+++ /dev/null
@@ -1,184 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Vitessce custom plugin definition"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " OmeTiffWrapper,\n",
- " MultiImageWrapper,\n",
- " VitesscePlugin\n",
- ")\n",
- "from oxc_py import transform"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "PLUGIN_ESM = transform(\"\"\"\n",
- "function createPlugins(utilsForPlugins) {\n",
- " const {\n",
- " React,\n",
- " PluginFileType,\n",
- " PluginViewType,\n",
- " PluginCoordinationType,\n",
- " PluginJointFileType,\n",
- " z,\n",
- " useCoordination,\n",
- " invokeCommand,\n",
- " } = utilsForPlugins;\n",
- " \n",
- " const CSS = `\n",
- " .chat {\n",
- " overflow-y: scroll;\n",
- " }\n",
- " `;\n",
- " \n",
- " function ChatView(props) {\n",
- " \n",
- " const [nextMessage, setNextMessage] = React.useState('');\n",
- " const [isLoading, setIsLoading] = React.useState(false);\n",
- " const [chatHistory, setChatHistory] = React.useState([]); // chatHistory is an array of message objects like [{ user, text }, ...]\n",
- " \n",
- " async function handleClick() { \n",
- " setChatHistory(prev => ([\n",
- " ...prev,\n",
- " { user: 'You', text: nextMessage },\n",
- " ]));\n",
- " setIsLoading(true);\n",
- " const [chatReceiveValue, chatReceiveBuffers] = await invokeCommand(\"chat_send\", nextMessage, []);\n",
- " setChatHistory(prev => ([\n",
- " ...prev,\n",
- " { user: 'AI', text: chatReceiveValue.text },\n",
- " ]));\n",
- " setIsLoading(false);\n",
- " }\n",
- " \n",
- " return (\n",
- " <>\n",
- " \n",
- " \n",
- "
Chat view
\n",
- "
\n",
- " {chatHistory.map(message => (\n",
- "
\n",
- " {message.user} :\n",
- " {message.text} \n",
- "
\n",
- " ))}\n",
- "
\n",
- "
setNextMessage(e.target.value)} disabled={isLoading} />\n",
- "
Send message \n",
- "
\n",
- " >\n",
- " );\n",
- " }\n",
- "\n",
- " const pluginViewTypes = [\n",
- " new PluginViewType('chat', ChatView, []),\n",
- " ];\n",
- " return { pluginViewTypes };\n",
- "}\n",
- "export default { createPlugins };\n",
- "\"\"\")\n",
- "\n",
- "\n",
- "def handle_chat_message(message, buffers):\n",
- " return { \"text\": message.upper() }, []\n",
- "\n",
- "\n",
- "class ChatPlugin(VitesscePlugin):\n",
- " plugin_esm = PLUGIN_ESM\n",
- " commands = {\n",
- " \"chat_send\": handle_chat_message,\n",
- " }"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='Spraggins Multi-Modal', description='PAS + IMS + AF From https://portal.hubmapconsortium.org/browse/collection/6a6efd0c1a2681dc7d2faab8e4ab0bca')\n",
- "dataset = vc.add_dataset(name='Spraggins').add_object(\n",
- " MultiImageWrapper(\n",
- " image_wrappers=[\n",
- " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/f4188a148e4c759092d19369d310883b/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-PAS_images/VAN0006-LK-2-85-PAS_registered.ome.tif?token=', name='PAS'),\n",
- " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/2130d5f91ce61d7157a42c0497b06de8/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-AF_preIMS_images/VAN0006-LK-2-85-AF_preIMS_registered.ome.tif?token=', name='AF'),\n",
- " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/be503a021ed910c0918842e318e6efa2/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_PosMode_multilayer.ome.tif?token=', name='IMS Pos Mode'),\n",
- " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/ca886a630b2038997a4cfbbf4abfd283/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_NegMode_multilayer.ome.tif?token=', name='IMS Neg Mode')\n",
- " ],\n",
- " use_physical_size_scaling=True,\n",
- " )\n",
- ")\n",
- "spatial = vc.add_view(cm.SPATIAL, dataset=dataset)\n",
- "status = vc.add_view(\"chat\", dataset=dataset)\n",
- "lc = vc.add_view(cm.LAYER_CONTROLLER, dataset=dataset).set_props(disableChannelsIfRgbDetected=True)\n",
- "vc.layout(spatial | (lc / status));"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 2. Create the Vitessce widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget(plugins=[ChatPlugin()])\n",
- "vw"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.14"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/widget_plugin_custom.mo.py b/docs/notebooks/widget_plugin_custom.mo.py
new file mode 100644
index 00000000..bc24ea8c
--- /dev/null
+++ b/docs/notebooks/widget_plugin_custom.mo.py
@@ -0,0 +1,175 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce custom plugin definition
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ from vitessce import (
+ VitessceConfig,
+ Component as cm,
+ CoordinationType as ct,
+ OmeTiffWrapper,
+ MultiImageWrapper,
+ VitesscePlugin
+ )
+ from oxc_py import transform
+ return (
+ MultiImageWrapper,
+ OmeTiffWrapper,
+ VitessceConfig,
+ VitesscePlugin,
+ cm,
+ transform,
+ )
+
+
+@app.cell
+def _(VitesscePlugin, transform):
+ PLUGIN_ESM = transform("""
+ function createPlugins(utilsForPlugins) {
+ const {
+ React,
+ PluginFileType,
+ PluginViewType,
+ PluginCoordinationType,
+ PluginJointFileType,
+ z,
+ useCoordination,
+ invokeCommand,
+ } = utilsForPlugins;
+
+ const CSS = `
+ .chat {
+ overflow-y: scroll;
+ }
+ `;
+
+ function ChatView(props) {
+
+ const [nextMessage, setNextMessage] = React.useState('');
+ const [isLoading, setIsLoading] = React.useState(false);
+ const [chatHistory, setChatHistory] = React.useState([]); // chatHistory is an array of message objects like [{ user, text }, ...]
+
+ async function handleClick() {
+ setChatHistory(prev => ([
+ ...prev,
+ { user: 'You', text: nextMessage },
+ ]));
+ setIsLoading(true);
+ const [chatReceiveValue, chatReceiveBuffers] = await invokeCommand("chat_send", nextMessage, []);
+ setChatHistory(prev => ([
+ ...prev,
+ { user: 'AI', text: chatReceiveValue.text },
+ ]));
+ setIsLoading(false);
+ }
+
+ return (
+ <>
+
+
+
Chat view
+
+ {chatHistory.map(message => (
+
+ {message.user} :
+ {message.text}
+
+ ))}
+
+
setNextMessage(e.target.value)} disabled={isLoading} />
+
Send message
+
+ >
+ );
+ }
+
+ const pluginViewTypes = [
+ new PluginViewType('chat', ChatView, []),
+ ];
+ return { pluginViewTypes };
+ }
+ export default { createPlugins };
+ """)
+
+
+ def handle_chat_message(message, buffers):
+ return { "text": message.upper() }, []
+
+
+ class ChatPlugin(VitesscePlugin):
+ plugin_esm = PLUGIN_ESM
+ commands = {
+ "chat_send": handle_chat_message,
+ }
+ return (ChatPlugin,)
+
+
+@app.cell
+def _(MultiImageWrapper, OmeTiffWrapper, VitessceConfig, cm):
+ vc = VitessceConfig(schema_version="1.0.15", name='Spraggins Multi-Modal', description='PAS + IMS + AF From https://portal.hubmapconsortium.org/browse/collection/6a6efd0c1a2681dc7d2faab8e4ab0bca')
+ dataset = vc.add_dataset(name='Spraggins').add_object(
+ MultiImageWrapper(
+ image_wrappers=[
+ OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/f4188a148e4c759092d19369d310883b/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-PAS_images/VAN0006-LK-2-85-PAS_registered.ome.tif?token=', name='PAS'),
+ OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/2130d5f91ce61d7157a42c0497b06de8/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-AF_preIMS_images/VAN0006-LK-2-85-AF_preIMS_registered.ome.tif?token=', name='AF'),
+ OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/be503a021ed910c0918842e318e6efa2/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_PosMode_multilayer.ome.tif?token=', name='IMS Pos Mode'),
+ OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/ca886a630b2038997a4cfbbf4abfd283/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_NegMode_multilayer.ome.tif?token=', name='IMS Neg Mode')
+ ],
+ use_physical_size_scaling=True,
+ )
+ )
+ spatial = vc.add_view(cm.SPATIAL, dataset=dataset)
+ status = vc.add_view("chat", dataset=dataset)
+ lc = vc.add_view(cm.LAYER_CONTROLLER, dataset=dataset).set_props(disableChannelsIfRgbDetected=True)
+ vc.layout(spatial | (lc / status));
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 2. Create the Vitessce widget
+ """
+ )
+ return
+
+
+@app.cell
+def _(ChatPlugin, vc):
+ vw = vc.widget(plugins=[ChatPlugin()])
+ vw
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/widget_plugin_demo.ipynb b/docs/notebooks/widget_plugin_demo.ipynb
deleted file mode 100644
index ca25fe1c..00000000
--- a/docs/notebooks/widget_plugin_demo.ipynb
+++ /dev/null
@@ -1,122 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Vitessce plugin usage demo"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "We visualize IMS, PAS, and AF imaging data overlaid from the Spraggins Lab of the Biomolecular Multimodal Imaging Center (BIOMC) at Vanderbilt University, uploaded to the HuBMAP data portal."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " OmeTiffWrapper,\n",
- " MultiImageWrapper,\n",
- ")\n",
- "from os.path import join"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce.widget_plugins import DemoPlugin"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 1. Configure Vitessce\n",
- "Set up the images from the three different assays, with the `use_physical_size_scaling` set to `True` so that the IMS image scales to the other images based on their physical sizes."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='Spraggins Multi-Modal', description='PAS + IMS + AF From https://portal.hubmapconsortium.org/browse/collection/6a6efd0c1a2681dc7d2faab8e4ab0bca')\n",
- "dataset = vc.add_dataset(name='Spraggins').add_object(\n",
- " MultiImageWrapper(\n",
- " image_wrappers=[\n",
- " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/f4188a148e4c759092d19369d310883b/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-PAS_images/VAN0006-LK-2-85-PAS_registered.ome.tif?token=', name='PAS'),\n",
- " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/2130d5f91ce61d7157a42c0497b06de8/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-AF_preIMS_images/VAN0006-LK-2-85-AF_preIMS_registered.ome.tif?token=', name='AF'),\n",
- " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/be503a021ed910c0918842e318e6efa2/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_PosMode_multilayer.ome.tif?token=', name='IMS Pos Mode'),\n",
- " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/ca886a630b2038997a4cfbbf4abfd283/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_NegMode_multilayer.ome.tif?token=', name='IMS Neg Mode')\n",
- " ],\n",
- " use_physical_size_scaling=True,\n",
- " )\n",
- ")\n",
- "spatial = vc.add_view(cm.SPATIAL, dataset=dataset)\n",
- "status = vc.add_view(\"demo\", dataset=dataset)\n",
- "lc = vc.add_view(cm.LAYER_CONTROLLER, dataset=dataset).set_props(disableChannelsIfRgbDetected=True)\n",
- "vc.layout(spatial | (lc / status));"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 2. Create the Vitessce widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget(plugins=[DemoPlugin()])\n",
- "vw"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.14"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/widget_plugin_demo.mo.py b/docs/notebooks/widget_plugin_demo.mo.py
new file mode 100644
index 00000000..7911b86f
--- /dev/null
+++ b/docs/notebooks/widget_plugin_demo.mo.py
@@ -0,0 +1,112 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce plugin usage demo
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ We visualize IMS, PAS, and AF imaging data overlaid from the Spraggins Lab of the Biomolecular Multimodal Imaging Center (BIOMC) at Vanderbilt University, uploaded to the HuBMAP data portal.
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ from vitessce import (
+ VitessceConfig,
+ Component as cm,
+ CoordinationType as ct,
+ OmeTiffWrapper,
+ MultiImageWrapper,
+ )
+ from os.path import join
+ return MultiImageWrapper, OmeTiffWrapper, VitessceConfig, cm
+
+
+@app.cell
+def _():
+ from vitessce.widget_plugins import DemoPlugin
+ return (DemoPlugin,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 1. Configure Vitessce
+ Set up the images from the three different assays, with the `use_physical_size_scaling` set to `True` so that the IMS image scales to the other images based on their physical sizes.
+ """
+ )
+ return
+
+
+@app.cell
+def _(MultiImageWrapper, OmeTiffWrapper, VitessceConfig, cm):
+ vc = VitessceConfig(schema_version="1.0.15", name='Spraggins Multi-Modal', description='PAS + IMS + AF From https://portal.hubmapconsortium.org/browse/collection/6a6efd0c1a2681dc7d2faab8e4ab0bca')
+ dataset = vc.add_dataset(name='Spraggins').add_object(
+ MultiImageWrapper(
+ image_wrappers=[
+ OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/f4188a148e4c759092d19369d310883b/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-PAS_images/VAN0006-LK-2-85-PAS_registered.ome.tif?token=', name='PAS'),
+ OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/2130d5f91ce61d7157a42c0497b06de8/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-AF_preIMS_images/VAN0006-LK-2-85-AF_preIMS_registered.ome.tif?token=', name='AF'),
+ OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/be503a021ed910c0918842e318e6efa2/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_PosMode_multilayer.ome.tif?token=', name='IMS Pos Mode'),
+ OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/ca886a630b2038997a4cfbbf4abfd283/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_NegMode_multilayer.ome.tif?token=', name='IMS Neg Mode')
+ ],
+ use_physical_size_scaling=True,
+ )
+ )
+ spatial = vc.add_view(cm.SPATIAL, dataset=dataset)
+ status = vc.add_view("demo", dataset=dataset)
+ lc = vc.add_view(cm.LAYER_CONTROLLER, dataset=dataset).set_props(disableChannelsIfRgbDetected=True)
+ vc.layout(spatial | (lc / status));
+ return (vc,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 2. Create the Vitessce widget
+ """
+ )
+ return
+
+
+@app.cell
+def _(DemoPlugin, vc):
+ vw = vc.widget(plugins=[DemoPlugin()])
+ vw
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/widget_plugin_spatial-query.ipynb b/docs/notebooks/widget_plugin_spatial-query.ipynb
deleted file mode 100644
index c204f834..00000000
--- a/docs/notebooks/widget_plugin_spatial-query.ipynb
+++ /dev/null
@@ -1,152 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Vitessce SpatialQuery plugin usage demo"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "tags": []
- },
- "outputs": [],
- "source": [
- "#!pip install \"vitessce[all]==3.3.0\" esbuild_py anndata\n",
- "!pip install \"mlxtend~=0.23.0\"\n",
- "#!pip install -i \"https://test.pypi.org/simple/\" SpatialQuery\n",
- "!pip install \"SpatialQuery @ git+https://github.com/ShaokunAn/Spatial-Query@main\""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 1,
- "metadata": {},
- "outputs": [],
- "source": [
- "from os.path import join\n",
- "from anndata import read_h5ad\n",
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " AnnDataWrapper,\n",
- " ViewType as vt,\n",
- " CoordinationType as ct,\n",
- " CoordinationLevel as CL,\n",
- ")\n",
- "from vitessce.widget_plugins import SpatialQueryPlugin"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "metadata": {},
- "outputs": [],
- "source": [
- "adata = read_h5ad(join(\"data\", \"HBM987_KWLK_254\", \"secondary_analysis.h5ad\"))\n",
- "zarr_path = join(\"data\", \"HBM987_KWLK_254\", \"secondary_analysis.h5ad.zarr\")\n",
- "adata.write_zarr(zarr_path)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "metadata": {},
- "outputs": [],
- "source": [
- "plugin = SpatialQueryPlugin(adata)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.16\", name=\"Spatial-Query\")\n",
- "dataset = vc.add_dataset(\"Query results\").add_object(AnnDataWrapper(\n",
- " adata_path=zarr_path,\n",
- " obs_feature_matrix_path=\"X\",\n",
- " obs_set_paths=[\"obs/predicted.ASCT.celltype\"],\n",
- " obs_set_names=[\"Cell Type\"],\n",
- " obs_spots_path=\"obsm/X_spatial\",\n",
- " feature_labels_path=\"var/hugo_symbol\",\n",
- " coordination_values={\n",
- " \"featureLabelsType\": \"Gene symbol\",\n",
- " }\n",
- "))\n",
- "\n",
- "spatial_view = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
- "lc_view = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
- "sets_view = vc.add_view(\"obsSets\", dataset=dataset)\n",
- "features_view = vc.add_view(\"featureList\", dataset=dataset)\n",
- "sq_view = vc.add_view(\"spatialQuery\", dataset=dataset)\n",
- "\n",
- "obs_set_selection_scope, = vc.add_coordination(\"obsSetSelection\",)\n",
- "obs_set_selection_scope.set_value(None)\n",
- "\n",
- "sets_view.use_coordination(obs_set_selection_scope)\n",
- "sq_view.use_coordination(obs_set_selection_scope)\n",
- "spatial_view.use_coordination(obs_set_selection_scope)\n",
- "features_view.use_coordination(obs_set_selection_scope)\n",
- "\n",
- "vc.link_views([spatial_view, lc_view, sets_view, features_view],\n",
- " [\"additionalObsSets\", \"obsSetColor\"],\n",
- " [plugin.additional_obs_sets, plugin.obs_set_color]\n",
- ")\n",
- "vc.link_views_by_dict([spatial_view, lc_view], {\n",
- " \"spotLayer\": CL([\n",
- " {\n",
- " \"obsType\": \"cell\",\n",
- " \"spatialSpotRadius\": 15,\n",
- " },\n",
- " ])\n",
- "})\n",
- "\n",
- "vc.layout((spatial_view | (lc_view / features_view)) / (sets_view | sq_view));"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 13,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget(height=900, plugins=[plugin], remount_on_uid_change=False)\n",
- "vw"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.14"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/widget_plugin_spatial-query.mo.py b/docs/notebooks/widget_plugin_spatial-query.mo.py
new file mode 100644
index 00000000..4ae7ecce
--- /dev/null
+++ b/docs/notebooks/widget_plugin_spatial-query.mo.py
@@ -0,0 +1,134 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce SpatialQuery plugin usage demo
+ """
+ )
+ return
+
+
+app._unparsable_cell(
+ r"""
+ #!pip install \"vitessce[all]==3.3.0\" esbuild_py anndata
+ !pip install \"mlxtend~=0.23.0\"
+ #!pip install -i \"https://test.pypi.org/simple/\" SpatialQuery
+ !pip install \"SpatialQuery @ git+https://github.com/ShaokunAn/Spatial-Query@main\"
+ """,
+ name="_"
+)
+
+
+@app.cell
+def _():
+ from os.path import join
+ from anndata import read_h5ad
+ from vitessce import (
+ VitessceConfig,
+ AnnDataWrapper,
+ ViewType as vt,
+ CoordinationType as ct,
+ CoordinationLevel as CL,
+ )
+ from vitessce.widget_plugins import SpatialQueryPlugin
+ return (
+ AnnDataWrapper,
+ CL,
+ SpatialQueryPlugin,
+ VitessceConfig,
+ join,
+ read_h5ad,
+ )
+
+
+@app.cell
+def _(join, read_h5ad):
+ adata = read_h5ad(join("data", "HBM987_KWLK_254", "secondary_analysis.h5ad"))
+ zarr_path = join("data", "HBM987_KWLK_254", "secondary_analysis.h5ad.zarr")
+ adata.write_zarr(zarr_path)
+ return adata, zarr_path
+
+
+@app.cell
+def _(SpatialQueryPlugin, adata):
+ plugin = SpatialQueryPlugin(adata)
+ return (plugin,)
+
+
+@app.cell
+def _(AnnDataWrapper, CL, VitessceConfig, plugin, zarr_path):
+ vc = VitessceConfig(schema_version="1.0.16", name="Spatial-Query")
+ dataset = vc.add_dataset("Query results").add_object(AnnDataWrapper(
+ adata_path=zarr_path,
+ obs_feature_matrix_path="X",
+ obs_set_paths=["obs/predicted.ASCT.celltype"],
+ obs_set_names=["Cell Type"],
+ obs_spots_path="obsm/X_spatial",
+ feature_labels_path="var/hugo_symbol",
+ coordination_values={
+ "featureLabelsType": "Gene symbol",
+ }
+ ))
+
+ spatial_view = vc.add_view("spatialBeta", dataset=dataset)
+ lc_view = vc.add_view("layerControllerBeta", dataset=dataset)
+ sets_view = vc.add_view("obsSets", dataset=dataset)
+ features_view = vc.add_view("featureList", dataset=dataset)
+ sq_view = vc.add_view("spatialQuery", dataset=dataset)
+
+ obs_set_selection_scope, = vc.add_coordination("obsSetSelection",)
+ obs_set_selection_scope.set_value(None)
+
+ sets_view.use_coordination(obs_set_selection_scope)
+ sq_view.use_coordination(obs_set_selection_scope)
+ spatial_view.use_coordination(obs_set_selection_scope)
+ features_view.use_coordination(obs_set_selection_scope)
+
+ vc.link_views([spatial_view, lc_view, sets_view, features_view],
+ ["additionalObsSets", "obsSetColor"],
+ [plugin.additional_obs_sets, plugin.obs_set_color]
+ )
+ vc.link_views_by_dict([spatial_view, lc_view], {
+ "spotLayer": CL([
+ {
+ "obsType": "cell",
+ "spatialSpotRadius": 15,
+ },
+ ])
+ })
+
+ vc.layout((spatial_view | (lc_view / features_view)) / (sets_view | sq_view));
+ return (vc,)
+
+
+@app.cell
+def _(plugin, vc):
+ vw = vc.widget(height=900, plugins=[plugin], remount_on_uid_change=False)
+ vw
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/widget_segmentations_beta.ipynb b/docs/notebooks/widget_segmentations_beta.ipynb
deleted file mode 100644
index d398414f..00000000
--- a/docs/notebooks/widget_segmentations_beta.ipynb
+++ /dev/null
@@ -1,104 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# Visualization of OME-TIFF images and segmentation masks"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " OmeTiffWrapper,\n",
- " MultiImageWrapper,\n",
- " CoordinationLevel as CL,\n",
- " ObsSegmentationsOmeTiffWrapper,\n",
- " ImageOmeTiffWrapper,\n",
- " get_initial_coordination_scope_prefix,\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.16\")\n",
- "dataset = vc.add_dataset(name='Spraggins').add_object(\n",
- " ImageOmeTiffWrapper(\n",
- " img_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2_bf.ome.tif\",\n",
- " offsets_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2_bf.offsets.json\"\n",
- " )\n",
- ").add_object(\n",
- " ObsSegmentationsOmeTiffWrapper(\n",
- " img_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2.ome.tif\",\n",
- " offsets_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2.offsets.json\",\n",
- " obs_types_from_channel_names=True\n",
- " )\n",
- ")\n",
- "\n",
- "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
- "lc = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
- "\n",
- "vc.link_views_by_dict([spatial, lc], {\n",
- " \"imageLayer\": CL([\n",
- " {\n",
- " \"photometricInterpretation\": \"RGB\" \n",
- " }\n",
- " ]),\n",
- "}, meta=True, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
- "\n",
- "vc.layout(spatial | lc);"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.14"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/widget_segmentations_beta.mo.py b/docs/notebooks/widget_segmentations_beta.mo.py
new file mode 100644
index 00000000..9f293f56
--- /dev/null
+++ b/docs/notebooks/widget_segmentations_beta.mo.py
@@ -0,0 +1,100 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Visualization of OME-TIFF images and segmentation masks
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ from vitessce import (
+ VitessceConfig,
+ Component as cm,
+ CoordinationType as ct,
+ OmeTiffWrapper,
+ MultiImageWrapper,
+ CoordinationLevel as CL,
+ ObsSegmentationsOmeTiffWrapper,
+ ImageOmeTiffWrapper,
+ get_initial_coordination_scope_prefix,
+ )
+ return (
+ CL,
+ ImageOmeTiffWrapper,
+ ObsSegmentationsOmeTiffWrapper,
+ VitessceConfig,
+ get_initial_coordination_scope_prefix,
+ )
+
+
+@app.cell
+def _(
+ CL,
+ ImageOmeTiffWrapper,
+ ObsSegmentationsOmeTiffWrapper,
+ VitessceConfig,
+ get_initial_coordination_scope_prefix,
+):
+ vc = VitessceConfig(schema_version="1.0.16")
+ dataset = vc.add_dataset(name='Spraggins').add_object(
+ ImageOmeTiffWrapper(
+ img_url="https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2_bf.ome.tif",
+ offsets_url="https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2_bf.offsets.json"
+ )
+ ).add_object(
+ ObsSegmentationsOmeTiffWrapper(
+ img_url="https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2.ome.tif",
+ offsets_url="https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2.offsets.json",
+ obs_types_from_channel_names=True
+ )
+ )
+
+ spatial = vc.add_view("spatialBeta", dataset=dataset)
+ lc = vc.add_view("layerControllerBeta", dataset=dataset)
+
+ vc.link_views_by_dict([spatial, lc], {
+ "imageLayer": CL([
+ {
+ "photometricInterpretation": "RGB"
+ }
+ ]),
+ }, meta=True, scope_prefix=get_initial_coordination_scope_prefix("A", "image"))
+
+ vc.layout(spatial | lc);
+ return (vc,)
+
+
+@app.cell
+def _(vc):
+ vw = vc.widget()
+ vw
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
diff --git a/docs/notebooks/widget_shortcut.ipynb b/docs/notebooks/widget_shortcut.ipynb
deleted file mode 100644
index 75f758d3..00000000
--- a/docs/notebooks/widget_shortcut.ipynb
+++ /dev/null
@@ -1,176 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "nbsphinx": "hidden"
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "# The from_object shortcut"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 1. Import dependencies\n",
- "\n",
- "Import the functions and classes that we will be using."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join\n",
- "from urllib.request import urlretrieve\n",
- "from anndata import read_h5ad\n",
- "import scanpy as sc\n",
- "\n",
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " AnnDataWrapper,\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 2. Download the data\n",
- "\n",
- "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "os.makedirs(\"data\", exist_ok=True)\n",
- "adata_filepath = join(\"data\", \"habib17.processed.h5ad\")\n",
- "urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 3. Load the data"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "adata = read_h5ad(join(\"data\", \"habib17.processed.h5ad\"))"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## 3.1. Preprocess the Data For Visualization"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "top_dispersion = adata.var[\"dispersions_norm\"][\n",
- " sorted(\n",
- " range(len(adata.var[\"dispersions_norm\"])),\n",
- " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
- " )[-51:][0]\n",
- "]\n",
- "adata.var[\"top_highly_variable\"] = (\n",
- " adata.var[\"dispersions_norm\"] > top_dispersion\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "With one line of code, you may create a Vitessce widget based on an automatically inferred configuration."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = VitessceConfig.from_object(AnnDataWrapper(\n",
- " adata,\n",
- " obs_embedding_paths=[\"obsm/X_umap\"],\n",
- " obs_embedding_names=[\"UMAP\"],\n",
- " obs_set_paths=[\"obs/CellType\"],\n",
- " obs_set_names=[\"Cell Type\"],\n",
- " obs_feature_matrix_path=\"X\",\n",
- " feature_filter_path=\"var/top_highly_variable\"\n",
- "), schema_version=\"1.0.15\").widget(height=800)\n",
- "vw"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3 (ipykernel)",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.8.0"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/docs/notebooks/widget_shortcut.mo.py b/docs/notebooks/widget_shortcut.mo.py
new file mode 100644
index 00000000..c3f7b970
--- /dev/null
+++ b/docs/notebooks/widget_shortcut.mo.py
@@ -0,0 +1,148 @@
+import marimo
+
+__generated_with = "0.13.15"
+app = marimo.App()
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # Vitessce Widget Tutorial
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ # The from_object shortcut
+ """
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 1. Import dependencies
+
+ Import the functions and classes that we will be using.
+ """
+ )
+ return
+
+
+@app.cell
+def _():
+ import os
+ from os.path import join
+ from urllib.request import urlretrieve
+ from anndata import read_h5ad
+ import scanpy as sc
+
+ from vitessce import (
+ VitessceConfig,
+ Component as cm,
+ CoordinationType as ct,
+ AnnDataWrapper,
+ )
+ return AnnDataWrapper, VitessceConfig, join, os, read_h5ad, urlretrieve
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 2. Download the data
+
+ For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17.
+ """
+ )
+ return
+
+
+@app.cell
+def _(join, os, urlretrieve):
+ os.makedirs("data", exist_ok=True)
+ adata_filepath = join("data", "habib17.processed.h5ad")
+ urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 3. Load the data
+ """
+ )
+ return
+
+
+@app.cell
+def _(join, read_h5ad):
+ adata = read_h5ad(join("data", "habib17.processed.h5ad"))
+ return (adata,)
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ ## 3.1. Preprocess the Data For Visualization
+ """
+ )
+ return
+
+
+@app.cell
+def _(adata):
+ top_dispersion = adata.var["dispersions_norm"][
+ sorted(
+ range(len(adata.var["dispersions_norm"])),
+ key=lambda k: adata.var["dispersions_norm"][k],
+ )[-51:][0]
+ ]
+ adata.var["top_highly_variable"] = (
+ adata.var["dispersions_norm"] > top_dispersion
+ )
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(
+ r"""
+ With one line of code, you may create a Vitessce widget based on an automatically inferred configuration.
+ """
+ )
+ return
+
+
+@app.cell
+def _(AnnDataWrapper, VitessceConfig, adata):
+ vw = VitessceConfig.from_object(AnnDataWrapper(
+ adata,
+ obs_embedding_paths=["obsm/X_umap"],
+ obs_embedding_names=["UMAP"],
+ obs_set_paths=["obs/CellType"],
+ obs_set_names=["Cell Type"],
+ obs_feature_matrix_path="X",
+ feature_filter_path="var/top_highly_variable"
+ ), schema_version="1.0.15").widget(height=800)
+ vw
+ return
+
+
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
+if __name__ == "__main__":
+ app.run()
From e994c0883aabcc0951be18c784acc0d7fe9c6a5c Mon Sep 17 00:00:00 2001
From: Mark Keller <7525285+keller-mark@users.noreply.github.com>
Date: Fri, 8 Aug 2025 11:05:38 -0400
Subject: [PATCH 02/10] Updates
---
.github/workflows/test_widget.yml | 6 +-
.gitignore | 4 +
...rowser_to_vitessce_config_conversion.ipynb | 156 ++++
.../__ipynb__/config_to_python.ipynb | 166 +++++
.../notebooks/__ipynb__/data_conversion.ipynb | 99 +++
.../__ipynb__/data_export_files.ipynb | 222 ++++++
docs/notebooks/__ipynb__/data_export_s3.ipynb | 223 ++++++
.../__ipynb__/page_mode_comparative.ipynb | 476 ++++++++++++
.../__ipynb__/page_mode_example.ipynb | 196 +++++
docs/notebooks/__ipynb__/spatial_data.ipynb | 164 +++++
.../__ipynb__/spatial_data_blobs.ipynb | 196 +++++
.../__ipynb__/spatial_data_kpmp_vis.ipynb | 455 ++++++++++++
.../__ipynb__/spatial_data_merfish.ipynb | 193 +++++
.../__ipynb__/spatial_data_merfish_2.ipynb | 165 +++++
.../__ipynb__/spatial_data_mouseliver.ipynb | 694 ++++++++++++++++++
.../spatial_data_mouseliver_remote.ipynb | 514 +++++++++++++
.../__ipynb__/spatial_data_visium_hd.ipynb | 241 ++++++
docs/notebooks/__ipynb__/web_app_brain.ipynb | 264 +++++++
.../__ipynb__/widget_anndata_with_image.ipynb | 128 ++++
docs/notebooks/__ipynb__/widget_brain.ipynb | 293 ++++++++
.../__ipynb__/widget_brain_h5ad.ipynb | 168 +++++
.../widget_brain_with_base_dir.ipynb | 338 +++++++++
.../widget_brain_with_quality_metric.ipynb | 247 +++++++
.../__ipynb__/widget_from_dict.ipynb | 99 +++
.../__ipynb__/widget_genomic_profiles.ipynb | 217 ++++++
docs/notebooks/__ipynb__/widget_imaging.ipynb | 104 +++
.../__ipynb__/widget_imaging_beta.ipynb | 142 ++++
.../widget_imaging_segmentation.ipynb | 101 +++
docs/notebooks/__ipynb__/widget_loom.ipynb | 214 ++++++
.../__ipynb__/widget_modify_config.ipynb | 147 ++++
.../__ipynb__/widget_neuroglancer.ipynb | 215 ++++++
docs/notebooks/__ipynb__/widget_pbmc.ipynb | 189 +++++
.../__ipynb__/widget_pbmc_remote.ipynb | 140 ++++
.../__ipynb__/widget_plugin_custom.ipynb | 181 +++++
.../__ipynb__/widget_plugin_demo.ipynb | 121 +++
.../__ipynb__/widget_segmentations_beta.ipynb | 99 +++
.../notebooks/__ipynb__/widget_shortcut.ipynb | 157 ++++
.../{marimo-wasm.py => marimo-wasm.mo.py} | 4 +-
docs/notebooks/{marimo.py => marimo.mo.py} | 0
scripts/convert_mo_to_ipynb.sh | 6 +
tests-widget/example.spec.js | 4 +-
41 files changed, 7741 insertions(+), 7 deletions(-)
create mode 100644 docs/notebooks/__ipynb__/cellbrowser_to_vitessce_config_conversion.ipynb
create mode 100644 docs/notebooks/__ipynb__/config_to_python.ipynb
create mode 100644 docs/notebooks/__ipynb__/data_conversion.ipynb
create mode 100644 docs/notebooks/__ipynb__/data_export_files.ipynb
create mode 100644 docs/notebooks/__ipynb__/data_export_s3.ipynb
create mode 100644 docs/notebooks/__ipynb__/page_mode_comparative.ipynb
create mode 100644 docs/notebooks/__ipynb__/page_mode_example.ipynb
create mode 100644 docs/notebooks/__ipynb__/spatial_data.ipynb
create mode 100644 docs/notebooks/__ipynb__/spatial_data_blobs.ipynb
create mode 100644 docs/notebooks/__ipynb__/spatial_data_kpmp_vis.ipynb
create mode 100644 docs/notebooks/__ipynb__/spatial_data_merfish.ipynb
create mode 100644 docs/notebooks/__ipynb__/spatial_data_merfish_2.ipynb
create mode 100644 docs/notebooks/__ipynb__/spatial_data_mouseliver.ipynb
create mode 100644 docs/notebooks/__ipynb__/spatial_data_mouseliver_remote.ipynb
create mode 100644 docs/notebooks/__ipynb__/spatial_data_visium_hd.ipynb
create mode 100644 docs/notebooks/__ipynb__/web_app_brain.ipynb
create mode 100644 docs/notebooks/__ipynb__/widget_anndata_with_image.ipynb
create mode 100644 docs/notebooks/__ipynb__/widget_brain.ipynb
create mode 100644 docs/notebooks/__ipynb__/widget_brain_h5ad.ipynb
create mode 100644 docs/notebooks/__ipynb__/widget_brain_with_base_dir.ipynb
create mode 100644 docs/notebooks/__ipynb__/widget_brain_with_quality_metric.ipynb
create mode 100644 docs/notebooks/__ipynb__/widget_from_dict.ipynb
create mode 100644 docs/notebooks/__ipynb__/widget_genomic_profiles.ipynb
create mode 100644 docs/notebooks/__ipynb__/widget_imaging.ipynb
create mode 100644 docs/notebooks/__ipynb__/widget_imaging_beta.ipynb
create mode 100644 docs/notebooks/__ipynb__/widget_imaging_segmentation.ipynb
create mode 100644 docs/notebooks/__ipynb__/widget_loom.ipynb
create mode 100644 docs/notebooks/__ipynb__/widget_modify_config.ipynb
create mode 100644 docs/notebooks/__ipynb__/widget_neuroglancer.ipynb
create mode 100644 docs/notebooks/__ipynb__/widget_pbmc.ipynb
create mode 100644 docs/notebooks/__ipynb__/widget_pbmc_remote.ipynb
create mode 100644 docs/notebooks/__ipynb__/widget_plugin_custom.ipynb
create mode 100644 docs/notebooks/__ipynb__/widget_plugin_demo.ipynb
create mode 100644 docs/notebooks/__ipynb__/widget_segmentations_beta.ipynb
create mode 100644 docs/notebooks/__ipynb__/widget_shortcut.ipynb
rename docs/notebooks/{marimo-wasm.py => marimo-wasm.mo.py} (96%)
rename docs/notebooks/{marimo.py => marimo.mo.py} (100%)
create mode 100644 scripts/convert_mo_to_ipynb.sh
diff --git a/.github/workflows/test_widget.yml b/.github/workflows/test_widget.yml
index b8c0fe02..333be5cd 100644
--- a/.github/workflows/test_widget.yml
+++ b/.github/workflows/test_widget.yml
@@ -29,11 +29,11 @@ jobs:
- name: Install vitessce
run: uv sync --extra dev --extra all --extra notebook
- name: Export Jupyter notebook to HTML
- run: uv run jupyter nbconvert --to=html --execute docs/notebooks/widget_from_dict.ipynb
+ run: uv run jupyter nbconvert --to=html --execute docs/notebooks/__ipynb__/widget_from_dict.ipynb
- name: Export Marimo notebook to HTML
- run: uv run marimo export html docs/notebooks/marimo.py -o docs/notebooks/marimo.html
+ run: uv run marimo export html docs/notebooks/marimo.mo.py -o docs/notebooks/marimo.mo.html
- name: Export Marimo notebook to HTML-WASM
- run: uv run marimo export html-wasm docs/notebooks/marimo-wasm.py -o docs/notebooks/marimo-wasm.html --mode edit
+ run: uv run marimo export html-wasm docs/notebooks/marimo-wasm.mo.py -o docs/notebooks/marimo-wasm.mo.html --mode edit
- name: Check that widget renders in HTML output using Playwright
run: pnpm exec playwright test
working-directory: ./tests-widget
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 4e008044..5fab4c92 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,7 +11,10 @@ tests/data/*
!tests/data/test.ome.tif
./notebooks/
docs/notebooks/data/
+docs/notebooks/data-cropped/
docs/notebooks/*.html
+docs/notebooks/*.ipynb
+docs/notebooks/*.zarr/
__pycache__/
.snakemake/
.coverage
@@ -19,6 +22,7 @@ demos/*/data/
demos/*/vitessce.local.json
demos/*/vitessce.remote.json
.pytest_cache/
+__marimo__/
# Compiled javascript
vitessce/static/
diff --git a/docs/notebooks/__ipynb__/cellbrowser_to_vitessce_config_conversion.ipynb b/docs/notebooks/__ipynb__/cellbrowser_to_vitessce_config_conversion.ipynb
new file mode 100644
index 00000000..cd9b5cd2
--- /dev/null
+++ b/docs/notebooks/__ipynb__/cellbrowser_to_vitessce_config_conversion.ipynb
@@ -0,0 +1,156 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "import json\n",
+ "from os.path import join\n",
+ "from vitessce import (\n",
+ " convert_cell_browser_project_to_anndata,\n",
+ " AnnDataWrapper,\n",
+ " VitessceConfig,\n",
+ ")\n",
+ "from vitessce.data_utils import VAR_CHUNK_SIZE"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "## 3. Convert UCSC Cell Browser project to a Vitessce view config"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Hstk",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Example run, coverting \"adultPancreas\" project:\n",
+ "adata = convert_cell_browser_project_to_anndata(project_name=\"adultPancreas\", keep_only_marker_genes=True)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "BYtC",
+ "metadata": {},
+ "source": [
+ "## 3. Configure Vitessce with the AnnData-Zarr store"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {},
+ "source": [
+ "## 1. Convert UCSC Cell Browser project to a format that is supported by Vitessce\n",
+ "#### Output:\n",
+ "An AnnData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "This notebook shows you how to use the `convert_cell_browser_project_to_anndata` function, which allows you to take an existing project, published in https://cells.ucsc.edu/ and:\n",
+ "1. Convert it into the AnnData format that is supported by Vitessce\n",
+ "2. Save the AnnData object as a Zarr store\n",
+ "3. Configure Vitessce with the AnnData-Zarr store\n",
+ "4. Render a Vitessce widget based on the config (step 3) directly in the notebook.\n",
+ "\n",
+ "The dataset that you choose to convert needs to be a valid UCSC Cell Browser \"project\", accessible from https://cells.ucsc.edu/, with a configuration available in https://github.com/ucscGenomeBrowser/cellbrowser-confs\n",
+ "\n",
+ "The `convert_cell_browser_project_to_anndata` function takes the name of that project as an input. For example, to convert this project, https://cells.ucsc.edu/?ds=adultPancreas, you will neeed to pass `\"adultPancreas\"` as the project name."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Kclp",
+ "metadata": {},
+ "source": [
+ "## 4. Render the Vitessce widget"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Xref",
+ "metadata": {},
+ "source": [
+ "## 2. Save the AnnData object as a Zarr store"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Load UCSC Cell Browser project in Vitessce"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "zarr_filepath = join(\"data\", \"out.adata.zarr\")\n",
+ "os.makedirs(os.path.dirname(zarr_filepath), exist_ok=True)\n",
+ "adata.write_zarr(zarr_filepath, chunks=[adata.shape[0], VAR_CHUNK_SIZE])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "anndata_wrapper_inst = AnnDataWrapper(\n",
+ " adata_path=zarr_filepath,\n",
+ " obs_feature_matrix_path=\"X\",\n",
+ " obs_embedding_paths=[\"obsm/X_tsne\"],\n",
+ " obs_embedding_names=[\"t-SNE\"],\n",
+ " obs_set_paths=[\"obs/cluster\", \"obs/age\"],\n",
+ " obs_set_names=[\"cluster\", \"age\"],\n",
+ ")\n",
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name=\"Vitessce configuration for CellBrowser project adultPancreas\")\n",
+ "anndata_wrapper_inst.auto_view_config(vc)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "emfo",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/config_to_python.ipynb b/docs/notebooks/__ipynb__/config_to_python.ipynb
new file mode 100644
index 00000000..0d23caa2
--- /dev/null
+++ b/docs/notebooks/__ipynb__/config_to_python.ipynb
@@ -0,0 +1,166 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "MJUe",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import VitessceConfig, VitessceChainableConfig, VitessceConfigDatasetFile"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from example_configs import dries as dries_config"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ROlb",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig.from_dict(dries_config)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "nWHF",
+ "metadata": {},
+ "source": [
+ "## Evaluate the code and render a Vitessce widget"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hstk",
+ "metadata": {},
+ "source": [
+ "The second value is the code snippet. When evaluated, the result will be a new `VitessceConfig` instance."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "PKri",
+ "metadata": {},
+ "source": [
+ "## Print to JSON"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "SFPL",
+ "metadata": {},
+ "source": [
+ "## Print to Python\n",
+ "\n",
+ "The `vc.to_python` function generates formatted Python code which can be used to re-generate the `vc` instance."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "RGSE",
+ "metadata": {},
+ "source": [
+ "The first value returned is a list of classes used by the code snippet."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {},
+ "source": [
+ "## Load a view config from a dict representation"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Generate Python code to reconstruct a VitessceConfig instance"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "imports, code = vc.to_python()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import json\n",
+ "print(json.dumps(vc.to_dict(), indent=2))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "iLit",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "reconstructed_vc = eval(code)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "emfo",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "print(code)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Kclp",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "imports"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ZHCJ",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "reconstructed_vc.widget()"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/data_conversion.ipynb b/docs/notebooks/__ipynb__/data_conversion.ipynb
new file mode 100644
index 00000000..24645174
--- /dev/null
+++ b/docs/notebooks/__ipynb__/data_conversion.ipynb
@@ -0,0 +1,99 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import SnapWrapper\n",
+ "from os.path import join\n",
+ "from scipy.io import mmread\n",
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "import json"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "mtx = mmread(join('data', 'snapatac', 'filtered_cell_by_bin.mtx'))\n",
+ "barcodes_df = pd.read_csv(join('data', 'snapatac', 'barcodes.txt'), header=None)\n",
+ "bins_df = pd.read_csv(join('data', 'snapatac', 'bins.txt'), header=None)\n",
+ "clusters_df = pd.read_csv(join('data', 'snapatac', 'umap_coords_clusters.csv'), index_col=0)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {},
+ "source": [
+ "When running the Vitessce widget, data is converted on-the-fly into formats that the Vitessce JavaScript component can render.\n",
+ "The converted data is stored in temporary files, preventing long-term use of the converted files.\n",
+ "\n",
+ "However, the data conversion utilities used by the widget are exposed so that their outputs can be saved to regular files.\n",
+ "This allows the files to be saved for future use with the Vitessce web application by serving the files locally or moving the files onto an object storage system such as AWS S3 (for long-term storage and data sharing).\n",
+ "\n",
+ "This notebook demonstrates how to save the processed outputs of the `AnnDataWrapper` and `SnapWrapper` classes."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Convert data manually"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Data Preparation Tutorial"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "zarr_filepath = join('data', 'snapatac', 'out.snap.multires.zarr')\n",
+ "\n",
+ "w = SnapWrapper(mtx, barcodes_df, bins_df, clusters_df)\n",
+ "\n",
+ "cells_json = w.create_cells_json()\n",
+ "cell_sets_json = w.create_cell_sets_json()\n",
+ "\n",
+ "with open(join('data', 'snapatac', 'out.cells.json'), 'w') as f:\n",
+ " json.dump(cells_json, f)\n",
+ "\n",
+ "with open(join('data', 'snapatac', 'out.cell-sets.json'), 'w') as f:\n",
+ " json.dump(cell_sets_json, f)\n",
+ "\n",
+ "\n",
+ "w.create_genomic_multivec_zarr(zarr_filepath)"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/data_export_files.ipynb b/docs/notebooks/__ipynb__/data_export_files.ipynb
new file mode 100644
index 00000000..972257bb
--- /dev/null
+++ b/docs/notebooks/__ipynb__/data_export_files.ipynb
@@ -0,0 +1,222 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "import json\n",
+ "from urllib.parse import quote_plus\n",
+ "from os.path import join, isfile, isdir\n",
+ "from urllib.request import urlretrieve\n",
+ "from anndata import read_h5ad\n",
+ "import scanpy as sc\n",
+ "\n",
+ "from vitessce import (\n",
+ " VitessceWidget,\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " AnnDataWrapper,\n",
+ ")\n",
+ "from vitessce.data_utils import (\n",
+ " optimize_adata,\n",
+ " VAR_CHUNK_SIZE,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ROlb",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata_filepath = join(\"data\", \"habib17.processed.h5ad\")\n",
+ "if not isfile(adata_filepath):\n",
+ " os.makedirs(\"data\", exist_ok=True)\n",
+ " urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)\n",
+ "\n",
+ "adata = read_h5ad(adata_filepath)\n",
+ "top_dispersion = adata.var[\"dispersions_norm\"][\n",
+ " sorted(\n",
+ " range(len(adata.var[\"dispersions_norm\"])),\n",
+ " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
+ " )[-51:][0]\n",
+ "]\n",
+ "adata.var[\"top_highly_variable\"] = (\n",
+ " adata.var[\"dispersions_norm\"] > top_dispersion\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {},
+ "source": [
+ "## 2. Download and process data\n",
+ "\n",
+ "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hstk",
+ "metadata": {},
+ "source": [
+ "## 5. Serve the files"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {},
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the classes and functions that we will be using from the corresponding packages."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Data Preparation Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "SFPL",
+ "metadata": {},
+ "source": [
+ "## 3. Create the Vitessce configuration"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "BYtC",
+ "metadata": {},
+ "source": [
+ "Set up the configuration by adding the views and datasets of interest."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Kclp",
+ "metadata": {},
+ "source": [
+ "## 4. Export files to a local directory\n",
+ "\n",
+ "The `.export(to='files')` method on the view config instance will export files to the specified directory `out_dir`. The `base_url` parameter is required so that the file URLs in the view config point to the location where you ultimately intend to serve the files."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "nWHF",
+ "metadata": {},
+ "source": [
+ "Now that the files have been saved to the `./test` directory, they can be served by any static web server.\n",
+ "\n",
+ "If you would like to serve the files locally, we recommend [http-server](https://github.com/http-party/http-server) which can be installed with NPM or Homebrew:\n",
+ "```sh\n",
+ "cd test\n",
+ "http-server ./ --cors -p 3000\n",
+ "```"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Export data to local files"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "iLit",
+ "metadata": {},
+ "source": [
+ "## 6. View on vitessce.io\n",
+ "\n",
+ "The returned view config dict can be converted to a URL, and if the files are served on the internet (rather than locally), this URL can be used to share the interactive visualizations with colleagues."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "zarr_filepath = join('data', 'habib17.processed.zarr')\n",
+ "if not isdir(zarr_filepath):\n",
+ " adata_1 = optimize_adata(adata, obs_cols=['CellType'], obsm_keys=['X_umap'], var_cols=['top_highly_variable'], optimize_X=True)\n",
+ " adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', description='COVID-19 Healthy Donor Brain')\n",
+ "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
+ " adata_path=zarr_filepath,\n",
+ " obs_embedding_paths=[\"obsm/X_umap\"],\n",
+ " obs_embedding_names=[\"UMAP\"],\n",
+ " obs_set_paths=[\"obs/CellType\"],\n",
+ " obs_set_names=[\"Cell Type\"],\n",
+ " obs_feature_matrix_path=\"X\",\n",
+ " feature_filter_path=\"var/top_highly_variable\"\n",
+ "))\n",
+ "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"X_umap\")\n",
+ "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
+ "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
+ "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)\n",
+ "vc.layout((scatterplot | (cell_sets / genes)) / heatmap);"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "emfo",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "config_dict = vc.export(to='files', base_url='http://localhost:3000', out_dir='./test')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ZHCJ",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vitessce_url = \"http://vitessce.io/?url=data:,\" + quote_plus(json.dumps(config_dict))\n",
+ "import webbrowser\n",
+ "webbrowser.open(vitessce_url)"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/data_export_s3.ipynb b/docs/notebooks/__ipynb__/data_export_s3.ipynb
new file mode 100644
index 00000000..fcb6b6e9
--- /dev/null
+++ b/docs/notebooks/__ipynb__/data_export_s3.ipynb
@@ -0,0 +1,223 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "import boto3\n",
+ "import json\n",
+ "from urllib.parse import quote_plus\n",
+ "from os.path import join, isfile, isdir\n",
+ "from urllib.request import urlretrieve\n",
+ "from anndata import read_h5ad\n",
+ "import scanpy as sc\n",
+ "\n",
+ "from vitessce import (\n",
+ " VitessceWidget,\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " AnnDataWrapper,\n",
+ ")\n",
+ "from vitessce.data_utils import (\n",
+ " optimize_adata,\n",
+ " VAR_CHUNK_SIZE,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ROlb",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "emfo",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s3 = boto3.resource(\n",
+ " service_name='s3',\n",
+ " aws_access_key_id=os.environ['VITESSCE_S3_ACCESS_KEY_ID'],\n",
+ " aws_secret_access_key=os.environ['VITESSCE_S3_SECRET_ACCESS_KEY'],\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata_filepath = join(\"data\", \"habib17.processed.h5ad\")\n",
+ "if not isfile(adata_filepath):\n",
+ " os.makedirs(\"data\", exist_ok=True)\n",
+ " urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)\n",
+ "\n",
+ "adata = read_h5ad(adata_filepath)\n",
+ "top_dispersion = adata.var[\"dispersions_norm\"][\n",
+ " sorted(\n",
+ " range(len(adata.var[\"dispersions_norm\"])),\n",
+ " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
+ " )[-51:][0]\n",
+ "]\n",
+ "adata.var[\"top_highly_variable\"] = (\n",
+ " adata.var[\"dispersions_norm\"] > top_dispersion\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {},
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the classes and functions that we will be using from the corresponding packages."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "SFPL",
+ "metadata": {},
+ "source": [
+ "## 3. Create the Vitessce configuration"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Data Preparation Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {},
+ "source": [
+ "## 2. Download and process data\n",
+ "\n",
+ "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "BYtC",
+ "metadata": {},
+ "source": [
+ "Set up the configuration by adding the views and datasets of interest."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "iLit",
+ "metadata": {},
+ "source": [
+ "## 6. View on vitessce.io\n",
+ "\n",
+ "The returned view config dict can be converted to a URL, and can be used to share the interactive visualizations with colleagues."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Kclp",
+ "metadata": {},
+ "source": [
+ "## 4. Create a `boto3` resource with S3 credentials"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Export data to AWS S3"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hstk",
+ "metadata": {},
+ "source": [
+ "## 5. Upload files to S3\n",
+ "\n",
+ "The `.export(to='S3')` method on the view config instance will upload all data objects to the specified bucket. Then, the processed view config will be returned as a `dict`, with the file URLs filled in, pointing to the S3 bucket files. For more information about configuring the S3 bucket so that files are accessible over the internet, visit the \"Hosting Data\" page of our core documentation site."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "zarr_filepath = join('data', 'habib17.processed.zarr')\n",
+ "if not isdir(zarr_filepath):\n",
+ " adata_1 = optimize_adata(adata, obs_cols=['CellType'], obsm_keys=['X_umap'], var_cols=['top_highly_variable'], optimize_X=True)\n",
+ " adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', description='COVID-19 Healthy Donor Brain')\n",
+ "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
+ " adata_path=zarr_filepath,\n",
+ " obs_embedding_paths=[\"obsm/X_umap\"],\n",
+ " obs_embedding_names=[\"UMAP\"],\n",
+ " obs_set_paths=[\"obs/CellType\"],\n",
+ " obs_set_names=[\"Cell Type\"],\n",
+ " obs_feature_matrix_path=\"X\",\n",
+ " feature_filter_path=\"var/top_highly_variable\"\n",
+ "))\n",
+ "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
+ "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
+ "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
+ "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)\n",
+ "vc.layout((scatterplot | (cell_sets / genes)) / heatmap);"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "nWHF",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "config_dict = vc.export(to='S3', s3=s3, bucket_name='vitessce-export-examples', prefix='test')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ZHCJ",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vitessce_url = \"http://vitessce.io/?url=data:,\" + quote_plus(json.dumps(config_dict))\n",
+ "import webbrowser\n",
+ "webbrowser.open(vitessce_url)"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/page_mode_comparative.ipynb b/docs/notebooks/__ipynb__/page_mode_comparative.ipynb
new file mode 100644
index 00000000..4156eea4
--- /dev/null
+++ b/docs/notebooks/__ipynb__/page_mode_comparative.ipynb
@@ -0,0 +1,476 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from oxc_py import transform\n",
+ "from vitessce import VitessceConfig, hconcat, vconcat"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Reference: https://github.com/vitessce/vitessce/blob/main/examples/configs/src/view-configs/kpmp-premiere.js"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "base_url = 'https://storage.googleapis.com/vitessce-demo-data/kpmp-jan-2025/kpmp_premiere_20250330.adata.zarr'"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Hstk",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "PAGE_ESM = transform(\"\"\"\n",
+ "import clsx from \"https://unpkg.com/clsx@1.1.1/dist/clsx.m.js\";\n",
+ "\n",
+ "function createPage(utilsForPages) {\n",
+ " const {\n",
+ " React,\n",
+ " usePageModeView,\n",
+ " } = utilsForPages;\n",
+ " function PageComponent(props) {\n",
+ " const BiomarkerSelect = usePageModeView('biomarker-select');\n",
+ " const ComparativeHeading = usePageModeView('comparative-heading');\n",
+ " const CellSets = usePageModeView('cell-sets');\n",
+ " const SampleSets = usePageModeView('sample-sets');\n",
+ " const DualScatterplot = usePageModeView('scatterplot');\n",
+ " const ViolinPlot = usePageModeView('violin-plot');\n",
+ " const DotPlot = usePageModeView('dot-plot');\n",
+ " const Treemap = usePageModeView('treemap');\n",
+ " const VolcanoPlot = usePageModeView('volcano-plot');\n",
+ " const VolcanoPlotTable = usePageModeView('volcano-plot-table');\n",
+ " const SccodaPlot = usePageModeView('sccoda-plot');\n",
+ " const PathwaysPlot = usePageModeView('pathways-plot');\n",
+ "\n",
+ "\n",
+ " return (\n",
+ " <>\n",
+ " \n",
+ " \n",
+ "
\n",
+ "
Comparative visualization of single-cell atlas data \n",
+ " \n",
+ " \n",
+ "
\n",
+ "\n",
+ " \n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
This view contains a treemap visualization to communicate cell type composition in each of the selected sample groups.
\n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
This view displays the results of a cell type composition analysis performed using the ScCODA algorithm (Büttner et al. 2021). Cell types with significantly different composition between the selected sample groups are displayed opaque while not-signficant results are displayed with transparent bars. The single outlined bar denotes the automatically-selected reference cell type.
\n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
This view displays differential expression test results, performed using the rank_genes_groups function from Scanpy (Wolf et al. 2018) with method "wilcoxon". The arrows on the bottom left and bottom right denote the direction of the effect. Click a point in the plot to select the corresponding gene. Note that differential expression tests have been run for each cell type separately, so the each gene can appear multiple times (once per cell type). If there are too many points on the plot, cell types can be selected to filter the points.
\n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
This view displays differential expression test results in tabular form. Click a row in the table to select the corresponding gene.
\n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
This view displays gene set enrichment test results based on the differential expression results. Gene set enrichment tests have been performed using Reactome 2022 pathway gene sets from BlitzGSEA (Lachmann et al. 2022) via the hypergeometric function of Pertpy (Heumos et al. 2024).
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
This view contains contour scatterplots which display the results of a density-preserving dimensionality reduction (Narayan et al. 2021). Contour opacities correspond to the shown percentile thresholds.
\n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
This dot plot view displays gene expression values per cell type and sample group for the selected biomarkers.
\n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
This violin plot view displays gene expression values per cell type and sample group for the selected biomarker.
\n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ " {/*
Neighborhood-level representations \n",
+ "
TODO \n",
+ "
Segmented instance-level representations \n",
+ "
TODO \n",
+ "
Image-level representations \n",
+ "
TODO \n",
+ "
Participant-level representations \n",
+ "
TODO */}\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "\n",
+ "
\n",
+ " >\n",
+ " );\n",
+ " }\n",
+ " return PageComponent;\n",
+ "}\n",
+ "export default { createPage };\n",
+ "\"\"\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.17\", name='Lake et al.')\n",
+ "\n",
+ "dataset = vc.add_dataset('lake_et_al').add_file(\n",
+ " file_type='comparisonMetadata.anndata.zarr',\n",
+ " url=base_url,\n",
+ " options={\n",
+ " \"path\": 'uns/comparison_metadata',\n",
+ " },\n",
+ " coordination_values={\n",
+ " \"obsType\": 'cell',\n",
+ " \"sampleType\": 'sample',\n",
+ " },\n",
+ ").add_file(\n",
+ " file_type='comparativeFeatureStats.anndata.zarr',\n",
+ " url=base_url,\n",
+ " options= {\n",
+ " \"metadataPath\": 'uns/comparison_metadata',\n",
+ " \"indexColumn\": 'names',\n",
+ " \"pValueColumn\": 'pvals_adj',\n",
+ " \"foldChangeColumn\": 'logfoldchanges',\n",
+ " \"pValueAdjusted\": True,\n",
+ " \"foldChangeTransformation\": 'log2',\n",
+ " },\n",
+ " coordination_values={\n",
+ " \"obsType\": 'cell',\n",
+ " \"sampleType\": 'sample',\n",
+ " \"featureType\": 'gene',\n",
+ " },\n",
+ ").add_file(\n",
+ " file_type= 'comparativeObsSetStats.anndata.zarr',\n",
+ " url= base_url,\n",
+ " options= {\n",
+ " \"metadataPath\": 'uns/comparison_metadata',\n",
+ " \"indexColumn\": 'Cell Type',\n",
+ " \"interceptExpectedSampleColumn\": 'Expected Sample_intercept',\n",
+ " \"effectExpectedSampleColumn\": 'Expected Sample_effect',\n",
+ " \"foldChangeColumn\": 'log2-fold change',\n",
+ " \"foldChangeTransformation\": 'log2',\n",
+ " \"isCredibleEffectColumn\": 'is_credible_effect',\n",
+ " },\n",
+ " coordination_values= {\n",
+ " \"obsType\": 'cell',\n",
+ " \"sampleType\": 'sample',\n",
+ " },\n",
+ ").add_file(\n",
+ " file_type='comparativeFeatureSetStats.anndata.zarr',\n",
+ " url=base_url,\n",
+ " options= {\n",
+ " \"metadataPath\": 'uns/comparison_metadata',\n",
+ " \"indexColumn\": 'pathway_name',\n",
+ " \"termColumn\": 'pathway_term',\n",
+ " \"pValueColumn\": 'pvals_adj',\n",
+ " \"pValueAdjusted\": True,\n",
+ " \"analysisType\": 'pertpy_hypergeometric',\n",
+ " \"featureSetLibrary\": 'Reactome_2022',\n",
+ " },\n",
+ " coordination_values= {\n",
+ " \"obsType\": 'cell',\n",
+ " \"featureType\": 'gene',\n",
+ " \"sampleType\": 'sample',\n",
+ " },\n",
+ ").add_file(\n",
+ " file_type='anndata.zarr',\n",
+ " url=base_url,\n",
+ " coordination_values={\n",
+ " \"obsType\": 'cell',\n",
+ " \"featureType\": 'gene',\n",
+ " \"featureValueType\": 'expression',\n",
+ " \"sampleType\": 'sample',\n",
+ " },\n",
+ " options={\n",
+ " \"obsFeatureMatrix\": {\n",
+ " \"path\": 'layers/pearson_residuals',\n",
+ " },\n",
+ " \"obsEmbedding\": [\n",
+ " {\n",
+ " \"path\": 'obsm/X_densmap',\n",
+ " \"embeddingType\": 'densMAP',\n",
+ " },\n",
+ " ],\n",
+ " \"obsSets\": [\n",
+ " {\n",
+ " \"name\": 'Cell Type',\n",
+ " \"path\": 'obs/cell_type',\n",
+ " },\n",
+ " {\n",
+ " \"name\": 'Subclass L1',\n",
+ " \"path\": 'obs/subclass_l1',\n",
+ " },\n",
+ " {\n",
+ " \"name\": 'Subclass L2',\n",
+ " \"path\": 'obs/subclass_l2',\n",
+ " },\n",
+ " {\n",
+ " \"name\": 'Donor ID',\n",
+ " \"path\": 'obs/donor_id',\n",
+ " },\n",
+ " ],\n",
+ " \"sampleEdges\": {\n",
+ " \"path\": 'obs/SampleID',\n",
+ " },\n",
+ " },\n",
+ ").add_file(\n",
+ " file_type='sampleSets.anndata.zarr',\n",
+ " url=f\"{base_url}/uns/__all__.samples\",\n",
+ " options={\n",
+ " \"sampleSets\": [\n",
+ " {\n",
+ " \"name\": 'Disease Type',\n",
+ " \"path\": 'diseasetype',\n",
+ " },\n",
+ " {\n",
+ " \"name\": 'Adjudicated Category',\n",
+ " \"path\": 'AdjudicatedCategory',\n",
+ " },\n",
+ " {\n",
+ " \"name\": 'Enrollment Category',\n",
+ " \"path\": 'EnrollmentCategory',\n",
+ " },\n",
+ " ],\n",
+ " },\n",
+ " coordination_values= {\n",
+ " \"sampleType\": 'sample',\n",
+ " },\n",
+ ")\n",
+ "\n",
+ "biomarkerSelect = vc.add_view('biomarkerSelect', dataset=dataset, uid='biomarker-select')\n",
+ "comparativeHeading = vc.add_view('comparativeHeading', dataset=dataset, uid='comparative-heading')\n",
+ "dualScatterplot = vc.add_view('dualScatterplot', dataset=dataset, uid='scatterplot')\n",
+ "obsSets = vc.add_view('obsSets', dataset=dataset, uid='cell-sets')\n",
+ "sampleSets = vc.add_view('sampleSetPairManager', dataset=dataset, uid='sample-sets')\n",
+ "obsSetSizes = vc.add_view('obsSetSizes', dataset=dataset)\n",
+ "featureList = vc.add_view('featureList', dataset=dataset)\n",
+ "violinPlots = vc.add_view('obsSetFeatureValueDistribution', dataset=dataset, uid='violin-plot')\n",
+ "dotPlot = vc.add_view('dotPlot', dataset=dataset, uid='dot-plot')\n",
+ "treemap = vc.add_view('treemap', dataset=dataset, uid='treemap')\n",
+ "volcanoPlot = vc.add_view('volcanoPlot', dataset=dataset, uid='volcano-plot')\n",
+ "volcanoPlotTable = vc.add_view('featureStatsTable', dataset=dataset, uid='volcano-plot-table')\n",
+ "obsSetCompositionBarPlot = vc.add_view('obsSetCompositionBarPlot', dataset=dataset, uid='sccoda-plot')\n",
+ "featureSetEnrichmentBarPlot = vc.add_view('featureSetEnrichmentBarPlot', dataset=dataset, uid='pathways-plot')\n",
+ "\n",
+ "[sampleSetScope_caseControl] = vc.add_coordination('sampleSetSelection')\n",
+ "sampleSetScope_caseControl.set_value([['Disease Type', 'CKD'], ['Disease Type', 'Reference']])\n",
+ "\n",
+ "[featureSelectionScope] = vc.add_coordination('featureSelection')\n",
+ "featureSelectionScope.set_value(['UMOD', 'NPHS2'])\n",
+ "\n",
+ "vc.link_views_by_dict([dualScatterplot], {\n",
+ " \"embeddingType\": 'densMAP',\n",
+ " \"embeddingContoursVisible\": True,\n",
+ " \"embeddingPointsVisible\": False,\n",
+ " \"embeddingObsSetLabelsVisible\": True,\n",
+ "}, meta=False);\n",
+ "\n",
+ "\n",
+ "vc.link_views([biomarkerSelect, dualScatterplot, obsSets, obsSetSizes, featureList, violinPlots, dotPlot, treemap, volcanoPlot, volcanoPlotTable, comparativeHeading, obsSetCompositionBarPlot, featureSetEnrichmentBarPlot, sampleSets], ['sampleType'], ['sample'])\n",
+ "\n",
+ "vc.link_views_by_dict([biomarkerSelect, dualScatterplot, obsSets, obsSetSizes, featureList, violinPlots, dotPlot, treemap, volcanoPlot, volcanoPlotTable, comparativeHeading, obsSetCompositionBarPlot, featureSetEnrichmentBarPlot, sampleSets], {\n",
+ " \"sampleSetSelection\": sampleSetScope_caseControl,\n",
+ " \"featureSelection\": featureSelectionScope,\n",
+ "}, meta=False)\n",
+ "\n",
+ "vc.link_views_by_dict([dualScatterplot, violinPlots, featureList, dotPlot], {\n",
+ " # \"featureSelection\": ['UMOD', 'NPHS2'], // , 'ENSG00000074803', 'ENSG00000164825'],\n",
+ " \"obsColorEncoding\": 'geneSelection',\n",
+ " \"featureValueColormap\": 'jet',\n",
+ " \"featureValueColormapRange\": [0, 0.25],\n",
+ " \"featureAggregationStrategy\": None,\n",
+ "}, meta=False)\n",
+ "\n",
+ "vc.layout(hconcat(\n",
+ " vconcat(dualScatterplot, biomarkerSelect, comparativeHeading, obsSets, obsSetSizes, featureList),\n",
+ " vconcat(treemap, featureSetEnrichmentBarPlot, violinPlots, dotPlot, obsSetCompositionBarPlot, sampleSets),\n",
+ " volcanoPlotTable,\n",
+ "));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Kclp",
+ "metadata": {},
+ "source": [
+ "## Render page as widget"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {},
+ "source": [
+ "## Configure the data and views"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "BYtC",
+ "metadata": {},
+ "source": [
+ "## Define the page layout"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Visualization of ComparativeData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {},
+ "source": [
+ "## Configure Vitessce"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "emfo",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget(page_esm=PAGE_ESM, page_mode=True, height=4700, prevent_scroll=False)\n",
+ "vw"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/page_mode_example.ipynb b/docs/notebooks/__ipynb__/page_mode_example.ipynb
new file mode 100644
index 00000000..daa0aedd
--- /dev/null
+++ b/docs/notebooks/__ipynb__/page_mode_example.ipynb
@@ -0,0 +1,196 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " AnnDataWrapper,\n",
+ " CsvWrapper,\n",
+ ")\n",
+ "from oxc_py import transform"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "url = 'https://storage.googleapis.com/vitessce-demo-data/anndata-test/pbmc3k_processed.zarr'"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "emfo",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "PAGE_ESM = transform(\"\"\"\n",
+ "function createPage(utilsForPages) {\n",
+ " const {\n",
+ " React,\n",
+ " usePageModeView,\n",
+ " } = utilsForPages;\n",
+ " function PageComponent(props) {\n",
+ " const ScatterplotUmap = usePageModeView('scatterplot-umap');\n",
+ " const ScatterplotPca = usePageModeView('scatterplot-pca');\n",
+ " const CellSets = usePageModeView('cell-sets');\n",
+ " const GeneList = usePageModeView('gene-list');\n",
+ " const Heatmap = usePageModeView('heatmap');\n",
+ "\n",
+ " return (\n",
+ " <>\n",
+ " \n",
+ " \n",
+ "
\n",
+ "
This is an arbitrary HTML element with custom CSS \n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
Another HTML element \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
\n",
+ " \n",
+ " \n",
+ "
\n",
+ "
\n",
+ "\n",
+ " >\n",
+ " );\n",
+ " }\n",
+ " return PageComponent;\n",
+ "}\n",
+ "export default { createPage };\n",
+ "\"\"\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.17\", name='PBMC Reference')\n",
+ "dataset = vc.add_dataset(name='PBMC 3k').add_object(\n",
+ " AnnDataWrapper(\n",
+ " adata_url=url,\n",
+ " obs_set_paths=[\"obs/louvain\"],\n",
+ " obs_set_names=[\"Louvain\"],\n",
+ " obs_embedding_paths=[\"obsm/X_umap\", \"obsm/X_pca\"],\n",
+ " obs_embedding_names=[\"UMAP\", \"PCA\"],\n",
+ " obs_feature_matrix_path=\"X\"\n",
+ " )\n",
+ ")\n",
+ "\n",
+ "umap = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\", uid=\"scatterplot-umap\")\n",
+ "pca = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"PCA\", uid=\"scatterplot-pca\")\n",
+ "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset, uid=\"cell-sets\")\n",
+ "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset, uid=\"gene-list\")\n",
+ "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset, uid=\"heatmap\")\n",
+ "\n",
+ "vc.layout((umap / pca) | ((cell_sets | genes) / heatmap));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {},
+ "source": [
+ "## Configure the data and views"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Page mode example"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "SFPL",
+ "metadata": {},
+ "source": [
+ "## Define the page layout"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {},
+ "source": [
+ "## Configure Vitessce"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "RGSE",
+ "metadata": {},
+ "source": [
+ "## Render page as widget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Kclp",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget(page_esm=PAGE_ESM, page_mode=True, height=1100)\n",
+ "vw"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/spatial_data.ipynb b/docs/notebooks/__ipynb__/spatial_data.ipynb
new file mode 100644
index 00000000..a7bb5b00
--- /dev/null
+++ b/docs/notebooks/__ipynb__/spatial_data.ipynb
@@ -0,0 +1,164 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from os.path import join, isfile, isdir\n",
+ "from urllib.request import urlretrieve\n",
+ "import zipfile\n",
+ "\n",
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " ViewType as vt,\n",
+ " CoordinationType as ct,\n",
+ " CoordinationLevel as CL,\n",
+ " SpatialDataWrapper,\n",
+ " get_initial_coordination_scope_prefix\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Kclp",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "data_dir = \"data\"\n",
+ "zip_filepath = join(data_dir, \"visium.spatialdata.zarr.zip\")\n",
+ "spatialdata_filepath = join(data_dir, \"visium.spatialdata.zarr\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {},
+ "source": [
+ "## Import dependencies"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Xref",
+ "metadata": {},
+ "source": [
+ "## Configure Vitessce\n",
+ "\n",
+ "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Visualization of a SpatialData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "BYtC",
+ "metadata": {},
+ "source": [
+ "### Render the widget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(\n",
+ " schema_version=\"1.0.18\",\n",
+ " name='Visium SpatialData Demo (visium_associated_xenium_io)',\n",
+ ")\n",
+ "# Add data to the configuration:\n",
+ "wrapper = SpatialDataWrapper(\n",
+ " sdata_path=spatialdata_filepath,\n",
+ " # The following paths are relative to the root of the SpatialData zarr store on-disk.\n",
+ " image_path=\"images/CytAssist_FFPE_Human_Breast_Cancer_full_image\",\n",
+ " table_path=\"tables/table\",\n",
+ " obs_feature_matrix_path=\"tables/table/X\",\n",
+ " obs_spots_path=\"shapes/CytAssist_FFPE_Human_Breast_Cancer\",\n",
+ " region=\"CytAssist_FFPE_Human_Breast_Cancer\",\n",
+ " coordinate_system=\"global\",\n",
+ " coordination_values={\n",
+ " # The following tells Vitessce to consider each observation as a \"spot\"\n",
+ " \"obsType\": \"spot\",\n",
+ " }\n",
+ ")\n",
+ "dataset = vc.add_dataset(name='Breast Cancer Visium').add_object(wrapper)\n",
+ "\n",
+ "# Add views (visualizations) to the configuration:\n",
+ "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
+ "feature_list = vc.add_view(vt.FEATURE_LIST, dataset=dataset)\n",
+ "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
+ "vc.link_views_by_dict([spatial, layer_controller], {\n",
+ " 'imageLayer': CL([{\n",
+ " 'photometricInterpretation': 'RGB',\n",
+ " }]),\n",
+ "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
+ "obs_sets = vc.add_view(vt.OBS_SETS, dataset=dataset)\n",
+ "vc.link_views([spatial, layer_controller, feature_list, obs_sets], ['obsType'], [wrapper.obs_type_label])\n",
+ "\n",
+ "# Layout the views\n",
+ "vc.layout(spatial | (feature_list / layer_controller / obs_sets));"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "if not isdir(spatialdata_filepath):\n",
+ " if not isfile(zip_filepath):\n",
+ " os.makedirs(data_dir, exist_ok=True)\n",
+ " urlretrieve('https://s3.embl.de/spatialdata/spatialdata-sandbox/visium_associated_xenium_io.zip', zip_filepath)\n",
+ " with zipfile.ZipFile(zip_filepath,\"r\") as zip_ref:\n",
+ " zip_ref.extractall(data_dir)\n",
+ " os.rename(join(data_dir, \"data.zarr\"), spatialdata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/spatial_data_blobs.ipynb b/docs/notebooks/__ipynb__/spatial_data_blobs.ipynb
new file mode 100644
index 00000000..f7584c92
--- /dev/null
+++ b/docs/notebooks/__ipynb__/spatial_data_blobs.ipynb
@@ -0,0 +1,196 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import spatialdata\n",
+ "from os.path import join"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " ViewType as vt,\n",
+ " CoordinationType as ct,\n",
+ " CoordinationLevel as CL,\n",
+ " SpatialDataWrapper,\n",
+ " get_initial_coordination_scope_prefix\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Hstk",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "spatialdata_filepath = join(\"data\", \"blobs.spatialdata.zarr\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "sdata = spatialdata.datasets.blobs()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Visualization of a SpatialData object, blobs example"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Kclp",
+ "metadata": {},
+ "source": [
+ "### Render the widget"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {},
+ "source": [
+ "## Import dependencies"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "BYtC",
+ "metadata": {},
+ "source": [
+ "## Configure Vitessce\n",
+ "\n",
+ "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(\n",
+ " schema_version=\"1.0.18\",\n",
+ " name='Visium SpatialData Demo (blobs)',\n",
+ ")\n",
+ "# Add data to the configuration:\n",
+ "wrapper = SpatialDataWrapper(\n",
+ " sdata_store=spatialdata_filepath,\n",
+ " # The following paths are relative to the root of the SpatialData zarr store on-disk.\n",
+ " image_path=\"images/blobs_image\",\n",
+ " obs_segmentations_path=\"labels/blobs_labels\",\n",
+ " coordinate_system=\"global\",\n",
+ " coordination_values={\n",
+ " \"obsType\": \"blob\",\n",
+ " \"fileUid\": \"my_unique_id\"\n",
+ " }\n",
+ ")\n",
+ "dataset = vc.add_dataset(name='Blobs').add_object(wrapper)\n",
+ "\n",
+ "# Add views (visualizations) to the configuration:\n",
+ "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
+ "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
+ "\n",
+ "vc.link_views_by_dict([spatial, layer_controller], {\n",
+ " 'imageLayer': CL([{\n",
+ " \"fileUid\": \"my_unique_id\",\n",
+ " 'photometricInterpretation': 'BlackIsZero',\n",
+ " 'spatialLayerOpacity': 0.9,\n",
+ " 'imageChannel': CL([\n",
+ " {\n",
+ " \"spatialTargetC\": 0,\n",
+ " \"spatialChannelColor\": [255, 0, 0],\n",
+ " \"spatialChannelOpacity\": 1.0\n",
+ " },\n",
+ " {\n",
+ " \"spatialTargetC\": 1,\n",
+ " \"spatialChannelColor\": [0, 255, 0],\n",
+ " \"spatialChannelOpacity\": 1.0\n",
+ " },\n",
+ " {\n",
+ " \"spatialTargetC\": 2,\n",
+ " \"spatialChannelColor\": [0, 0, 255],\n",
+ " \"spatialChannelOpacity\": 1.0\n",
+ " }\n",
+ " ])\n",
+ " }]),\n",
+ "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
+ "\n",
+ "vc.link_views_by_dict([spatial, layer_controller], {\n",
+ " 'segmentationLayer': CL([{\n",
+ " \"fileUid\": \"my_unique_id\",\n",
+ " 'segmentationChannel': CL([{\n",
+ " 'spatialChannelVisible': True,\n",
+ " 'obsType': 'blob',\n",
+ " }]),\n",
+ " }]),\n",
+ "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"obsSegmentations\"))\n",
+ "\n",
+ "# Layout the views\n",
+ "vc.layout(spatial | layer_controller);"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "sdata.write(spatialdata_filepath, overwrite=True)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "emfo",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/spatial_data_kpmp_vis.ipynb b/docs/notebooks/__ipynb__/spatial_data_kpmp_vis.ipynb
new file mode 100644
index 00000000..49c2fe65
--- /dev/null
+++ b/docs/notebooks/__ipynb__/spatial_data_kpmp_vis.ipynb
@@ -0,0 +1,455 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Reference: https://github.com/vitessce/vitessce/blob/main/examples/configs/src/view-configs/spatial-beta/kpmp.js"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " ViewType as vt,\n",
+ " CoordinationType as ct,\n",
+ " CoordinationLevel as CL,\n",
+ " SpatialDataWrapper,\n",
+ " AnnDataWrapper,\n",
+ " ImageOmeTiffWrapper,\n",
+ " ImageOmeZarrWrapper,\n",
+ " ObsSegmentationsOmeZarrWrapper,\n",
+ " get_initial_coordination_scope_prefix,\n",
+ " hconcat,\n",
+ " vconcat,\n",
+ ")\n",
+ "from os.path import join"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "sdata_url = \"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/sdata.zarr\""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "#import json\n",
+ "#print(json.dumps(vc.to_dict(), indent=2))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Create a VitessceConfig instance.\n",
+ "vc = VitessceConfig(schema_version=\"1.0.18\", name=\"SpatialData\")\n",
+ "\n",
+ "t_obstype = \"Tubule\"\n",
+ "a_obstype = \"Artery\"\n",
+ "ci_obstype = \"Cortical Interstitium\"\n",
+ "gsg_obstype = \"G. S. Glomerulus\"\n",
+ "ngsg_obstype = \"Non-G. S. Glomerulus\"\n",
+ "ifta_obstype = \"Interstitial Fibrosis and Tubular Atrophy\"\n",
+ "ptc_obstype = \"Peritubular Capillaries\"\n",
+ "\n",
+ "# Add a new dataset to the Vitessce configuration,\n",
+ "# then add the wrapper class instance to this dataset.\n",
+ "dataset = vc.add_dataset(name='KPMP').add_object(\n",
+ " SpatialDataWrapper(\n",
+ " sdata_url=sdata_url,\n",
+ " image_path=\"images/image\",\n",
+ " coordinate_system=\"global\",\n",
+ " )\n",
+ ").add_object(\n",
+ " SpatialDataWrapper(\n",
+ " sdata_url=sdata_url,\n",
+ " table_path=\"tables/table_tubules\",\n",
+ " obs_segmentations_path=\"labels/labels_tubules\",\n",
+ " obs_feature_matrix_path=\"tables/table_tubules/X\",\n",
+ " coordinate_system=\"global\",\n",
+ " coordination_values={\n",
+ " \"fileUid\": \"labels_tubules\",\n",
+ " \"obsType\": t_obstype,\n",
+ " \"featureType\": 'feature',\n",
+ " \"featureValueType\": 'value',\n",
+ " }\n",
+ " )\n",
+ ").add_object(\n",
+ " SpatialDataWrapper(\n",
+ " sdata_url=sdata_url,\n",
+ " obs_segmentations_path=\"labels/labels_arteries_arterioles\",\n",
+ " coordinate_system=\"global\",\n",
+ " coordination_values={\n",
+ " \"fileUid\": \"labels_arteries_arterioles\",\n",
+ " \"obsType\": a_obstype,\n",
+ " \"featureType\": 'feature',\n",
+ " \"featureValueType\": 'value',\n",
+ " }\n",
+ " )\n",
+ ").add_object(\n",
+ " SpatialDataWrapper(\n",
+ " sdata_url=sdata_url,\n",
+ " table_path=\"tables/table_cortical_interstitia\",\n",
+ " obs_segmentations_path=\"labels/labels_cortical_interstitia\",\n",
+ " obs_feature_matrix_path=\"tables/table_cortical_interstitia/X\",\n",
+ " coordinate_system=\"global\",\n",
+ " coordination_values={\n",
+ " \"fileUid\": \"labels_cortical_interstitia\",\n",
+ " \"obsType\": ci_obstype,\n",
+ " \"featureType\": 'feature',\n",
+ " \"featureValueType\": 'value',\n",
+ " }\n",
+ " )\n",
+ ").add_object(\n",
+ " SpatialDataWrapper(\n",
+ " sdata_url=sdata_url,\n",
+ " table_path=\"tables/table_globally_sclerotic_glomeruli\",\n",
+ " obs_segmentations_path=\"labels/labels_globally_sclerotic_glomeruli\",\n",
+ " obs_feature_matrix_path=\"tables/table_globally_sclerotic_glomeruli/X\",\n",
+ " coordinate_system=\"global\",\n",
+ " coordination_values={\n",
+ " \"fileUid\": \"labels_globally_sclerotic_glomeruli\",\n",
+ " \"obsType\": gsg_obstype,\n",
+ " \"featureType\": 'feature',\n",
+ " \"featureValueType\": 'value',\n",
+ " }\n",
+ " )\n",
+ ").add_object(\n",
+ " SpatialDataWrapper(\n",
+ " sdata_url=sdata_url,\n",
+ " table_path=\"tables/table_non_globally_sclerotic_glomeruli\",\n",
+ " obs_segmentations_path=\"labels/labels_non_globally_sclerotic_glomeruli\",\n",
+ " obs_feature_matrix_path=\"tables/table_non_globally_sclerotic_glomeruli/X\",\n",
+ " coordinate_system=\"global\",\n",
+ " coordination_values={\n",
+ " \"fileUid\": \"labels_non_globally_sclerotic_glomeruli\",\n",
+ " \"obsType\": ngsg_obstype,\n",
+ " \"featureType\": 'feature',\n",
+ " \"featureValueType\": 'value',\n",
+ " }\n",
+ " )\n",
+ ").add_object(\n",
+ " SpatialDataWrapper(\n",
+ " sdata_url=sdata_url,\n",
+ " table_path=\"tables/table_interstitialfibrosis_and_tubular_atrophy\",\n",
+ " obs_segmentations_path=\"labels/labels_interstitialfibrosis_and_tubular_atrophy\",\n",
+ " coordinate_system=\"global\",\n",
+ " coordination_values={\n",
+ " \"fileUid\": \"labels_interstitialfibrosis_and_tubular_atrophy\",\n",
+ " \"obsType\": ifta_obstype,\n",
+ " \"featureType\": 'feature',\n",
+ " \"featureValueType\": 'value',\n",
+ " }\n",
+ " )\n",
+ ").add_object(\n",
+ " SpatialDataWrapper(\n",
+ " sdata_url=sdata_url,\n",
+ " table_path=\"tables/table_peritubular_capillaries\",\n",
+ " obs_segmentations_path=\"labels/labels_peritubular_capillaries\",\n",
+ " obs_feature_matrix_path=\"tables/table_peritubular_capillaries/X\",\n",
+ " obs_set_paths=[\n",
+ " \"tables/table_peritubular_capillaries/obs/cortex_ifta_set\",\n",
+ " \"tables/table_peritubular_capillaries/obs/cortex_set\",\n",
+ " \"tables/table_peritubular_capillaries/obs/ifta_set\",\n",
+ " [\"tables/table_peritubular_capillaries/obs/cortex_set\", \"tables/table_peritubular_capillaries/obs/ifta_set\"],\n",
+ " ],\n",
+ " obs_set_names=[\n",
+ " \"Cortex and IFTA membership\",\n",
+ " \"Cortex membership\",\n",
+ " \"IFTA membership\",\n",
+ " \"Cortex and IFTA hierarchy\",\n",
+ " ],\n",
+ " coordinate_system=\"global\",\n",
+ " coordination_values={\n",
+ " \"fileUid\": \"labels_peritubular_capillaries\",\n",
+ " \"obsType\": ptc_obstype,\n",
+ " \"featureType\": 'feature',\n",
+ " \"featureValueType\": 'value',\n",
+ " }\n",
+ " )\n",
+ ")\n",
+ "\n",
+ "# Add views (visualizations) to the configuration.\n",
+ "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
+ "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
+ "# Tubules\n",
+ "tubules_feature_list = vc.add_view(\"featureList\", dataset=dataset).set_props(title=\"Tubules\")\n",
+ "tubules_histogram = vc.add_view(\"featureValueHistogram\", dataset=dataset)\n",
+ "# Peritubular capillaries\n",
+ "pt_feature_list = vc.add_view(\"featureList\", dataset=dataset).set_props(title=\"Peritubular Capillaries\")\n",
+ "pt_histogram = vc.add_view(\"featureValueHistogram\", dataset=dataset)\n",
+ "# GSG\n",
+ "gsg_feature_list = vc.add_view(\"featureList\", dataset=dataset).set_props(title=\"Globally Sclerotic Glomeruli\")\n",
+ "gsg_histogram = vc.add_view(\"featureValueHistogram\", dataset=dataset)\n",
+ "# NGSG\n",
+ "ngsg_feature_list = vc.add_view(\"featureList\", dataset=dataset).set_props(title=\"Non-Globally Sclerotic Glomeruli\")\n",
+ "ngsg_histogram = vc.add_view(\"featureValueHistogram\", dataset=dataset)\n",
+ "\n",
+ "# Add obsSets, obsSetSizes, and violin plot views for PTC sets+areas/aspectRatio\n",
+ "pt_sets = vc.add_view(\"obsSets\", dataset=dataset)\n",
+ "pt_bar_plot = vc.add_view(\"obsSetSizes\", dataset=dataset)\n",
+ "pt_violin_plot = vc.add_view(\"obsSetFeatureValueDistribution\", dataset=dataset).set_props(jitter=True)\n",
+ "\n",
+ "\n",
+ "# Coordination of views.\n",
+ "[ft_scope, fvt_scope] = vc.add_coordination(\"featureType\", \"featureValueType\")\n",
+ "ft_scope.set_value(\"feature\")\n",
+ "fvt_scope.set_value(\"value\")\n",
+ "\n",
+ "[t_ot_scope, t_fs_scope, t_oce_scope] = vc.add_coordination(\"obsType\", \"featureSelection\", \"obsColorEncoding\")\n",
+ "t_ot_scope.set_value(t_obstype)\n",
+ "t_oce_scope.set_value(\"spatialChannelColor\")\n",
+ "\n",
+ "[pt_ot_scope, pt_fs_scope, pt_oce_scope] = vc.add_coordination(\"obsType\", \"featureSelection\", \"obsColorEncoding\")\n",
+ "pt_ot_scope.set_value(ptc_obstype)\n",
+ "pt_fs_scope.set_value([\"Area\"])\n",
+ "pt_oce_scope.set_value(\"cellSetSelection\")\n",
+ "\n",
+ "\n",
+ "[gsg_ot_scope, gsg_fs_scope, gsg_oce_scope, gsg_fvcr_scope] = vc.add_coordination(\"obsType\", \"featureSelection\", \"obsColorEncoding\", \"featureValueColormapRange\")\n",
+ "gsg_ot_scope.set_value(gsg_obstype)\n",
+ "gsg_oce_scope.set_value(\"spatialChannelColor\")\n",
+ "gsg_fvcr_scope.set_value([(3077 - 2333) / (29911 - 2333), 1.0])\n",
+ "\n",
+ "[ngsg_ot_scope, ngsg_fs_scope, ngsg_oce_scope, ngsg_fvcr_scope] = vc.add_coordination(\"obsType\", \"featureSelection\", \"obsColorEncoding\", \"featureValueColormapRange\")\n",
+ "ngsg_ot_scope.set_value(ngsg_obstype)\n",
+ "ngsg_oce_scope.set_value(\"spatialChannelColor\")\n",
+ "ngsg_fvcr_scope.set_value([0.0, 1 - (59451 - 29911) / (59451 - 3077)])\n",
+ "\n",
+ "vc.link_views_by_dict([spatial, layer_controller], {\n",
+ " \"imageLayer\": CL([{\n",
+ " \"spatialLayerOpacity\": 0.1,\n",
+ " \"photometricInterpretation\": \"RGB\",\n",
+ " }]),\n",
+ "}, meta=True, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
+ "\n",
+ "vc.link_views_by_dict([spatial, layer_controller], {\n",
+ " \"segmentationLayer\": CL([\n",
+ " {\n",
+ " \"fileUid\": \"labels_tubules\",\n",
+ " \"segmentationChannel\": CL([{\n",
+ " \"spatialTargetC\": 0,\n",
+ " \"obsType\": t_ot_scope,\n",
+ " \"featureType\": ft_scope,\n",
+ " \"featureValueType\": fvt_scope,\n",
+ " \"featureSelection\": t_fs_scope,\n",
+ " \"spatialChannelVisible\": False,\n",
+ " \"spatialChannelColor\": [73, 155, 119],\n",
+ " \"spatialChannelOpacity\": 0.5,\n",
+ " \"obsColorEncoding\": t_oce_scope,\n",
+ " \"featureValueColormapRange\": [0, 1],\n",
+ " \"featureAggregationStrategy\": \"first\",\n",
+ " \"spatialSegmentationFilled\": True,\n",
+ " \"obsHighlight\": None,\n",
+ " }]),\n",
+ " },\n",
+ " {\n",
+ " \"fileUid\": \"labels_arteries_arterioles\",\n",
+ " \"segmentationChannel\": CL([{\n",
+ " \"spatialTargetC\": 0,\n",
+ " \"obsType\": \"Artery\",\n",
+ " \"featureType\": ft_scope,\n",
+ " \"featureValueType\": fvt_scope,\n",
+ " \"spatialChannelVisible\": False,\n",
+ " \"spatialChannelColor\": [237, 226, 107],\n",
+ " \"spatialChannelOpacity\": 0.5,\n",
+ " \"obsColorEncoding\": \"spatialChannelColor\",\n",
+ " \"featureValueColormapRange\": [0, 1],\n",
+ " \"featureAggregationStrategy\": \"first\",\n",
+ " \"spatialSegmentationFilled\": True,\n",
+ " \"obsHighlight\": None,\n",
+ " }]),\n",
+ " },\n",
+ " {\n",
+ " \"fileUid\": \"labels_cortical_interstitia\",\n",
+ " \"segmentationChannel\": CL([{\n",
+ " \"spatialTargetC\": 0,\n",
+ " \"obsType\": \"Cortical Interstitium\",\n",
+ " \"featureType\": ft_scope,\n",
+ " \"featureValueType\": fvt_scope,\n",
+ " \"spatialChannelVisible\": False,\n",
+ " \"spatialChannelColor\": [255, 255, 255],\n",
+ " \"spatialChannelOpacity\": 0.5,\n",
+ " \"obsColorEncoding\": \"spatialChannelColor\",\n",
+ " \"featureValueColormapRange\": [0, 1],\n",
+ " \"featureAggregationStrategy\": \"first\",\n",
+ " \"spatialSegmentationFilled\": True,\n",
+ " \"obsHighlight\": None,\n",
+ " }]),\n",
+ " },\n",
+ " {\n",
+ " \"fileUid\": \"labels_globally_sclerotic_glomeruli\",\n",
+ " \"segmentationChannel\": CL([{\n",
+ " \"spatialTargetC\": 0,\n",
+ " \"obsType\": gsg_ot_scope,\n",
+ " \"featureType\": ft_scope,\n",
+ " \"featureValueType\": fvt_scope,\n",
+ " \"featureSelection\": gsg_fs_scope,\n",
+ " \"spatialChannelVisible\": False,\n",
+ " \"spatialChannelColor\": [52, 113, 171],\n",
+ " \"spatialChannelOpacity\": 0.5,\n",
+ " \"obsColorEncoding\": gsg_oce_scope,\n",
+ " \"featureValueColormapRange\": gsg_fvcr_scope,\n",
+ " \"featureAggregationStrategy\": \"first\",\n",
+ " \"spatialSegmentationFilled\": True,\n",
+ " \"obsHighlight\": None,\n",
+ " }]),\n",
+ " },\n",
+ " {\n",
+ " \"fileUid\": \"labels_non_globally_sclerotic_glomeruli\",\n",
+ " \"segmentationChannel\": CL([{\n",
+ " \"spatialTargetC\": 0,\n",
+ " \"obsType\": ngsg_ot_scope,\n",
+ " \"featureType\": ft_scope,\n",
+ " \"featureValueType\": fvt_scope,\n",
+ " \"featureSelection\": ngsg_fs_scope,\n",
+ " \"spatialChannelVisible\": False,\n",
+ " \"spatialChannelColor\": [114, 179, 226],\n",
+ " \"spatialChannelOpacity\": 0.5,\n",
+ " \"obsColorEncoding\": ngsg_oce_scope,\n",
+ " \"featureValueColormapRange\": ngsg_fvcr_scope,\n",
+ " \"featureAggregationStrategy\": \"first\",\n",
+ " \"spatialSegmentationFilled\": True,\n",
+ " \"obsHighlight\": None,\n",
+ " }]),\n",
+ " },\n",
+ " {\n",
+ " \"fileUid\": \"labels_interstitialfibrosis_and_tubular_atrophy\",\n",
+ " \"segmentationChannel\": CL([{\n",
+ " \"spatialTargetC\": 0,\n",
+ " \"obsType\": \"Interstitial Fibrosis and Tubular Atrophy\",\n",
+ " \"featureType\": ft_scope,\n",
+ " \"featureValueType\": fvt_scope,\n",
+ " \"spatialChannelVisible\": True,\n",
+ " \"spatialChannelColor\": [218, 161, 66],\n",
+ " \"spatialChannelOpacity\": 1.0,\n",
+ " \"obsColorEncoding\": \"spatialChannelColor\",\n",
+ " \"featureValueColormapRange\": [0, 1],\n",
+ " \"featureAggregationStrategy\": \"first\",\n",
+ " \"spatialSegmentationFilled\": False,\n",
+ " \"obsHighlight\": None,\n",
+ " }]),\n",
+ " },\n",
+ " {\n",
+ " \"fileUid\": \"labels_peritubular_capillaries\",\n",
+ " \"segmentationChannel\": CL([{\n",
+ " \"spatialTargetC\": 0,\n",
+ " \"obsType\": pt_ot_scope,\n",
+ " \"featureType\": ft_scope,\n",
+ " \"featureValueType\": fvt_scope,\n",
+ " \"featureSelection\": pt_fs_scope,\n",
+ " \"spatialChannelVisible\": True,\n",
+ " \"spatialChannelColor\": [197, 101, 47],\n",
+ " \"spatialChannelOpacity\": 1.0,\n",
+ " \"obsColorEncoding\": pt_oce_scope,\n",
+ " \"featureValueColormapRange\": [0, 0.5],\n",
+ " \"featureAggregationStrategy\": \"first\",\n",
+ " \"spatialSegmentationFilled\": True,\n",
+ " \"obsHighlight\": None,\n",
+ " }]),\n",
+ " }\n",
+ " ]),\n",
+ "}, meta=True, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"obsSegmentations\"))\n",
+ "\n",
+ "tubules_feature_list.use_coordination(t_ot_scope, ft_scope, fvt_scope, t_fs_scope, t_oce_scope)\n",
+ "tubules_histogram.use_coordination(t_ot_scope, ft_scope, fvt_scope, t_fs_scope, t_oce_scope)\n",
+ "\n",
+ "pt_feature_list.use_coordination(pt_ot_scope, ft_scope, fvt_scope, pt_fs_scope, pt_oce_scope)\n",
+ "pt_histogram.use_coordination(pt_ot_scope, ft_scope, fvt_scope, pt_fs_scope, pt_oce_scope)\n",
+ "\n",
+ "pt_sets.use_coordination(pt_ot_scope, ft_scope, fvt_scope, pt_fs_scope, pt_oce_scope)\n",
+ "pt_bar_plot.use_coordination(pt_ot_scope, ft_scope, fvt_scope, pt_fs_scope, pt_oce_scope)\n",
+ "pt_violin_plot.use_coordination(pt_ot_scope, ft_scope, fvt_scope, pt_fs_scope, pt_oce_scope)\n",
+ "\n",
+ "\n",
+ "gsg_feature_list.use_coordination(gsg_ot_scope, ft_scope, fvt_scope, gsg_fs_scope, gsg_oce_scope, gsg_fvcr_scope)\n",
+ "gsg_histogram.use_coordination(gsg_ot_scope, ft_scope, fvt_scope, gsg_fs_scope, gsg_oce_scope, gsg_fvcr_scope)\n",
+ "\n",
+ "ngsg_feature_list.use_coordination(ngsg_ot_scope, ft_scope, fvt_scope, ngsg_fs_scope, ngsg_oce_scope, ngsg_fvcr_scope)\n",
+ "ngsg_histogram.use_coordination(ngsg_ot_scope, ft_scope, fvt_scope, ngsg_fs_scope, ngsg_oce_scope, ngsg_fvcr_scope)\n",
+ "\n",
+ "\n",
+ "# Layout the views in a grid arrangement.\n",
+ "vc.layout(vconcat(\n",
+ " hconcat(spatial, layer_controller, split=[3, 1]),\n",
+ " hconcat(\n",
+ " (tubules_feature_list / tubules_histogram),\n",
+ " (pt_feature_list / pt_histogram),\n",
+ " (gsg_feature_list / gsg_histogram),\n",
+ " (ngsg_feature_list / ngsg_histogram)\n",
+ " ),\n",
+ " hconcat(pt_sets, pt_bar_plot, pt_violin_plot)\n",
+ "));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "## Import dependencies"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {},
+ "source": [
+ "## Configure Vitessce"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget(height=1000)\n",
+ "vw"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/spatial_data_merfish.ipynb b/docs/notebooks/__ipynb__/spatial_data_merfish.ipynb
new file mode 100644
index 00000000..e525bde6
--- /dev/null
+++ b/docs/notebooks/__ipynb__/spatial_data_merfish.ipynb
@@ -0,0 +1,193 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "sdata_url = \"https://data-2.vitessce.io/data/moffitt/merfish_mouse_ileum.sdata.zarr\""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " ViewType as vt,\n",
+ " CoordinationType as ct,\n",
+ " CoordinationLevel as CL,\n",
+ " SpatialDataWrapper,\n",
+ " get_initial_coordination_scope_prefix\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(\n",
+ " schema_version=\"1.0.18\",\n",
+ " name='SpatialData with MERFISH data',\n",
+ ")\n",
+ "# Add data to the configuration:\n",
+ "\n",
+ "dataset = vc.add_dataset(name='MERFISH').add_object(SpatialDataWrapper(\n",
+ " sdata_url=sdata_url,\n",
+ " # The following paths are relative to the root of the SpatialData zarr store on-disk.\n",
+ " image_path=\"images/stains\",\n",
+ " coordinate_system=\"global\",\n",
+ " coordination_values={\n",
+ " \"fileUid\": \"stains\"\n",
+ " }\n",
+ ")).add_object(SpatialDataWrapper(\n",
+ " sdata_url=sdata_url,\n",
+ " # The following paths are relative to the root of the SpatialData zarr store on-disk.\n",
+ " obs_segmentations_path=\"labels/dapi_labels\",\n",
+ " coordinate_system=\"global\",\n",
+ " coordination_values={\n",
+ " \"obsType\": \"nucleus\",\n",
+ " \"fileUid\": \"dapi\"\n",
+ " }\n",
+ ")).add_object(SpatialDataWrapper(\n",
+ " sdata_url=sdata_url,\n",
+ " # The following paths are relative to the root of the SpatialData zarr store on-disk.\n",
+ " obs_segmentations_path=\"labels/membrane_labels\",\n",
+ " coordinate_system=\"global\",\n",
+ " coordination_values={\n",
+ " \"obsType\": \"cell\",\n",
+ " \"fileUid\": \"membrane\"\n",
+ " }\n",
+ "))\n",
+ "\n",
+ "# Add views (visualizations) to the configuration:\n",
+ "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
+ "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
+ "\n",
+ "vc.link_views_by_dict([spatial, layer_controller], {\n",
+ " 'imageLayer': CL([{\n",
+ " \"fileUid\": \"stains\",\n",
+ " 'photometricInterpretation': 'BlackIsZero',\n",
+ " 'spatialLayerOpacity': 1.0,\n",
+ " 'spatialLayerVisible': True,\n",
+ " 'imageChannel': CL([\n",
+ " {\n",
+ " 'spatialChannelVisible': True,\n",
+ " \"spatialTargetC\": 0, # DAPI, Nucleus\n",
+ " \"spatialChannelColor\": [0, 0, 255],\n",
+ " \"spatialChannelOpacity\": 1.0\n",
+ " },\n",
+ " {\n",
+ " 'spatialChannelVisible': True,\n",
+ " \"spatialTargetC\": 1, # Membrane, Cell\n",
+ " \"spatialChannelColor\": [255, 255, 255],\n",
+ " \"spatialChannelOpacity\": 1.0\n",
+ " }\n",
+ " ])\n",
+ " }]),\n",
+ "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
+ "\n",
+ "vc.link_views_by_dict([spatial, layer_controller], {\n",
+ " 'segmentationLayer': CL([{\n",
+ " \"fileUid\": \"membrane\",\n",
+ " 'spatialLayerOpacity': 1.0,\n",
+ " 'spatialLayerVisible': True,\n",
+ " 'segmentationChannel': CL([{\n",
+ " 'spatialChannelVisible': True,\n",
+ " 'obsType': 'cell',\n",
+ " \"spatialChannelColor\": [200, 200, 200],\n",
+ " \"obsColorEncoding\": \"spatialChannelColor\",\n",
+ " }]),\n",
+ " }, {\n",
+ " \"fileUid\": \"dapi\",\n",
+ " 'spatialLayerOpacity': 1.0,\n",
+ " 'spatialLayerVisible': True,\n",
+ " 'segmentationChannel': CL([{\n",
+ " 'spatialChannelVisible': True,\n",
+ " 'obsType': 'nucleus',\n",
+ " \"spatialChannelColor\": [255, 255, 255],\n",
+ " \"obsColorEncoding\": \"spatialChannelColor\",\n",
+ " }]),\n",
+ " }]),\n",
+ "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"obsSegmentations\"))\n",
+ "\n",
+ "# Layout the views\n",
+ "vc.layout(spatial | layer_controller);"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Visualization of a SpatialData object, blobs example"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "SFPL",
+ "metadata": {},
+ "source": [
+ "### Render the widget"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "PKri",
+ "metadata": {},
+ "source": [
+ "## Configure Vitessce\n",
+ "\n",
+ "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {},
+ "source": [
+ "## Import dependencies"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/spatial_data_merfish_2.ipynb b/docs/notebooks/__ipynb__/spatial_data_merfish_2.ipynb
new file mode 100644
index 00000000..d3111b15
--- /dev/null
+++ b/docs/notebooks/__ipynb__/spatial_data_merfish_2.ipynb
@@ -0,0 +1,165 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from os.path import join, isfile, isdir\n",
+ "from urllib.request import urlretrieve\n",
+ "import zipfile\n",
+ "\n",
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " ViewType as vt,\n",
+ " CoordinationType as ct,\n",
+ " CoordinationLevel as CL,\n",
+ " SpatialDataWrapper,\n",
+ " get_initial_coordination_scope_prefix\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Kclp",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "data_dir = \"data\"\n",
+ "zip_filepath = join(data_dir, \"merfish_2.spatialdata.zarr.zip\")\n",
+ "spatialdata_filepath = join(data_dir, \"merfish_2.spatialdata.zarr\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Visualization of a SpatialData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Xref",
+ "metadata": {},
+ "source": [
+ "## Configure Vitessce\n",
+ "\n",
+ "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {},
+ "source": [
+ "## Import dependencies"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "BYtC",
+ "metadata": {},
+ "source": [
+ "### Render the widget"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "if not isdir(spatialdata_filepath):\n",
+ " if not isfile(zip_filepath):\n",
+ " os.makedirs(data_dir, exist_ok=True)\n",
+ " urlretrieve('https://s3.embl.de/spatialdata/spatialdata-sandbox/merfish.zip', zip_filepath)\n",
+ " with zipfile.ZipFile(zip_filepath,\"r\") as zip_ref:\n",
+ " zip_ref.extractall(data_dir)\n",
+ " os.rename(join(data_dir, \"data.zarr\"), spatialdata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(\n",
+ " schema_version=\"1.0.18\",\n",
+ " name='MERFISH SpatialData Demo',\n",
+ ")\n",
+ "# Add data to the configuration:\n",
+ "wrapper = SpatialDataWrapper(\n",
+ " sdata_path=spatialdata_filepath,\n",
+ " # The following paths are relative to the root of the SpatialData zarr store on-disk.\n",
+ " image_path=\"images/rasterized\",\n",
+ " table_path=\"tables/table\",\n",
+ " obs_feature_matrix_path=\"tables/table/X\",\n",
+ " obs_spots_path=\"shapes/cells\",\n",
+ " coordinate_system=\"global\",\n",
+ " coordination_values={\n",
+ " # The following tells Vitessce to consider each observation as a \"spot\"\n",
+ " \"obsType\": \"cell\",\n",
+ " }\n",
+ ")\n",
+ "dataset = vc.add_dataset(name='MERFISH').add_object(wrapper)\n",
+ "\n",
+ "# Add views (visualizations) to the configuration:\n",
+ "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
+ "feature_list = vc.add_view(\"featureList\", dataset=dataset)\n",
+ "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
+ "obs_sets = vc.add_view(\"obsSets\", dataset=dataset)\n",
+ "\n",
+ "vc.link_views_by_dict([spatial, layer_controller], {\n",
+ " 'spotLayer': CL([{\n",
+ " 'obsType': 'cell',\n",
+ " }]),\n",
+ "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"obsSpots\"))\n",
+ "\n",
+ "vc.link_views([spatial, layer_controller, feature_list, obs_sets], ['obsType'], [wrapper.obs_type_label])\n",
+ "\n",
+ "# Layout the views\n",
+ "vc.layout(spatial | (feature_list / layer_controller / obs_sets));"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/spatial_data_mouseliver.ipynb b/docs/notebooks/__ipynb__/spatial_data_mouseliver.ipynb
new file mode 100644
index 00000000..6cdf2b57
--- /dev/null
+++ b/docs/notebooks/__ipynb__/spatial_data_mouseliver.ipynb
@@ -0,0 +1,694 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from os.path import join, isfile, isdir\n",
+ "from urllib.request import urlretrieve\n",
+ "import zipfile\n",
+ "import json"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " ViewType as vt,\n",
+ " CoordinationType as ct,\n",
+ " CoordinationLevel as CL,\n",
+ " SpatialDataWrapper,\n",
+ " AnnDataWrapper,\n",
+ " ImageOmeTiffWrapper,\n",
+ " ImageOmeZarrWrapper,\n",
+ " ObsSegmentationsOmeZarrWrapper,\n",
+ " get_initial_coordination_scope_prefix,\n",
+ " hconcat,\n",
+ " vconcat,\n",
+ ")\n",
+ "from vitessce.data_utils import (\n",
+ " VAR_CHUNK_SIZE,\n",
+ " generate_h5ad_ref_spec,\n",
+ " multiplex_img_to_ome_tiff,\n",
+ " multiplex_img_to_ome_zarr,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Hstk",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import numpy as np\n",
+ "from spatialdata import read_zarr\n",
+ "from anndata import AnnData\n",
+ "from ome_zarr.writer import write_image\n",
+ "import tifffile\n",
+ "from generate_tiff_offsets import get_offsets"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "EJmg",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ZHCJ",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "data_dir = \"data\"\n",
+ "zip_filepath = join(data_dir, \"mouse_liver.spatialdata.zarr.zip\")\n",
+ "spatialdata_filepath = join(data_dir, \"mouse_liver.spatialdata.zarr\")\n",
+ "adata_zarr_filepath = join(data_dir, \"mouse_liver.anndata.zarr\")\n",
+ "adata_h5ad_filepath = join(data_dir, \"mouse_liver.h5ad\")\n",
+ "ref_spec_json_filepath = join(data_dir, \"mouse_liver.h5ad.ref.json\")\n",
+ "ome_tiff_filepath = join(data_dir, \"mouse_liver.ome.tif\")\n",
+ "offsets_json_filepath = join(data_dir, \"mouse_liver.ome.tif.offsets.json\")\n",
+ "ome_zarr_filepath = join(data_dir, \"mouse_liver.ome.zarr\")\n",
+ "labels_ome_zarr_filepath = join(data_dir, \"mouse_liver.labels.ome.zarr\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ZBYS",
+ "metadata": {},
+ "source": [
+ "## Extract AnnData object from SpatialData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "iLit",
+ "metadata": {},
+ "source": [
+ "We download a mouse liver dataset which serves as a SpatialData [example dataset](https://github.com/scverse/spatialdata-notebooks/blob/main/notebooks/examples/transformations.ipynb).\n",
+ "\n",
+ "This dataset was generated by [Guilliams et al.](https://doi.org/10.1016/j.cell.2021.12.018) and processed using [SPArrOW](https://doi.org/10.1101/2024.07.04.601829) during the SpatialData [developer workshop](https://doi.org/10.37044/osf.io/8ck3e) in 2024."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "aLJB",
+ "metadata": {},
+ "source": [
+ "The above example demonstrates how to visualize a spatial 'omics dataset containing not only single-cell information (e.g., a cell-by-gene expression matrix, cell type annotations) but also an image and cell segmentations.\n",
+ "To demonstrate how to use Vitessce to visualize data from a (non-spatial) single-cell experiment, we will extract this information from the SpatialData object and save it to a simpler [AnnData](https://anndata.readthedocs.io/) object (ignoring the imaging and spatially-resolved elements)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "mWxS",
+ "metadata": {},
+ "source": [
+ "To efficiently visualize OME-TIFF data using Vitessce, a JSON-based offsets file can be constructed using [generate-tiff-offsets](https://github.com/hms-dbmi/generate-tiff-offsets).\n",
+ "This JSON file contains byte offsets into different partitions of the TIFF file, effectively resulting in an \"indexed TIFF\" which is described by [Manz et al. 2022](https://doi.org/10.1038/s41592-022-01482-7)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ecfG",
+ "metadata": {},
+ "source": [
+ "### Render the widget"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "wAgl",
+ "metadata": {},
+ "source": [
+ "### H5AD-based AnnData"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "iXej",
+ "metadata": {},
+ "source": [
+ "## Data location options\n",
+ "\n",
+ "Vitessce can visualize data [not only stored](https://python-docs.vitessce.io/data_options.html) locally (referenced using local file or directory paths) but also stored remotely (referenced using absolute URL paths).\n",
+ "Depending on whether the Python kernel running the Jupyter process is running locally versus remotely (e.g., on a cluster or cloud platform such as Google Colab), certain data locations may be challenging to access from the machine running the Jupyter notebook frontend (i.e., the machine on which the web browser used to view the notebook is installed).\n",
+ "\n",
+ "To provide data via one of these alternative mechanisms, use parameters with the following suffices when instantiating the data wrapper classes.\n",
+ "\n",
+ "- `_path`: Local file or directory\n",
+ "- `_url`: Remote file or directory\n",
+ "- `_store`: Zarr-store-accessible (for zarr-based formats)\n",
+ "- `_artifact`: Lamin artifact\n",
+ "\n",
+ "For example, `adata_path` can be exchanged for one of the following options.\n",
+ "\n",
+ "```diff\n",
+ "AnnDataWrapper(\n",
+ "- adata_path=\"./mouse_liver.spatialdata.zarr\",\n",
+ "+ adata_url=\"https://example.com/mouse_liver.spatialdata.zarr\", # Absolute URL\n",
+ "+ adata_store=\"./mouse_liver.spatialdata.zarr\", # String interpreted as root of DirectoryStore\n",
+ "+ adata_store=zarr.DirectoryStore(\"./mouse_liver.spatialdata.zarr\"), # Instance of zarr.storage\n",
+ "+ adata_artifact=adata_zarr_artifact, # Instance of ln.Artifact\n",
+ " ...\n",
+ "```\n",
+ "\n",
+ "Note that the `_store` options are only available for Zarr-based formats, such as AnnDataWrapper, SpatialDataWrapper, and ImageOmeZarrWrapper.\n",
+ "Further, when multiple files are required, such as both `adata_path` and `ref_path` (for the JSON reference specification file accompanying an H5AD file) or `img_path` and `offsets_path`, multiple parameter suffices may need to be changed."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "YWSi",
+ "metadata": {},
+ "source": [
+ "## Visualization of an image file"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "BYtC",
+ "metadata": {},
+ "source": [
+ "Here, we import classes and functions from the `vitessce` Python package.\n",
+ "This package includes not only APIs for [visualization configuration](https://python-docs.vitessce.io/api_config.html) but also [helper functions](https://python-docs.vitessce.io/api_data.html#vitessce-data-utils) for basic data transformation tasks.\n",
+ "To specify mappings between data fields and visualization properties, the package contains [classes](https://python-docs.vitessce.io/api_data.html#module-vitessce.wrappers) which wrap standard single-cell data structures stored in formats including [AnnData](https://doi.org/10.1101/2021.12.16.473007), [SpatialData](https://doi.org/10.1038/s41592-024-02212-x), [OME-TIFF](https://doi.org/10.1007/978-3-030-23937-4_1), and [OME-Zarr](https://doi.org/10.1038/s41592-021-01326-w):\n",
+ "\n",
+ "- [AnnDataWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.AnnDataWrapper)\n",
+ "- [ImageOmeTiffWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ImageOmeTiffWrapper)\n",
+ "- [ImageOmeZarrWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ImageOmeZarrWrapper)\n",
+ "- [ObsSegmentationsOmeTiffWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ObsSegmentationsOmeTiffWrapper)\n",
+ "- [ObsSegmentationsOmeZarrWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ObsSegmentationsOmeZarrWrapper)\n",
+ "- [SpatialDataWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.SpatialDataWrapper)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "PKri",
+ "metadata": {},
+ "source": [
+ "First, we import utility dependencies which will be used to download the example dataset and manipulate file paths, zip files, and JSON files."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "SFPL",
+ "metadata": {},
+ "source": [
+ "## Dependencies for Vitessce"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "TqIu",
+ "metadata": {},
+ "source": [
+ "## Visualization of a SpatialData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "zlud",
+ "metadata": {},
+ "source": [
+ "### OME-Zarr image"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "dNNg",
+ "metadata": {},
+ "source": [
+ "## Visualization of an AnnData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "AjVT",
+ "metadata": {},
+ "source": [
+ "As Zarr-formatted data can be easily visualized by Vitessce, we recommend saving the AnnData object to a Zarr store using the [write_zarr](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_zarr.html) method.\n",
+ "Optionally, the shape of array chunks (for the AnnData `X` array) can be specified as a parameter, to optimize performance based on data access patterns.\n",
+ "For example, a common pattern is to visualize data across all cells for one gene.\n",
+ "To support such a pattern, the chunk shape can be specified as follows, `(total number of cells, small number of genes)`, resulting in tall-and-skinny array chunks."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "nWHF",
+ "metadata": {},
+ "source": [
+ "## Download example dataset"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "LJZf",
+ "metadata": {},
+ "source": [
+ "For small images, the data can be saved to OME-Zarr or OME-TIFF format using [utility functions](https://python-docs.vitessce.io/api_data.html#vitessce-data-utils) from the Vitessce package.\n",
+ "Larger images require generation of an [image pyramid](https://en.wikipedia.org/wiki/Pyramid_(image_processing)), which can be performed using tools from the OME ecosystem such as [bioformats2raw](https://github.com/glencoesoftware/bioformats2raw) and [raw2ometiff](https://github.com/glencoesoftware/raw2ometiff)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "yCnT",
+ "metadata": {},
+ "source": [
+ "### Zarr-based AnnData"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {},
+ "source": [
+ "This notebook explains how to create interactive visualizations of data that is accessible locally.\n",
+ "\n",
+ "\n",
+ "We progress through different visualization tasks, first demonstrating how Vitessce facilitates integrated imaging and spatial single-cell visualizations, then demonstrating visualization of non-spatial and image-only datasets."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "emfo",
+ "metadata": {},
+ "source": [
+ "In this blog post, we perform basic data transformation tasks to save individual elements of an integrated SpatialData object to separate files in AnnData, OME-TIFF, and OME-Zarr formats.\n",
+ "To perform these data transformations, we import the following dependencies.\n",
+ "In general, you will typically not need to import all of these dependencies, either because you are only working with data in one of these formats, or because the data you intend to visualize is already saved to a file or directory.\n",
+ "\n",
+ "Note: Dependencies such as `spatialdata` may need to be installed before they can be imported in the next code cell."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Kclp",
+ "metadata": {},
+ "source": [
+ "## Dependencies for data structures"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ROlb",
+ "metadata": {},
+ "source": [
+ "The following code uses Python's `urlretrieve` to download the SpatialData object as a zip file, then unzips the file using the `zipfile` module."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "DnEU",
+ "metadata": {},
+ "source": [
+ "## Configure Vitessce\n",
+ "\n",
+ "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views.\n",
+ "To visualize data stored in a SpatialData object, we use the `SpatialDataWrapper` class and specify the paths (relative to the root of the Zarr [directory store](https://zarr.readthedocs.io/en/v2.18.5/api/storage.html#zarr.storage.DirectoryStore)) to different spatial elements of interest."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lgWD",
+ "metadata": {},
+ "source": [
+ "In contrast to extraction of the non-spatial data from the SpatialData object, we can extract the imaging (and segmentation/label image) data and save it to a dedicated bioimaging file format."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {},
+ "source": [
+ "## Utility dependencies"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "SdmI",
+ "metadata": {},
+ "source": [
+ "## Extract image from SpatialData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Visualization of a SpatialData object and individual Spatial Elements, local data"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "fwwy",
+ "metadata": {},
+ "source": [
+ "### Save image to OME-Zarr"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Vxnm",
+ "metadata": {},
+ "source": [
+ "SpatialData objects are the most complex type of data structure we will work with in this blog post.\n",
+ "SpatialData objects function as contains for multiple types of Spatial Elements:\n",
+ "\n",
+ "- Tables (each table is represented as an AnnData object)\n",
+ "- Points (e.g., coordinates of transcripts from FISH-based experiments)\n",
+ "- Shapes (vector-based shapes such as polygons and circles)\n",
+ "- Labels (label images, i.e., segmentation bitmasks; each label image is stored using OME-Zarr)\n",
+ "- Images (microscopy images; each image is stored using OME-Zarr)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "CLip",
+ "metadata": {},
+ "source": [
+ "### OME-TIFF image"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "jxvo",
+ "metadata": {},
+ "source": [
+ "### Save image and segmentations to OME-TIFF"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "TRpd",
+ "metadata": {},
+ "source": [
+ "To read H5AD-formatted data, Vitessce requires an accompanying JSON [references specification](https://fsspec.github.io/kerchunk/spec.html) file, which can be constructed using the `generate_h5ad_ref_spec` utility function."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {},
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "NCOB",
+ "metadata": {},
+ "source": [
+ "Alternatively, your AnnData object may already be stored using the H5AD (HDF5-based) format.\n",
+ "To demonstrate this scenario, we save the object using the [write_h5ad](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_h5ad.html) method."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ulZA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version='1.0.18', name='SpatialData Demo')\n",
+ "_wrapper = SpatialDataWrapper(sdata_path=spatialdata_filepath, table_path='tables/table', image_path='images/raw_image', obs_segmentations_path='labels/segmentation_mask', obs_feature_matrix_path='tables/table/X', obs_set_paths=['tables/table/obs/annotation'], obs_set_names=['Annotation'], region='nucleus_boundaries', coordinate_system='global', coordination_values={'obsType': 'cell'})\n",
+ "_dataset = vc.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
+ "_spatial = vc.add_view('spatialBeta', dataset=_dataset)\n",
+ "feature_list = vc.add_view('featureList', dataset=_dataset)\n",
+ "_layer_controller = vc.add_view('layerControllerBeta', dataset=_dataset)\n",
+ "obs_sets = vc.add_view('obsSets', dataset=_dataset)\n",
+ "_heatmap = vc.add_view('heatmap', dataset=_dataset)\n",
+ "[obs_color_encoding_scope] = vc.add_coordination('obsColorEncoding')\n",
+ "obs_color_encoding_scope.set_value('cellSetSelection')\n",
+ "vc.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))\n",
+ "vc.link_views_by_dict([_spatial, _layer_controller], {'segmentationLayer': CL([{'segmentationChannel': CL([{'obsColorEncoding': obs_color_encoding_scope}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'obsSegmentations'))\n",
+ "vc.link_views([_spatial, _layer_controller, feature_list, obs_sets, _heatmap], ['obsType'], [_wrapper.obs_type_label])\n",
+ "vc.link_views_by_dict([feature_list, obs_sets, _heatmap], {'obsColorEncoding': obs_color_encoding_scope}, meta=False)\n",
+ "vc.layout(_spatial / _heatmap | _layer_controller / (feature_list | obs_sets))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "nHfw",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "sdata = read_zarr(spatialdata_filepath)\n",
+ "sdata"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "wlCL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc_1 = VitessceConfig(schema_version='1.0.18', name='AnnData (zarr)')\n",
+ "_wrapper = AnnDataWrapper(adata_path=adata_zarr_filepath, obs_feature_matrix_path='X', obs_set_paths=['obs/annotation'], obs_set_names=['Annotation'], coordination_values={'obsType': 'cell'})\n",
+ "_dataset = vc_1.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
+ "_heatmap = vc_1.add_view(vt.HEATMAP, dataset=_dataset)\n",
+ "feature_list_1 = vc_1.add_view(vt.FEATURE_LIST, dataset=_dataset)\n",
+ "obs_sets_1 = vc_1.add_view(vt.OBS_SETS, dataset=_dataset)\n",
+ "_violin_plots = vc_1.add_view('obsSetFeatureValueDistribution', dataset=_dataset)\n",
+ "vc_1.link_views([_heatmap, feature_list_1, obs_sets_1], ['obsType', 'featureValueColormapRange'], ['cell', [0, 0.01]])\n",
+ "vc_1.layout(_heatmap / _violin_plots | feature_list_1 / obs_sets_1)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "qnkX",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "if not isdir(spatialdata_filepath):\n",
+ " if not isfile(zip_filepath):\n",
+ " os.makedirs(data_dir, exist_ok=True)\n",
+ " urlretrieve('https://s3.embl.de/spatialdata/spatialdata-sandbox/mouse_liver.zip', zip_filepath)\n",
+ " with zipfile.ZipFile(zip_filepath,\"r\") as zip_ref:\n",
+ " zip_ref.extractall(data_dir)\n",
+ " os.rename(join(data_dir, \"data.zarr\"), spatialdata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "YECM",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc_4 = VitessceConfig(schema_version='1.0.18', name='Image and segmentations (ome-tiff)')\n",
+ "_wrapper = ImageOmeTiffWrapper(img_path=ome_tiff_filepath, offsets_path=offsets_json_filepath)\n",
+ "_dataset = vc_4.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
+ "_spatial = vc_4.add_view('spatialBeta', dataset=_dataset)\n",
+ "_layer_controller = vc_4.add_view('layerControllerBeta', dataset=_dataset)\n",
+ "vc_4.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))\n",
+ "vc_4.layout(hconcat(_spatial, _layer_controller, split=(2, 1)))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "TXez",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ref_dict = generate_h5ad_ref_spec(adata_h5ad_filepath)\n",
+ "with open(ref_spec_json_filepath, 'w') as _f:\n",
+ " json.dump(ref_dict, _f)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "rEll",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc_2 = VitessceConfig(schema_version='1.0.18', name='AnnData (h5ad)')\n",
+ "_wrapper = AnnDataWrapper(adata_path=adata_h5ad_filepath, ref_path=ref_spec_json_filepath, obs_feature_matrix_path='X', obs_set_paths=['obs/annotation'], obs_set_names=['Annotation'], coordination_values={'obsType': 'cell'})\n",
+ "_dataset = vc_2.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
+ "_heatmap = vc_2.add_view(vt.HEATMAP, dataset=_dataset)\n",
+ "feature_list_2 = vc_2.add_view(vt.FEATURE_LIST, dataset=_dataset)\n",
+ "obs_sets_2 = vc_2.add_view(vt.OBS_SETS, dataset=_dataset)\n",
+ "_violin_plots = vc_2.add_view('obsSetFeatureValueDistribution', dataset=_dataset)\n",
+ "vc_2.link_views([_heatmap, feature_list_2, obs_sets_2], ['obsType', 'featureValueColormapRange'], ['cell', [0, 0.01]])\n",
+ "vc_2.layout(_heatmap / _violin_plots | feature_list_2 / obs_sets_2)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Pvdt",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "_vw = vc.widget()\n",
+ "_vw"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "yOPj",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "img_arr = sdata.images['raw_image'].to_numpy()\n",
+ "labels_arr = sdata.labels['segmentation_mask'].to_numpy()\n",
+ "labels_arr = labels_arr[np.newaxis, :]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "xXTn",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata = sdata.tables['table']\n",
+ "adata"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "kqZH",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc_1.widget()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "cEAS",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc_4.widget()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "dGlV",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc_2.widget()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "tZnO",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc_3 = VitessceConfig(schema_version='1.0.18', name='Image (ome-zarr)')\n",
+ "img_wrapper = ImageOmeZarrWrapper(img_path=ome_zarr_filepath, coordination_values={'fileUid': 'image'})\n",
+ "segmentations_wrapper = ObsSegmentationsOmeZarrWrapper(img_path=labels_ome_zarr_filepath, coordination_values={'fileUid': 'segmentations'})\n",
+ "_dataset = vc_3.add_dataset(name='Mouse Liver').add_object(img_wrapper).add_object(segmentations_wrapper)\n",
+ "_spatial = vc_3.add_view('spatialBeta', dataset=_dataset)\n",
+ "_layer_controller = vc_3.add_view('layerControllerBeta', dataset=_dataset)\n",
+ "vc_3.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'fileUid': 'image', 'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))\n",
+ "vc_3.link_views_by_dict([_spatial, _layer_controller], {'segmentationLayer': CL([{'fileUid': 'segmentations', 'segmentationChannel': CL([{'obsColorEncoding': 'spatialChannelColor', 'spatialChannelColor': [0, 255, 0], 'spatialChannelOpacity': 0.75, 'spatialSegmentationFilled': False, 'spatialSegmentationStrokeWidth': 0.25}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'obsSegmentations'))\n",
+ "vc_3.link_views([_spatial, _layer_controller, feature_list_2, obs_sets_2], ['obsType'], ['cell'])\n",
+ "vc_3.layout(hconcat(_spatial, _layer_controller, split=(2, 1)))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "CcZR",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "multiplex_img_to_ome_tiff(img_arr, ['Channel 0'], ome_tiff_filepath)\n",
+ "offsets = get_offsets(ome_tiff_filepath)\n",
+ "with open(offsets_json_filepath, 'w') as _f:\n",
+ " json.dump(offsets, _f)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "urSm",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "multiplex_img_to_ome_zarr(img_arr, [\"Channel 0\"], ome_zarr_filepath)\n",
+ "multiplex_img_to_ome_zarr(labels_arr, [\"cell\"], labels_ome_zarr_filepath)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "pHFh",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata.write_zarr(adata_zarr_filepath, chunks=(adata.shape[0], VAR_CHUNK_SIZE))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "aqbW",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata.write_h5ad(adata_h5ad_filepath)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "xvXZ",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "_vw = vc_3.widget()\n",
+ "_vw"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/spatial_data_mouseliver_remote.ipynb b/docs/notebooks/__ipynb__/spatial_data_mouseliver_remote.ipynb
new file mode 100644
index 00000000..c5b5dc07
--- /dev/null
+++ b/docs/notebooks/__ipynb__/spatial_data_mouseliver_remote.ipynb
@@ -0,0 +1,514 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from os.path import join, isfile, isdir\n",
+ "from urllib.request import urlretrieve\n",
+ "import zipfile\n",
+ "import json"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " ViewType as vt,\n",
+ " CoordinationType as ct,\n",
+ " CoordinationLevel as CL,\n",
+ " SpatialDataWrapper,\n",
+ " AnnDataWrapper,\n",
+ " ImageOmeTiffWrapper,\n",
+ " ImageOmeZarrWrapper,\n",
+ " ObsSegmentationsOmeZarrWrapper,\n",
+ " get_initial_coordination_scope_prefix,\n",
+ " hconcat,\n",
+ " vconcat,\n",
+ ")\n",
+ "from vitessce.data_utils import (\n",
+ " VAR_CHUNK_SIZE,\n",
+ " generate_h5ad_ref_spec,\n",
+ " multiplex_img_to_ome_tiff,\n",
+ " multiplex_img_to_ome_zarr,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "nWHF",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "base_url = \"https://storage.googleapis.com/vitessce-demo-data/spatialdata-may-2025\""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SdmI",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "iLit",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "zip_filepath = f\"{base_url}/mouse_liver.spatialdata.zarr.zip\"\n",
+ "spatialdata_filepath = f\"{base_url}/mouse_liver.spatialdata.zarr\"\n",
+ "adata_zarr_filepath = f\"{base_url}/mouse_liver.anndata.zarr\"\n",
+ "adata_h5ad_filepath = f\"{base_url}/mouse_liver.h5ad\"\n",
+ "ref_spec_json_filepath = f\"{base_url}/mouse_liver.h5ad.ref.json\"\n",
+ "ome_tiff_filepath = f\"{base_url}/mouse_liver.ome.tif\"\n",
+ "offsets_json_filepath = f\"{base_url}/mouse_liver.ome.tif.offsets.json\"\n",
+ "ome_zarr_filepath = f\"{base_url}/mouse_liver.ome.zarr\"\n",
+ "labels_ome_zarr_filepath = f\"{base_url}/mouse_liver.labels.ome.zarr\""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {},
+ "source": [
+ "## Utility dependencies"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Vxnm",
+ "metadata": {},
+ "source": [
+ "### Render the widget"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ecfG",
+ "metadata": {},
+ "source": [
+ "The above example demonstrates how to visualize a spatial 'omics dataset containing not only single-cell information (e.g., a cell-by-gene expression matrix, cell type annotations) but also an image and cell segmentations.\n",
+ "To demonstrate how to use Vitessce to visualize data from a (non-spatial) single-cell experiment, we will extract this information from the SpatialData object and save it to a simpler [AnnData](https://anndata.readthedocs.io/) object (ignoring the imaging and spatially-resolved elements)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Pvdt",
+ "metadata": {},
+ "source": [
+ "As Zarr-formatted data can be easily visualized by Vitessce, we recommend saving the AnnData object to a Zarr store using the [write_zarr](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_zarr.html) method.\n",
+ "Optionally, the shape of array chunks (for the AnnData `X` array) can be specified as a parameter, to optimize performance based on data access patterns.\n",
+ "For example, a common pattern is to visualize data across all cells for one gene.\n",
+ "To support such a pattern, the chunk shape can be specified as follows, `(total number of cells, small number of genes)`, resulting in tall-and-skinny array chunks."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "PKri",
+ "metadata": {},
+ "source": [
+ "First, we import utility dependencies which will be used to download the example dataset and manipulate file paths, zip files, and JSON files."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "BYtC",
+ "metadata": {},
+ "source": [
+ "Here, we import classes and functions from the `vitessce` Python package.\n",
+ "This package includes not only APIs for [visualization configuration](https://python-docs.vitessce.io/api_config.html) but also [helper functions](https://python-docs.vitessce.io/api_data.html#vitessce-data-utils) for basic data transformation tasks.\n",
+ "To specify mappings between data fields and visualization properties, the package contains [classes](https://python-docs.vitessce.io/api_data.html#module-vitessce.wrappers) which wrap standard single-cell data structures stored in formats including [AnnData](https://doi.org/10.1101/2021.12.16.473007), [SpatialData](https://doi.org/10.1038/s41592-024-02212-x), [OME-TIFF](https://doi.org/10.1007/978-3-030-23937-4_1), and [OME-Zarr](https://doi.org/10.1038/s41592-021-01326-w):\n",
+ "\n",
+ "- [AnnDataWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.AnnDataWrapper)\n",
+ "- [ImageOmeTiffWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ImageOmeTiffWrapper)\n",
+ "- [ImageOmeZarrWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ImageOmeZarrWrapper)\n",
+ "- [ObsSegmentationsOmeTiffWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ObsSegmentationsOmeTiffWrapper)\n",
+ "- [ObsSegmentationsOmeZarrWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ObsSegmentationsOmeZarrWrapper)\n",
+ "- [SpatialDataWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.SpatialDataWrapper)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {},
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "kqZH",
+ "metadata": {},
+ "source": [
+ "### OME-TIFF image"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "xXTn",
+ "metadata": {},
+ "source": [
+ "### Zarr-based AnnData"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "SFPL",
+ "metadata": {},
+ "source": [
+ "## Dependencies for Vitessce"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ZBYS",
+ "metadata": {},
+ "source": [
+ "Alternatively, your AnnData object may already be stored using the H5AD (HDF5-based) format.\n",
+ "To demonstrate this scenario, we save the object using the [write_h5ad](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_h5ad.html) method."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "aLJB",
+ "metadata": {},
+ "source": [
+ "To read H5AD-formatted data, Vitessce requires an accompanying JSON [references specification](https://fsspec.github.io/kerchunk/spec.html) file, which can be constructed using the `generate_h5ad_ref_spec` utility function."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Kclp",
+ "metadata": {},
+ "source": [
+ "In this blog post, we perform basic data transformation tasks to save individual elements of an integrated SpatialData object to separate files in AnnData, OME-TIFF, and OME-Zarr formats.\n",
+ "To perform these data transformations, we import the following dependencies.\n",
+ "In general, you will typically not need to import all of these dependencies, either because you are only working with data in one of these formats, or because the data you intend to visualize is already saved to a file or directory."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "nHfw",
+ "metadata": {},
+ "source": [
+ "## Visualization of an AnnData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "dNNg",
+ "metadata": {},
+ "source": [
+ "### OME-Zarr image"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "emfo",
+ "metadata": {},
+ "source": [
+ "## Download example dataset"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "NCOB",
+ "metadata": {},
+ "source": [
+ "### H5AD-based AnnData"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ROlb",
+ "metadata": {},
+ "source": [
+ "SpatialData objects are the most complex type of data structure we will work with in this blog post.\n",
+ "SpatialData objects function as contains for multiple types of Spatial Elements:\n",
+ "\n",
+ "- Tables (each table is represented as an AnnData object)\n",
+ "- Points (e.g., coordinates of transcripts from FISH-based experiments)\n",
+ "- Shapes (vector-based shapes such as polygons and circles)\n",
+ "- Labels (label images, i.e., segmentation bitmasks; each label image is stored using OME-Zarr)\n",
+ "- Images (microscopy images; each image is stored using OME-Zarr)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ZHCJ",
+ "metadata": {},
+ "source": [
+ "## Visualization of a SpatialData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "dGlV",
+ "metadata": {},
+ "source": [
+ "## Data location options\n",
+ "\n",
+ "Vitessce can visualize data [not only stored](https://python-docs.vitessce.io/data_options.html) locally (referenced using local file or directory paths) but also stored remotely (referenced using absolute URL paths).\n",
+ "Depending on whether the Python kernel running the Jupyter process is running locally versus remotely (e.g., on a cluster or cloud platform such as Google Colab), certain data locations may be challenging to access from the machine running the Jupyter notebook frontend (i.e., the machine on which the web browser used to view the notebook is installed).\n",
+ "\n",
+ "To provide data via one of these alternative mechanisms, use parameters with the following suffices when instantiating the data wrapper classes.\n",
+ "\n",
+ "- `_path`: Local file or directory\n",
+ "- `_url`: Remote file or directory\n",
+ "- `_store`: Zarr-store-accessible (for zarr-based formats)\n",
+ "- `_artifact`: Lamin artifact\n",
+ "\n",
+ "For example, `adata_path` can be exchanged for one of the following options.\n",
+ "\n",
+ "```diff\n",
+ "AnnDataWrapper(\n",
+ "- adata_path=\"./mouse_liver.spatialdata.zarr\",\n",
+ "+ adata_url=\"https://example.com/mouse_liver.spatialdata.zarr\", # Absolute URL\n",
+ "+ adata_store=\"./mouse_liver.spatialdata.zarr\", # String interpreted as root of DirectoryStore\n",
+ "+ adata_store=zarr.DirectoryStore(\"./mouse_liver.spatialdata.zarr\"), # Instance of zarr.storage\n",
+ "+ adata_artifact=adata_zarr_artifact, # Instance of ln.Artifact\n",
+ " ...\n",
+ "```\n",
+ "\n",
+ "Note that the `_store` options are only available for Zarr-based formats, such as AnnDataWrapper, SpatialDataWrapper, and ImageOmeZarrWrapper.\n",
+ "Further, when multiple files are required, such as both `adata_path` and `ref_path` (for the JSON reference specification file accompanying an H5AD file) or `img_path` and `offsets_path`, multiple parameter suffices may need to be changed."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {},
+ "source": [
+ "This notebook explains how to create interactive visualizations of data that are accessible remotely.\n",
+ "\n",
+ "\n",
+ "We progress through different visualization tasks, first demonstrating how Vitessce facilitates integrated imaging and spatial single-cell visualizations, then demonstrating visualization of non-spatial and image-only datasets."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "qnkX",
+ "metadata": {},
+ "source": [
+ "## Configure Vitessce\n",
+ "\n",
+ "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views.\n",
+ "To visualize data stored in a SpatialData object, we use the `SpatialDataWrapper` class and specify the paths (relative to the root of the Zarr [directory store](https://zarr.readthedocs.io/en/v2.18.5/api/storage.html#zarr.storage.DirectoryStore)) to different spatial elements of interest."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ulZA",
+ "metadata": {},
+ "source": [
+ "## Extract AnnData object from SpatialData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "TXez",
+ "metadata": {},
+ "source": [
+ "## Visualization of an image file"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hstk",
+ "metadata": {},
+ "source": [
+ "We download a mouse liver dataset which serves as a SpatialData [example dataset](https://github.com/scverse/spatialdata-notebooks/blob/main/notebooks/examples/transformations.ipynb).\n",
+ "\n",
+ "This dataset was generated by [Guilliams et al.](https://doi.org/10.1016/j.cell.2021.12.018) and processed using [SPArrOW](https://doi.org/10.1101/2024.07.04.601829) during the SpatialData [developer workshop](https://doi.org/10.37044/osf.io/8ck3e) in 2024."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Visualization of a SpatialData object and individual Spatial Elements, remote data"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "aqbW",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc_2 = VitessceConfig(schema_version='1.0.18', name='AnnData (h5ad)')\n",
+ "_wrapper = AnnDataWrapper(adata_url=adata_h5ad_filepath, ref_url=ref_spec_json_filepath, obs_feature_matrix_path='X', obs_set_paths=['obs/annotation'], obs_set_names=['Annotation'], coordination_values={'obsType': 'cell'})\n",
+ "_dataset = vc_2.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
+ "_heatmap = vc_2.add_view(vt.HEATMAP, dataset=_dataset)\n",
+ "feature_list_2 = vc_2.add_view(vt.FEATURE_LIST, dataset=_dataset)\n",
+ "obs_sets_2 = vc_2.add_view(vt.OBS_SETS, dataset=_dataset)\n",
+ "_violin_plots = vc_2.add_view('obsSetFeatureValueDistribution', dataset=_dataset)\n",
+ "vc_2.link_views([_heatmap, feature_list_2, obs_sets_2], ['obsType', 'featureValueColormapRange'], ['cell', [0, 0.01]])\n",
+ "vc_2.layout(_heatmap / _violin_plots | feature_list_2 / obs_sets_2)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "TqIu",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version='1.0.18', name='SpatialData Demo')\n",
+ "_wrapper = SpatialDataWrapper(sdata_url=spatialdata_filepath, table_path='tables/table', image_path='images/raw_image', obs_segmentations_path='labels/segmentation_mask', obs_feature_matrix_path='tables/table/X', obs_set_paths=['tables/table/obs/annotation'], obs_set_names=['Annotation'], region='nucleus_boundaries', coordinate_system='global', coordination_values={'obsType': 'cell'})\n",
+ "_dataset = vc.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
+ "_spatial = vc.add_view('spatialBeta', dataset=_dataset)\n",
+ "feature_list = vc.add_view('featureList', dataset=_dataset)\n",
+ "_layer_controller = vc.add_view('layerControllerBeta', dataset=_dataset)\n",
+ "obs_sets = vc.add_view('obsSets', dataset=_dataset)\n",
+ "_heatmap = vc.add_view('heatmap', dataset=_dataset)\n",
+ "[obs_color_encoding_scope] = vc.add_coordination('obsColorEncoding')\n",
+ "obs_color_encoding_scope.set_value('cellSetSelection')\n",
+ "vc.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))\n",
+ "vc.link_views_by_dict([_spatial, _layer_controller], {'segmentationLayer': CL([{'segmentationChannel': CL([{'obsColorEncoding': obs_color_encoding_scope}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'obsSegmentations'))\n",
+ "vc.link_views([_spatial, _layer_controller, feature_list, obs_sets, _heatmap], ['obsType'], [_wrapper.obs_type_label])\n",
+ "vc.link_views_by_dict([feature_list, obs_sets, _heatmap], {'obsColorEncoding': obs_color_encoding_scope}, meta=False)\n",
+ "vc.layout(_spatial / _heatmap | _layer_controller / (feature_list | obs_sets))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "AjVT",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc_1 = VitessceConfig(schema_version='1.0.18', name='AnnData (zarr)')\n",
+ "_wrapper = AnnDataWrapper(adata_url=adata_zarr_filepath, obs_feature_matrix_path='X', obs_set_paths=['obs/annotation'], obs_set_names=['Annotation'], coordination_values={'obsType': 'cell'})\n",
+ "_dataset = vc_1.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
+ "_heatmap = vc_1.add_view(vt.HEATMAP, dataset=_dataset)\n",
+ "feature_list_1 = vc_1.add_view(vt.FEATURE_LIST, dataset=_dataset)\n",
+ "obs_sets_1 = vc_1.add_view(vt.OBS_SETS, dataset=_dataset)\n",
+ "_violin_plots = vc_1.add_view('obsSetFeatureValueDistribution', dataset=_dataset)\n",
+ "vc_1.link_views([_heatmap, feature_list_1, obs_sets_1], ['obsType', 'featureValueColormapRange'], ['cell', [0, 0.01]])\n",
+ "vc_1.layout(_heatmap / _violin_plots | feature_list_1 / obs_sets_1)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "wAgl",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc_4 = VitessceConfig(schema_version='1.0.18', name='Image and segmentations (ome-tiff)')\n",
+ "_wrapper = ImageOmeTiffWrapper(img_url=ome_tiff_filepath, offsets_url=offsets_json_filepath)\n",
+ "_dataset = vc_4.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
+ "_spatial = vc_4.add_view('spatialBeta', dataset=_dataset)\n",
+ "_layer_controller = vc_4.add_view('layerControllerBeta', dataset=_dataset)\n",
+ "vc_4.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))\n",
+ "vc_4.layout(hconcat(_spatial, _layer_controller, split=(2, 1)))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "TRpd",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc_2.widget()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "yCnT",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc_3 = VitessceConfig(schema_version='1.0.18', name='Image (ome-zarr)')\n",
+ "img_wrapper = ImageOmeZarrWrapper(img_url=ome_zarr_filepath, coordination_values={'fileUid': 'image'})\n",
+ "segmentations_wrapper = ObsSegmentationsOmeZarrWrapper(img_url=labels_ome_zarr_filepath, coordination_values={'fileUid': 'segmentations'})\n",
+ "_dataset = vc_3.add_dataset(name='Mouse Liver').add_object(img_wrapper).add_object(segmentations_wrapper)\n",
+ "_spatial = vc_3.add_view('spatialBeta', dataset=_dataset)\n",
+ "_layer_controller = vc_3.add_view('layerControllerBeta', dataset=_dataset)\n",
+ "vc_3.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'fileUid': 'image', 'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))\n",
+ "vc_3.link_views_by_dict([_spatial, _layer_controller], {'segmentationLayer': CL([{'fileUid': 'segmentations', 'segmentationChannel': CL([{'obsColorEncoding': 'spatialChannelColor', 'spatialChannelColor': [0, 255, 0], 'spatialChannelOpacity': 0.75, 'spatialSegmentationFilled': False, 'spatialSegmentationStrokeWidth': 0.25}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'obsSegmentations'))\n",
+ "vc_3.link_views([_spatial, _layer_controller, feature_list_2, obs_sets_2], ['obsType'], ['cell'])\n",
+ "vc_3.layout(hconcat(_spatial, _layer_controller, split=(2, 1)))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "DnEU",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "_vw = vc.widget(height=900)\n",
+ "_vw"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "pHFh",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc_1.widget()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "rEll",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc_4.widget()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "wlCL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "_vw = vc_3.widget()\n",
+ "_vw"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/spatial_data_visium_hd.ipynb b/docs/notebooks/__ipynb__/spatial_data_visium_hd.ipynb
new file mode 100644
index 00000000..ac735a78
--- /dev/null
+++ b/docs/notebooks/__ipynb__/spatial_data_visium_hd.ipynb
@@ -0,0 +1,241 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from os.path import join, isfile, isdir\n",
+ "from urllib.request import urlretrieve\n",
+ "import zipfile\n",
+ "\n",
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " ViewType as vt,\n",
+ " CoordinationType as ct,\n",
+ " CoordinationLevel as CL,\n",
+ " SpatialDataWrapper,\n",
+ " get_initial_coordination_scope_prefix\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from spatialdata import (\n",
+ " read_zarr,\n",
+ " rasterize_bins,\n",
+ " rasterize_bins_link_table_to_labels\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "iLit",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "data_dir = \"data\"\n",
+ "zip_filepath = join(data_dir, \"visium_hd_3.0.0_io.zip\")\n",
+ "spatialdata_filepath = join(data_dir, \"visium_hd_3.0.0.spatialdata.zarr\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Xref",
+ "metadata": {},
+ "source": [
+ "## Rasterize bins\n",
+ "Reference: https://spatialdata.scverse.org/en/stable/tutorials/notebooks/notebooks/examples/technology_visium_hd.html#performant-on-the-fly-data-rasterization"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Visualization of a SpatialData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {},
+ "source": [
+ "## Import dependencies"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Kclp",
+ "metadata": {},
+ "source": [
+ "## Configure Vitessce\n",
+ "\n",
+ "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hstk",
+ "metadata": {},
+ "source": [
+ "### Render the widget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "emfo",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(\n",
+ " schema_version=\"1.0.18\",\n",
+ " name='Visium HD SpatialData Demo',\n",
+ ")\n",
+ "# Add data to the configuration:\n",
+ "wrapper = SpatialDataWrapper(\n",
+ " sdata_path=spatialdata_filepath,\n",
+ " # The following paths are relative to the root of the SpatialData zarr store on-disk.\n",
+ " image_path=\"images/Visium_HD_Mouse_Small_Intestine_full_image\",\n",
+ " table_path=\"tables/square_016um\",\n",
+ " obs_feature_matrix_path=\"tables/square_016um/X\",\n",
+ " obs_segmentations_path=\"labels/rasterized_016um\",\n",
+ " #region=\"CytAssist_FFPE_Human_Breast_Cancer\",\n",
+ " coordinate_system=\"Visium_HD_Mouse_Small_Intestine\",\n",
+ " coordination_values={\n",
+ " # The following tells Vitessce to consider each observation as a \"bin\"\n",
+ " \"obsType\": \"bin\",\n",
+ " }\n",
+ ")\n",
+ "dataset = vc.add_dataset(name='Visium HD').add_object(wrapper)\n",
+ "\n",
+ "# Add views (visualizations) to the configuration:\n",
+ "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
+ "feature_list = vc.add_view(\"featureList\", dataset=dataset)\n",
+ "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
+ "vc.link_views_by_dict([spatial, layer_controller], {\n",
+ " 'imageLayer': CL([{\n",
+ " 'photometricInterpretation': 'RGB',\n",
+ " }]),\n",
+ "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
+ "vc.link_views_by_dict([spatial, layer_controller], {\n",
+ " 'segmentationLayer': CL([{\n",
+ " 'segmentationChannel': CL([{\n",
+ " 'spatialChannelOpacity': 0.5,\n",
+ " 'obsColorEncoding': 'geneSelection',\n",
+ " 'featureValueColormapRange': [0, 0.5],\n",
+ " }])\n",
+ " }]),\n",
+ "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"obsSegmentations\"))\n",
+ "obs_sets = vc.add_view(vt.OBS_SETS, dataset=dataset)\n",
+ "vc.link_views([spatial, layer_controller, feature_list, obs_sets], ['obsType', 'featureSelection'], [wrapper.obs_type_label, ['AA986860']])\n",
+ "\n",
+ "# Layout the views\n",
+ "vc.layout(spatial | (feature_list / layer_controller / obs_sets));"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "if not isdir(spatialdata_filepath):\n",
+ " if not isfile(zip_filepath):\n",
+ " os.makedirs(data_dir, exist_ok=True)\n",
+ " urlretrieve('https://s3.embl.de/spatialdata/spatialdata-sandbox/visium_hd_3.0.0_io.zip', zip_filepath)\n",
+ " with zipfile.ZipFile(zip_filepath,\"r\") as zip_ref:\n",
+ " zip_ref.extractall(data_dir)\n",
+ " os.rename(join(data_dir, \"data.zarr\"), spatialdata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "sdata = read_zarr(spatialdata_filepath)\n",
+ "\n",
+ "for bin_size in [\"016\", \"008\", \"002\"]:\n",
+ " # rasterize_bins() requires a compresed sparse column (csc) matrix\n",
+ " sdata.tables[f\"square_{bin_size}um\"].X = sdata.tables[f\"square_{bin_size}um\"].X.tocsc()\n",
+ " rasterized = rasterize_bins(\n",
+ " sdata,\n",
+ " f\"Visium_HD_Mouse_Small_Intestine_square_{bin_size}um\",\n",
+ " f\"square_{bin_size}um\",\n",
+ " \"array_col\",\n",
+ " \"array_row\",\n",
+ " # We want to rasterize to a Labels element, rather than an Image element.\n",
+ " return_region_as_labels=True\n",
+ " )\n",
+ " sdata[f\"rasterized_{bin_size}um\"] = rasterized\n",
+ " rasterize_bins_link_table_to_labels(\n",
+ " sdata,\n",
+ " table_name=f\"square_{bin_size}um\",\n",
+ " rasterized_labels_name=f\"rasterized_{bin_size}um\",\n",
+ " )\n",
+ " try:\n",
+ " sdata.write_element(f\"rasterized_{bin_size}um\")\n",
+ " except:\n",
+ " pass\n",
+ "\n",
+ "sdata"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "nWHF",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "sdata"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/web_app_brain.ipynb b/docs/notebooks/__ipynb__/web_app_brain.ipynb
new file mode 100644
index 00000000..00ae949b
--- /dev/null
+++ b/docs/notebooks/__ipynb__/web_app_brain.ipynb
@@ -0,0 +1,264 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from os.path import join\n",
+ "from urllib.request import urlretrieve\n",
+ "from anndata import read_h5ad\n",
+ "import scanpy as sc\n",
+ "\n",
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " AnnDataWrapper,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ulZA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Hstk",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', description='COVID-19 Healthy Donor Brain')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "os.makedirs(\"data\", exist_ok=True)\n",
+ "adata_filepath = join(\"data\", \"habib17.processed.h5ad\")\n",
+ "urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "emfo",
+ "metadata": {},
+ "source": [
+ "### 4.1. Instantiate a `VitessceConfig` object\n",
+ "\n",
+ "Use the `VitessceConfig(name, description)` constructor to create an instance."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {},
+ "source": [
+ "## 2. Download the data\n",
+ "\n",
+ "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "BYtC",
+ "metadata": {},
+ "source": [
+ "## 3.1. Preprocess the Data For Visualization\n",
+ "\n",
+ "This dataset contains 25,587 genes. In order to visualize it efficiently, we convert it to CSC sparse format so that we can make fast requests for gene data. We also prepare to visualize the top 50 highly variable genes for the heatmap as ranked by dispersion norm, although one may use any boolean array filter for the heatmap."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {},
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the classes and functions that we will be using from the corresponding packages."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Vxnm",
+ "metadata": {},
+ "source": [
+ "## 5. Launch the web application\n",
+ "\n",
+ "The `vc.web_app()` method serves the processed data locally and opens a web browser to `http://vitessce.io/?url={config_as_json}`"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Visualization of single-cell RNA seq data using vitessce.io"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Xref",
+ "metadata": {},
+ "source": [
+ "## 3. Load the data\n",
+ "\n",
+ "Note: this function may print a `FutureWarning`"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "qnkX",
+ "metadata": {},
+ "source": [
+ "### 4.4. Define the visualization layout\n",
+ "\n",
+ "The `vc.layout(view_concat)` method allows us to specify how our views will be arranged in the layout grid in the widget. The `|` and `/` characters are magic syntax for `hconcat(v1, v2)` and `vconcat(v1, v2)`, respectively."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Kclp",
+ "metadata": {},
+ "source": [
+ "## 4. Create the Vitessce widget configuration\n",
+ "\n",
+ "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Web App Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "nWHF",
+ "metadata": {},
+ "source": [
+ "### 4.2. Add a dataset to the `VitessceConfig` instance\n",
+ "\n",
+ "In Vitessce, a dataset is a container for one file per data type. The `.add_dataset(name)` method on the `vc` instance sets up and returns a new dataset instance.\n",
+ "\n",
+ "Then, we can call the dataset's `.add_object(wrapper_object)` method to attach a \"data wrapper\" instance to our new dataset. For example, the `AnnDataWrapper` class knows how to convert AnnData objects to the corresponding Vitessce data types.\n",
+ "\n",
+ "Dataset wrapper classes may require additional parameters to resolve ambiguities. For instance, `AnnData` objects may store multiple clusterings or cell type annotation columns in the `adata.obs` dataframe. We can use the parameter `cell_set_obs_cols` to tell Vitessce which columns of the `obs` dataframe correspond to cell sets."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ZHCJ",
+ "metadata": {},
+ "source": [
+ "### 4.3. Add visualizations to the `VitessceConfig` instance\n",
+ "\n",
+ "Now that we have added a dataset, we can configure visualizations. The `.add_view(dataset, component_type)` method adds a view (i.e. visualization or controller component) to the configuration.\n",
+ "\n",
+ "The `Component` enum class (which we have imported as `cm` here) can be used to fill in the `component_type` parameter.\n",
+ "\n",
+ "For convenience, the `SCATTERPLOT` component type takes the extra `mapping` keyword argument, which specifies which embedding should be used for mapping cells to (x,y) points on the plot."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "DnEU",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc.web_app()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata = read_h5ad(adata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "iLit",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
+ " adata,\n",
+ " obs_embedding_paths=[\"obsm/X_umap\"],\n",
+ " obs_embedding_names=[\"UMAP\"],\n",
+ " obs_set_paths=[\"obs/CellType\"],\n",
+ " obs_set_names=[\"Cell Type\"],\n",
+ " obs_feature_matrix_path=\"X\",\n",
+ " feature_filter_path=\"var/top_highly_variable\"\n",
+ " )\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "top_dispersion = adata.var[\"dispersions_norm\"][\n",
+ " sorted(\n",
+ " range(len(adata.var[\"dispersions_norm\"])),\n",
+ " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
+ " )[-51:][0]\n",
+ "]\n",
+ "adata.var[\"top_highly_variable\"] = (\n",
+ " adata.var[\"dispersions_norm\"] > top_dispersion\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ROlb",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
+ "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
+ "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
+ "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "TqIu",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc.layout((scatterplot | cell_sets) / (heatmap | genes));"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/widget_anndata_with_image.ipynb b/docs/notebooks/__ipynb__/widget_anndata_with_image.ipynb
new file mode 100644
index 00000000..f2934064
--- /dev/null
+++ b/docs/notebooks/__ipynb__/widget_anndata_with_image.ipynb
@@ -0,0 +1,128 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import scanpy as sc\n",
+ "import numpy as np\n",
+ "from vitessce.data_utils import rgb_img_to_ome_zarr, VAR_CHUNK_SIZE\n",
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " AnnDataWrapper,\n",
+ " ImageOmeZarrWrapper,\n",
+ ")\n",
+ "from os.path import join"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "output_img = join(\"data\", \"V1_Human_Lymph_Node.ome.zarr\")\n",
+ "output_adata = join(\"data\", \"V1_Human_Lymph_Node.anndata.zarr\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {},
+ "source": [
+ "Note: This approach to storing images within AnnData objects is no longer recommended now that [SpatialData](https://spatialdata.scverse.org/en/stable/) has been introduced."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Visualization of AnnData object containing an image in `uns`"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata = sc.datasets.visium_sge(sample_id=\"V1_Human_Lymph_Node\", include_hires_tiff=True)\n",
+ "\n",
+ "# Write img_arr to OME-Zarr.\n",
+ "# Need to convert images from interleaved to non-interleaved (color axis should be first).\n",
+ "img_hires = adata.uns['spatial']['V1_Human_Lymph_Node']['images']['hires']\n",
+ "img_arr = np.transpose(img_hires, (2, 0, 1))\n",
+ "# Convert values from [0, 1] to [0, 255].\n",
+ "img_arr *= 255.0\n",
+ "\n",
+ "# First, save the image to an OME-Zarr image format\n",
+ "rgb_img_to_ome_zarr(img_arr, output_img, axes=\"cyx\", chunks=(1, 256, 256), img_name=\"Image\")\n",
+ "# Second, save the AnnData object to Zarr format\n",
+ "adata.write_zarr(output_adata, chunks=[adata.shape[0], VAR_CHUNK_SIZE])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.17\", name=\"AnnData with image\")\n",
+ "dataset = vc.add_dataset(\"My dataset\").add_object(\n",
+ " AnnDataWrapper(\n",
+ " adata_path=output_adata,\n",
+ "\n",
+ " )\n",
+ ").add_object(\n",
+ " ImageOmeZarrWrapper(\n",
+ " img_path=output_img,\n",
+ " )\n",
+ ")\n",
+ "\n",
+ "spatial_view = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
+ "lc_view = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
+ "\n",
+ "vc.layout(spatial_view | lc_view);"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/widget_brain.ipynb b/docs/notebooks/__ipynb__/widget_brain.ipynb
new file mode 100644
index 00000000..9e99cad8
--- /dev/null
+++ b/docs/notebooks/__ipynb__/widget_brain.ipynb
@@ -0,0 +1,293 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from os.path import join, isfile, isdir\n",
+ "from urllib.request import urlretrieve\n",
+ "from anndata import read_h5ad\n",
+ "import scanpy as sc\n",
+ "\n",
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " AnnDataWrapper,\n",
+ ")\n",
+ "from vitessce.data_utils import (\n",
+ " optimize_adata,\n",
+ " VAR_CHUNK_SIZE,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Pvdt",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "iLit",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', description='COVID-19 Healthy Donor Brain')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata_filepath = join(\"data\", \"habib17.processed.h5ad\")\n",
+ "if not isfile(adata_filepath):\n",
+ " os.makedirs(\"data\", exist_ok=True)\n",
+ " urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "qnkX",
+ "metadata": {},
+ "source": [
+ "### 4.3. Add visualizations to the `VitessceConfig` instance\n",
+ "\n",
+ "Now that we have added a dataset, we can configure visualizations. The `.add_view` method adds a view (i.e. visualization or controller component) to the configuration.\n",
+ "\n",
+ "The `Component` enum class (which we have imported as `cm` here) can be used to fill in the `component_type` parameter.\n",
+ "\n",
+ "For convenience, the `SCATTERPLOT` component type takes the extra `mapping` keyword argument, which specifies which embedding should be used for mapping cells to (x,y) points on the plot."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Vxnm",
+ "metadata": {},
+ "source": [
+ "### 4.4. Define the visualization layout\n",
+ "\n",
+ "The `vc.layout(view_concat)` method allows us to specify how our views will be arranged in the layout grid in the widget. The `|` and `/` characters are magic syntax for `hconcat(v1, v2)` and `vconcat(v1, v2)`, respectively."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ZHCJ",
+ "metadata": {},
+ "source": [
+ "### 4.2. Add a dataset to the `VitessceConfig` instance\n",
+ "\n",
+ "In Vitessce, a dataset is a container for one file per data type. The `.add_dataset(name)` method on the `vc` instance sets up and returns a new dataset instance.\n",
+ "\n",
+ "Then, we can call the dataset's `.add_object(wrapper_object)` method to attach a \"data wrapper\" instance to our new dataset. For example, the `AnnDataWrapper` helps to configure AnnData Zarr stores for use in the Vitessce configuration.\n",
+ "\n",
+ "Dataset wrapper classes may require additional parameters to resolve ambiguities. For instance, `AnnData` objects may store multiple clusterings or cell type annotation columns in the `adata.obs` dataframe. We can use the parameter `obs_set_paths` to tell Vitessce that certain columns of the `obs` dataframe correspond to cell type annotations or cell clusterings."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {},
+ "source": [
+ "## 2. Download the data\n",
+ "\n",
+ "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Kclp",
+ "metadata": {},
+ "source": [
+ "## 3.2 Save the Data to Zarr store\n",
+ "\n",
+ "We want to convert the original `h5ad` file to a [Zarr](https://zarr.readthedocs.io/en/stable/) store, which Vitessce is able to load. We can use the `optimize_adata` function to ensure that all arrays and dataframe columns that we intend to use in our visualization are in the optimal format to be loaded by Vitessce. This function will cast arrays to numerical data types that take up less space (as long as the values allow). Note: unused arrays and columns (i.e., not specified in any of the parameters to `optimize_adata`) will not be copied into the new AnnData object."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {},
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the classes and functions that we will be using from the corresponding packages."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ulZA",
+ "metadata": {},
+ "source": [
+ "## 5. Create the widget\n",
+ "\n",
+ "The `vc.widget()` method returns the configured widget instance."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Visualization of single-cell RNA seq data"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "BYtC",
+ "metadata": {},
+ "source": [
+ "## 3.1. Preprocess the Data For Visualization\n",
+ "\n",
+ "This dataset contains 25,587 genes. We prepare to visualize the top 50 highly variable genes for the heatmap as ranked by dispersion norm, although one may use any boolean array filter for the heatmap."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "nWHF",
+ "metadata": {},
+ "source": [
+ "### 4.1. Instantiate a `VitessceConfig` object\n",
+ "\n",
+ "Use the `VitessceConfig` constructor to create an instance."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Xref",
+ "metadata": {},
+ "source": [
+ "## 3. Load the data\n",
+ "\n",
+ "Note: this function may print a `FutureWarning`"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hstk",
+ "metadata": {},
+ "source": [
+ "## 4. Create the Vitessce widget configuration\n",
+ "\n",
+ "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ecfG",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata = read_h5ad(adata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "top_dispersion = adata.var[\"dispersions_norm\"][\n",
+ " sorted(\n",
+ " range(len(adata.var[\"dispersions_norm\"])),\n",
+ " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
+ " )[-51:][0]\n",
+ "]\n",
+ "adata.var[\"top_highly_variable\"] = (\n",
+ " adata.var[\"dispersions_norm\"] > top_dispersion\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "emfo",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "zarr_filepath = join('data', 'habib17.processed.zarr')\n",
+ "if not isdir(zarr_filepath):\n",
+ " adata_1 = optimize_adata(adata, obs_cols=['CellType'], obsm_keys=['X_umap'], optimize_X=True, var_cols=['top_highly_variable'])\n",
+ " adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ROlb",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
+ " adata_path=zarr_filepath,\n",
+ " obs_embedding_paths=[\"obsm/X_umap\"],\n",
+ " obs_embedding_names=[\"UMAP\"],\n",
+ " obs_set_paths=[\"obs/CellType\"],\n",
+ " obs_set_names=[\"Cell Type\"],\n",
+ " obs_feature_matrix_path=\"X\",\n",
+ " initial_feature_filter_path=\"var/top_highly_variable\"\n",
+ " )\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "TqIu",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
+ "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
+ "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
+ "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "DnEU",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc.layout((scatterplot | cell_sets) / (heatmap | genes));"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/widget_brain_h5ad.ipynb b/docs/notebooks/__ipynb__/widget_brain_h5ad.ipynb
new file mode 100644
index 00000000..9a5879a5
--- /dev/null
+++ b/docs/notebooks/__ipynb__/widget_brain_h5ad.ipynb
@@ -0,0 +1,168 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from os.path import join, isfile, isdir\n",
+ "from urllib.request import urlretrieve\n",
+ "from anndata import read_h5ad\n",
+ "import scanpy as sc\n",
+ "import json\n",
+ "\n",
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " AnnDataWrapper,\n",
+ ")\n",
+ "from vitessce.data_utils import (\n",
+ " generate_h5ad_ref_spec\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "h5_url = \"https://datasets.cellxgene.cziscience.com/84df8fa1-ab53-43c9-a439-95dcb9148265.h5ad\""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Hstk",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata_filepath = join(\"data\", \"84df8fa1-ab53-43c9-a439-95dcb9148265.h5ad\")\n",
+ "if not isfile(adata_filepath):\n",
+ " os.makedirs(\"data\", exist_ok=True)\n",
+ " urlretrieve(h5_url, adata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "json_filepath = join(\"data\", \"84df8fa1-ab53-43c9-a439-95dcb9148265.h5ad.reference.json\")\n",
+ "if not isfile(json_filepath):\n",
+ " ref_dict = generate_h5ad_ref_spec(h5_url)\n",
+ " with open(json_filepath, \"w\") as f:\n",
+ " json.dump(ref_dict, f)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "BYtC",
+ "metadata": {},
+ "source": [
+ "## 2. Create the Vitessce widget configuration"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Visualization of single-cell RNA seq data from H5AD file"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Xref",
+ "metadata": {},
+ "source": [
+ "## 1. Create a Reference Spec JSON file for the H5AD file\n",
+ "\n",
+ "In order for Vitessce to load H5AD files, we also need to provide a corresponding [Reference Spec](https://fsspec.github.io/kerchunk/spec.html) JSON file which contains mappings between AnnData object keys and the byte offsets at which those AnnData object values begin within the H5AD file binary contents."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {},
+ "source": [
+ "## 0. Download data"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Kclp",
+ "metadata": {},
+ "source": [
+ "## 3. Create the widget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.17\", name='Nakshatri et al', description='snRNA-seq analyses of breast tissues of healthy women of diverse genetic ancestry')\n",
+ "\n",
+ "dataset = vc.add_dataset(name='84df8fa1').add_object(AnnDataWrapper(\n",
+ " adata_path=adata_filepath,\n",
+ " ref_path=json_filepath, # We specify paths to both the H5AD and JSON files\n",
+ " obs_embedding_paths=[\"obsm/X_wnn.umap\"],\n",
+ " obs_embedding_names=[\"UMAP\"],\n",
+ " obs_set_paths=[\"obs/cell_type\"],\n",
+ " obs_set_names=[\"Cell Type\"],\n",
+ " obs_feature_matrix_path=\"X\",\n",
+ " )\n",
+ ")\n",
+ "\n",
+ "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
+ "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
+ "cell_set_sizes = vc.add_view(cm.OBS_SET_SIZES, dataset=dataset)\n",
+ "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
+ "\n",
+ "vc.layout((scatterplot | cell_sets) / (cell_set_sizes | genes));"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "emfo",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/widget_brain_with_base_dir.ipynb b/docs/notebooks/__ipynb__/widget_brain_with_base_dir.ipynb
new file mode 100644
index 00000000..eafbb348
--- /dev/null
+++ b/docs/notebooks/__ipynb__/widget_brain_with_base_dir.ipynb
@@ -0,0 +1,338 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from os.path import join, isfile, isdir\n",
+ "from urllib.request import urlretrieve\n",
+ "from anndata import read_h5ad\n",
+ "\n",
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " AnnDataWrapper,\n",
+ " BASE_URL_PLACEHOLDER,\n",
+ ")\n",
+ "from vitessce.data_utils import (\n",
+ " optimize_adata,\n",
+ " VAR_CHUNK_SIZE,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "BASE_DIR = \"data\""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "xXTn",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata_relative_filepath = \"habib17.processed.h5ad\" # Relative to BASE_DIR\n",
+ "adata_filepath = join(BASE_DIR, adata_relative_filepath)\n",
+ "if not isfile(adata_filepath):\n",
+ " os.makedirs(BASE_DIR, exist_ok=True)\n",
+ " urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ROlb",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', base_dir=BASE_DIR)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Xref",
+ "metadata": {},
+ "source": [
+ "## 3. Download the data\n",
+ "\n",
+ "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ZHCJ",
+ "metadata": {},
+ "source": [
+ "### 5.1. Instantiate a `VitessceConfig` object\n",
+ "\n",
+ "Use the `VitessceConfig` constructor to create an instance. In this case, we want to construct our configuration using local data that is relative to a particular directory, so we provide the `base_dir` parameter.\n",
+ "\n",
+ "Note: This `base_dir` parameter is optional. When it is omitted, local data paths are assumed to be relative to the current working directory."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "BYtC",
+ "metadata": {},
+ "source": [
+ "## 4. Load the data\n",
+ "\n",
+ "Note: this function may print a `FutureWarning`"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "aLJB",
+ "metadata": {},
+ "source": [
+ "## 7. Check the URLs in the configuration\n",
+ "\n",
+ "We can check that the data URLs in the configuration respected the specified `base_dir`."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Pvdt",
+ "metadata": {},
+ "source": [
+ "## 6. Create the widget\n",
+ "\n",
+ "The `vc.widget()` method returns the configured widget instance."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Configure relative to a base_dir"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Vxnm",
+ "metadata": {},
+ "source": [
+ "### 5.3. Add visualizations to the `VitessceConfig` instance\n",
+ "\n",
+ "Now that we have added a dataset, we can configure visualizations. The `.add_view` method adds a view (i.e. visualization or controller component) to the configuration.\n",
+ "\n",
+ "The `Component` enum class (which we have imported as `cm` here) can be used to fill in the `component_type` parameter.\n",
+ "\n",
+ "For convenience, the `SCATTERPLOT` component type takes the extra `mapping` keyword argument, which specifies which embedding should be used for mapping cells to (x,y) points on the plot."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Kclp",
+ "metadata": {},
+ "source": [
+ "## 4.1. Preprocess the Data For Visualization\n",
+ "\n",
+ "This dataset contains 25,587 genes. We prepare to visualize the top 50 highly variable genes for the heatmap as ranked by dispersion norm, although one may use any boolean array filter for the heatmap."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "qnkX",
+ "metadata": {},
+ "source": [
+ "### 5.2. Add a dataset to the `VitessceConfig` instance\n",
+ "\n",
+ "In Vitessce, a dataset is a container for one file per data type. The `.add_dataset(name)` method on the `vc` instance sets up and returns a new dataset instance.\n",
+ "\n",
+ "Then, we can call the dataset's `.add_object(wrapper_object)` method to attach a \"data wrapper\" instance to our new dataset. For example, the `AnnDataWrapper` helps to configure AnnData Zarr stores for use in the Vitessce configuration.\n",
+ "\n",
+ "Dataset wrapper classes may require additional parameters to resolve ambiguities. For instance, `AnnData` objects may store multiple clusterings or cell type annotation columns in the `adata.obs` dataframe. We can use the parameter `obs_set_paths` to tell Vitessce that certain columns of the `obs` dataframe correspond to cell type annotations or cell clusterings."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {},
+ "source": [
+ "## 2. Define a `base_dir`\n",
+ "\n",
+ "We will define a `base_dir` inside which our data will live. We will provide this to `VitessceConfig` in order to construct a configuration that contains URL paths relative to this directory."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hstk",
+ "metadata": {},
+ "source": [
+ "## 4.2 Save the Data to Zarr store\n",
+ "\n",
+ "We want to convert the original `h5ad` file to a [Zarr](https://zarr.readthedocs.io/en/stable/) store, which Vitessce is able to load. We can use the `optimize_adata` function to ensure that all arrays and dataframe columns that we intend to use in our visualization are in the optimal format to be loaded by Vitessce. This function will cast arrays to numerical data types that take up less space (as long as the values allow). Note: unused arrays and columns (i.e., not specified in any of the parameters to `optimize_adata`) will not be copied into the new AnnData object."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ulZA",
+ "metadata": {},
+ "source": [
+ "### 5.4. Define the visualization layout\n",
+ "\n",
+ "The `vc.layout(view_concat)` method allows us to specify how our views will be arranged in the layout grid in the widget. The `|` and `/` characters are magic syntax for `hconcat(v1, v2)` and `vconcat(v1, v2)`, respectively."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {},
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the classes and functions that we will be using from the corresponding packages."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "iLit",
+ "metadata": {},
+ "source": [
+ "## 5. Create the Vitessce widget configuration\n",
+ "\n",
+ "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata = read_h5ad(adata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "nHfw",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "config_dict = vc.to_dict(base_url=BASE_URL_PLACEHOLDER)\n",
+ "config_dict"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ZBYS",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "nWHF",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "zarr_relative_filepath = 'habib17.processed.zarr'\n",
+ "zarr_filepath = join(BASE_DIR, zarr_relative_filepath)\n",
+ "if not isdir(zarr_filepath):\n",
+ " adata_1 = optimize_adata(adata, obs_cols=['CellType'], obsm_keys=['X_umap'], optimize_X=True, var_cols=['top_highly_variable'])\n",
+ " adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "emfo",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "top_dispersion = adata.var[\"dispersions_norm\"][\n",
+ " sorted(\n",
+ " range(len(adata.var[\"dispersions_norm\"])),\n",
+ " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
+ " )[-51:][0]\n",
+ "]\n",
+ "adata.var[\"top_highly_variable\"] = (\n",
+ " adata.var[\"dispersions_norm\"] > top_dispersion\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "TqIu",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
+ " adata_path=zarr_relative_filepath, # Relative to BASE_DIR (because we specified base_dir in the VitessceConfig constructor)\n",
+ " obs_embedding_paths=[\"obsm/X_umap\"],\n",
+ " obs_embedding_names=[\"UMAP\"],\n",
+ " obs_set_paths=[\"obs/CellType\"],\n",
+ " obs_set_names=[\"Cell Type\"],\n",
+ " obs_feature_matrix_path=\"X\",\n",
+ " initial_feature_filter_path=\"var/top_highly_variable\"\n",
+ " )\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "DnEU",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
+ "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
+ "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
+ "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ecfG",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc.layout((scatterplot | cell_sets) / (heatmap | genes));"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/widget_brain_with_quality_metric.ipynb b/docs/notebooks/__ipynb__/widget_brain_with_quality_metric.ipynb
new file mode 100644
index 00000000..7fdbf62b
--- /dev/null
+++ b/docs/notebooks/__ipynb__/widget_brain_with_quality_metric.ipynb
@@ -0,0 +1,247 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from os.path import join, isfile, isdir\n",
+ "from urllib.request import urlretrieve\n",
+ "from anndata import read_h5ad\n",
+ "import scanpy as sc\n",
+ "\n",
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " AnnDataWrapper,\n",
+ ")\n",
+ "from vitessce.data_utils import (\n",
+ " optimize_adata,\n",
+ " VAR_CHUNK_SIZE,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ZHCJ",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata_filepath = join(\"data\", \"habib17.processed.h5ad\")\n",
+ "if not isfile(adata_filepath):\n",
+ " os.makedirs(\"data\", exist_ok=True)\n",
+ " urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {},
+ "source": [
+ "## 2. Download the data\n",
+ "\n",
+ "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "BYtC",
+ "metadata": {},
+ "source": [
+ "## 3.1. Preprocess the Data For Visualization\n",
+ "\n",
+ "This dataset contains 25,587 genes. We prepare to visualize the top 50 highly variable genes for the heatmap as ranked by dispersion norm, although one may use any boolean array filter for the heatmap."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "nWHF",
+ "metadata": {},
+ "source": [
+ "## 5. Create the widget"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Kclp",
+ "metadata": {},
+ "source": [
+ "## 3.2 Save the Data to Zarr store\n",
+ "\n",
+ "We want to convert the original `h5ad` file to a [Zarr](https://zarr.readthedocs.io/en/stable/) store, which Vitessce is able to load. We can use the `optimize_adata` function to ensure that all arrays and dataframe columns that we intend to use in our visualization are in the optimal format to be loaded by Vitessce. This function will cast arrays to numerical data types that take up less space (as long as the values allow). Note: unused arrays and columns (i.e., not specified in any of the parameters to `optimize_adata`) will not be copied into the new AnnData object."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {},
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the classes and functions that we will be using from the corresponding packages."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Xref",
+ "metadata": {},
+ "source": [
+ "## 3. Load the data\n",
+ "\n",
+ "Note: this function may print a `FutureWarning`"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Visualization of single-cell RNA seq data"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata = read_h5ad(adata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "top_dispersion = adata.var[\"dispersions_norm\"][\n",
+ " sorted(\n",
+ " range(len(adata.var[\"dispersions_norm\"])),\n",
+ " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
+ " )[-51:][0]\n",
+ "]\n",
+ "adata.var[\"top_highly_variable\"] = (\n",
+ " adata.var[\"dispersions_norm\"] > top_dispersion\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "emfo",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "zarr_filepath = join(\"data\", \"habib17.h5ad.zarr\")\n",
+ "if not isdir(zarr_filepath):\n",
+ " adata.write_zarr(zarr_filepath, chunks=[adata.shape[0], VAR_CHUNK_SIZE])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Hstk",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(\n",
+ " schema_version=\"1.0.17\",\n",
+ " name='Habib et al',\n",
+ " description='COVID-19 Healthy Donor Brain'\n",
+ ")\n",
+ "\n",
+ "# Add data.\n",
+ "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
+ " adata_path=zarr_filepath,\n",
+ " obs_embedding_paths=[\"obsm/X_umap\"],\n",
+ " obs_embedding_names=[\"UMAP\"],\n",
+ " obs_set_paths=[\"obs/CellType\"],\n",
+ " obs_set_names=[\"Cell Type\"],\n",
+ " obs_feature_matrix_path=\"X\",\n",
+ " initial_feature_filter_path=\"var/top_highly_variable\",\n",
+ " coordination_values={\n",
+ " \"obsType\": 'cell',\n",
+ " \"featureType\": 'gene',\n",
+ " \"featureValueType\": 'expression',\n",
+ " },\n",
+ ")).add_object(AnnDataWrapper(\n",
+ " adata_path=zarr_filepath,\n",
+ " obs_feature_column_paths=[\"obs/percent_mito\"],\n",
+ " coordination_values={\n",
+ " \"obsType\": 'cell',\n",
+ " \"featureType\": 'qualityMetric',\n",
+ " \"featureValueType\": 'value',\n",
+ " }\n",
+ "))\n",
+ "\n",
+ "# Add views.\n",
+ "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
+ "scatterplot_2 = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
+ "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
+ "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
+ "histogram = vc.add_view(cm.FEATURE_VALUE_HISTOGRAM, dataset=dataset)\n",
+ "\n",
+ "# Link views.\n",
+ "\n",
+ "# Color one of the two scatterplots by the percent_mito quality metric.\n",
+ "# Also use this quality metric for the histogram values.\n",
+ "vc.link_views_by_dict([histogram, scatterplot_2], {\n",
+ " \"obsType\": 'cell',\n",
+ " \"featureType\": 'qualityMetric',\n",
+ " \"featureValueType\": 'value',\n",
+ " \"featureSelection\": [\"percent_mito\"],\n",
+ " \"obsColorEncoding\": \"geneSelection\",\n",
+ "}, meta=False)\n",
+ "\n",
+ "# Synchronize the zooming and panning of the two scatterplots\n",
+ "vc.link_views_by_dict([scatterplot, scatterplot_2], {\n",
+ " \"embeddingZoom\": None,\n",
+ " \"embeddingTargetX\": None,\n",
+ " \"embeddingTargetY\": None,\n",
+ "}, meta=False)\n",
+ "\n",
+ "# Define the layout.\n",
+ "vc.layout((scatterplot | (cell_sets / genes)) / (scatterplot_2 | histogram));"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "iLit",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/widget_from_dict.ipynb b/docs/notebooks/__ipynb__/widget_from_dict.ipynb
new file mode 100644
index 00000000..93ace24b
--- /dev/null
+++ b/docs/notebooks/__ipynb__/widget_from_dict.ipynb
@@ -0,0 +1,99 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import VitessceConfig"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from example_configs import dries as dries_config"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig.from_dict(dries_config)\n",
+ "vw = vc.widget()\n",
+ "vw"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Xref",
+ "metadata": {},
+ "source": [
+ "## 3. Create the Vitessce widget\n",
+ "\n",
+ "Create the widget by creating a new config instance using the `VitessceConfig.from_dict` static method, then calling the config's `.widget()` method.\n",
+ "\n",
+ "Render the widget by placing the widget variable on its own line at the end of the notebook cell."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {},
+ "source": [
+ "## 2. Import config of interest as a dict\n",
+ "\n",
+ "The Vitessce config at its lowest level is a JSON object or a Python `dict` that specifies a layout for the Vitessce components will be rendered in the widget. These components may be scatterplots, spatial plots, heatmaps, or control components. The config also describes the datasets and files that will be visualized.\n",
+ "\n",
+ "The `vitessce` package provides helper functions and classes to simplify the process of defining Vitessce configs. Those functions are demonstrated in the other notebooks. The helper functions are intended to make visualization of local datasets easy. However, in this case, we are importing a config that has been pre-defined in the file `example_configs.py`, in which the dataset being visualized is stored remotely in AWS S3 (rather than locally)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Using an existing view config dict"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {},
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the `VitessceConfig` class."
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/widget_genomic_profiles.ipynb b/docs/notebooks/__ipynb__/widget_genomic_profiles.ipynb
new file mode 100644
index 00000000..7965bdbe
--- /dev/null
+++ b/docs/notebooks/__ipynb__/widget_genomic_profiles.ipynb
@@ -0,0 +1,217 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " ViewType as vt,\n",
+ " CoordinationType as ct,\n",
+ " AnnDataWrapper,\n",
+ " MultivecZarrWrapper,\n",
+ ")\n",
+ "from vitessce.data_utils import (\n",
+ " adata_to_multivec_zarr,\n",
+ ")\n",
+ "from os.path import join\n",
+ "from scipy.io import mmread\n",
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "from anndata import AnnData"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ROlb",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "multivec_zarr_path = join(\"data\", \"HBM485.TBWH.322.multivec.zarr\")\n",
+ "adata_zarr_path = join(\"data\", \"HBM485.TBWH.322.adata.zarr\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "mtx = mmread(join('data', 'snapatac', 'filtered_cell_by_bin.mtx')).toarray()\n",
+ "barcodes_df = pd.read_csv(join('data', 'snapatac', 'barcodes.txt'), header=None)\n",
+ "bins_df = pd.read_csv(join('data', 'snapatac', 'bins.txt'), header=None, names=[\"interval\"])\n",
+ "clusters_df = pd.read_csv(join('data', 'snapatac', 'umap_coords_clusters.csv'), index_col=0)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "iLit",
+ "metadata": {},
+ "source": [
+ "## 5. Create the widget"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {},
+ "source": [
+ "## 2. Load the data\n",
+ "\n",
+ "In this step, we load the raw data that has been downloaded from the HuBMAP portal https://portal.hubmapconsortium.org/browse/dataset/210d118a14c8624b6bb9610a9062656e"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hstk",
+ "metadata": {},
+ "source": [
+ "## 4. Make a Vitessce configuration\n",
+ "\n",
+ "We need to tell Vitessce about the data that we want to load and the visualization components that we want to include in the widget.\n",
+ "For this dataset, we want to add the `GENOMIC_PROFILES` component, which renders genome browser tracks with [HiGlass](http://higlass.io)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Xref",
+ "metadata": {},
+ "source": [
+ "## 3. Convert the data to Vitessce-compatible formats\n",
+ "\n",
+ "Vitessce can load AnnData objects saved to Zarr formats efficiently."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Visualization of genomic profiles"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {},
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the classes and functions that we will be using from the corresponding packages."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "nWHF",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='HuBMAP snATAC-seq')\n",
+ "dataset = vc.add_dataset(name='HBM485.TBWH.322').add_object(MultivecZarrWrapper(\n",
+ " zarr_path=multivec_zarr_path\n",
+ ")).add_object(AnnDataWrapper(\n",
+ " adata_path=adata_zarr_path,\n",
+ " obs_embedding_paths=[\"obsm/X_umap\"],\n",
+ " obs_embedding_names=[\"UMAP\"],\n",
+ " obs_set_paths=[\"obs/cluster\"],\n",
+ " obs_set_names=[\"Cluster\"],\n",
+ "))\n",
+ "\n",
+ "genomic_profiles = vc.add_view(vt.GENOMIC_PROFILES, dataset=dataset)\n",
+ "scatter = vc.add_view(vt.SCATTERPLOT, dataset=dataset, mapping = \"UMAP\")\n",
+ "cell_sets = vc.add_view(vt.OBS_SETS, dataset=dataset)\n",
+ "\n",
+ "vc.layout(genomic_profiles / (scatter | cell_sets));"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# The genome assembly is GRCh38 but the chromosome names in the bin names do not start with the \"chr\" prefix.\n",
+ "# This is incompatible with the chromosome names from `negspy`, so we need to append the prefix.\n",
+ "bins_df[\"interval\"] = bins_df[\"interval\"].apply(lambda x: \"chr\" + x)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "obs = clusters_df[[\"cluster\"]]\n",
+ "obs[\"cluster\"] = obs[\"cluster\"].astype(str)\n",
+ "obsm = { \"X_umap\": clusters_df[[\"umap.1\", \"umap.2\"]].values }\n",
+ "adata = AnnData(X=mtx, obs=obs, var=bins_df, obsm=obsm)\n",
+ "adata"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ZHCJ",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget(height=800)\n",
+ "vw"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Kclp",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Sort cluster IDs\n",
+ "cluster_ids = obs[\"cluster\"].unique().tolist()\n",
+ "cluster_ids.sort(key=int)\n",
+ "# Save genomic profiles to multivec-zarr format.\n",
+ "adata_to_multivec_zarr(adata, multivec_zarr_path, obs_set_col=\"cluster\", obs_set_name=\"Cluster\", obs_set_vals=cluster_ids)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "emfo",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Save anndata object to AnnData-Zarr format.\n",
+ "adata.write_zarr(adata_zarr_path)"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/widget_imaging.ipynb b/docs/notebooks/__ipynb__/widget_imaging.ipynb
new file mode 100644
index 00000000..3102a8f4
--- /dev/null
+++ b/docs/notebooks/__ipynb__/widget_imaging.ipynb
@@ -0,0 +1,104 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " OmeTiffWrapper,\n",
+ " MultiImageWrapper,\n",
+ ")\n",
+ "from os.path import join"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='Spraggins Multi-Modal', description='PAS + IMS + AF From https://portal.hubmapconsortium.org/browse/collection/6a6efd0c1a2681dc7d2faab8e4ab0bca')\n",
+ "dataset = vc.add_dataset(name='Spraggins').add_object(\n",
+ " MultiImageWrapper(\n",
+ " image_wrappers=[\n",
+ " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/f4188a148e4c759092d19369d310883b/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-PAS_images/VAN0006-LK-2-85-PAS_registered.ome.tif?token=', name='PAS'),\n",
+ " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/2130d5f91ce61d7157a42c0497b06de8/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-AF_preIMS_images/VAN0006-LK-2-85-AF_preIMS_registered.ome.tif?token=', name='AF'),\n",
+ " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/be503a021ed910c0918842e318e6efa2/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_PosMode_multilayer.ome.tif?token=', name='IMS Pos Mode'),\n",
+ " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/ca886a630b2038997a4cfbbf4abfd283/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_NegMode_multilayer.ome.tif?token=', name='IMS Neg Mode')\n",
+ " ],\n",
+ " use_physical_size_scaling=True,\n",
+ " )\n",
+ ")\n",
+ "spatial = vc.add_view(cm.SPATIAL, dataset=dataset)\n",
+ "status = vc.add_view(cm.STATUS, dataset=dataset)\n",
+ "lc = vc.add_view(cm.LAYER_CONTROLLER, dataset=dataset).set_props(disableChannelsIfRgbDetected=True)\n",
+ "vc.layout(spatial | (lc / status));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Visualization of Multi-Modal Imaging Data\n",
+ "We visualize IMS, PAS, and AF imaging data overlaid from the Spraggins Lab of the Biomolecular Multimodal Imaging Center (BIOMC) at Vanderbilt University, uploaded to the HuBMAP data portal."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {},
+ "source": [
+ "## 1. Configure Vitessce\n",
+ "Set up the images from the three different assays, with the `use_physical_size_scaling` set to `True` so that the IMS image scales to the other images based on their physical sizes."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "PKri",
+ "metadata": {},
+ "source": [
+ "## 2. Create the Vitessce widget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/widget_imaging_beta.ipynb b/docs/notebooks/__ipynb__/widget_imaging_beta.ipynb
new file mode 100644
index 00000000..f5081e74
--- /dev/null
+++ b/docs/notebooks/__ipynb__/widget_imaging_beta.ipynb
@@ -0,0 +1,142 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " OmeTiffWrapper,\n",
+ " MultiImageWrapper,\n",
+ " CoordinationLevel as CL,\n",
+ ")\n",
+ "from os.path import join"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.16\", name='Spraggins Multi-Modal', description='PAS + IMS + AF From https://portal.hubmapconsortium.org/browse/collection/6a6efd0c1a2681dc7d2faab8e4ab0bca')\n",
+ "dataset = vc.add_dataset(name='Spraggins').add_file(\n",
+ " url='https://assets.hubmapconsortium.org/f4188a148e4c759092d19369d310883b/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-PAS_images/VAN0006-LK-2-85-PAS_registered.ome.tif?token=',\n",
+ " file_type=\"image.ome-tiff\",\n",
+ " coordination_values={\n",
+ " \"fileUid\": \"PAS\",\n",
+ " },\n",
+ ")\n",
+ "\n",
+ "imageScopes = vc.add_coordination_by_dict({\n",
+ " \"imageLayer\": CL([\n",
+ " {\n",
+ " \"fileUid\": 'PAS',\n",
+ " \"spatialLayerOpacity\": 1,\n",
+ " \"spatialLayerVisible\": True,\n",
+ " \"photometricInterpretation\": 'RGB',\n",
+ " \"imageChannel\": CL([\n",
+ " {\n",
+ " \"spatialTargetC\": 0,\n",
+ " \"spatialChannelColor\": [255, 0, 0],\n",
+ " \"spatialChannelVisible\": True,\n",
+ " \"spatialChannelOpacity\": 1.0,\n",
+ " \"spatialChannelWindow\": [0, 255],\n",
+ " },\n",
+ " {\n",
+ " \"spatialTargetC\": 1,\n",
+ " \"spatialChannelColor\": [0, 255, 0],\n",
+ " \"spatialChannelVisible\": True,\n",
+ " \"spatialChannelOpacity\": 1.0,\n",
+ " \"spatialChannelWindow\": [0, 255],\n",
+ " },\n",
+ " {\n",
+ " \"spatialTargetC\": 2,\n",
+ " \"spatialChannelColor\": [0, 0, 255],\n",
+ " \"spatialChannelVisible\": True,\n",
+ " \"spatialChannelOpacity\": 1.0,\n",
+ " \"spatialChannelWindow\": [0, 255],\n",
+ " },\n",
+ " ]),\n",
+ " }\n",
+ " ])\n",
+ "})\n",
+ "\n",
+ "metaCoordinationScope = vc.add_meta_coordination()\n",
+ "metaCoordinationScope.use_coordination_by_dict(imageScopes)\n",
+ "\n",
+ "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
+ "lc = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
+ "\n",
+ "spatial.use_meta_coordination(metaCoordinationScope)\n",
+ "lc.use_meta_coordination(metaCoordinationScope)\n",
+ "\n",
+ "vc.layout(spatial | lc);"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {},
+ "source": [
+ "## 1. Configure Vitessce\n",
+ "Set up the images from the three different assays, with the `use_physical_size_scaling` set to `True` so that the IMS image scales to the other images based on their physical sizes."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "PKri",
+ "metadata": {},
+ "source": [
+ "## 2. Create the Vitessce widget"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Visualization of Multi-Modal Imaging Data\n",
+ "We visualize IMS, PAS, and AF imaging data overlaid from the Spraggins Lab of the Biomolecular Multimodal Imaging Center (BIOMC) at Vanderbilt University, uploaded to the HuBMAP data portal."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget(custom_js_url='http://localhost:8000/packages/main/prod/dist/index.min.js')\n",
+ "vw"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/widget_imaging_segmentation.ipynb b/docs/notebooks/__ipynb__/widget_imaging_segmentation.ipynb
new file mode 100644
index 00000000..212893b4
--- /dev/null
+++ b/docs/notebooks/__ipynb__/widget_imaging_segmentation.ipynb
@@ -0,0 +1,101 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " OmeTiffWrapper,\n",
+ " MultiImageWrapper,\n",
+ ")\n",
+ "from os.path import join"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='MCMicro Bitmask Visualization', description='Segmentation + Data of Exemplar 001')\n",
+ "dataset = vc.add_dataset(name='MCMicro').add_object(\n",
+ " MultiImageWrapper(\n",
+ " image_wrappers=[\n",
+ " OmeTiffWrapper(img_url='https://vitessce-demo-data.storage.googleapis.com/exemplar-001/exemplar-001.pyramid.ome.tif', name='Image'),\n",
+ " OmeTiffWrapper(img_url='https://vitessce-demo-data.storage.googleapis.com/exemplar-001/cellMask.pyramid.ome.tif', name='Mask', is_bitmask=True),\n",
+ " ]\n",
+ " )\n",
+ ")\n",
+ "spatial = vc.add_view(cm.SPATIAL, dataset=dataset)\n",
+ "status = vc.add_view(cm.STATUS, dataset=dataset)\n",
+ "lc = vc.add_view(cm.LAYER_CONTROLLER, dataset=dataset)\n",
+ "vc.layout(spatial | (lc / status));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "PKri",
+ "metadata": {},
+ "source": [
+ "## 2. Create the Vitessce widget"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {},
+ "source": [
+ "## 1. Configure Vitessce\n",
+ "Set up the two images, already pyramidal from the [bioformats2raw + raw2ometiff pipeline](https://github.com/hms-dbmi/viv/tree/master/tutorial), labeling the segmentation \"on top\" as the bitmask and the other as simply the image data."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Visualization of Segmentation Bitmask\n",
+ "We visualize raw imaging data + a segmentation bitmask the [MCMicro piplene](https://mcmicro.org/) - see https://www.biorxiv.org/content/10.1101/2021.03.15.435473v1.full and specifically [Figure S1](https://www.google.com/url?q=https://www.biorxiv.org/content/10.1101/2021.03.15.435473v1.full%23F3&sa=D&source=editors&ust=1623173627976000&usg=AOvVaw3JkzCxYyE86q8jxfNCgShh)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/widget_loom.ipynb b/docs/notebooks/__ipynb__/widget_loom.ipynb
new file mode 100644
index 00000000..024d4971
--- /dev/null
+++ b/docs/notebooks/__ipynb__/widget_loom.ipynb
@@ -0,0 +1,214 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from os.path import join, isfile, isdir\n",
+ "from urllib.request import urlretrieve\n",
+ "from anndata import read_loom\n",
+ "import numpy as np\n",
+ "\n",
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " AnnDataWrapper,\n",
+ ")\n",
+ "from vitessce.data_utils import (\n",
+ " optimize_adata,\n",
+ " to_diamond,\n",
+ " VAR_CHUNK_SIZE,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "qnkX",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "loom_filepath = join(\"data\", \"osmFISH_SScortex_mouse_all_cells.loom\")\n",
+ "if not isfile(loom_filepath):\n",
+ " os.makedirs(\"data\", exist_ok=True)\n",
+ " urlretrieve('http://loom.linnarssonlab.org/clone/osmFISH/osmFISH_SScortex_mouse_all_cells.loom', loom_filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "BYtC",
+ "metadata": {},
+ "source": [
+ "Generate pseudo-segmentations as diamond-shaped polygons centered on the spatial coordinate of each cell, and store in `adata.obsm[\"segmentations\"]`"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {},
+ "source": [
+ "## 1. Import dependencies"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Xref",
+ "metadata": {},
+ "source": [
+ "## 3. Open Loom file with AnnData's read_loom"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Kclp",
+ "metadata": {},
+ "source": [
+ "Save the AnnData object to a Zarr store:"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {},
+ "source": [
+ "## 2. Download data\n",
+ "\n",
+ "Download `osmFISH_SScortex_mouse_all_cells.loom` from http://loom.linnarssonlab.org/."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Visualization of a Loom file"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hstk",
+ "metadata": {},
+ "source": [
+ "## 4. Configure Vitessce\n",
+ "\n",
+ "Create a Vitessce view config."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ZHCJ",
+ "metadata": {},
+ "source": [
+ "A widget can be created with the `.widget()` method on the config instance."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "iLit",
+ "metadata": {},
+ "source": [
+ "## 5. Render the widget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata = read_loom(loom_filepath, obsm_names={\"tSNE\": [\"_tSNE_1\", \"_tSNE_2\"], \"spatial\": [\"X\", \"Y\"]})"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "emfo",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "zarr_filepath = join('data', 'osmFISH_SScortex_mouse_all_cells.zarr')\n",
+ "if not isdir(zarr_filepath) or True:\n",
+ " adata_1 = optimize_adata(adata, obs_cols=['ClusterName'], obsm_keys=['tSNE', 'spatial', 'segmentations'], optimize_X=True)\n",
+ " adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "num_cells = adata.obs.shape[0]\n",
+ "adata.obsm[\"segmentations\"] = np.zeros((num_cells, 4, 2))\n",
+ "radius = 100\n",
+ "for i in range(num_cells):\n",
+ " adata.obsm[\"segmentations\"][i, :, :] = to_diamond(adata.obsm['spatial'][i, 0], adata.obsm['spatial'][i, 1], radius)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "nWHF",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='Loom Example', description='osmFISH dataset of the mouse cortex including all cells')\n",
+ "w = AnnDataWrapper(adata_path=zarr_filepath, obs_set_paths=[\"obs/ClusterName\"], obs_set_names=[\"Clusters\"], obs_locations_path=\"obsm/spatial\", obs_segmentations_path=\"obsm/segmentations\", obs_embedding_paths=[\"obsm/tSNE\"])\n",
+ "dataset = vc.add_dataset(name='SScortex').add_object(w)\n",
+ "\n",
+ "tsne = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"tSNE\")\n",
+ "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
+ "spatial = vc.add_view(cm.SPATIAL, dataset=dataset)\n",
+ "\n",
+ "spatial_segmentation_layer_value = {\n",
+ " \"opacity\": 1,\n",
+ " \"radius\": 0,\n",
+ " \"visible\": True,\n",
+ " \"stroked\": False\n",
+ "}\n",
+ "\n",
+ "vc.link_views([spatial], [ct.SPATIAL_ZOOM, ct.SPATIAL_TARGET_X, ct.SPATIAL_TARGET_Y, ct.SPATIAL_SEGMENTATION_LAYER], [-6.43, 10417.69, 24885.55, spatial_segmentation_layer_value])\n",
+ "vc.layout(spatial | (tsne / cell_sets));"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ROlb",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/widget_modify_config.ipynb b/docs/notebooks/__ipynb__/widget_modify_config.ipynb
new file mode 100644
index 00000000..fd8608e2
--- /dev/null
+++ b/docs/notebooks/__ipynb__/widget_modify_config.ipynb
@@ -0,0 +1,147 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " OmeTiffWrapper,\n",
+ " MultiImageWrapper,\n",
+ " CoordinationLevel as CL,\n",
+ " ObsSegmentationsOmeTiffWrapper,\n",
+ " ImageOmeTiffWrapper,\n",
+ " get_initial_coordination_scope_prefix,\n",
+ ")\n",
+ "import random"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.16\")\n",
+ "dataset = vc.add_dataset(name='Spraggins').add_object(\n",
+ " ImageOmeTiffWrapper(\n",
+ " img_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2_bf.ome.tif\",\n",
+ " offsets_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2_bf.offsets.json\"\n",
+ " )\n",
+ ").add_object(\n",
+ " ObsSegmentationsOmeTiffWrapper(\n",
+ " img_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2.ome.tif\",\n",
+ " offsets_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2.offsets.json\",\n",
+ " obs_types_from_channel_names=True\n",
+ " )\n",
+ ")\n",
+ "\n",
+ "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
+ "lc = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
+ "\n",
+ "vc.link_views_by_dict([spatial, lc], {\n",
+ " \"imageLayer\": CL([\n",
+ " {\n",
+ " \"photometricInterpretation\": \"RGB\"\n",
+ " }\n",
+ " ]),\n",
+ "}, meta=True, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
+ "\n",
+ "vc.layout(spatial | lc);"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Programmatic modification of widget configuration"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget(remount_on_uid_change=False)\n",
+ "vw"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Programatically set a different zoom level and toggle the visibility/color of different segmentation layers:\n",
+ "vw.config = {\n",
+ " **vw.config,\n",
+ " # Need to provide a fresh \"uid\" value.\n",
+ " # This will tell Vitessce that the contents should be diff-ed against the previous config.\n",
+ " \"uid\": f\"new_config_{random.random()}\",\n",
+ " \"coordinationSpace\": {\n",
+ " # Information about the coordination space can be found at https://vitessce.io/docs/coordination-types/\n",
+ " **vw.config[\"coordinationSpace\"],\n",
+ " \"spatialZoom\": {\n",
+ " **vw.config[\"coordinationSpace\"][\"spatialZoom\"],\n",
+ " \"A\": -8\n",
+ " },\n",
+ " \"spatialChannelVisible\": {\n",
+ " **vw.config[\"coordinationSpace\"][\"spatialChannelVisible\"],\n",
+ " \"init_A_obsSegmentations_0\": True,\n",
+ " \"init_A_obsSegmentations_1\": False,\n",
+ " \"init_A_obsSegmentations_2\": False,\n",
+ " \"init_A_obsSegmentations_3\": False\n",
+ " },\n",
+ " \"spatialChannelColor\": {\n",
+ " **vw.config[\"coordinationSpace\"][\"spatialChannelColor\"],\n",
+ " \"init_A_obsSegmentations_0\": [255, 0, 0],\n",
+ " }\n",
+ " }\n",
+ "}"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Inspect the current configuration value.\n",
+ "# This is a dict in the JSON-based format https://vitessce.io/docs/view-config-json/\n",
+ "vw.config"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/widget_neuroglancer.ipynb b/docs/notebooks/__ipynb__/widget_neuroglancer.ipynb
new file mode 100644
index 00000000..122c936a
--- /dev/null
+++ b/docs/notebooks/__ipynb__/widget_neuroglancer.ipynb
@@ -0,0 +1,215 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " ImageOmeTiffWrapper,\n",
+ " CsvWrapper,\n",
+ " hconcat,\n",
+ " vconcat,\n",
+ " get_initial_coordination_scope_prefix,\n",
+ " CoordinationLevel as CL\n",
+ ")\n",
+ "from os.path import join"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.17\")\n",
+ "dataset = vc.add_dataset(name='Meshes').add_object(\n",
+ " ImageOmeTiffWrapper(\n",
+ " img_url='https://lsp-public-data.s3.amazonaws.com/yapp-2023-3d-melanoma/Dataset1-LSP13626-invasive-margin.ome.tiff',\n",
+ " offsets_url='https://lsp-public-data.s3.amazonaws.com/yapp-2023-3d-melanoma/Dataset1-LSP13626-invasive-margin.offsets.json',\n",
+ " coordination_values={\n",
+ " \"fileUid\": 'melanoma',\n",
+ " },\n",
+ " )\n",
+ ").add_object(\n",
+ " CsvWrapper(\n",
+ " data_type=\"obsEmbedding\",\n",
+ " csv_url='https://storage.googleapis.com/vitessce-demo-data/neuroglancer-march-2025/melanoma_with_embedding_filtered_ids.csv',\n",
+ " options= {\n",
+ " \"obsIndex\": 'id',\n",
+ " \"obsEmbedding\": ['tSNE1', 'tSNE2'],\n",
+ " },\n",
+ " coordination_values= {\n",
+ " \"obsType\": 'cell',\n",
+ " \"embeddingType\": 'TSNE',\n",
+ " },\n",
+ " )\n",
+ ").add_object(\n",
+ " CsvWrapper(\n",
+ " data_type=\"obsSets\",\n",
+ " csv_url='https://storage.googleapis.com/vitessce-demo-data/neuroglancer-march-2025/melanoma_with_embedding_filtered_ids.csv',\n",
+ " coordination_values={\n",
+ " \"obsType\": 'cell',\n",
+ " },\n",
+ " options= {\n",
+ " \"obsIndex\": 'id',\n",
+ " \"obsSets\": [\n",
+ " {\n",
+ " \"name\": 'Clusters',\n",
+ " \"column\": 'cluster',\n",
+ " },\n",
+ " ],\n",
+ " },\n",
+ " )\n",
+ ")\n",
+ "spatialThreeView = vc.add_view('spatialBeta', dataset=dataset);\n",
+ "lcView = vc.add_view('layerControllerBeta', dataset=dataset);\n",
+ "obsSets = vc.add_view('obsSets', dataset=dataset);\n",
+ "scatterView = vc.add_view('scatterplot', dataset=dataset, mapping=\"TSNE\");\n",
+ "# Configuration via props.viewerState is temporary and subject to change.\n",
+ "neuroglancerView = vc.add_view('neuroglancer', dataset=dataset).set_props(viewerState={\n",
+ " \"dimensions\": {\n",
+ " \"x\": [\n",
+ " 1e-9,\n",
+ " \"m\"\n",
+ " ],\n",
+ " \"y\": [\n",
+ " 1e-9,\n",
+ " \"m\"\n",
+ " ],\n",
+ " \"z\": [\n",
+ " 1e-9,\n",
+ " \"m\"\n",
+ " ]\n",
+ " },\n",
+ " \"position\": [\n",
+ " 49.5,\n",
+ " 1000.5,\n",
+ " 5209.5\n",
+ " ],\n",
+ " \"crossSectionScale\": 1,\n",
+ " \"projectionOrientation\": [\n",
+ " -0.636204183101654,\n",
+ " -0.5028395652770996,\n",
+ " 0.5443811416625977,\n",
+ " 0.2145828753709793\n",
+ " ],\n",
+ " \"projectionScale\": 1024,\n",
+ " \"layers\": [\n",
+ " {\n",
+ " \"type\": \"segmentation\",\n",
+ " \"source\": \"precomputed://https://vitessce-data-v2.s3.us-east-1.amazonaws.com/data/sorger/invasive_meshes\",\n",
+ " \"segments\": [\n",
+ " \"5\"\n",
+ " ],\n",
+ " \"segmentColors\": {\n",
+ " \"5\": \"red\"\n",
+ " },\n",
+ " \"name\": \"segmentation\"\n",
+ " }\n",
+ " ],\n",
+ " \"showSlices\": False,\n",
+ " \"layout\": \"3d\"\n",
+ "});\n",
+ "\n",
+ "vc.link_views([scatterView], ['embeddingObsRadiusMode', 'embeddingObsRadius'], ['manual', 4]);\n",
+ "\n",
+ "# Sync the zoom/rotation/pan states\n",
+ "vc.link_views_by_dict([spatialThreeView, lcView, neuroglancerView], {\n",
+ " \"spatialRenderingMode\": '3D',\n",
+ " \"spatialZoom\": 0,\n",
+ " \"spatialTargetT\": 0,\n",
+ " \"spatialTargetX\": 0,\n",
+ " \"spatialTargetY\": 0,\n",
+ " \"spatialTargetZ\": 0,\n",
+ " \"spatialRotationX\": 0,\n",
+ " \"spatialRotationY\": 0,\n",
+ "}, meta=False);\n",
+ "\n",
+ "# Initialize the image properties\n",
+ "vc.link_views_by_dict([spatialThreeView, lcView], {\n",
+ " \"imageLayer\": CL([\n",
+ " {\n",
+ " \"fileUid\": 'melanoma',\n",
+ " \"spatialLayerOpacity\": 1,\n",
+ " \"spatialTargetResolution\": None,\n",
+ " \"imageChannel\": CL([\n",
+ " {\n",
+ " \"spatialTargetC\": 0,\n",
+ " \"spatialChannelColor\": [255, 0, 0],\n",
+ " \"spatialChannelVisible\": True,\n",
+ " \"spatialChannelOpacity\": 1.0,\n",
+ " },\n",
+ " ]),\n",
+ " },\n",
+ " ]),\n",
+ "}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'));\n",
+ "\n",
+ "\n",
+ "vc.layout(hconcat(neuroglancerView, spatialThreeView, vconcat(lcView, obsSets, scatterView)));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "PKri",
+ "metadata": {},
+ "source": [
+ "## 2. Create the Vitessce widget"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {},
+ "source": [
+ "## 1. Configure Vitessce"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Example usage of Neuroglancer view"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/widget_pbmc.ipynb b/docs/notebooks/__ipynb__/widget_pbmc.ipynb
new file mode 100644
index 00000000..53ab9e82
--- /dev/null
+++ b/docs/notebooks/__ipynb__/widget_pbmc.ipynb
@@ -0,0 +1,189 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from os.path import join, isfile, isdir\n",
+ "from urllib.request import urlretrieve\n",
+ "from anndata import read_h5ad\n",
+ "import scanpy as sc\n",
+ "\n",
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " AnnDataWrapper,\n",
+ ")\n",
+ "from vitessce.data_utils import (\n",
+ " optimize_adata,\n",
+ " VAR_CHUNK_SIZE,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "iLit",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata_filepath = join(\"data\", \"pbmc3k_final.h5ad\")\n",
+ "if not isfile(adata_filepath):\n",
+ " os.makedirs(\"data\", exist_ok=True)\n",
+ " urlretrieve('https://seurat.nygenome.org/pbmc3k_final.h5ad', adata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Visualization of 3k PBMC reference"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {},
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the classes and functions that we will be using from the corresponding packages."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {},
+ "source": [
+ "## 2. Download the dataset\n",
+ "\n",
+ "Download `pbmc3k_final.h5ad` from https://seurat.nygenome.org/pbmc3k_final.h5ad"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "BYtC",
+ "metadata": {},
+ "source": [
+ "## 3.1 Save the AnnData object to Zarr"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Kclp",
+ "metadata": {},
+ "source": [
+ "## 4. Create a Vitessce view config\n",
+ "\n",
+ "Define the data and views you would like to include in the widget.\n",
+ "\n",
+ "For more details about how to configure data depending on where the files are located relative to the notebook execution, see https://python-docs.vitessce.io/data_options.html."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hstk",
+ "metadata": {},
+ "source": [
+ "## 5. Create the Vitessce widget"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Xref",
+ "metadata": {},
+ "source": [
+ "## 3. Load the dataset\n",
+ "\n",
+ "Load the dataset using AnnData's `read_h5ad` function."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata = read_h5ad(adata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "zarr_filepath = join('data', 'pbmc3k_final.zarr')\n",
+ "if not isdir(zarr_filepath):\n",
+ " adata_1 = optimize_adata(adata, obs_cols=['leiden'], obsm_keys=['X_umap', 'X_pca'], optimize_X=True)\n",
+ " adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "emfo",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='PBMC Reference')\n",
+ "dataset = vc.add_dataset(name='PBMC 3k').add_object(AnnDataWrapper(\n",
+ " adata_store=zarr_filepath,\n",
+ " obs_set_paths=[\"obs/leiden\"],\n",
+ " obs_set_names=[\"Leiden\"],\n",
+ " obs_embedding_paths=[\"obsm/X_umap\", \"obsm/X_pca\"],\n",
+ " obs_embedding_names=[\"UMAP\", \"PCA\"],\n",
+ " obs_feature_matrix_path=\"X\"\n",
+ "))\n",
+ "\n",
+ "umap = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
+ "pca = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"PCA\")\n",
+ "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
+ "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
+ "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)\n",
+ "\n",
+ "vc.layout((umap / pca) | ((cell_sets | genes) / heatmap));"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "nWHF",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/widget_pbmc_remote.ipynb b/docs/notebooks/__ipynb__/widget_pbmc_remote.ipynb
new file mode 100644
index 00000000..0cf0f95b
--- /dev/null
+++ b/docs/notebooks/__ipynb__/widget_pbmc_remote.ipynb
@@ -0,0 +1,140 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from os.path import join\n",
+ "from urllib.request import urlretrieve\n",
+ "from anndata import read_h5ad\n",
+ "import scanpy as sc\n",
+ "\n",
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " AnnDataWrapper,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "url = 'https://storage.googleapis.com/vitessce-demo-data/anndata-test/pbmc3k_processed.zarr/'"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "emfo",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='PBMC Reference')\n",
+ "dataset = vc.add_dataset(name='PBMC 3k').add_object(AnnDataWrapper(adata_url=url, obs_set_paths=[\"obs/louvain\"], obs_set_names=[\"Louvain\"], obs_embedding_paths=[\"obsm/X_umap\", \"obsm/X_pca\"], obs_embedding_names=[\"UMAP\", \"PCA\"], obs_feature_matrix_path=\"X\"))\n",
+ "\n",
+ "umap = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
+ "pca = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"PCA\")\n",
+ "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
+ "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
+ "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)\n",
+ "\n",
+ "vc.layout((umap / pca) | ((cell_sets | genes) / heatmap));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {},
+ "source": [
+ "## 2. Set the URL for the Remote Dataset\n",
+ "\n",
+ "For this example, we already have uploaded the `pbmc3k` dataset as a zarr store from the [scanpy docs](https://scanpy.readthedocs.io/en/stable/api/scanpy.datasets.pbmc3k.html) to the cloud."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Xref",
+ "metadata": {},
+ "source": [
+ "## 3. Create a Vitessce view config\n",
+ "\n",
+ "Define the data and views you would like to include in the widget."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Visualization of 3k PBMC reference from Remote Zarr Store"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "BYtC",
+ "metadata": {},
+ "source": [
+ "## 4. Create the Vitessce widget"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "RGSE",
+ "metadata": {},
+ "source": [
+ "A widget can be created with the `.widget()` method on the config instance. Here, the `proxy=True` parameter allows this widget to be used in a cloud notebook environment, such as Binder."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {},
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the classes and functions that we will be using from the corresponding packages."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Kclp",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/widget_plugin_custom.ipynb b/docs/notebooks/__ipynb__/widget_plugin_custom.ipynb
new file mode 100644
index 00000000..84733619
--- /dev/null
+++ b/docs/notebooks/__ipynb__/widget_plugin_custom.ipynb
@@ -0,0 +1,181 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " OmeTiffWrapper,\n",
+ " MultiImageWrapper,\n",
+ " VitesscePlugin\n",
+ ")\n",
+ "from oxc_py import transform"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "PLUGIN_ESM = transform(\"\"\"\n",
+ "function createPlugins(utilsForPlugins) {\n",
+ " const {\n",
+ " React,\n",
+ " PluginFileType,\n",
+ " PluginViewType,\n",
+ " PluginCoordinationType,\n",
+ " PluginJointFileType,\n",
+ " z,\n",
+ " useCoordination,\n",
+ " invokeCommand,\n",
+ " } = utilsForPlugins;\n",
+ "\n",
+ " const CSS = `\n",
+ " .chat {\n",
+ " overflow-y: scroll;\n",
+ " }\n",
+ " `;\n",
+ "\n",
+ " function ChatView(props) {\n",
+ "\n",
+ " const [nextMessage, setNextMessage] = React.useState('');\n",
+ " const [isLoading, setIsLoading] = React.useState(false);\n",
+ " const [chatHistory, setChatHistory] = React.useState([]); // chatHistory is an array of message objects like [{ user, text }, ...]\n",
+ "\n",
+ " async function handleClick() { \n",
+ " setChatHistory(prev => ([\n",
+ " ...prev,\n",
+ " { user: 'You', text: nextMessage },\n",
+ " ]));\n",
+ " setIsLoading(true);\n",
+ " const [chatReceiveValue, chatReceiveBuffers] = await invokeCommand(\"chat_send\", nextMessage, []);\n",
+ " setChatHistory(prev => ([\n",
+ " ...prev,\n",
+ " { user: 'AI', text: chatReceiveValue.text },\n",
+ " ]));\n",
+ " setIsLoading(false);\n",
+ " }\n",
+ "\n",
+ " return (\n",
+ " <>\n",
+ " \n",
+ " \n",
+ "
Chat view
\n",
+ "
\n",
+ " {chatHistory.map(message => (\n",
+ "
\n",
+ " {message.user} :\n",
+ " {message.text} \n",
+ "
\n",
+ " ))}\n",
+ "
\n",
+ "
setNextMessage(e.target.value)} disabled={isLoading} />\n",
+ "
Send message \n",
+ "
\n",
+ " >\n",
+ " );\n",
+ " }\n",
+ "\n",
+ " const pluginViewTypes = [\n",
+ " new PluginViewType('chat', ChatView, []),\n",
+ " ];\n",
+ " return { pluginViewTypes };\n",
+ "}\n",
+ "export default { createPlugins };\n",
+ "\"\"\")\n",
+ "\n",
+ "\n",
+ "def handle_chat_message(message, buffers):\n",
+ " return { \"text\": message.upper() }, []\n",
+ "\n",
+ "\n",
+ "class ChatPlugin(VitesscePlugin):\n",
+ " plugin_esm = PLUGIN_ESM\n",
+ " commands = {\n",
+ " \"chat_send\": handle_chat_message,\n",
+ " }"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='Spraggins Multi-Modal', description='PAS + IMS + AF From https://portal.hubmapconsortium.org/browse/collection/6a6efd0c1a2681dc7d2faab8e4ab0bca')\n",
+ "dataset = vc.add_dataset(name='Spraggins').add_object(\n",
+ " MultiImageWrapper(\n",
+ " image_wrappers=[\n",
+ " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/f4188a148e4c759092d19369d310883b/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-PAS_images/VAN0006-LK-2-85-PAS_registered.ome.tif?token=', name='PAS'),\n",
+ " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/2130d5f91ce61d7157a42c0497b06de8/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-AF_preIMS_images/VAN0006-LK-2-85-AF_preIMS_registered.ome.tif?token=', name='AF'),\n",
+ " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/be503a021ed910c0918842e318e6efa2/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_PosMode_multilayer.ome.tif?token=', name='IMS Pos Mode'),\n",
+ " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/ca886a630b2038997a4cfbbf4abfd283/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_NegMode_multilayer.ome.tif?token=', name='IMS Neg Mode')\n",
+ " ],\n",
+ " use_physical_size_scaling=True,\n",
+ " )\n",
+ ")\n",
+ "spatial = vc.add_view(cm.SPATIAL, dataset=dataset)\n",
+ "status = vc.add_view(\"chat\", dataset=dataset)\n",
+ "lc = vc.add_view(cm.LAYER_CONTROLLER, dataset=dataset).set_props(disableChannelsIfRgbDetected=True)\n",
+ "vc.layout(spatial | (lc / status));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "PKri",
+ "metadata": {},
+ "source": [
+ "## 2. Create the Vitessce widget"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Vitessce custom plugin definition"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget(plugins=[ChatPlugin()])\n",
+ "vw"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/widget_plugin_demo.ipynb b/docs/notebooks/__ipynb__/widget_plugin_demo.ipynb
new file mode 100644
index 00000000..cb6b0492
--- /dev/null
+++ b/docs/notebooks/__ipynb__/widget_plugin_demo.ipynb
@@ -0,0 +1,121 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " OmeTiffWrapper,\n",
+ " MultiImageWrapper,\n",
+ ")\n",
+ "from os.path import join"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce.widget_plugins import DemoPlugin"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='Spraggins Multi-Modal', description='PAS + IMS + AF From https://portal.hubmapconsortium.org/browse/collection/6a6efd0c1a2681dc7d2faab8e4ab0bca')\n",
+ "dataset = vc.add_dataset(name='Spraggins').add_object(\n",
+ " MultiImageWrapper(\n",
+ " image_wrappers=[\n",
+ " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/f4188a148e4c759092d19369d310883b/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-PAS_images/VAN0006-LK-2-85-PAS_registered.ome.tif?token=', name='PAS'),\n",
+ " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/2130d5f91ce61d7157a42c0497b06de8/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-AF_preIMS_images/VAN0006-LK-2-85-AF_preIMS_registered.ome.tif?token=', name='AF'),\n",
+ " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/be503a021ed910c0918842e318e6efa2/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_PosMode_multilayer.ome.tif?token=', name='IMS Pos Mode'),\n",
+ " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/ca886a630b2038997a4cfbbf4abfd283/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_NegMode_multilayer.ome.tif?token=', name='IMS Neg Mode')\n",
+ " ],\n",
+ " use_physical_size_scaling=True,\n",
+ " )\n",
+ ")\n",
+ "spatial = vc.add_view(cm.SPATIAL, dataset=dataset)\n",
+ "status = vc.add_view(\"demo\", dataset=dataset)\n",
+ "lc = vc.add_view(cm.LAYER_CONTROLLER, dataset=dataset).set_props(disableChannelsIfRgbDetected=True)\n",
+ "vc.layout(spatial | (lc / status));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "PKri",
+ "metadata": {},
+ "source": [
+ "## 1. Configure Vitessce\n",
+ "Set up the images from the three different assays, with the `use_physical_size_scaling` set to `True` so that the IMS image scales to the other images based on their physical sizes."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "SFPL",
+ "metadata": {},
+ "source": [
+ "## 2. Create the Vitessce widget"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {},
+ "source": [
+ "We visualize IMS, PAS, and AF imaging data overlaid from the Spraggins Lab of the Biomolecular Multimodal Imaging Center (BIOMC) at Vanderbilt University, uploaded to the HuBMAP data portal."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Vitessce plugin usage demo"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget(plugins=[DemoPlugin()])\n",
+ "vw"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/widget_segmentations_beta.ipynb b/docs/notebooks/__ipynb__/widget_segmentations_beta.ipynb
new file mode 100644
index 00000000..582d924a
--- /dev/null
+++ b/docs/notebooks/__ipynb__/widget_segmentations_beta.ipynb
@@ -0,0 +1,99 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " OmeTiffWrapper,\n",
+ " MultiImageWrapper,\n",
+ " CoordinationLevel as CL,\n",
+ " ObsSegmentationsOmeTiffWrapper,\n",
+ " ImageOmeTiffWrapper,\n",
+ " get_initial_coordination_scope_prefix,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.16\")\n",
+ "dataset = vc.add_dataset(name='Spraggins').add_object(\n",
+ " ImageOmeTiffWrapper(\n",
+ " img_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2_bf.ome.tif\",\n",
+ " offsets_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2_bf.offsets.json\"\n",
+ " )\n",
+ ").add_object(\n",
+ " ObsSegmentationsOmeTiffWrapper(\n",
+ " img_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2.ome.tif\",\n",
+ " offsets_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2.offsets.json\",\n",
+ " obs_types_from_channel_names=True\n",
+ " )\n",
+ ")\n",
+ "\n",
+ "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
+ "lc = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
+ "\n",
+ "vc.link_views_by_dict([spatial, lc], {\n",
+ " \"imageLayer\": CL([\n",
+ " {\n",
+ " \"photometricInterpretation\": \"RGB\" \n",
+ " }\n",
+ " ]),\n",
+ "}, meta=True, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
+ "\n",
+ "vc.layout(spatial | lc);"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# Visualization of OME-TIFF images and segmentation masks"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/__ipynb__/widget_shortcut.ipynb b/docs/notebooks/__ipynb__/widget_shortcut.ipynb
new file mode 100644
index 00000000..f80c8de7
--- /dev/null
+++ b/docs/notebooks/__ipynb__/widget_shortcut.ipynb
@@ -0,0 +1,157 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from os.path import join\n",
+ "from urllib.request import urlretrieve\n",
+ "from anndata import read_h5ad\n",
+ "import scanpy as sc\n",
+ "\n",
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " AnnDataWrapper,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Hstk",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata = read_h5ad(join(\"data\", \"habib17.processed.h5ad\"))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "os.makedirs(\"data\", exist_ok=True)\n",
+ "adata_filepath = join(\"data\", \"habib17.processed.h5ad\")\n",
+ "urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "BYtC",
+ "metadata": {},
+ "source": [
+ "## 3.1. Preprocess the Data For Visualization"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Xref",
+ "metadata": {},
+ "source": [
+ "## 3. Load the data"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Kclp",
+ "metadata": {},
+ "source": [
+ "With one line of code, you may create a Vitessce widget based on an automatically inferred configuration."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {},
+ "source": [
+ "# The from_object shortcut"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {},
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {},
+ "source": [
+ "## 2. Download the data\n",
+ "\n",
+ "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {},
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "Import the functions and classes that we will be using."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "top_dispersion = adata.var[\"dispersions_norm\"][\n",
+ " sorted(\n",
+ " range(len(adata.var[\"dispersions_norm\"])),\n",
+ " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
+ " )[-51:][0]\n",
+ "]\n",
+ "adata.var[\"top_highly_variable\"] = (\n",
+ " adata.var[\"dispersions_norm\"] > top_dispersion\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "emfo",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = VitessceConfig.from_object(AnnDataWrapper(\n",
+ " adata,\n",
+ " obs_embedding_paths=[\"obsm/X_umap\"],\n",
+ " obs_embedding_names=[\"UMAP\"],\n",
+ " obs_set_paths=[\"obs/CellType\"],\n",
+ " obs_set_names=[\"Cell Type\"],\n",
+ " obs_feature_matrix_path=\"X\",\n",
+ " feature_filter_path=\"var/top_highly_variable\"\n",
+ "), schema_version=\"1.0.15\").widget(height=800)\n",
+ "vw"
+ ]
+ }
+ ],
+ "metadata": {},
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/docs/notebooks/marimo-wasm.py b/docs/notebooks/marimo-wasm.mo.py
similarity index 96%
rename from docs/notebooks/marimo-wasm.py
rename to docs/notebooks/marimo-wasm.mo.py
index 78c82ace..4ec0806c 100644
--- a/docs/notebooks/marimo-wasm.py
+++ b/docs/notebooks/marimo-wasm.mo.py
@@ -68,13 +68,13 @@ def _(mo):
@app.cell
def _(vw):
- vw.config
+ vw._config
return
@app.cell
def _(vw):
- vw.config["coordinationSpace"]["spatialZoom"]
+ vw._config["coordinationSpace"]["spatialZoom"]
return
@app.cell
diff --git a/docs/notebooks/marimo.py b/docs/notebooks/marimo.mo.py
similarity index 100%
rename from docs/notebooks/marimo.py
rename to docs/notebooks/marimo.mo.py
diff --git a/scripts/convert_mo_to_ipynb.sh b/scripts/convert_mo_to_ipynb.sh
new file mode 100644
index 00000000..bd27ca78
--- /dev/null
+++ b/scripts/convert_mo_to_ipynb.sh
@@ -0,0 +1,6 @@
+cd docs/notebooks
+
+for file in *.mo.py; do
+ echo "Converting $file to ${file%.mo.py}.ipynb"
+ marimo export ipynb "$file" --output "__ipynb__/${file%.mo.py}.ipynb" --force
+done
\ No newline at end of file
diff --git a/tests-widget/example.spec.js b/tests-widget/example.spec.js
index 6f165468..6d3d4c84 100644
--- a/tests-widget/example.spec.js
+++ b/tests-widget/example.spec.js
@@ -3,7 +3,7 @@ import { test, expect } from '@playwright/test';
test('Renders Vitessce widget containing a scatterplot view (Jupyter)', async ({ page }) => {
test.setTimeout(60_000);
- await page.goto('http://localhost:3000/widget_from_dict.html');
+ await page.goto('http://localhost:3000/__ipynb__/widget_from_dict.html');
// Expect a title "to contain" a substring.
await expect(page).toHaveTitle('widget_from_dict');
@@ -14,7 +14,7 @@ test('Renders Vitessce widget containing a scatterplot view (Jupyter)', async ({
test('Renders Vitessce widget containing a scatterplot view (Marimo)', async ({ page }) => {
test.setTimeout(60_000);
- await page.goto('http://localhost:3000/marimo.html');
+ await page.goto('http://localhost:3000/marimo.mo.html');
// Expect a title "to contain" a substring.
await expect(page).toHaveTitle('marimo');
From 98363e5a734b449ea3bcb8b8bd6823e65711ef9e Mon Sep 17 00:00:00 2001
From: Mark Keller <7525285+keller-mark@users.noreply.github.com>
Date: Fri, 8 Aug 2025 11:26:26 -0400
Subject: [PATCH 03/10] Update
---
.github/workflows/docs.yml | 3 ++-
.gitignore | 5 +++++
docs/_static/mo/.gitkeep | 0
docs/data_examples.rst | 8 ++++----
docs/widget_examples.rst | 40 +++++++++++++++++++-------------------
5 files changed, 31 insertions(+), 25 deletions(-)
create mode 100644 docs/_static/mo/.gitkeep
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index c5a5f282..74cfbff5 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -14,5 +14,6 @@ jobs:
run: |
sudo apt-get update
sudo apt-get install -y pandoc
- - run: uv sync --extra docs --extra all
+ - run: uv sync --extra docs --extra notebook --extra all
+ - run: uv run marimo export html-wasm docs/notebooks/marimo-wasm.mo.py -o docs/_static/mo/marimo-wasm.mo.html --mode edit
- run: uv run make html
diff --git a/.gitignore b/.gitignore
index 5fab4c92..7059a3a7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,9 @@ tests/data/*
./notebooks/
docs/notebooks/data/
docs/notebooks/data-cropped/
+docs/notebooks/kpmp-2024/
+docs/notebooks/segmentations/
+docs/notebooks/*.json
docs/notebooks/*.html
docs/notebooks/*.ipynb
docs/notebooks/*.zarr/
@@ -23,6 +26,8 @@ demos/*/vitessce.local.json
demos/*/vitessce.remote.json
.pytest_cache/
__marimo__/
+assets/
+docs/_static/mo/
# Compiled javascript
vitessce/static/
diff --git a/docs/_static/mo/.gitkeep b/docs/_static/mo/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/docs/data_examples.rst b/docs/data_examples.rst
index 4553453c..f39979a1 100644
--- a/docs/data_examples.rst
+++ b/docs/data_examples.rst
@@ -5,7 +5,7 @@ Data preparation examples
.. toctree::
:maxdepth: 2
- notebooks/data_export_s3
- notebooks/data_export_files
- notebooks/widget_brain_with_base_dir
- notebooks/widget_brain_h5ad
\ No newline at end of file
+ notebooks/__ipynb__/data_export_s3
+ notebooks/__ipynb__/data_export_files
+ notebooks/__ipynb__/widget_brain_with_base_dir
+ notebooks/__ipynb__/widget_brain_h5ad
\ No newline at end of file
diff --git a/docs/widget_examples.rst b/docs/widget_examples.rst
index 4e81237c..2a94cbef 100644
--- a/docs/widget_examples.rst
+++ b/docs/widget_examples.rst
@@ -4,23 +4,23 @@ Widget examples
.. toctree::
:maxdepth: 1
- notebooks/widget_brain
- notebooks/widget_brain_h5ad
- notebooks/widget_brain_with_base_dir
- notebooks/web_app_brain
- notebooks/widget_genomic_profiles
- notebooks/widget_imaging
- notebooks/widget_segmentations_beta
- notebooks/widget_pbmc
- notebooks/widget_pbmc_remote
- notebooks/spatial_data
- notebooks/spatial_data_blobs
- notebooks/spatial_data_mouseliver
- notebooks/spatial_data_mouseliver_remote
- notebooks/widget_loom
- notebooks/widget_from_dict
- notebooks/widget_modify_config
- notebooks/widget_plugin_demo
- notebooks/widget_plugin_custom
- notebooks/widget_plugin_spatial-query
- notebooks/page_mode_example
+ notebooks/__ipynb__/widget_brain
+ notebooks/__ipynb__/widget_brain_h5ad
+ notebooks/__ipynb__/widget_brain_with_base_dir
+ notebooks/__ipynb__/web_app_brain
+ notebooks/__ipynb__/widget_genomic_profiles
+ notebooks/__ipynb__/widget_imaging
+ notebooks/__ipynb__/widget_segmentations_beta
+ notebooks/__ipynb__/widget_pbmc
+ notebooks/__ipynb__/widget_pbmc_remote
+ notebooks/__ipynb__/spatial_data
+ notebooks/__ipynb__/spatial_data_blobs
+ notebooks/__ipynb__/spatial_data_mouseliver
+ notebooks/__ipynb__/spatial_data_mouseliver_remote
+ notebooks/__ipynb__/widget_loom
+ notebooks/__ipynb__/widget_from_dict
+ notebooks/__ipynb__/widget_modify_config
+ notebooks/__ipynb__/widget_plugin_demo
+ notebooks/__ipynb__/widget_plugin_custom
+ notebooks/__ipynb__/widget_plugin_spatial-query
+ notebooks/__ipynb__/page_mode_example
From 6b6061d7113cdf6520409bca24484dad8c495973 Mon Sep 17 00:00:00 2001
From: Mark Keller <7525285+keller-mark@users.noreply.github.com>
Date: Fri, 8 Aug 2025 11:28:18 -0400
Subject: [PATCH 04/10] Update
---
docs/notebooks/__ipynb__/example_configs.py | 107 ++++++++++++++++++++
scripts/convert_mo_to_ipynb.sh | 4 +-
2 files changed, 110 insertions(+), 1 deletion(-)
create mode 100644 docs/notebooks/__ipynb__/example_configs.py
diff --git a/docs/notebooks/__ipynb__/example_configs.py b/docs/notebooks/__ipynb__/example_configs.py
new file mode 100644
index 00000000..c965f282
--- /dev/null
+++ b/docs/notebooks/__ipynb__/example_configs.py
@@ -0,0 +1,107 @@
+dries = {
+ "name": "Dries",
+ "version": "1.0.0",
+ "description": "Giotto, a pipeline for integrative analysis and visualization of single-cell spatial transcriptomic data",
+ "public": True,
+ "datasets": [
+ {
+ "uid": 'dries-2019',
+ "name": 'Dries 2019',
+ "files": [
+ {
+ "type": "cells",
+ "fileType": "cells.json",
+ "url": "https://s3.amazonaws.com/vitessce-data/0.0.31/master_release/dries/dries.cells.json"
+ },
+ {
+ "type": "cell-sets",
+ "fileType": "cell-sets.json",
+ "url": "https://s3.amazonaws.com/vitessce-data/0.0.31/master_release/dries/dries.cell-sets.json"
+ }
+ ]
+ }
+ ],
+ "initStrategy": "auto",
+ "coordinationSpace": {
+ "embeddingType": {
+ "TSNE": 't-SNE',
+ "UMAP": 'UMAP',
+ },
+ "embeddingZoom": {
+ "TSNE": 3,
+ "UMAP": 3,
+ },
+ "spatialZoom": {
+ "A": -4.4,
+ },
+ "spatialTargetX": {
+ "A": 3800,
+ },
+ "spatialTargetY": {
+ "A": -900,
+ },
+ },
+ "layout": [
+ {
+ "component": "description",
+ "props": {
+ "description": "Giotto, a pipeline for integrative analysis and visualization of single-cell spatial transcriptomic data"
+ },
+ "x": 9,
+ "y": 0,
+ "w": 3,
+ "h": 4
+ },
+ {
+ "component": "cellSets",
+ "x": 9,
+ "y": 4,
+ "w": 3,
+ "h": 4
+ },
+ {
+ "component": "cellSetSizes",
+ "x": 5,
+ "y": 4,
+ "w": 4,
+ "h": 4
+ },
+ {
+ "component": "scatterplot",
+ "coordinationScopes": {
+ "embeddingType": 'TSNE',
+ "embeddingZoom": 'TSNE'
+ },
+ "x": 0,
+ "y": 2,
+ "w": 5,
+ "h": 4
+ },
+ {
+ "component": "spatial",
+ "props": {
+ "cellRadius": 50
+ },
+ "coordinationScopes": {
+ "spatialZoom": 'A',
+ "spatialTargetX": 'A',
+ "spatialTargetY": 'A'
+ },
+ "x": 5,
+ "y": 0,
+ "w": 4,
+ "h": 4
+ },
+ {
+ "component": "scatterplot",
+ "coordinationScopes": {
+ "embeddingType": 'UMAP',
+ "embeddingZoom": 'UMAP'
+ },
+ "x": 0,
+ "y": 0,
+ "w": 5,
+ "h": 4
+ }
+ ]
+}
diff --git a/scripts/convert_mo_to_ipynb.sh b/scripts/convert_mo_to_ipynb.sh
index bd27ca78..0d4854fb 100644
--- a/scripts/convert_mo_to_ipynb.sh
+++ b/scripts/convert_mo_to_ipynb.sh
@@ -3,4 +3,6 @@ cd docs/notebooks
for file in *.mo.py; do
echo "Converting $file to ${file%.mo.py}.ipynb"
marimo export ipynb "$file" --output "__ipynb__/${file%.mo.py}.ipynb" --force
-done
\ No newline at end of file
+done
+
+cp example_configs.py "__ipynb__/example_configs.py"
\ No newline at end of file
From 084cfacbe3029438190fb3ddccaacd79324c0fe9 Mon Sep 17 00:00:00 2001
From: Mark Keller <7525285+keller-mark@users.noreply.github.com>
Date: Fri, 8 Aug 2025 11:48:44 -0400
Subject: [PATCH 05/10] Script options
---
scripts/convert_mo_to_ipynb.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/convert_mo_to_ipynb.sh b/scripts/convert_mo_to_ipynb.sh
index 0d4854fb..7aed1a0d 100644
--- a/scripts/convert_mo_to_ipynb.sh
+++ b/scripts/convert_mo_to_ipynb.sh
@@ -2,7 +2,7 @@ cd docs/notebooks
for file in *.mo.py; do
echo "Converting $file to ${file%.mo.py}.ipynb"
- marimo export ipynb "$file" --output "__ipynb__/${file%.mo.py}.ipynb" --force
+ uv run marimo export ipynb —-sort=top-down --force --output "__ipynb__/${file%.mo.py}.ipynb" "$file"
done
cp example_configs.py "__ipynb__/example_configs.py"
\ No newline at end of file
From cddcccc8d2220fa7b2b5ffba98d32f07d20d6648 Mon Sep 17 00:00:00 2001
From: Mark Keller <7525285+keller-mark@users.noreply.github.com>
Date: Fri, 8 Aug 2025 12:16:21 -0400
Subject: [PATCH 06/10] Update
---
...rowser_to_vitessce_config_conversion.ipynb | 152 +--
.../__ipynb__/config_to_python.ipynb | 144 ++-
.../notebooks/__ipynb__/data_conversion.ipynb | 90 +-
.../__ipynb__/data_export_files.ipynb | 224 +++--
docs/notebooks/__ipynb__/data_export_s3.ipynb | 222 +++--
.../__ipynb__/page_mode_comparative.ipynb | 470 ++++-----
.../__ipynb__/page_mode_example.ipynb | 166 ++--
docs/notebooks/__ipynb__/spatial_data.ipynb | 118 ++-
.../__ipynb__/spatial_data_blobs.ipynb | 124 +--
.../__ipynb__/spatial_data_kpmp_vis.ipynb | 90 +-
.../__ipynb__/spatial_data_merfish.ipynb | 100 +-
.../__ipynb__/spatial_data_merfish_2.ipynb | 130 +--
.../__ipynb__/spatial_data_mouseliver.ipynb | 916 +++++++++++-------
.../spatial_data_mouseliver_remote.ipynb | 680 ++++++++-----
.../__ipynb__/spatial_data_visium_hd.ipynb | 210 ++--
docs/notebooks/__ipynb__/web_app_brain.ipynb | 296 +++---
.../__ipynb__/widget_anndata_with_image.ipynb | 82 +-
docs/notebooks/__ipynb__/widget_brain.ipynb | 338 ++++---
.../__ipynb__/widget_brain_h5ad.ipynb | 136 +--
.../widget_brain_with_base_dir.ipynb | 386 +++++---
.../widget_brain_with_quality_metric.ipynb | 188 ++--
.../__ipynb__/widget_from_dict.ipynb | 110 ++-
.../__ipynb__/widget_genomic_profiles.ipynb | 206 ++--
docs/notebooks/__ipynb__/widget_imaging.ipynb | 76 +-
.../__ipynb__/widget_imaging_beta.ipynb | 76 +-
.../widget_imaging_segmentation.ipynb | 76 +-
docs/notebooks/__ipynb__/widget_loom.ipynb | 224 +++--
.../__ipynb__/widget_modify_config.ipynb | 58 +-
.../__ipynb__/widget_neuroglancer.ipynb | 72 +-
docs/notebooks/__ipynb__/widget_pbmc.ipynb | 186 ++--
.../__ipynb__/widget_pbmc_remote.ipynb | 140 +--
.../__ipynb__/widget_plugin_custom.ipynb | 60 +-
.../__ipynb__/widget_plugin_demo.ipynb | 98 +-
.../__ipynb__/widget_segmentations_beta.ipynb | 48 +-
.../notebooks/__ipynb__/widget_shortcut.ipynb | 156 +--
...rowser_to_vitessce_config_conversion.mo.py | 18 +-
docs/notebooks/data_conversion.mo.py | 10 -
docs/notebooks/data_export_files.mo.py | 10 -
docs/notebooks/data_export_s3.mo.py | 10 -
docs/notebooks/page_mode_comparative.mo.py | 10 -
docs/notebooks/page_mode_example.mo.py | 10 -
docs/notebooks/spatial_data.mo.py | 10 -
docs/notebooks/spatial_data_blobs.mo.py | 10 -
docs/notebooks/spatial_data_kpmp_vis.mo.py | 2 +-
docs/notebooks/spatial_data_merfish.mo.py | 10 -
docs/notebooks/spatial_data_merfish_2.mo.py | 10 -
docs/notebooks/spatial_data_mouseliver.mo.py | 10 -
.../spatial_data_mouseliver_remote.mo.py | 250 ++---
docs/notebooks/spatial_data_visium_hd.mo.py | 62 +-
.../notebooks/widget_anndata_with_image.mo.py | 10 -
docs/notebooks/widget_brain.mo.py | 10 -
docs/notebooks/widget_brain_h5ad.mo.py | 10 -
.../widget_brain_with_base_dir.mo.py | 10 -
.../widget_brain_with_quality_metric.mo.py | 10 -
docs/notebooks/widget_from_dict.mo.py | 10 -
docs/notebooks/widget_genomic_profiles.mo.py | 10 -
docs/notebooks/widget_imaging.mo.py | 10 -
docs/notebooks/widget_imaging_beta.mo.py | 10 -
.../widget_imaging_segmentation.mo.py | 10 -
docs/notebooks/widget_loom.mo.py | 10 -
docs/notebooks/widget_modify_config.mo.py | 10 -
docs/notebooks/widget_neuroglancer.mo.py | 10 -
docs/notebooks/widget_on_colab.mo.py | 10 -
docs/notebooks/widget_pbmc.mo.py | 10 -
docs/notebooks/widget_pbmc_remote.mo.py | 10 -
docs/notebooks/widget_plugin_custom.mo.py | 10 -
docs/notebooks/widget_plugin_demo.mo.py | 10 -
.../widget_plugin_spatial-query.mo.py | 10 -
.../notebooks/widget_segmentations_beta.mo.py | 10 -
docs/notebooks/widget_shortcut.mo.py | 10 -
pyproject.toml | 2 +-
scripts/convert_mo_to_ipynb.sh | 9 +-
72 files changed, 4148 insertions(+), 3353 deletions(-)
diff --git a/docs/notebooks/__ipynb__/cellbrowser_to_vitessce_config_conversion.ipynb b/docs/notebooks/__ipynb__/cellbrowser_to_vitessce_config_conversion.ipynb
index cd9b5cd2..df25ea7c 100644
--- a/docs/notebooks/__ipynb__/cellbrowser_to_vitessce_config_conversion.ipynb
+++ b/docs/notebooks/__ipynb__/cellbrowser_to_vitessce_config_conversion.ipynb
@@ -3,74 +3,37 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "vblA",
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "import json\n",
- "from os.path import join\n",
- "from vitessce import (\n",
- " convert_cell_browser_project_to_anndata,\n",
- " AnnDataWrapper,\n",
- " VitessceConfig,\n",
- ")\n",
- "from vitessce.data_utils import VAR_CHUNK_SIZE"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "lEQa",
- "metadata": {},
- "outputs": [],
- "source": [
- "## 3. Convert UCSC Cell Browser project to a Vitessce view config"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Hstk",
+ "id": "Hbol",
"metadata": {},
"outputs": [],
"source": [
"import marimo as mo"
]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "PKri",
- "metadata": {},
- "outputs": [],
- "source": [
- "# Example run, coverting \"adultPancreas\" project:\n",
- "adata = convert_cell_browser_project_to_anndata(project_name=\"adultPancreas\", keep_only_marker_genes=True)"
- ]
- },
{
"cell_type": "markdown",
- "id": "BYtC",
- "metadata": {},
- "source": [
- "## 3. Configure Vitessce with the AnnData-Zarr store"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "bkHC",
- "metadata": {},
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## 1. Convert UCSC Cell Browser project to a format that is supported by Vitessce\n",
- "#### Output:\n",
- "An AnnData object"
+ "# Load UCSC Cell Browser project in Vitessce"
]
},
{
"cell_type": "markdown",
- "id": "MJUe",
- "metadata": {},
+ "id": "vblA",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"This notebook shows you how to use the `convert_cell_browser_project_to_anndata` function, which allows you to take an existing project, published in https://cells.ucsc.edu/ and:\n",
"1. Convert it into the AnnData format that is supported by Vitessce\n",
@@ -84,27 +47,62 @@
]
},
{
- "cell_type": "markdown",
- "id": "Kclp",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
"metadata": {},
+ "outputs": [],
"source": [
- "## 4. Render the Vitessce widget"
+ "import os\n",
+ "import json\n",
+ "from os.path import join\n",
+ "from vitessce import (\n",
+ " convert_cell_browser_project_to_anndata,\n",
+ " AnnDataWrapper,\n",
+ " VitessceConfig,\n",
+ ")\n",
+ "from vitessce.data_utils import VAR_CHUNK_SIZE"
]
},
{
"cell_type": "markdown",
- "id": "Xref",
+ "id": "lEQa",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Convert UCSC Cell Browser project to a format that is supported by Vitessce\n",
+ "#### Output:\n",
+ "An AnnData object"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
"metadata": {},
+ "outputs": [],
"source": [
- "## 2. Save the AnnData object as a Zarr store"
+ "# Example run, coverting \"adultPancreas\" project:\n",
+ "adata = convert_cell_browser_project_to_anndata(project_name=\"adultPancreas\", keep_only_marker_genes=True)"
]
},
{
"cell_type": "markdown",
- "id": "Hbol",
- "metadata": {},
+ "id": "Xref",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "# Load UCSC Cell Browser project in Vitessce"
+ "## 2. Save the AnnData object as a Zarr store"
]
},
{
@@ -119,6 +117,20 @@
"adata.write_zarr(zarr_filepath, chunks=[adata.shape[0], VAR_CHUNK_SIZE])"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "BYtC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 3. Configure Vitessce with the AnnData-Zarr store"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
@@ -138,6 +150,20 @@
"anndata_wrapper_inst.auto_view_config(vc)"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "Kclp",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 4. Render the Vitessce widget"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
diff --git a/docs/notebooks/__ipynb__/config_to_python.ipynb b/docs/notebooks/__ipynb__/config_to_python.ipynb
index 0d23caa2..672f44c4 100644
--- a/docs/notebooks/__ipynb__/config_to_python.ipynb
+++ b/docs/notebooks/__ipynb__/config_to_python.ipynb
@@ -1,5 +1,19 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Generate Python code to reconstruct a VitessceConfig instance"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
@@ -21,13 +35,17 @@
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "ROlb",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "import marimo as mo"
+ "## Load a view config from a dict representation"
]
},
{
@@ -42,32 +60,39 @@
},
{
"cell_type": "markdown",
- "id": "nWHF",
- "metadata": {},
- "source": [
- "## Evaluate the code and render a Vitessce widget"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Hstk",
- "metadata": {},
+ "id": "PKri",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "The second value is the code snippet. When evaluated, the result will be a new `VitessceConfig` instance."
+ "## Print to JSON"
]
},
{
- "cell_type": "markdown",
- "id": "PKri",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
"metadata": {},
+ "outputs": [],
"source": [
- "## Print to JSON"
+ "import json\n",
+ "print(json.dumps(vc.to_dict(), indent=2))"
]
},
{
"cell_type": "markdown",
"id": "SFPL",
- "metadata": {},
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"## Print to Python\n",
"\n",
@@ -75,88 +100,105 @@
]
},
{
- "cell_type": "markdown",
- "id": "RGSE",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
"metadata": {},
+ "outputs": [],
"source": [
- "The first value returned is a list of classes used by the code snippet."
+ "imports, code = vc.to_python()"
]
},
{
"cell_type": "markdown",
- "id": "bkHC",
- "metadata": {},
+ "id": "RGSE",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## Load a view config from a dict representation"
+ "The first value returned is a list of classes used by the code snippet."
]
},
{
- "cell_type": "markdown",
- "id": "Hbol",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Kclp",
"metadata": {},
+ "outputs": [],
"source": [
- "# Generate Python code to reconstruct a VitessceConfig instance"
+ "imports"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "BYtC",
+ "id": "emfo",
"metadata": {},
"outputs": [],
"source": [
- "imports, code = vc.to_python()"
+ "print(code)"
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "Hstk",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "import json\n",
- "print(json.dumps(vc.to_dict(), indent=2))"
+ "The second value is the code snippet. When evaluated, the result will be a new `VitessceConfig` instance."
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "iLit",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "nWHF",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "reconstructed_vc = eval(code)"
+ "## Evaluate the code and render a Vitessce widget"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "emfo",
+ "id": "iLit",
"metadata": {},
"outputs": [],
"source": [
- "print(code)"
+ "reconstructed_vc = eval(code)"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "Kclp",
+ "id": "ZHCJ",
"metadata": {},
"outputs": [],
"source": [
- "imports"
+ "reconstructed_vc.widget()"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "ZHCJ",
+ "id": "ROlb",
"metadata": {},
"outputs": [],
"source": [
- "reconstructed_vc.widget()"
+ "import marimo as mo"
]
}
],
diff --git a/docs/notebooks/__ipynb__/data_conversion.ipynb b/docs/notebooks/__ipynb__/data_conversion.ipynb
index 24645174..0490c213 100644
--- a/docs/notebooks/__ipynb__/data_conversion.ipynb
+++ b/docs/notebooks/__ipynb__/data_conversion.ipynb
@@ -1,47 +1,29 @@
{
"cells": [
{
- "cell_type": "code",
- "execution_count": null,
- "id": "bkHC",
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import SnapWrapper\n",
- "from os.path import join\n",
- "from scipy.io import mmread\n",
- "import pandas as pd\n",
- "import numpy as np\n",
- "import json"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "lEQa",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "mtx = mmread(join('data', 'snapatac', 'filtered_cell_by_bin.mtx'))\n",
- "barcodes_df = pd.read_csv(join('data', 'snapatac', 'barcodes.txt'), header=None)\n",
- "bins_df = pd.read_csv(join('data', 'snapatac', 'bins.txt'), header=None)\n",
- "clusters_df = pd.read_csv(join('data', 'snapatac', 'umap_coords_clusters.csv'), index_col=0)"
+ "# Convert data manually"
]
},
{
"cell_type": "markdown",
- "id": "vblA",
- "metadata": {},
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"When running the Vitessce widget, data is converted on-the-fly into formats that the Vitessce JavaScript component can render.\n",
"The converted data is stored in temporary files, preventing long-term use of the converted files.\n",
@@ -53,25 +35,37 @@
]
},
{
- "cell_type": "markdown",
- "id": "MJUe",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
"metadata": {},
+ "outputs": [],
"source": [
- "# Convert data manually"
+ "from vitessce import SnapWrapper\n",
+ "from os.path import join\n",
+ "from scipy.io import mmread\n",
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "import json"
]
},
{
- "cell_type": "markdown",
- "id": "Hbol",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
"metadata": {},
+ "outputs": [],
"source": [
- "# Vitessce Data Preparation Tutorial"
+ "mtx = mmread(join('data', 'snapatac', 'filtered_cell_by_bin.mtx'))\n",
+ "barcodes_df = pd.read_csv(join('data', 'snapatac', 'barcodes.txt'), header=None)\n",
+ "bins_df = pd.read_csv(join('data', 'snapatac', 'bins.txt'), header=None)\n",
+ "clusters_df = pd.read_csv(join('data', 'snapatac', 'umap_coords_clusters.csv'), index_col=0)"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "PKri",
+ "id": "lEQa",
"metadata": {},
"outputs": [],
"source": [
@@ -91,6 +85,16 @@
"\n",
"w.create_genomic_multivec_zarr(zarr_filepath)"
]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
}
],
"metadata": {},
diff --git a/docs/notebooks/__ipynb__/data_export_files.ipynb b/docs/notebooks/__ipynb__/data_export_files.ipynb
index 972257bb..97827fc1 100644
--- a/docs/notebooks/__ipynb__/data_export_files.ipynb
+++ b/docs/notebooks/__ipynb__/data_export_files.ipynb
@@ -1,9 +1,39 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Export data to local files"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the classes and functions that we will be using from the corresponding packages."
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "bkHC",
+ "id": "vblA",
"metadata": {},
"outputs": [],
"source": [
@@ -29,19 +59,25 @@
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "ROlb",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "import marimo as mo"
+ "## 2. Download and process data\n",
+ "\n",
+ "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "PKri",
+ "id": "lEQa",
"metadata": {},
"outputs": [],
"source": [
@@ -63,71 +99,120 @@
]
},
{
- "cell_type": "markdown",
- "id": "lEQa",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
"metadata": {},
+ "outputs": [],
"source": [
- "## 2. Download and process data\n",
- "\n",
- "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
+ "zarr_filepath = join('data', 'habib17.processed.zarr')\n",
+ "if not isdir(zarr_filepath):\n",
+ " adata_1 = optimize_adata(adata, obs_cols=['CellType'], obsm_keys=['X_umap'], var_cols=['top_highly_variable'], optimize_X=True)\n",
+ " adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])"
]
},
{
"cell_type": "markdown",
- "id": "Hstk",
- "metadata": {},
+ "id": "Xref",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## 5. Serve the files"
+ "## 3. Create the Vitessce configuration"
]
},
{
"cell_type": "markdown",
- "id": "vblA",
- "metadata": {},
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## 1. Import dependencies\n",
- "\n",
- "We need to import the classes and functions that we will be using from the corresponding packages."
+ "Set up the configuration by adding the views and datasets of interest."
]
},
{
- "cell_type": "markdown",
- "id": "Hbol",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
"metadata": {},
+ "outputs": [],
"source": [
- "# Vitessce Data Preparation Tutorial"
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', description='COVID-19 Healthy Donor Brain')\n",
+ "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
+ " adata_path=zarr_filepath,\n",
+ " obs_embedding_paths=[\"obsm/X_umap\"],\n",
+ " obs_embedding_names=[\"UMAP\"],\n",
+ " obs_set_paths=[\"obs/CellType\"],\n",
+ " obs_set_names=[\"Cell Type\"],\n",
+ " obs_feature_matrix_path=\"X\",\n",
+ " feature_filter_path=\"var/top_highly_variable\"\n",
+ "))\n",
+ "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"X_umap\")\n",
+ "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
+ "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
+ "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)\n",
+ "vc.layout((scatterplot | (cell_sets / genes)) / heatmap);"
]
},
{
"cell_type": "markdown",
- "id": "SFPL",
- "metadata": {},
+ "id": "RGSE",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## 3. Create the Vitessce configuration"
+ "## 4. Export files to a local directory\n",
+ "\n",
+ "The `.export(to='files')` method on the view config instance will export files to the specified directory `out_dir`. The `base_url` parameter is required so that the file URLs in the view config point to the location where you ultimately intend to serve the files."
]
},
{
- "cell_type": "markdown",
- "id": "BYtC",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Kclp",
"metadata": {},
+ "outputs": [],
"source": [
- "Set up the configuration by adding the views and datasets of interest."
+ "config_dict = vc.export(to='files', base_url='http://localhost:3000', out_dir='./test')"
]
},
{
"cell_type": "markdown",
- "id": "Kclp",
- "metadata": {},
+ "id": "emfo",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## 4. Export files to a local directory\n",
- "\n",
- "The `.export(to='files')` method on the view config instance will export files to the specified directory `out_dir`. The `base_url` parameter is required so that the file URLs in the view config point to the location where you ultimately intend to serve the files."
+ "## 5. Serve the files"
]
},
{
"cell_type": "markdown",
- "id": "nWHF",
- "metadata": {},
+ "id": "Hstk",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"Now that the files have been saved to the `./test` directory, they can be served by any static web server.\n",
"\n",
@@ -140,16 +225,14 @@
},
{
"cell_type": "markdown",
- "id": "MJUe",
- "metadata": {},
- "source": [
- "# Export data to local files"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "iLit",
- "metadata": {},
+ "id": "nWHF",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"## 6. View on vitessce.io\n",
"\n",
@@ -159,48 +242,13 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "zarr_filepath = join('data', 'habib17.processed.zarr')\n",
- "if not isdir(zarr_filepath):\n",
- " adata_1 = optimize_adata(adata, obs_cols=['CellType'], obsm_keys=['X_umap'], var_cols=['top_highly_variable'], optimize_X=True)\n",
- " adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "RGSE",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', description='COVID-19 Healthy Donor Brain')\n",
- "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
- " adata_path=zarr_filepath,\n",
- " obs_embedding_paths=[\"obsm/X_umap\"],\n",
- " obs_embedding_names=[\"UMAP\"],\n",
- " obs_set_paths=[\"obs/CellType\"],\n",
- " obs_set_names=[\"Cell Type\"],\n",
- " obs_feature_matrix_path=\"X\",\n",
- " feature_filter_path=\"var/top_highly_variable\"\n",
- "))\n",
- "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"X_umap\")\n",
- "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
- "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
- "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)\n",
- "vc.layout((scatterplot | (cell_sets / genes)) / heatmap);"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "emfo",
+ "id": "iLit",
"metadata": {},
"outputs": [],
"source": [
- "config_dict = vc.export(to='files', base_url='http://localhost:3000', out_dir='./test')"
+ "vitessce_url = \"http://vitessce.io/?url=data:,\" + quote_plus(json.dumps(config_dict))\n",
+ "import webbrowser\n",
+ "webbrowser.open(vitessce_url)"
]
},
{
@@ -210,9 +258,7 @@
"metadata": {},
"outputs": [],
"source": [
- "vitessce_url = \"http://vitessce.io/?url=data:,\" + quote_plus(json.dumps(config_dict))\n",
- "import webbrowser\n",
- "webbrowser.open(vitessce_url)"
+ "import marimo as mo"
]
}
],
diff --git a/docs/notebooks/__ipynb__/data_export_s3.ipynb b/docs/notebooks/__ipynb__/data_export_s3.ipynb
index fcb6b6e9..a6ffc19f 100644
--- a/docs/notebooks/__ipynb__/data_export_s3.ipynb
+++ b/docs/notebooks/__ipynb__/data_export_s3.ipynb
@@ -1,9 +1,39 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Export data to AWS S3"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the classes and functions that we will be using from the corresponding packages."
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "bkHC",
+ "id": "vblA",
"metadata": {},
"outputs": [],
"source": [
@@ -30,33 +60,25 @@
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "ROlb",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "emfo",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "s3 = boto3.resource(\n",
- " service_name='s3',\n",
- " aws_access_key_id=os.environ['VITESSCE_S3_ACCESS_KEY_ID'],\n",
- " aws_secret_access_key=os.environ['VITESSCE_S3_SECRET_ACCESS_KEY'],\n",
- ")"
+ "## 2. Download and process data\n",
+ "\n",
+ "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "PKri",
+ "id": "lEQa",
"metadata": {},
"outputs": [],
"source": [
@@ -78,79 +100,108 @@
]
},
{
- "cell_type": "markdown",
- "id": "vblA",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
"metadata": {},
+ "outputs": [],
"source": [
- "## 1. Import dependencies\n",
- "\n",
- "We need to import the classes and functions that we will be using from the corresponding packages."
+ "zarr_filepath = join('data', 'habib17.processed.zarr')\n",
+ "if not isdir(zarr_filepath):\n",
+ " adata_1 = optimize_adata(adata, obs_cols=['CellType'], obsm_keys=['X_umap'], var_cols=['top_highly_variable'], optimize_X=True)\n",
+ " adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])"
]
},
{
"cell_type": "markdown",
- "id": "SFPL",
- "metadata": {},
+ "id": "Xref",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"## 3. Create the Vitessce configuration"
]
},
{
"cell_type": "markdown",
- "id": "Hbol",
- "metadata": {},
- "source": [
- "# Vitessce Data Preparation Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "lEQa",
- "metadata": {},
- "source": [
- "## 2. Download and process data\n",
- "\n",
- "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "BYtC",
- "metadata": {},
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"Set up the configuration by adding the views and datasets of interest."
]
},
{
- "cell_type": "markdown",
- "id": "iLit",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
"metadata": {},
+ "outputs": [],
"source": [
- "## 6. View on vitessce.io\n",
- "\n",
- "The returned view config dict can be converted to a URL, and can be used to share the interactive visualizations with colleagues."
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', description='COVID-19 Healthy Donor Brain')\n",
+ "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
+ " adata_path=zarr_filepath,\n",
+ " obs_embedding_paths=[\"obsm/X_umap\"],\n",
+ " obs_embedding_names=[\"UMAP\"],\n",
+ " obs_set_paths=[\"obs/CellType\"],\n",
+ " obs_set_names=[\"Cell Type\"],\n",
+ " obs_feature_matrix_path=\"X\",\n",
+ " feature_filter_path=\"var/top_highly_variable\"\n",
+ "))\n",
+ "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
+ "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
+ "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
+ "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)\n",
+ "vc.layout((scatterplot | (cell_sets / genes)) / heatmap);"
]
},
{
"cell_type": "markdown",
- "id": "Kclp",
- "metadata": {},
+ "id": "RGSE",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"## 4. Create a `boto3` resource with S3 credentials"
]
},
{
- "cell_type": "markdown",
- "id": "MJUe",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Kclp",
"metadata": {},
+ "outputs": [],
"source": [
- "# Export data to AWS S3"
+ "s3 = boto3.resource(\n",
+ " service_name='s3',\n",
+ " aws_access_key_id=os.environ['VITESSCE_S3_ACCESS_KEY_ID'],\n",
+ " aws_secret_access_key=os.environ['VITESSCE_S3_SECRET_ACCESS_KEY'],\n",
+ ")"
]
},
{
"cell_type": "markdown",
- "id": "Hstk",
- "metadata": {},
+ "id": "emfo",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"## 5. Upload files to S3\n",
"\n",
@@ -160,48 +211,39 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "Xref",
+ "id": "Hstk",
"metadata": {},
"outputs": [],
"source": [
- "zarr_filepath = join('data', 'habib17.processed.zarr')\n",
- "if not isdir(zarr_filepath):\n",
- " adata_1 = optimize_adata(adata, obs_cols=['CellType'], obsm_keys=['X_umap'], var_cols=['top_highly_variable'], optimize_X=True)\n",
- " adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])"
+ "config_dict = vc.export(to='S3', s3=s3, bucket_name='vitessce-export-examples', prefix='test')"
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "RGSE",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "nWHF",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', description='COVID-19 Healthy Donor Brain')\n",
- "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
- " adata_path=zarr_filepath,\n",
- " obs_embedding_paths=[\"obsm/X_umap\"],\n",
- " obs_embedding_names=[\"UMAP\"],\n",
- " obs_set_paths=[\"obs/CellType\"],\n",
- " obs_set_names=[\"Cell Type\"],\n",
- " obs_feature_matrix_path=\"X\",\n",
- " feature_filter_path=\"var/top_highly_variable\"\n",
- "))\n",
- "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
- "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
- "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
- "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)\n",
- "vc.layout((scatterplot | (cell_sets / genes)) / heatmap);"
+ "## 6. View on vitessce.io\n",
+ "\n",
+ "The returned view config dict can be converted to a URL, and can be used to share the interactive visualizations with colleagues."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "nWHF",
+ "id": "iLit",
"metadata": {},
"outputs": [],
"source": [
- "config_dict = vc.export(to='S3', s3=s3, bucket_name='vitessce-export-examples', prefix='test')"
+ "vitessce_url = \"http://vitessce.io/?url=data:,\" + quote_plus(json.dumps(config_dict))\n",
+ "import webbrowser\n",
+ "webbrowser.open(vitessce_url)"
]
},
{
@@ -211,9 +253,7 @@
"metadata": {},
"outputs": [],
"source": [
- "vitessce_url = \"http://vitessce.io/?url=data:,\" + quote_plus(json.dumps(config_dict))\n",
- "import webbrowser\n",
- "webbrowser.open(vitessce_url)"
+ "import marimo as mo"
]
}
],
diff --git a/docs/notebooks/__ipynb__/page_mode_comparative.ipynb b/docs/notebooks/__ipynb__/page_mode_comparative.ipynb
index 4156eea4..31ee589a 100644
--- a/docs/notebooks/__ipynb__/page_mode_comparative.ipynb
+++ b/docs/notebooks/__ipynb__/page_mode_comparative.ipynb
@@ -1,235 +1,82 @@
{
"cells": [
{
- "cell_type": "code",
- "execution_count": null,
- "id": "bkHC",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "from oxc_py import transform\n",
- "from vitessce import VitessceConfig, hconcat, vconcat"
+ "# Visualization of ComparativeData object"
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "PKri",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "# Reference: https://github.com/vitessce/vitessce/blob/main/examples/configs/src/view-configs/kpmp-premiere.js"
+ "## Configure Vitessce"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "Xref",
+ "id": "vblA",
"metadata": {},
"outputs": [],
"source": [
- "base_url = 'https://storage.googleapis.com/vitessce-demo-data/kpmp-jan-2025/kpmp_premiere_20250330.adata.zarr'"
+ "from oxc_py import transform\n",
+ "from vitessce import VitessceConfig, hconcat, vconcat"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Configure the data and views"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "Hstk",
+ "id": "lEQa",
"metadata": {},
"outputs": [],
"source": [
- "import marimo as mo"
+ "# Reference: https://github.com/vitessce/vitessce/blob/main/examples/configs/src/view-configs/kpmp-premiere.js"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "RGSE",
+ "id": "PKri",
"metadata": {},
"outputs": [],
"source": [
- "PAGE_ESM = transform(\"\"\"\n",
- "import clsx from \"https://unpkg.com/clsx@1.1.1/dist/clsx.m.js\";\n",
- "\n",
- "function createPage(utilsForPages) {\n",
- " const {\n",
- " React,\n",
- " usePageModeView,\n",
- " } = utilsForPages;\n",
- " function PageComponent(props) {\n",
- " const BiomarkerSelect = usePageModeView('biomarker-select');\n",
- " const ComparativeHeading = usePageModeView('comparative-heading');\n",
- " const CellSets = usePageModeView('cell-sets');\n",
- " const SampleSets = usePageModeView('sample-sets');\n",
- " const DualScatterplot = usePageModeView('scatterplot');\n",
- " const ViolinPlot = usePageModeView('violin-plot');\n",
- " const DotPlot = usePageModeView('dot-plot');\n",
- " const Treemap = usePageModeView('treemap');\n",
- " const VolcanoPlot = usePageModeView('volcano-plot');\n",
- " const VolcanoPlotTable = usePageModeView('volcano-plot-table');\n",
- " const SccodaPlot = usePageModeView('sccoda-plot');\n",
- " const PathwaysPlot = usePageModeView('pathways-plot');\n",
- "\n",
- "\n",
- " return (\n",
- " <>\n",
- " \n",
- " \n",
- "
\n",
- "
Comparative visualization of single-cell atlas data \n",
- " \n",
- " \n",
- "
\n",
- "\n",
- " \n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "
\n",
- "
This view contains a treemap visualization to communicate cell type composition in each of the selected sample groups.
\n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "
\n",
- "
\n",
- "
This view displays the results of a cell type composition analysis performed using the ScCODA algorithm (Büttner et al. 2021). Cell types with significantly different composition between the selected sample groups are displayed opaque while not-signficant results are displayed with transparent bars. The single outlined bar denotes the automatically-selected reference cell type.
\n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "
\n",
- "
\n",
- "
This view displays differential expression test results, performed using the rank_genes_groups function from Scanpy (Wolf et al. 2018) with method "wilcoxon". The arrows on the bottom left and bottom right denote the direction of the effect. Click a point in the plot to select the corresponding gene. Note that differential expression tests have been run for each cell type separately, so the each gene can appear multiple times (once per cell type). If there are too many points on the plot, cell types can be selected to filter the points.
\n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "
\n",
- "
\n",
- "
This view displays differential expression test results in tabular form. Click a row in the table to select the corresponding gene.
\n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "
\n",
- "
\n",
- "
This view displays gene set enrichment test results based on the differential expression results. Gene set enrichment tests have been performed using Reactome 2022 pathway gene sets from BlitzGSEA (Lachmann et al. 2022) via the hypergeometric function of Pertpy (Heumos et al. 2024).
\n",
- "
\n",
- "
\n",
- "
\n",
- "
\n",
- "
\n",
- "
This view contains contour scatterplots which display the results of a density-preserving dimensionality reduction (Narayan et al. 2021). Contour opacities correspond to the shown percentile thresholds.
\n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "
\n",
- "
\n",
- "
This dot plot view displays gene expression values per cell type and sample group for the selected biomarkers.
\n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "
\n",
- "
\n",
- "
This violin plot view displays gene expression values per cell type and sample group for the selected biomarker.
\n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- " {/*
Neighborhood-level representations \n",
- "
TODO \n",
- "
Segmented instance-level representations \n",
- "
TODO \n",
- "
Image-level representations \n",
- "
TODO \n",
- "
Participant-level representations \n",
- "
TODO */}\n",
- "
\n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "\n",
- "
\n",
- " >\n",
- " );\n",
- " }\n",
- " return PageComponent;\n",
- "}\n",
- "export default { createPage };\n",
- "\"\"\")"
+ "base_url = 'https://storage.googleapis.com/vitessce-demo-data/kpmp-jan-2025/kpmp_premiere_20250330.adata.zarr'"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "SFPL",
+ "id": "Xref",
"metadata": {},
"outputs": [],
"source": [
@@ -412,50 +259,226 @@
},
{
"cell_type": "markdown",
- "id": "Kclp",
- "metadata": {},
- "source": [
- "## Render page as widget"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "lEQa",
- "metadata": {},
- "source": [
- "## Configure the data and views"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "BYtC",
- "metadata": {},
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"## Define the page layout"
]
},
{
- "cell_type": "markdown",
- "id": "MJUe",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
"metadata": {},
+ "outputs": [],
"source": [
- "# Visualization of ComparativeData object"
+ "PAGE_ESM = transform(\"\"\"\n",
+ "import clsx from \"https://unpkg.com/clsx@1.1.1/dist/clsx.m.js\";\n",
+ "\n",
+ "function createPage(utilsForPages) {\n",
+ " const {\n",
+ " React,\n",
+ " usePageModeView,\n",
+ " } = utilsForPages;\n",
+ " function PageComponent(props) {\n",
+ " const BiomarkerSelect = usePageModeView('biomarker-select');\n",
+ " const ComparativeHeading = usePageModeView('comparative-heading');\n",
+ " const CellSets = usePageModeView('cell-sets');\n",
+ " const SampleSets = usePageModeView('sample-sets');\n",
+ " const DualScatterplot = usePageModeView('scatterplot');\n",
+ " const ViolinPlot = usePageModeView('violin-plot');\n",
+ " const DotPlot = usePageModeView('dot-plot');\n",
+ " const Treemap = usePageModeView('treemap');\n",
+ " const VolcanoPlot = usePageModeView('volcano-plot');\n",
+ " const VolcanoPlotTable = usePageModeView('volcano-plot-table');\n",
+ " const SccodaPlot = usePageModeView('sccoda-plot');\n",
+ " const PathwaysPlot = usePageModeView('pathways-plot');\n",
+ "\n",
+ "\n",
+ " return (\n",
+ " <>\n",
+ " \n",
+ " \n",
+ "
\n",
+ "
Comparative visualization of single-cell atlas data \n",
+ " \n",
+ " \n",
+ "
\n",
+ "\n",
+ " \n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
This view contains a treemap visualization to communicate cell type composition in each of the selected sample groups.
\n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
This view displays the results of a cell type composition analysis performed using the ScCODA algorithm (Büttner et al. 2021). Cell types with significantly different composition between the selected sample groups are displayed opaque while not-signficant results are displayed with transparent bars. The single outlined bar denotes the automatically-selected reference cell type.
\n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
This view displays differential expression test results, performed using the rank_genes_groups function from Scanpy (Wolf et al. 2018) with method "wilcoxon". The arrows on the bottom left and bottom right denote the direction of the effect. Click a point in the plot to select the corresponding gene. Note that differential expression tests have been run for each cell type separately, so the each gene can appear multiple times (once per cell type). If there are too many points on the plot, cell types can be selected to filter the points.
\n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
This view displays differential expression test results in tabular form. Click a row in the table to select the corresponding gene.
\n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
This view displays gene set enrichment test results based on the differential expression results. Gene set enrichment tests have been performed using Reactome 2022 pathway gene sets from BlitzGSEA (Lachmann et al. 2022) via the hypergeometric function of Pertpy (Heumos et al. 2024).
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
This view contains contour scatterplots which display the results of a density-preserving dimensionality reduction (Narayan et al. 2021). Contour opacities correspond to the shown percentile thresholds.
\n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
This dot plot view displays gene expression values per cell type and sample group for the selected biomarkers.
\n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
This violin plot view displays gene expression values per cell type and sample group for the selected biomarker.
\n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ " {/*
Neighborhood-level representations \n",
+ "
TODO \n",
+ "
Segmented instance-level representations \n",
+ "
TODO \n",
+ "
Image-level representations \n",
+ "
TODO \n",
+ "
Participant-level representations \n",
+ "
TODO */}\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "\n",
+ "
\n",
+ " >\n",
+ " );\n",
+ " }\n",
+ " return PageComponent;\n",
+ "}\n",
+ "export default { createPage };\n",
+ "\"\"\")"
]
},
{
"cell_type": "markdown",
- "id": "Hbol",
- "metadata": {},
+ "id": "RGSE",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "# Vitessce Widget Tutorial"
+ "## Render page as widget"
]
},
{
- "cell_type": "markdown",
- "id": "vblA",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Kclp",
"metadata": {},
+ "outputs": [],
"source": [
- "## Configure Vitessce"
+ "vw = vc.widget(page_esm=PAGE_ESM, page_mode=True, height=4700, prevent_scroll=False)\n",
+ "vw"
]
},
{
@@ -465,8 +488,7 @@
"metadata": {},
"outputs": [],
"source": [
- "vw = vc.widget(page_esm=PAGE_ESM, page_mode=True, height=4700, prevent_scroll=False)\n",
- "vw"
+ "import marimo as mo"
]
}
],
diff --git a/docs/notebooks/__ipynb__/page_mode_example.ipynb b/docs/notebooks/__ipynb__/page_mode_example.ipynb
index daa0aedd..bc6f676d 100644
--- a/docs/notebooks/__ipynb__/page_mode_example.ipynb
+++ b/docs/notebooks/__ipynb__/page_mode_example.ipynb
@@ -1,9 +1,37 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Page mode example"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Configure Vitessce"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "bkHC",
+ "id": "vblA",
"metadata": {},
"outputs": [],
"source": [
@@ -17,10 +45,24 @@
"from oxc_py import transform"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Configure the data and views"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "PKri",
+ "id": "lEQa",
"metadata": {},
"outputs": [],
"source": [
@@ -30,17 +72,49 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "emfo",
+ "id": "PKri",
"metadata": {},
"outputs": [],
"source": [
- "import marimo as mo"
+ "vc = VitessceConfig(schema_version=\"1.0.17\", name='PBMC Reference')\n",
+ "dataset = vc.add_dataset(name='PBMC 3k').add_object(\n",
+ " AnnDataWrapper(\n",
+ " adata_url=url,\n",
+ " obs_set_paths=[\"obs/louvain\"],\n",
+ " obs_set_names=[\"Louvain\"],\n",
+ " obs_embedding_paths=[\"obsm/X_umap\", \"obsm/X_pca\"],\n",
+ " obs_embedding_names=[\"UMAP\", \"PCA\"],\n",
+ " obs_feature_matrix_path=\"X\"\n",
+ " )\n",
+ ")\n",
+ "\n",
+ "umap = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\", uid=\"scatterplot-umap\")\n",
+ "pca = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"PCA\", uid=\"scatterplot-pca\")\n",
+ "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset, uid=\"cell-sets\")\n",
+ "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset, uid=\"gene-list\")\n",
+ "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset, uid=\"heatmap\")\n",
+ "\n",
+ "vc.layout((umap / pca) | ((cell_sets | genes) / heatmap));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Xref",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Define the page layout"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "BYtC",
+ "id": "SFPL",
"metadata": {},
"outputs": [],
"source": [
@@ -102,80 +176,29 @@
"\"\"\")"
]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.17\", name='PBMC Reference')\n",
- "dataset = vc.add_dataset(name='PBMC 3k').add_object(\n",
- " AnnDataWrapper(\n",
- " adata_url=url,\n",
- " obs_set_paths=[\"obs/louvain\"],\n",
- " obs_set_names=[\"Louvain\"],\n",
- " obs_embedding_paths=[\"obsm/X_umap\", \"obsm/X_pca\"],\n",
- " obs_embedding_names=[\"UMAP\", \"PCA\"],\n",
- " obs_feature_matrix_path=\"X\"\n",
- " )\n",
- ")\n",
- "\n",
- "umap = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\", uid=\"scatterplot-umap\")\n",
- "pca = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"PCA\", uid=\"scatterplot-pca\")\n",
- "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset, uid=\"cell-sets\")\n",
- "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset, uid=\"gene-list\")\n",
- "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset, uid=\"heatmap\")\n",
- "\n",
- "vc.layout((umap / pca) | ((cell_sets | genes) / heatmap));"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "lEQa",
- "metadata": {},
- "source": [
- "## Configure the data and views"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {},
- "source": [
- "# Page mode example"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "SFPL",
- "metadata": {},
- "source": [
- "## Define the page layout"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {},
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
{
"cell_type": "markdown",
- "id": "vblA",
- "metadata": {},
+ "id": "BYtC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## Configure Vitessce"
+ "## Render page as widget"
]
},
{
- "cell_type": "markdown",
+ "cell_type": "code",
+ "execution_count": null,
"id": "RGSE",
"metadata": {},
+ "outputs": [],
"source": [
- "## Render page as widget"
+ "vw = vc.widget(page_esm=PAGE_ESM, page_mode=True, height=1100)\n",
+ "vw"
]
},
{
@@ -185,8 +208,7 @@
"metadata": {},
"outputs": [],
"source": [
- "vw = vc.widget(page_esm=PAGE_ESM, page_mode=True, height=1100)\n",
- "vw"
+ "import marimo as mo"
]
}
],
diff --git a/docs/notebooks/__ipynb__/spatial_data.ipynb b/docs/notebooks/__ipynb__/spatial_data.ipynb
index a7bb5b00..c183933c 100644
--- a/docs/notebooks/__ipynb__/spatial_data.ipynb
+++ b/docs/notebooks/__ipynb__/spatial_data.ipynb
@@ -1,9 +1,37 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of a SpatialData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Import dependencies"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "bkHC",
+ "id": "vblA",
"metadata": {},
"outputs": [],
"source": [
@@ -25,11 +53,13 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "Kclp",
+ "id": "bkHC",
"metadata": {},
"outputs": [],
"source": [
- "import marimo as mo"
+ "data_dir = \"data\"\n",
+ "zip_filepath = join(data_dir, \"visium.spatialdata.zarr.zip\")\n",
+ "spatialdata_filepath = join(data_dir, \"visium.spatialdata.zarr\")"
]
},
{
@@ -39,57 +69,35 @@
"metadata": {},
"outputs": [],
"source": [
- "data_dir = \"data\"\n",
- "zip_filepath = join(data_dir, \"visium.spatialdata.zarr.zip\")\n",
- "spatialdata_filepath = join(data_dir, \"visium.spatialdata.zarr\")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "vblA",
- "metadata": {},
- "source": [
- "## Import dependencies"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {},
- "source": [
- "# Vitessce Widget Tutorial"
+ "if not isdir(spatialdata_filepath):\n",
+ " if not isfile(zip_filepath):\n",
+ " os.makedirs(data_dir, exist_ok=True)\n",
+ " urlretrieve('https://s3.embl.de/spatialdata/spatialdata-sandbox/visium_associated_xenium_io.zip', zip_filepath)\n",
+ " with zipfile.ZipFile(zip_filepath,\"r\") as zip_ref:\n",
+ " zip_ref.extractall(data_dir)\n",
+ " os.rename(join(data_dir, \"data.zarr\"), spatialdata_filepath)"
]
},
{
"cell_type": "markdown",
- "id": "Xref",
- "metadata": {},
+ "id": "PKri",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"## Configure Vitessce\n",
"\n",
"Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
]
},
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {},
- "source": [
- "# Visualization of a SpatialData object"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "BYtC",
- "metadata": {},
- "source": [
- "### Render the widget"
- ]
- },
{
"cell_type": "code",
"execution_count": null,
- "id": "SFPL",
+ "id": "Xref",
"metadata": {},
"outputs": [],
"source": [
@@ -130,20 +138,29 @@
"vc.layout(spatial | (feature_list / layer_controller / obs_sets));"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### Render the widget"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "PKri",
+ "id": "BYtC",
"metadata": {},
"outputs": [],
"source": [
- "if not isdir(spatialdata_filepath):\n",
- " if not isfile(zip_filepath):\n",
- " os.makedirs(data_dir, exist_ok=True)\n",
- " urlretrieve('https://s3.embl.de/spatialdata/spatialdata-sandbox/visium_associated_xenium_io.zip', zip_filepath)\n",
- " with zipfile.ZipFile(zip_filepath,\"r\") as zip_ref:\n",
- " zip_ref.extractall(data_dir)\n",
- " os.rename(join(data_dir, \"data.zarr\"), spatialdata_filepath)"
+ "vw = vc.widget()\n",
+ "vw"
]
},
{
@@ -153,8 +170,7 @@
"metadata": {},
"outputs": [],
"source": [
- "vw = vc.widget()\n",
- "vw"
+ "import marimo as mo"
]
}
],
diff --git a/docs/notebooks/__ipynb__/spatial_data_blobs.ipynb b/docs/notebooks/__ipynb__/spatial_data_blobs.ipynb
index f7584c92..83d023ea 100644
--- a/docs/notebooks/__ipynb__/spatial_data_blobs.ipynb
+++ b/docs/notebooks/__ipynb__/spatial_data_blobs.ipynb
@@ -1,51 +1,52 @@
{
"cells": [
{
- "cell_type": "code",
- "execution_count": null,
- "id": "bkHC",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "import spatialdata\n",
- "from os.path import join"
+ "# Visualization of a SpatialData object, blobs example"
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "SFPL",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " ViewType as vt,\n",
- " CoordinationType as ct,\n",
- " CoordinationLevel as CL,\n",
- " SpatialDataWrapper,\n",
- " get_initial_coordination_scope_prefix\n",
- ")"
+ "## Import dependencies"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "Hstk",
+ "id": "vblA",
"metadata": {},
"outputs": [],
"source": [
- "import marimo as mo"
+ "import spatialdata\n",
+ "from os.path import join"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "PKri",
+ "id": "bkHC",
"metadata": {},
"outputs": [],
"source": [
- "spatialdata_filepath = join(\"data\", \"blobs.spatialdata.zarr\")"
+ "sdata = spatialdata.datasets.blobs()"
]
},
{
@@ -55,45 +56,46 @@
"metadata": {},
"outputs": [],
"source": [
- "sdata = spatialdata.datasets.blobs()"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {},
- "source": [
- "# Visualization of a SpatialData object, blobs example"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Kclp",
- "metadata": {},
- "source": [
- "### Render the widget"
+ "spatialdata_filepath = join(\"data\", \"blobs.spatialdata.zarr\")"
]
},
{
- "cell_type": "markdown",
- "id": "vblA",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
"metadata": {},
+ "outputs": [],
"source": [
- "## Import dependencies"
+ "sdata.write(spatialdata_filepath, overwrite=True)"
]
},
{
- "cell_type": "markdown",
- "id": "Hbol",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
"metadata": {},
+ "outputs": [],
"source": [
- "# Vitessce Widget Tutorial"
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " ViewType as vt,\n",
+ " CoordinationType as ct,\n",
+ " CoordinationLevel as CL,\n",
+ " SpatialDataWrapper,\n",
+ " get_initial_coordination_scope_prefix\n",
+ ")"
]
},
{
"cell_type": "markdown",
- "id": "BYtC",
- "metadata": {},
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"## Configure Vitessce\n",
"\n",
@@ -103,7 +105,7 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "RGSE",
+ "id": "BYtC",
"metadata": {},
"outputs": [],
"source": [
@@ -168,14 +170,29 @@
"vc.layout(spatial | layer_controller);"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "RGSE",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### Render the widget"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "Xref",
+ "id": "Kclp",
"metadata": {},
"outputs": [],
"source": [
- "sdata.write(spatialdata_filepath, overwrite=True)"
+ "vw = vc.widget()\n",
+ "vw"
]
},
{
@@ -185,8 +202,7 @@
"metadata": {},
"outputs": [],
"source": [
- "vw = vc.widget()\n",
- "vw"
+ "import marimo as mo"
]
}
],
diff --git a/docs/notebooks/__ipynb__/spatial_data_kpmp_vis.ipynb b/docs/notebooks/__ipynb__/spatial_data_kpmp_vis.ipynb
index 49c2fe65..bef7be79 100644
--- a/docs/notebooks/__ipynb__/spatial_data_kpmp_vis.ipynb
+++ b/docs/notebooks/__ipynb__/spatial_data_kpmp_vis.ipynb
@@ -1,5 +1,33 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of a SpatialData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Import dependencies"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
@@ -35,34 +63,27 @@
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "PKri",
- "metadata": {},
- "outputs": [],
- "source": [
- "sdata_url = \"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/sdata.zarr\""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "BYtC",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "#import json\n",
- "#print(json.dumps(vc.to_dict(), indent=2))"
+ "## Configure Vitessce"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "RGSE",
+ "id": "PKri",
"metadata": {},
"outputs": [],
"source": [
- "import marimo as mo"
+ "sdata_url = \"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/sdata.zarr\""
]
},
{
@@ -414,38 +435,35 @@
]
},
{
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {},
- "source": [
- "## Import dependencies"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Hbol",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
"metadata": {},
+ "outputs": [],
"source": [
- "# Vitessce Widget Tutorial"
+ "vw = vc.widget(height=1000)\n",
+ "vw"
]
},
{
- "cell_type": "markdown",
- "id": "lEQa",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
"metadata": {},
+ "outputs": [],
"source": [
- "## Configure Vitessce"
+ "#import json\n",
+ "#print(json.dumps(vc.to_dict(), indent=2))"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "SFPL",
+ "id": "RGSE",
"metadata": {},
"outputs": [],
"source": [
- "vw = vc.widget(height=1000)\n",
- "vw"
+ "import marimo as mo"
]
}
],
diff --git a/docs/notebooks/__ipynb__/spatial_data_merfish.ipynb b/docs/notebooks/__ipynb__/spatial_data_merfish.ipynb
index e525bde6..13823404 100644
--- a/docs/notebooks/__ipynb__/spatial_data_merfish.ipynb
+++ b/docs/notebooks/__ipynb__/spatial_data_merfish.ipynb
@@ -1,9 +1,37 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of a SpatialData object, blobs example"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Import dependencies"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "bkHC",
+ "id": "vblA",
"metadata": {},
"outputs": [],
"source": [
@@ -13,7 +41,7 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "lEQa",
+ "id": "bkHC",
"metadata": {},
"outputs": [],
"source": [
@@ -28,19 +56,25 @@
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "RGSE",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "import marimo as mo"
+ "## Configure Vitessce\n",
+ "\n",
+ "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "Xref",
+ "id": "PKri",
"metadata": {},
"outputs": [],
"source": [
@@ -135,44 +169,27 @@
},
{
"cell_type": "markdown",
- "id": "MJUe",
- "metadata": {},
- "source": [
- "# Visualization of a SpatialData object, blobs example"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {},
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "SFPL",
- "metadata": {},
+ "id": "Xref",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"### Render the widget"
]
},
{
- "cell_type": "markdown",
- "id": "PKri",
- "metadata": {},
- "source": [
- "## Configure Vitessce\n",
- "\n",
- "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "vblA",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
"metadata": {},
+ "outputs": [],
"source": [
- "## Import dependencies"
+ "vw = vc.widget()\n",
+ "vw"
]
},
{
@@ -182,8 +199,7 @@
"metadata": {},
"outputs": [],
"source": [
- "vw = vc.widget()\n",
- "vw"
+ "import marimo as mo"
]
}
],
diff --git a/docs/notebooks/__ipynb__/spatial_data_merfish_2.ipynb b/docs/notebooks/__ipynb__/spatial_data_merfish_2.ipynb
index d3111b15..bb6eaf83 100644
--- a/docs/notebooks/__ipynb__/spatial_data_merfish_2.ipynb
+++ b/docs/notebooks/__ipynb__/spatial_data_merfish_2.ipynb
@@ -1,9 +1,37 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of a SpatialData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Import dependencies"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "bkHC",
+ "id": "vblA",
"metadata": {},
"outputs": [],
"source": [
@@ -25,17 +53,7 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "Kclp",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "lEQa",
+ "id": "bkHC",
"metadata": {},
"outputs": [],
"source": [
@@ -44,52 +62,10 @@
"spatialdata_filepath = join(data_dir, \"merfish_2.spatialdata.zarr\")"
]
},
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {},
- "source": [
- "# Visualization of a SpatialData object"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Xref",
- "metadata": {},
- "source": [
- "## Configure Vitessce\n",
- "\n",
- "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "vblA",
- "metadata": {},
- "source": [
- "## Import dependencies"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "BYtC",
- "metadata": {},
- "source": [
- "### Render the widget"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {},
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
{
"cell_type": "code",
"execution_count": null,
- "id": "PKri",
+ "id": "lEQa",
"metadata": {},
"outputs": [],
"source": [
@@ -102,10 +78,26 @@
" os.rename(join(data_dir, \"data.zarr\"), spatialdata_filepath)"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "PKri",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Configure Vitessce\n",
+ "\n",
+ "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "SFPL",
+ "id": "Xref",
"metadata": {},
"outputs": [],
"source": [
@@ -147,16 +139,40 @@
"vc.layout(spatial | (feature_list / layer_controller / obs_sets));"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### Render the widget"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "RGSE",
+ "id": "BYtC",
"metadata": {},
"outputs": [],
"source": [
"vw = vc.widget()\n",
"vw"
]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
}
],
"metadata": {},
diff --git a/docs/notebooks/__ipynb__/spatial_data_mouseliver.ipynb b/docs/notebooks/__ipynb__/spatial_data_mouseliver.ipynb
index 6cdf2b57..f83f56bb 100644
--- a/docs/notebooks/__ipynb__/spatial_data_mouseliver.ipynb
+++ b/docs/notebooks/__ipynb__/spatial_data_mouseliver.ipynb
@@ -1,189 +1,123 @@
{
"cells": [
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join, isfile, isdir\n",
- "from urllib.request import urlretrieve\n",
- "import zipfile\n",
- "import json"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "RGSE",
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " ViewType as vt,\n",
- " CoordinationType as ct,\n",
- " CoordinationLevel as CL,\n",
- " SpatialDataWrapper,\n",
- " AnnDataWrapper,\n",
- " ImageOmeTiffWrapper,\n",
- " ImageOmeZarrWrapper,\n",
- " ObsSegmentationsOmeZarrWrapper,\n",
- " get_initial_coordination_scope_prefix,\n",
- " hconcat,\n",
- " vconcat,\n",
- ")\n",
- "from vitessce.data_utils import (\n",
- " VAR_CHUNK_SIZE,\n",
- " generate_h5ad_ref_spec,\n",
- " multiplex_img_to_ome_tiff,\n",
- " multiplex_img_to_ome_zarr,\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Hstk",
- "metadata": {},
- "outputs": [],
- "source": [
- "import numpy as np\n",
- "from spatialdata import read_zarr\n",
- "from anndata import AnnData\n",
- "from ome_zarr.writer import write_image\n",
- "import tifffile\n",
- "from generate_tiff_offsets import get_offsets"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "EJmg",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "ZHCJ",
- "metadata": {},
- "outputs": [],
- "source": [
- "data_dir = \"data\"\n",
- "zip_filepath = join(data_dir, \"mouse_liver.spatialdata.zarr.zip\")\n",
- "spatialdata_filepath = join(data_dir, \"mouse_liver.spatialdata.zarr\")\n",
- "adata_zarr_filepath = join(data_dir, \"mouse_liver.anndata.zarr\")\n",
- "adata_h5ad_filepath = join(data_dir, \"mouse_liver.h5ad\")\n",
- "ref_spec_json_filepath = join(data_dir, \"mouse_liver.h5ad.ref.json\")\n",
- "ome_tiff_filepath = join(data_dir, \"mouse_liver.ome.tif\")\n",
- "offsets_json_filepath = join(data_dir, \"mouse_liver.ome.tif.offsets.json\")\n",
- "ome_zarr_filepath = join(data_dir, \"mouse_liver.ome.zarr\")\n",
- "labels_ome_zarr_filepath = join(data_dir, \"mouse_liver.labels.ome.zarr\")"
- ]
- },
{
"cell_type": "markdown",
- "id": "ZBYS",
- "metadata": {},
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## Extract AnnData object from SpatialData object"
+ "# Visualization of a SpatialData object and individual Spatial Elements, local data"
]
},
{
"cell_type": "markdown",
- "id": "iLit",
- "metadata": {},
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "We download a mouse liver dataset which serves as a SpatialData [example dataset](https://github.com/scverse/spatialdata-notebooks/blob/main/notebooks/examples/transformations.ipynb).\n",
+ "This notebook explains how to create interactive visualizations of data that is accessible locally.\n",
"\n",
- "This dataset was generated by [Guilliams et al.](https://doi.org/10.1016/j.cell.2021.12.018) and processed using [SPArrOW](https://doi.org/10.1101/2024.07.04.601829) during the SpatialData [developer workshop](https://doi.org/10.37044/osf.io/8ck3e) in 2024."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "aLJB",
- "metadata": {},
- "source": [
- "The above example demonstrates how to visualize a spatial 'omics dataset containing not only single-cell information (e.g., a cell-by-gene expression matrix, cell type annotations) but also an image and cell segmentations.\n",
- "To demonstrate how to use Vitessce to visualize data from a (non-spatial) single-cell experiment, we will extract this information from the SpatialData object and save it to a simpler [AnnData](https://anndata.readthedocs.io/) object (ignoring the imaging and spatially-resolved elements)."
+ "\n",
+ "We progress through different visualization tasks, first demonstrating how Vitessce facilitates integrated imaging and spatial single-cell visualizations, then demonstrating visualization of non-spatial and image-only datasets."
]
},
{
"cell_type": "markdown",
- "id": "mWxS",
- "metadata": {},
+ "id": "vblA",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "To efficiently visualize OME-TIFF data using Vitessce, a JSON-based offsets file can be constructed using [generate-tiff-offsets](https://github.com/hms-dbmi/generate-tiff-offsets).\n",
- "This JSON file contains byte offsets into different partitions of the TIFF file, effectively resulting in an \"indexed TIFF\" which is described by [Manz et al. 2022](https://doi.org/10.1038/s41592-022-01482-7)."
+ ""
]
},
{
"cell_type": "markdown",
- "id": "ecfG",
- "metadata": {},
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "### Render the widget"
+ "## Utility dependencies"
]
},
{
"cell_type": "markdown",
- "id": "wAgl",
- "metadata": {},
+ "id": "lEQa",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "### H5AD-based AnnData"
+ "First, we import utility dependencies which will be used to download the example dataset and manipulate file paths, zip files, and JSON files."
]
},
{
- "cell_type": "markdown",
- "id": "iXej",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
"metadata": {},
+ "outputs": [],
"source": [
- "## Data location options\n",
- "\n",
- "Vitessce can visualize data [not only stored](https://python-docs.vitessce.io/data_options.html) locally (referenced using local file or directory paths) but also stored remotely (referenced using absolute URL paths).\n",
- "Depending on whether the Python kernel running the Jupyter process is running locally versus remotely (e.g., on a cluster or cloud platform such as Google Colab), certain data locations may be challenging to access from the machine running the Jupyter notebook frontend (i.e., the machine on which the web browser used to view the notebook is installed).\n",
- "\n",
- "To provide data via one of these alternative mechanisms, use parameters with the following suffices when instantiating the data wrapper classes.\n",
- "\n",
- "- `_path`: Local file or directory\n",
- "- `_url`: Remote file or directory\n",
- "- `_store`: Zarr-store-accessible (for zarr-based formats)\n",
- "- `_artifact`: Lamin artifact\n",
- "\n",
- "For example, `adata_path` can be exchanged for one of the following options.\n",
- "\n",
- "```diff\n",
- "AnnDataWrapper(\n",
- "- adata_path=\"./mouse_liver.spatialdata.zarr\",\n",
- "+ adata_url=\"https://example.com/mouse_liver.spatialdata.zarr\", # Absolute URL\n",
- "+ adata_store=\"./mouse_liver.spatialdata.zarr\", # String interpreted as root of DirectoryStore\n",
- "+ adata_store=zarr.DirectoryStore(\"./mouse_liver.spatialdata.zarr\"), # Instance of zarr.storage\n",
- "+ adata_artifact=adata_zarr_artifact, # Instance of ln.Artifact\n",
- " ...\n",
- "```\n",
- "\n",
- "Note that the `_store` options are only available for Zarr-based formats, such as AnnDataWrapper, SpatialDataWrapper, and ImageOmeZarrWrapper.\n",
- "Further, when multiple files are required, such as both `adata_path` and `ref_path` (for the JSON reference specification file accompanying an H5AD file) or `img_path` and `offsets_path`, multiple parameter suffices may need to be changed."
+ "import os\n",
+ "from os.path import join, isfile, isdir\n",
+ "from urllib.request import urlretrieve\n",
+ "import zipfile\n",
+ "import json"
]
},
{
"cell_type": "markdown",
- "id": "YWSi",
- "metadata": {},
+ "id": "Xref",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## Visualization of an image file"
+ "## Dependencies for Vitessce"
]
},
{
"cell_type": "markdown",
- "id": "BYtC",
- "metadata": {},
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"Here, we import classes and functions from the `vitessce` Python package.\n",
"This package includes not only APIs for [visualization configuration](https://python-docs.vitessce.io/api_config.html) but also [helper functions](https://python-docs.vitessce.io/api_data.html#vitessce-data-utils) for basic data transformation tasks.\n",
@@ -198,132 +132,205 @@
]
},
{
- "cell_type": "markdown",
- "id": "PKri",
- "metadata": {},
- "source": [
- "First, we import utility dependencies which will be used to download the example dataset and manipulate file paths, zip files, and JSON files."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "SFPL",
- "metadata": {},
- "source": [
- "## Dependencies for Vitessce"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "TqIu",
- "metadata": {},
- "source": [
- "## Visualization of a SpatialData object"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "zlud",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
"metadata": {},
+ "outputs": [],
"source": [
- "### OME-Zarr image"
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " ViewType as vt,\n",
+ " CoordinationType as ct,\n",
+ " CoordinationLevel as CL,\n",
+ " SpatialDataWrapper,\n",
+ " AnnDataWrapper,\n",
+ " ImageOmeTiffWrapper,\n",
+ " ImageOmeZarrWrapper,\n",
+ " ObsSegmentationsOmeZarrWrapper,\n",
+ " get_initial_coordination_scope_prefix,\n",
+ " hconcat,\n",
+ " vconcat,\n",
+ ")\n",
+ "from vitessce.data_utils import (\n",
+ " VAR_CHUNK_SIZE,\n",
+ " generate_h5ad_ref_spec,\n",
+ " multiplex_img_to_ome_tiff,\n",
+ " multiplex_img_to_ome_zarr,\n",
+ ")"
]
},
{
"cell_type": "markdown",
- "id": "dNNg",
- "metadata": {},
+ "id": "RGSE",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## Visualization of an AnnData object"
+ "## Dependencies for data structures"
]
},
{
"cell_type": "markdown",
- "id": "AjVT",
- "metadata": {},
+ "id": "Kclp",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "As Zarr-formatted data can be easily visualized by Vitessce, we recommend saving the AnnData object to a Zarr store using the [write_zarr](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_zarr.html) method.\n",
- "Optionally, the shape of array chunks (for the AnnData `X` array) can be specified as a parameter, to optimize performance based on data access patterns.\n",
- "For example, a common pattern is to visualize data across all cells for one gene.\n",
- "To support such a pattern, the chunk shape can be specified as follows, `(total number of cells, small number of genes)`, resulting in tall-and-skinny array chunks."
+ "In this blog post, we perform basic data transformation tasks to save individual elements of an integrated SpatialData object to separate files in AnnData, OME-TIFF, and OME-Zarr formats.\n",
+ "To perform these data transformations, we import the following dependencies.\n",
+ "In general, you will typically not need to import all of these dependencies, either because you are only working with data in one of these formats, or because the data you intend to visualize is already saved to a file or directory.\n",
+ "\n",
+ "Note: Dependencies such as `spatialdata` may need to be installed before they can be imported in the next code cell."
]
},
{
- "cell_type": "markdown",
- "id": "Hbol",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "emfo",
"metadata": {},
+ "outputs": [],
"source": [
- "# Vitessce Widget Tutorial"
+ "import numpy as np\n",
+ "from spatialdata import read_zarr\n",
+ "from anndata import AnnData\n",
+ "from ome_zarr.writer import write_image\n",
+ "import tifffile\n",
+ "from generate_tiff_offsets import get_offsets"
]
},
{
"cell_type": "markdown",
- "id": "nWHF",
- "metadata": {},
+ "id": "Hstk",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"## Download example dataset"
]
},
{
"cell_type": "markdown",
- "id": "LJZf",
- "metadata": {},
+ "id": "nWHF",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "For small images, the data can be saved to OME-Zarr or OME-TIFF format using [utility functions](https://python-docs.vitessce.io/api_data.html#vitessce-data-utils) from the Vitessce package.\n",
- "Larger images require generation of an [image pyramid](https://en.wikipedia.org/wiki/Pyramid_(image_processing)), which can be performed using tools from the OME ecosystem such as [bioformats2raw](https://github.com/glencoesoftware/bioformats2raw) and [raw2ometiff](https://github.com/glencoesoftware/raw2ometiff)."
+ "We download a mouse liver dataset which serves as a SpatialData [example dataset](https://github.com/scverse/spatialdata-notebooks/blob/main/notebooks/examples/transformations.ipynb).\n",
+ "\n",
+ "This dataset was generated by [Guilliams et al.](https://doi.org/10.1016/j.cell.2021.12.018) and processed using [SPArrOW](https://doi.org/10.1101/2024.07.04.601829) during the SpatialData [developer workshop](https://doi.org/10.37044/osf.io/8ck3e) in 2024."
]
},
{
- "cell_type": "markdown",
- "id": "yCnT",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "iLit",
"metadata": {},
+ "outputs": [],
"source": [
- "### Zarr-based AnnData"
+ "data_dir = \"data\"\n",
+ "zip_filepath = join(data_dir, \"mouse_liver.spatialdata.zarr.zip\")\n",
+ "spatialdata_filepath = join(data_dir, \"mouse_liver.spatialdata.zarr\")\n",
+ "adata_zarr_filepath = join(data_dir, \"mouse_liver.anndata.zarr\")\n",
+ "adata_h5ad_filepath = join(data_dir, \"mouse_liver.h5ad\")\n",
+ "ref_spec_json_filepath = join(data_dir, \"mouse_liver.h5ad.ref.json\")\n",
+ "ome_tiff_filepath = join(data_dir, \"mouse_liver.ome.tif\")\n",
+ "offsets_json_filepath = join(data_dir, \"mouse_liver.ome.tif.offsets.json\")\n",
+ "ome_zarr_filepath = join(data_dir, \"mouse_liver.ome.zarr\")\n",
+ "labels_ome_zarr_filepath = join(data_dir, \"mouse_liver.labels.ome.zarr\")"
]
},
{
"cell_type": "markdown",
- "id": "vblA",
- "metadata": {},
+ "id": "ZHCJ",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "This notebook explains how to create interactive visualizations of data that is accessible locally.\n",
- "\n",
- "\n",
- "We progress through different visualization tasks, first demonstrating how Vitessce facilitates integrated imaging and spatial single-cell visualizations, then demonstrating visualization of non-spatial and image-only datasets."
+ "The following code uses Python's `urlretrieve` to download the SpatialData object as a zip file, then unzips the file using the `zipfile` module."
]
},
{
- "cell_type": "markdown",
- "id": "emfo",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ROlb",
"metadata": {},
+ "outputs": [],
"source": [
- "In this blog post, we perform basic data transformation tasks to save individual elements of an integrated SpatialData object to separate files in AnnData, OME-TIFF, and OME-Zarr formats.\n",
- "To perform these data transformations, we import the following dependencies.\n",
- "In general, you will typically not need to import all of these dependencies, either because you are only working with data in one of these formats, or because the data you intend to visualize is already saved to a file or directory.\n",
- "\n",
- "Note: Dependencies such as `spatialdata` may need to be installed before they can be imported in the next code cell."
+ "if not isdir(spatialdata_filepath):\n",
+ " if not isfile(zip_filepath):\n",
+ " os.makedirs(data_dir, exist_ok=True)\n",
+ " urlretrieve('https://s3.embl.de/spatialdata/spatialdata-sandbox/mouse_liver.zip', zip_filepath)\n",
+ " with zipfile.ZipFile(zip_filepath,\"r\") as zip_ref:\n",
+ " zip_ref.extractall(data_dir)\n",
+ " os.rename(join(data_dir, \"data.zarr\"), spatialdata_filepath)"
]
},
{
"cell_type": "markdown",
- "id": "Kclp",
- "metadata": {},
+ "id": "qnkX",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## Dependencies for data structures"
+ "## Visualization of a SpatialData object"
]
},
{
"cell_type": "markdown",
- "id": "ROlb",
- "metadata": {},
+ "id": "TqIu",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "The following code uses Python's `urlretrieve` to download the SpatialData object as a zip file, then unzips the file using the `zipfile` module."
+ "SpatialData objects are the most complex type of data structure we will work with in this blog post.\n",
+ "SpatialData objects function as contains for multiple types of Spatial Elements:\n",
+ "\n",
+ "- Tables (each table is represented as an AnnData object)\n",
+ "- Points (e.g., coordinates of transcripts from FISH-based experiments)\n",
+ "- Shapes (vector-based shapes such as polygons and circles)\n",
+ "- Labels (label images, i.e., segmentation bitmasks; each label image is stored using OME-Zarr)\n",
+ "- Images (microscopy images; each image is stored using OME-Zarr)"
]
},
{
"cell_type": "markdown",
- "id": "DnEU",
- "metadata": {},
+ "id": "Vxnm",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"## Configure Vitessce\n",
"\n",
@@ -332,103 +339,142 @@
]
},
{
- "cell_type": "markdown",
- "id": "lgWD",
- "metadata": {},
- "source": [
- "In contrast to extraction of the non-spatial data from the SpatialData object, we can extract the imaging (and segmentation/label image) data and save it to a dedicated bioimaging file format."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "lEQa",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "DnEU",
"metadata": {},
+ "outputs": [],
"source": [
- "## Utility dependencies"
+ "vc = VitessceConfig(schema_version='1.0.18', name='SpatialData Demo')\n",
+ "_wrapper = SpatialDataWrapper(sdata_path=spatialdata_filepath, table_path='tables/table', image_path='images/raw_image', obs_segmentations_path='labels/segmentation_mask', obs_feature_matrix_path='tables/table/X', obs_set_paths=['tables/table/obs/annotation'], obs_set_names=['Annotation'], region='nucleus_boundaries', coordinate_system='global', coordination_values={'obsType': 'cell'})\n",
+ "_dataset = vc.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
+ "_spatial = vc.add_view('spatialBeta', dataset=_dataset)\n",
+ "feature_list = vc.add_view('featureList', dataset=_dataset)\n",
+ "_layer_controller = vc.add_view('layerControllerBeta', dataset=_dataset)\n",
+ "obs_sets = vc.add_view('obsSets', dataset=_dataset)\n",
+ "_heatmap = vc.add_view('heatmap', dataset=_dataset)\n",
+ "[obs_color_encoding_scope] = vc.add_coordination('obsColorEncoding')\n",
+ "obs_color_encoding_scope.set_value('cellSetSelection')\n",
+ "vc.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))\n",
+ "vc.link_views_by_dict([_spatial, _layer_controller], {'segmentationLayer': CL([{'segmentationChannel': CL([{'obsColorEncoding': obs_color_encoding_scope}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'obsSegmentations'))\n",
+ "vc.link_views([_spatial, _layer_controller, feature_list, obs_sets, _heatmap], ['obsType'], [_wrapper.obs_type_label])\n",
+ "vc.link_views_by_dict([feature_list, obs_sets, _heatmap], {'obsColorEncoding': obs_color_encoding_scope}, meta=False)\n",
+ "vc.layout(_spatial / _heatmap | _layer_controller / (feature_list | obs_sets))"
]
},
{
"cell_type": "markdown",
- "id": "SdmI",
- "metadata": {},
+ "id": "ulZA",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## Extract image from SpatialData object"
+ "### Render the widget"
]
},
{
- "cell_type": "markdown",
- "id": "MJUe",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ecfG",
"metadata": {},
+ "outputs": [],
"source": [
- "# Visualization of a SpatialData object and individual Spatial Elements, local data"
+ "_vw = vc.widget()\n",
+ "_vw"
]
},
{
"cell_type": "markdown",
- "id": "fwwy",
- "metadata": {},
+ "id": "Pvdt",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "### Save image to OME-Zarr"
+ "## Extract AnnData object from SpatialData object"
]
},
{
"cell_type": "markdown",
- "id": "Vxnm",
- "metadata": {},
+ "id": "ZBYS",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "SpatialData objects are the most complex type of data structure we will work with in this blog post.\n",
- "SpatialData objects function as contains for multiple types of Spatial Elements:\n",
- "\n",
- "- Tables (each table is represented as an AnnData object)\n",
- "- Points (e.g., coordinates of transcripts from FISH-based experiments)\n",
- "- Shapes (vector-based shapes such as polygons and circles)\n",
- "- Labels (label images, i.e., segmentation bitmasks; each label image is stored using OME-Zarr)\n",
- "- Images (microscopy images; each image is stored using OME-Zarr)"
+ "The above example demonstrates how to visualize a spatial 'omics dataset containing not only single-cell information (e.g., a cell-by-gene expression matrix, cell type annotations) but also an image and cell segmentations.\n",
+ "To demonstrate how to use Vitessce to visualize data from a (non-spatial) single-cell experiment, we will extract this information from the SpatialData object and save it to a simpler [AnnData](https://anndata.readthedocs.io/) object (ignoring the imaging and spatially-resolved elements)."
]
},
{
- "cell_type": "markdown",
- "id": "CLip",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "aLJB",
"metadata": {},
+ "outputs": [],
"source": [
- "### OME-TIFF image"
+ "sdata = read_zarr(spatialdata_filepath)\n",
+ "sdata"
]
},
{
- "cell_type": "markdown",
- "id": "jxvo",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "nHfw",
"metadata": {},
+ "outputs": [],
"source": [
- "### Save image and segmentations to OME-TIFF"
+ "adata = sdata.tables['table']\n",
+ "adata"
]
},
{
"cell_type": "markdown",
- "id": "TRpd",
- "metadata": {},
+ "id": "xXTn",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "To read H5AD-formatted data, Vitessce requires an accompanying JSON [references specification](https://fsspec.github.io/kerchunk/spec.html) file, which can be constructed using the `generate_h5ad_ref_spec` utility function."
+ "As Zarr-formatted data can be easily visualized by Vitessce, we recommend saving the AnnData object to a Zarr store using the [write_zarr](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_zarr.html) method.\n",
+ "Optionally, the shape of array chunks (for the AnnData `X` array) can be specified as a parameter, to optimize performance based on data access patterns.\n",
+ "For example, a common pattern is to visualize data across all cells for one gene.\n",
+ "To support such a pattern, the chunk shape can be specified as follows, `(total number of cells, small number of genes)`, resulting in tall-and-skinny array chunks."
]
},
{
- "cell_type": "markdown",
- "id": "bkHC",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "AjVT",
"metadata": {},
+ "outputs": [],
"source": [
- ""
+ "adata.write_zarr(adata_zarr_filepath, chunks=(adata.shape[0], VAR_CHUNK_SIZE))"
]
},
{
"cell_type": "markdown",
- "id": "NCOB",
- "metadata": {},
+ "id": "pHFh",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"Alternatively, your AnnData object may already be stored using the H5AD (HDF5-based) format.\n",
"To demonstrate this scenario, we save the object using the [write_h5ad](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_h5ad.html) method."
@@ -437,42 +483,71 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "ulZA",
+ "id": "NCOB",
"metadata": {},
"outputs": [],
"source": [
- "vc = VitessceConfig(schema_version='1.0.18', name='SpatialData Demo')\n",
- "_wrapper = SpatialDataWrapper(sdata_path=spatialdata_filepath, table_path='tables/table', image_path='images/raw_image', obs_segmentations_path='labels/segmentation_mask', obs_feature_matrix_path='tables/table/X', obs_set_paths=['tables/table/obs/annotation'], obs_set_names=['Annotation'], region='nucleus_boundaries', coordinate_system='global', coordination_values={'obsType': 'cell'})\n",
- "_dataset = vc.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
- "_spatial = vc.add_view('spatialBeta', dataset=_dataset)\n",
- "feature_list = vc.add_view('featureList', dataset=_dataset)\n",
- "_layer_controller = vc.add_view('layerControllerBeta', dataset=_dataset)\n",
- "obs_sets = vc.add_view('obsSets', dataset=_dataset)\n",
- "_heatmap = vc.add_view('heatmap', dataset=_dataset)\n",
- "[obs_color_encoding_scope] = vc.add_coordination('obsColorEncoding')\n",
- "obs_color_encoding_scope.set_value('cellSetSelection')\n",
- "vc.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))\n",
- "vc.link_views_by_dict([_spatial, _layer_controller], {'segmentationLayer': CL([{'segmentationChannel': CL([{'obsColorEncoding': obs_color_encoding_scope}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'obsSegmentations'))\n",
- "vc.link_views([_spatial, _layer_controller, feature_list, obs_sets, _heatmap], ['obsType'], [_wrapper.obs_type_label])\n",
- "vc.link_views_by_dict([feature_list, obs_sets, _heatmap], {'obsColorEncoding': obs_color_encoding_scope}, meta=False)\n",
- "vc.layout(_spatial / _heatmap | _layer_controller / (feature_list | obs_sets))"
+ "adata.write_h5ad(adata_h5ad_filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "aqbW",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "To read H5AD-formatted data, Vitessce requires an accompanying JSON [references specification](https://fsspec.github.io/kerchunk/spec.html) file, which can be constructed using the `generate_h5ad_ref_spec` utility function."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "nHfw",
+ "id": "TRpd",
"metadata": {},
"outputs": [],
"source": [
- "sdata = read_zarr(spatialdata_filepath)\n",
- "sdata"
+ "ref_dict = generate_h5ad_ref_spec(adata_h5ad_filepath)\n",
+ "with open(ref_spec_json_filepath, 'w') as _f:\n",
+ " json.dump(ref_dict, _f)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "TXez",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Visualization of an AnnData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "dNNg",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### Zarr-based AnnData"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "wlCL",
+ "id": "yCnT",
"metadata": {},
"outputs": [],
"source": [
@@ -490,51 +565,31 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "qnkX",
- "metadata": {},
- "outputs": [],
- "source": [
- "if not isdir(spatialdata_filepath):\n",
- " if not isfile(zip_filepath):\n",
- " os.makedirs(data_dir, exist_ok=True)\n",
- " urlretrieve('https://s3.embl.de/spatialdata/spatialdata-sandbox/mouse_liver.zip', zip_filepath)\n",
- " with zipfile.ZipFile(zip_filepath,\"r\") as zip_ref:\n",
- " zip_ref.extractall(data_dir)\n",
- " os.rename(join(data_dir, \"data.zarr\"), spatialdata_filepath)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "YECM",
+ "id": "wlCL",
"metadata": {},
"outputs": [],
"source": [
- "vc_4 = VitessceConfig(schema_version='1.0.18', name='Image and segmentations (ome-tiff)')\n",
- "_wrapper = ImageOmeTiffWrapper(img_path=ome_tiff_filepath, offsets_path=offsets_json_filepath)\n",
- "_dataset = vc_4.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
- "_spatial = vc_4.add_view('spatialBeta', dataset=_dataset)\n",
- "_layer_controller = vc_4.add_view('layerControllerBeta', dataset=_dataset)\n",
- "vc_4.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))\n",
- "vc_4.layout(hconcat(_spatial, _layer_controller, split=(2, 1)))"
+ "vc_1.widget()"
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "TXez",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "kqZH",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "ref_dict = generate_h5ad_ref_spec(adata_h5ad_filepath)\n",
- "with open(ref_spec_json_filepath, 'w') as _f:\n",
- " json.dump(ref_dict, _f)"
+ "### H5AD-based AnnData"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "rEll",
+ "id": "wAgl",
"metadata": {},
"outputs": [],
"source": [
@@ -552,18 +607,45 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "Pvdt",
+ "id": "rEll",
"metadata": {},
"outputs": [],
"source": [
- "_vw = vc.widget()\n",
- "_vw"
+ "vc_2.widget()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "dGlV",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Extract image from SpatialData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "SdmI",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "In contrast to extraction of the non-spatial data from the SpatialData object, we can extract the imaging (and segmentation/label image) data and save it to a dedicated bioimaging file format."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "yOPj",
+ "id": "lgWD",
"metadata": {},
"outputs": [],
"source": [
@@ -573,50 +655,119 @@
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "xXTn",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "yOPj",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "adata = sdata.tables['table']\n",
- "adata"
+ "### Save image to OME-Zarr"
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "kqZH",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "fwwy",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "vc_1.widget()"
+ "For small images, the data can be saved to OME-Zarr or OME-TIFF format using [utility functions](https://python-docs.vitessce.io/api_data.html#vitessce-data-utils) from the Vitessce package.\n",
+ "Larger images require generation of an [image pyramid](https://en.wikipedia.org/wiki/Pyramid_(image_processing)), which can be performed using tools from the OME ecosystem such as [bioformats2raw](https://github.com/glencoesoftware/bioformats2raw) and [raw2ometiff](https://github.com/glencoesoftware/raw2ometiff)."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "cEAS",
+ "id": "LJZf",
"metadata": {},
"outputs": [],
"source": [
- "vc_4.widget()"
+ "multiplex_img_to_ome_zarr(img_arr, [\"Channel 0\"], ome_zarr_filepath)\n",
+ "multiplex_img_to_ome_zarr(labels_arr, [\"cell\"], labels_ome_zarr_filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "urSm",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### Save image and segmentations to OME-TIFF"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "jxvo",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "To efficiently visualize OME-TIFF data using Vitessce, a JSON-based offsets file can be constructed using [generate-tiff-offsets](https://github.com/hms-dbmi/generate-tiff-offsets).\n",
+ "This JSON file contains byte offsets into different partitions of the TIFF file, effectively resulting in an \"indexed TIFF\" which is described by [Manz et al. 2022](https://doi.org/10.1038/s41592-022-01482-7)."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "dGlV",
+ "id": "mWxS",
"metadata": {},
"outputs": [],
"source": [
- "vc_2.widget()"
+ "multiplex_img_to_ome_tiff(img_arr, ['Channel 0'], ome_tiff_filepath)\n",
+ "offsets = get_offsets(ome_tiff_filepath)\n",
+ "with open(offsets_json_filepath, 'w') as _f:\n",
+ " json.dump(offsets, _f)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "CcZR",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Visualization of an image file"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "YWSi",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### OME-Zarr image"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "tZnO",
+ "id": "zlud",
"metadata": {},
"outputs": [],
"source": [
@@ -635,56 +786,101 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "CcZR",
+ "id": "tZnO",
"metadata": {},
"outputs": [],
"source": [
- "multiplex_img_to_ome_tiff(img_arr, ['Channel 0'], ome_tiff_filepath)\n",
- "offsets = get_offsets(ome_tiff_filepath)\n",
- "with open(offsets_json_filepath, 'w') as _f:\n",
- " json.dump(offsets, _f)"
+ "_vw = vc_3.widget()\n",
+ "_vw"
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "urSm",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "xvXZ",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "multiplex_img_to_ome_zarr(img_arr, [\"Channel 0\"], ome_zarr_filepath)\n",
- "multiplex_img_to_ome_zarr(labels_arr, [\"cell\"], labels_ome_zarr_filepath)"
+ "### OME-TIFF image"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "pHFh",
+ "id": "CLip",
"metadata": {},
"outputs": [],
"source": [
- "adata.write_zarr(adata_zarr_filepath, chunks=(adata.shape[0], VAR_CHUNK_SIZE))"
+ "vc_4 = VitessceConfig(schema_version='1.0.18', name='Image and segmentations (ome-tiff)')\n",
+ "_wrapper = ImageOmeTiffWrapper(img_path=ome_tiff_filepath, offsets_path=offsets_json_filepath)\n",
+ "_dataset = vc_4.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
+ "_spatial = vc_4.add_view('spatialBeta', dataset=_dataset)\n",
+ "_layer_controller = vc_4.add_view('layerControllerBeta', dataset=_dataset)\n",
+ "vc_4.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))\n",
+ "vc_4.layout(hconcat(_spatial, _layer_controller, split=(2, 1)))"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "aqbW",
+ "id": "YECM",
"metadata": {},
"outputs": [],
"source": [
- "adata.write_h5ad(adata_h5ad_filepath)"
+ "vc_4.widget()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "cEAS",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Data location options\n",
+ "\n",
+ "Vitessce can visualize data [not only stored](https://python-docs.vitessce.io/data_options.html) locally (referenced using local file or directory paths) but also stored remotely (referenced using absolute URL paths).\n",
+ "Depending on whether the Python kernel running the Jupyter process is running locally versus remotely (e.g., on a cluster or cloud platform such as Google Colab), certain data locations may be challenging to access from the machine running the Jupyter notebook frontend (i.e., the machine on which the web browser used to view the notebook is installed).\n",
+ "\n",
+ "To provide data via one of these alternative mechanisms, use parameters with the following suffices when instantiating the data wrapper classes.\n",
+ "\n",
+ "- `_path`: Local file or directory\n",
+ "- `_url`: Remote file or directory\n",
+ "- `_store`: Zarr-store-accessible (for zarr-based formats)\n",
+ "- `_artifact`: Lamin artifact\n",
+ "\n",
+ "For example, `adata_path` can be exchanged for one of the following options.\n",
+ "\n",
+ "```diff\n",
+ "AnnDataWrapper(\n",
+ "- adata_path=\"./mouse_liver.spatialdata.zarr\",\n",
+ "+ adata_url=\"https://example.com/mouse_liver.spatialdata.zarr\", # Absolute URL\n",
+ "+ adata_store=\"./mouse_liver.spatialdata.zarr\", # String interpreted as root of DirectoryStore\n",
+ "+ adata_store=zarr.DirectoryStore(\"./mouse_liver.spatialdata.zarr\"), # Instance of zarr.storage\n",
+ "+ adata_artifact=adata_zarr_artifact, # Instance of ln.Artifact\n",
+ " ...\n",
+ "```\n",
+ "\n",
+ "Note that the `_store` options are only available for Zarr-based formats, such as AnnDataWrapper, SpatialDataWrapper, and ImageOmeZarrWrapper.\n",
+ "Further, when multiple files are required, such as both `adata_path` and `ref_path` (for the JSON reference specification file accompanying an H5AD file) or `img_path` and `offsets_path`, multiple parameter suffices may need to be changed."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "xvXZ",
+ "id": "iXej",
"metadata": {},
"outputs": [],
"source": [
- "_vw = vc_3.widget()\n",
- "_vw"
+ "import marimo as mo"
]
}
],
diff --git a/docs/notebooks/__ipynb__/spatial_data_mouseliver_remote.ipynb b/docs/notebooks/__ipynb__/spatial_data_mouseliver_remote.ipynb
index c5b5dc07..d6d25b92 100644
--- a/docs/notebooks/__ipynb__/spatial_data_mouseliver_remote.ipynb
+++ b/docs/notebooks/__ipynb__/spatial_data_mouseliver_remote.ipynb
@@ -1,134 +1,137 @@
{
"cells": [
{
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join, isfile, isdir\n",
- "from urllib.request import urlretrieve\n",
- "import zipfile\n",
- "import json"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "RGSE",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " ViewType as vt,\n",
- " CoordinationType as ct,\n",
- " CoordinationLevel as CL,\n",
- " SpatialDataWrapper,\n",
- " AnnDataWrapper,\n",
- " ImageOmeTiffWrapper,\n",
- " ImageOmeZarrWrapper,\n",
- " ObsSegmentationsOmeZarrWrapper,\n",
- " get_initial_coordination_scope_prefix,\n",
- " hconcat,\n",
- " vconcat,\n",
- ")\n",
- "from vitessce.data_utils import (\n",
- " VAR_CHUNK_SIZE,\n",
- " generate_h5ad_ref_spec,\n",
- " multiplex_img_to_ome_tiff,\n",
- " multiplex_img_to_ome_zarr,\n",
- ")"
+ "# Vitessce Widget Tutorial"
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "nWHF",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "base_url = \"https://storage.googleapis.com/vitessce-demo-data/spatialdata-may-2025\""
+ "# Visualization of a SpatialData object and individual Spatial Elements, remote data"
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "SdmI",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "import marimo as mo"
+ "This notebook explains how to create interactive visualizations of data that are accessible remotely.\n",
+ "\n",
+ "\n",
+ "We progress through different visualization tasks, first demonstrating how Vitessce facilitates integrated imaging and spatial single-cell visualizations, then demonstrating visualization of non-spatial and image-only datasets."
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "iLit",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "zip_filepath = f\"{base_url}/mouse_liver.spatialdata.zarr.zip\"\n",
- "spatialdata_filepath = f\"{base_url}/mouse_liver.spatialdata.zarr\"\n",
- "adata_zarr_filepath = f\"{base_url}/mouse_liver.anndata.zarr\"\n",
- "adata_h5ad_filepath = f\"{base_url}/mouse_liver.h5ad\"\n",
- "ref_spec_json_filepath = f\"{base_url}/mouse_liver.h5ad.ref.json\"\n",
- "ome_tiff_filepath = f\"{base_url}/mouse_liver.ome.tif\"\n",
- "offsets_json_filepath = f\"{base_url}/mouse_liver.ome.tif.offsets.json\"\n",
- "ome_zarr_filepath = f\"{base_url}/mouse_liver.ome.zarr\"\n",
- "labels_ome_zarr_filepath = f\"{base_url}/mouse_liver.labels.ome.zarr\""
+ ""
]
},
{
"cell_type": "markdown",
"id": "lEQa",
- "metadata": {},
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"## Utility dependencies"
]
},
{
"cell_type": "markdown",
- "id": "Vxnm",
- "metadata": {},
- "source": [
- "### Render the widget"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "ecfG",
- "metadata": {},
+ "id": "PKri",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "The above example demonstrates how to visualize a spatial 'omics dataset containing not only single-cell information (e.g., a cell-by-gene expression matrix, cell type annotations) but also an image and cell segmentations.\n",
- "To demonstrate how to use Vitessce to visualize data from a (non-spatial) single-cell experiment, we will extract this information from the SpatialData object and save it to a simpler [AnnData](https://anndata.readthedocs.io/) object (ignoring the imaging and spatially-resolved elements)."
+ "First, we import utility dependencies which will be used to download the example dataset and manipulate file paths, zip files, and JSON files."
]
},
{
- "cell_type": "markdown",
- "id": "Pvdt",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
"metadata": {},
+ "outputs": [],
"source": [
- "As Zarr-formatted data can be easily visualized by Vitessce, we recommend saving the AnnData object to a Zarr store using the [write_zarr](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_zarr.html) method.\n",
- "Optionally, the shape of array chunks (for the AnnData `X` array) can be specified as a parameter, to optimize performance based on data access patterns.\n",
- "For example, a common pattern is to visualize data across all cells for one gene.\n",
- "To support such a pattern, the chunk shape can be specified as follows, `(total number of cells, small number of genes)`, resulting in tall-and-skinny array chunks."
+ "import os\n",
+ "from os.path import join, isfile, isdir\n",
+ "from urllib.request import urlretrieve\n",
+ "import zipfile\n",
+ "import json"
]
},
{
"cell_type": "markdown",
- "id": "PKri",
- "metadata": {},
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "First, we import utility dependencies which will be used to download the example dataset and manipulate file paths, zip files, and JSON files."
+ "## Dependencies for Vitessce"
]
},
{
"cell_type": "markdown",
"id": "BYtC",
- "metadata": {},
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"Here, we import classes and functions from the `vitessce` Python package.\n",
"This package includes not only APIs for [visualization configuration](https://python-docs.vitessce.io/api_config.html) but also [helper functions](https://python-docs.vitessce.io/api_data.html#vitessce-data-utils) for basic data transformation tasks.\n",
@@ -143,221 +146,352 @@
]
},
{
- "cell_type": "markdown",
- "id": "bkHC",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
"metadata": {},
+ "outputs": [],
"source": [
- ""
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " ViewType as vt,\n",
+ " CoordinationType as ct,\n",
+ " CoordinationLevel as CL,\n",
+ " SpatialDataWrapper,\n",
+ " AnnDataWrapper,\n",
+ " ImageOmeTiffWrapper,\n",
+ " ImageOmeZarrWrapper,\n",
+ " ObsSegmentationsOmeZarrWrapper,\n",
+ " get_initial_coordination_scope_prefix,\n",
+ " hconcat,\n",
+ " vconcat,\n",
+ ")\n",
+ "from vitessce.data_utils import (\n",
+ " VAR_CHUNK_SIZE,\n",
+ " generate_h5ad_ref_spec,\n",
+ " multiplex_img_to_ome_tiff,\n",
+ " multiplex_img_to_ome_zarr,\n",
+ ")"
]
},
{
"cell_type": "markdown",
- "id": "kqZH",
- "metadata": {},
+ "id": "Kclp",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "### OME-TIFF image"
+ "In this blog post, we perform basic data transformation tasks to save individual elements of an integrated SpatialData object to separate files in AnnData, OME-TIFF, and OME-Zarr formats.\n",
+ "To perform these data transformations, we import the following dependencies.\n",
+ "In general, you will typically not need to import all of these dependencies, either because you are only working with data in one of these formats, or because the data you intend to visualize is already saved to a file or directory."
]
},
{
"cell_type": "markdown",
- "id": "xXTn",
- "metadata": {},
+ "id": "emfo",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "### Zarr-based AnnData"
+ "## Download example dataset"
]
},
{
"cell_type": "markdown",
- "id": "SFPL",
- "metadata": {},
+ "id": "Hstk",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## Dependencies for Vitessce"
+ "We download a mouse liver dataset which serves as a SpatialData [example dataset](https://github.com/scverse/spatialdata-notebooks/blob/main/notebooks/examples/transformations.ipynb).\n",
+ "\n",
+ "This dataset was generated by [Guilliams et al.](https://doi.org/10.1016/j.cell.2021.12.018) and processed using [SPArrOW](https://doi.org/10.1101/2024.07.04.601829) during the SpatialData [developer workshop](https://doi.org/10.37044/osf.io/8ck3e) in 2024."
]
},
{
- "cell_type": "markdown",
- "id": "ZBYS",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "nWHF",
"metadata": {},
+ "outputs": [],
"source": [
- "Alternatively, your AnnData object may already be stored using the H5AD (HDF5-based) format.\n",
- "To demonstrate this scenario, we save the object using the [write_h5ad](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_h5ad.html) method."
+ "base_url = \"https://storage.googleapis.com/vitessce-demo-data/spatialdata-may-2025\""
]
},
{
- "cell_type": "markdown",
- "id": "aLJB",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "iLit",
"metadata": {},
+ "outputs": [],
"source": [
- "To read H5AD-formatted data, Vitessce requires an accompanying JSON [references specification](https://fsspec.github.io/kerchunk/spec.html) file, which can be constructed using the `generate_h5ad_ref_spec` utility function."
+ "zip_filepath = f\"{base_url}/mouse_liver.spatialdata.zarr.zip\"\n",
+ "spatialdata_filepath = f\"{base_url}/mouse_liver.spatialdata.zarr\"\n",
+ "adata_zarr_filepath = f\"{base_url}/mouse_liver.anndata.zarr\"\n",
+ "adata_h5ad_filepath = f\"{base_url}/mouse_liver.h5ad\"\n",
+ "ref_spec_json_filepath = f\"{base_url}/mouse_liver.h5ad.ref.json\"\n",
+ "ome_tiff_filepath = f\"{base_url}/mouse_liver.ome.tif\"\n",
+ "offsets_json_filepath = f\"{base_url}/mouse_liver.ome.tif.offsets.json\"\n",
+ "ome_zarr_filepath = f\"{base_url}/mouse_liver.ome.zarr\"\n",
+ "labels_ome_zarr_filepath = f\"{base_url}/mouse_liver.labels.ome.zarr\""
]
},
{
"cell_type": "markdown",
- "id": "Kclp",
- "metadata": {},
+ "id": "ZHCJ",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "In this blog post, we perform basic data transformation tasks to save individual elements of an integrated SpatialData object to separate files in AnnData, OME-TIFF, and OME-Zarr formats.\n",
- "To perform these data transformations, we import the following dependencies.\n",
- "In general, you will typically not need to import all of these dependencies, either because you are only working with data in one of these formats, or because the data you intend to visualize is already saved to a file or directory."
+ "## Visualization of a SpatialData object"
]
},
{
"cell_type": "markdown",
- "id": "Hbol",
- "metadata": {},
+ "id": "ROlb",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "# Vitessce Widget Tutorial"
+ "SpatialData objects are the most complex type of data structure we will work with in this blog post.\n",
+ "SpatialData objects function as contains for multiple types of Spatial Elements:\n",
+ "\n",
+ "- Tables (each table is represented as an AnnData object)\n",
+ "- Points (e.g., coordinates of transcripts from FISH-based experiments)\n",
+ "- Shapes (vector-based shapes such as polygons and circles)\n",
+ "- Labels (label images, i.e., segmentation bitmasks; each label image is stored using OME-Zarr)\n",
+ "- Images (microscopy images; each image is stored using OME-Zarr)"
]
},
{
"cell_type": "markdown",
- "id": "nHfw",
- "metadata": {},
+ "id": "qnkX",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## Visualization of an AnnData object"
+ "## Configure Vitessce\n",
+ "\n",
+ "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views.\n",
+ "To visualize data stored in a SpatialData object, we use the `SpatialDataWrapper` class and specify the paths (relative to the root of the Zarr [directory store](https://zarr.readthedocs.io/en/v2.18.5/api/storage.html#zarr.storage.DirectoryStore)) to different spatial elements of interest."
]
},
{
- "cell_type": "markdown",
- "id": "dNNg",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "TqIu",
"metadata": {},
+ "outputs": [],
"source": [
- "### OME-Zarr image"
+ "vc = VitessceConfig(schema_version='1.0.18', name='SpatialData Demo')\n",
+ "_wrapper = SpatialDataWrapper(sdata_url=spatialdata_filepath, table_path='tables/table', image_path='images/raw_image', obs_segmentations_path='labels/segmentation_mask', obs_feature_matrix_path='tables/table/X', obs_set_paths=['tables/table/obs/annotation'], obs_set_names=['Annotation'], region='nucleus_boundaries', coordinate_system='global', coordination_values={'obsType': 'cell'})\n",
+ "_dataset = vc.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
+ "_spatial = vc.add_view('spatialBeta', dataset=_dataset)\n",
+ "feature_list = vc.add_view('featureList', dataset=_dataset)\n",
+ "_layer_controller = vc.add_view('layerControllerBeta', dataset=_dataset)\n",
+ "obs_sets = vc.add_view('obsSets', dataset=_dataset)\n",
+ "_heatmap = vc.add_view('heatmap', dataset=_dataset)\n",
+ "[obs_color_encoding_scope] = vc.add_coordination('obsColorEncoding')\n",
+ "obs_color_encoding_scope.set_value('cellSetSelection')\n",
+ "vc.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))\n",
+ "vc.link_views_by_dict([_spatial, _layer_controller], {'segmentationLayer': CL([{'segmentationChannel': CL([{'obsColorEncoding': obs_color_encoding_scope}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'obsSegmentations'))\n",
+ "vc.link_views([_spatial, _layer_controller, feature_list, obs_sets, _heatmap], ['obsType'], [_wrapper.obs_type_label])\n",
+ "vc.link_views_by_dict([feature_list, obs_sets, _heatmap], {'obsColorEncoding': obs_color_encoding_scope}, meta=False)\n",
+ "vc.layout(_spatial / _heatmap | _layer_controller / (feature_list | obs_sets))"
]
},
{
"cell_type": "markdown",
- "id": "emfo",
- "metadata": {},
+ "id": "Vxnm",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## Download example dataset"
+ "### Render the widget"
]
},
{
- "cell_type": "markdown",
- "id": "NCOB",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "DnEU",
"metadata": {},
+ "outputs": [],
"source": [
- "### H5AD-based AnnData"
+ "_vw = vc.widget(height=900)\n",
+ "_vw"
]
},
{
"cell_type": "markdown",
- "id": "ROlb",
- "metadata": {},
+ "id": "ulZA",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "SpatialData objects are the most complex type of data structure we will work with in this blog post.\n",
- "SpatialData objects function as contains for multiple types of Spatial Elements:\n",
- "\n",
- "- Tables (each table is represented as an AnnData object)\n",
- "- Points (e.g., coordinates of transcripts from FISH-based experiments)\n",
- "- Shapes (vector-based shapes such as polygons and circles)\n",
- "- Labels (label images, i.e., segmentation bitmasks; each label image is stored using OME-Zarr)\n",
- "- Images (microscopy images; each image is stored using OME-Zarr)"
+ "## Extract AnnData object from SpatialData object"
]
},
{
"cell_type": "markdown",
- "id": "ZHCJ",
- "metadata": {},
+ "id": "ecfG",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## Visualization of a SpatialData object"
+ "The above example demonstrates how to visualize a spatial 'omics dataset containing not only single-cell information (e.g., a cell-by-gene expression matrix, cell type annotations) but also an image and cell segmentations.\n",
+ "To demonstrate how to use Vitessce to visualize data from a (non-spatial) single-cell experiment, we will extract this information from the SpatialData object and save it to a simpler [AnnData](https://anndata.readthedocs.io/) object (ignoring the imaging and spatially-resolved elements)."
]
},
{
"cell_type": "markdown",
- "id": "dGlV",
- "metadata": {},
+ "id": "Pvdt",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## Data location options\n",
- "\n",
- "Vitessce can visualize data [not only stored](https://python-docs.vitessce.io/data_options.html) locally (referenced using local file or directory paths) but also stored remotely (referenced using absolute URL paths).\n",
- "Depending on whether the Python kernel running the Jupyter process is running locally versus remotely (e.g., on a cluster or cloud platform such as Google Colab), certain data locations may be challenging to access from the machine running the Jupyter notebook frontend (i.e., the machine on which the web browser used to view the notebook is installed).\n",
- "\n",
- "To provide data via one of these alternative mechanisms, use parameters with the following suffices when instantiating the data wrapper classes.\n",
- "\n",
- "- `_path`: Local file or directory\n",
- "- `_url`: Remote file or directory\n",
- "- `_store`: Zarr-store-accessible (for zarr-based formats)\n",
- "- `_artifact`: Lamin artifact\n",
- "\n",
- "For example, `adata_path` can be exchanged for one of the following options.\n",
- "\n",
- "```diff\n",
- "AnnDataWrapper(\n",
- "- adata_path=\"./mouse_liver.spatialdata.zarr\",\n",
- "+ adata_url=\"https://example.com/mouse_liver.spatialdata.zarr\", # Absolute URL\n",
- "+ adata_store=\"./mouse_liver.spatialdata.zarr\", # String interpreted as root of DirectoryStore\n",
- "+ adata_store=zarr.DirectoryStore(\"./mouse_liver.spatialdata.zarr\"), # Instance of zarr.storage\n",
- "+ adata_artifact=adata_zarr_artifact, # Instance of ln.Artifact\n",
- " ...\n",
- "```\n",
- "\n",
- "Note that the `_store` options are only available for Zarr-based formats, such as AnnDataWrapper, SpatialDataWrapper, and ImageOmeZarrWrapper.\n",
- "Further, when multiple files are required, such as both `adata_path` and `ref_path` (for the JSON reference specification file accompanying an H5AD file) or `img_path` and `offsets_path`, multiple parameter suffices may need to be changed."
+ "As Zarr-formatted data can be easily visualized by Vitessce, we recommend saving the AnnData object to a Zarr store using the [write_zarr](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_zarr.html) method.\n",
+ "Optionally, the shape of array chunks (for the AnnData `X` array) can be specified as a parameter, to optimize performance based on data access patterns.\n",
+ "For example, a common pattern is to visualize data across all cells for one gene.\n",
+ "To support such a pattern, the chunk shape can be specified as follows, `(total number of cells, small number of genes)`, resulting in tall-and-skinny array chunks."
]
},
{
"cell_type": "markdown",
- "id": "vblA",
- "metadata": {},
+ "id": "ZBYS",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "This notebook explains how to create interactive visualizations of data that are accessible remotely.\n",
- "\n",
- "\n",
- "We progress through different visualization tasks, first demonstrating how Vitessce facilitates integrated imaging and spatial single-cell visualizations, then demonstrating visualization of non-spatial and image-only datasets."
+ "Alternatively, your AnnData object may already be stored using the H5AD (HDF5-based) format.\n",
+ "To demonstrate this scenario, we save the object using the [write_h5ad](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_h5ad.html) method."
]
},
{
"cell_type": "markdown",
- "id": "qnkX",
- "metadata": {},
+ "id": "aLJB",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## Configure Vitessce\n",
- "\n",
- "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views.\n",
- "To visualize data stored in a SpatialData object, we use the `SpatialDataWrapper` class and specify the paths (relative to the root of the Zarr [directory store](https://zarr.readthedocs.io/en/v2.18.5/api/storage.html#zarr.storage.DirectoryStore)) to different spatial elements of interest."
+ "To read H5AD-formatted data, Vitessce requires an accompanying JSON [references specification](https://fsspec.github.io/kerchunk/spec.html) file, which can be constructed using the `generate_h5ad_ref_spec` utility function."
]
},
{
"cell_type": "markdown",
- "id": "ulZA",
- "metadata": {},
+ "id": "nHfw",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## Extract AnnData object from SpatialData object"
+ "## Visualization of an AnnData object"
]
},
{
"cell_type": "markdown",
- "id": "TXez",
+ "id": "xXTn",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### Zarr-based AnnData"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "AjVT",
"metadata": {},
+ "outputs": [],
"source": [
- "## Visualization of an image file"
+ "vc_1 = VitessceConfig(schema_version='1.0.18', name='AnnData (zarr)')\n",
+ "_wrapper = AnnDataWrapper(adata_url=adata_zarr_filepath, obs_feature_matrix_path='X', obs_set_paths=['obs/annotation'], obs_set_names=['Annotation'], coordination_values={'obsType': 'cell'})\n",
+ "_dataset = vc_1.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
+ "_heatmap = vc_1.add_view(vt.HEATMAP, dataset=_dataset)\n",
+ "feature_list_1 = vc_1.add_view(vt.FEATURE_LIST, dataset=_dataset)\n",
+ "obs_sets_1 = vc_1.add_view(vt.OBS_SETS, dataset=_dataset)\n",
+ "_violin_plots = vc_1.add_view('obsSetFeatureValueDistribution', dataset=_dataset)\n",
+ "vc_1.link_views([_heatmap, feature_list_1, obs_sets_1], ['obsType', 'featureValueColormapRange'], ['cell', [0, 0.01]])\n",
+ "vc_1.layout(_heatmap / _violin_plots | feature_list_1 / obs_sets_1)"
]
},
{
- "cell_type": "markdown",
- "id": "Hstk",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "pHFh",
"metadata": {},
+ "outputs": [],
"source": [
- "We download a mouse liver dataset which serves as a SpatialData [example dataset](https://github.com/scverse/spatialdata-notebooks/blob/main/notebooks/examples/transformations.ipynb).\n",
- "\n",
- "This dataset was generated by [Guilliams et al.](https://doi.org/10.1016/j.cell.2021.12.018) and processed using [SPArrOW](https://doi.org/10.1101/2024.07.04.601829) during the SpatialData [developer workshop](https://doi.org/10.37044/osf.io/8ck3e) in 2024."
+ "vc_1.widget()"
]
},
{
"cell_type": "markdown",
- "id": "MJUe",
- "metadata": {},
+ "id": "NCOB",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "# Visualization of a SpatialData object and individual Spatial Elements, remote data"
+ "### H5AD-based AnnData"
]
},
{
@@ -381,69 +515,39 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "TqIu",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version='1.0.18', name='SpatialData Demo')\n",
- "_wrapper = SpatialDataWrapper(sdata_url=spatialdata_filepath, table_path='tables/table', image_path='images/raw_image', obs_segmentations_path='labels/segmentation_mask', obs_feature_matrix_path='tables/table/X', obs_set_paths=['tables/table/obs/annotation'], obs_set_names=['Annotation'], region='nucleus_boundaries', coordinate_system='global', coordination_values={'obsType': 'cell'})\n",
- "_dataset = vc.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
- "_spatial = vc.add_view('spatialBeta', dataset=_dataset)\n",
- "feature_list = vc.add_view('featureList', dataset=_dataset)\n",
- "_layer_controller = vc.add_view('layerControllerBeta', dataset=_dataset)\n",
- "obs_sets = vc.add_view('obsSets', dataset=_dataset)\n",
- "_heatmap = vc.add_view('heatmap', dataset=_dataset)\n",
- "[obs_color_encoding_scope] = vc.add_coordination('obsColorEncoding')\n",
- "obs_color_encoding_scope.set_value('cellSetSelection')\n",
- "vc.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))\n",
- "vc.link_views_by_dict([_spatial, _layer_controller], {'segmentationLayer': CL([{'segmentationChannel': CL([{'obsColorEncoding': obs_color_encoding_scope}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'obsSegmentations'))\n",
- "vc.link_views([_spatial, _layer_controller, feature_list, obs_sets, _heatmap], ['obsType'], [_wrapper.obs_type_label])\n",
- "vc.link_views_by_dict([feature_list, obs_sets, _heatmap], {'obsColorEncoding': obs_color_encoding_scope}, meta=False)\n",
- "vc.layout(_spatial / _heatmap | _layer_controller / (feature_list | obs_sets))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "AjVT",
+ "id": "TRpd",
"metadata": {},
"outputs": [],
"source": [
- "vc_1 = VitessceConfig(schema_version='1.0.18', name='AnnData (zarr)')\n",
- "_wrapper = AnnDataWrapper(adata_url=adata_zarr_filepath, obs_feature_matrix_path='X', obs_set_paths=['obs/annotation'], obs_set_names=['Annotation'], coordination_values={'obsType': 'cell'})\n",
- "_dataset = vc_1.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
- "_heatmap = vc_1.add_view(vt.HEATMAP, dataset=_dataset)\n",
- "feature_list_1 = vc_1.add_view(vt.FEATURE_LIST, dataset=_dataset)\n",
- "obs_sets_1 = vc_1.add_view(vt.OBS_SETS, dataset=_dataset)\n",
- "_violin_plots = vc_1.add_view('obsSetFeatureValueDistribution', dataset=_dataset)\n",
- "vc_1.link_views([_heatmap, feature_list_1, obs_sets_1], ['obsType', 'featureValueColormapRange'], ['cell', [0, 0.01]])\n",
- "vc_1.layout(_heatmap / _violin_plots | feature_list_1 / obs_sets_1)"
+ "vc_2.widget()"
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "wAgl",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "TXez",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "vc_4 = VitessceConfig(schema_version='1.0.18', name='Image and segmentations (ome-tiff)')\n",
- "_wrapper = ImageOmeTiffWrapper(img_url=ome_tiff_filepath, offsets_url=offsets_json_filepath)\n",
- "_dataset = vc_4.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
- "_spatial = vc_4.add_view('spatialBeta', dataset=_dataset)\n",
- "_layer_controller = vc_4.add_view('layerControllerBeta', dataset=_dataset)\n",
- "vc_4.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))\n",
- "vc_4.layout(hconcat(_spatial, _layer_controller, split=(2, 1)))"
+ "## Visualization of an image file"
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "TRpd",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "dNNg",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "vc_2.widget()"
+ "### OME-Zarr image"
]
},
{
@@ -468,22 +572,42 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "DnEU",
+ "id": "wlCL",
"metadata": {},
"outputs": [],
"source": [
- "_vw = vc.widget(height=900)\n",
+ "_vw = vc_3.widget()\n",
"_vw"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "kqZH",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### OME-TIFF image"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "pHFh",
+ "id": "wAgl",
"metadata": {},
"outputs": [],
"source": [
- "vc_1.widget()"
+ "vc_4 = VitessceConfig(schema_version='1.0.18', name='Image and segmentations (ome-tiff)')\n",
+ "_wrapper = ImageOmeTiffWrapper(img_url=ome_tiff_filepath, offsets_url=offsets_json_filepath)\n",
+ "_dataset = vc_4.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
+ "_spatial = vc_4.add_view('spatialBeta', dataset=_dataset)\n",
+ "_layer_controller = vc_4.add_view('layerControllerBeta', dataset=_dataset)\n",
+ "vc_4.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))\n",
+ "vc_4.layout(hconcat(_spatial, _layer_controller, split=(2, 1)))"
]
},
{
@@ -496,15 +620,53 @@
"vc_4.widget()"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "dGlV",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Data location options\n",
+ "\n",
+ "Vitessce can visualize data [not only stored](https://python-docs.vitessce.io/data_options.html) locally (referenced using local file or directory paths) but also stored remotely (referenced using absolute URL paths).\n",
+ "Depending on whether the Python kernel running the Jupyter process is running locally versus remotely (e.g., on a cluster or cloud platform such as Google Colab), certain data locations may be challenging to access from the machine running the Jupyter notebook frontend (i.e., the machine on which the web browser used to view the notebook is installed).\n",
+ "\n",
+ "To provide data via one of these alternative mechanisms, use parameters with the following suffices when instantiating the data wrapper classes.\n",
+ "\n",
+ "- `_path`: Local file or directory\n",
+ "- `_url`: Remote file or directory\n",
+ "- `_store`: Zarr-store-accessible (for zarr-based formats)\n",
+ "- `_artifact`: Lamin artifact\n",
+ "\n",
+ "For example, `adata_path` can be exchanged for one of the following options.\n",
+ "\n",
+ "```diff\n",
+ "AnnDataWrapper(\n",
+ "- adata_path=\"./mouse_liver.spatialdata.zarr\",\n",
+ "+ adata_url=\"https://example.com/mouse_liver.spatialdata.zarr\", # Absolute URL\n",
+ "+ adata_store=\"./mouse_liver.spatialdata.zarr\", # String interpreted as root of DirectoryStore\n",
+ "+ adata_store=zarr.DirectoryStore(\"./mouse_liver.spatialdata.zarr\"), # Instance of zarr.storage\n",
+ "+ adata_artifact=adata_zarr_artifact, # Instance of ln.Artifact\n",
+ " ...\n",
+ "```\n",
+ "\n",
+ "Note that the `_store` options are only available for Zarr-based formats, such as AnnDataWrapper, SpatialDataWrapper, and ImageOmeZarrWrapper.\n",
+ "Further, when multiple files are required, such as both `adata_path` and `ref_path` (for the JSON reference specification file accompanying an H5AD file) or `img_path` and `offsets_path`, multiple parameter suffices may need to be changed."
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "wlCL",
+ "id": "SdmI",
"metadata": {},
"outputs": [],
"source": [
- "_vw = vc_3.widget()\n",
- "_vw"
+ "import marimo as mo"
]
}
],
diff --git a/docs/notebooks/__ipynb__/spatial_data_visium_hd.ipynb b/docs/notebooks/__ipynb__/spatial_data_visium_hd.ipynb
index ac735a78..70d6aebf 100644
--- a/docs/notebooks/__ipynb__/spatial_data_visium_hd.ipynb
+++ b/docs/notebooks/__ipynb__/spatial_data_visium_hd.ipynb
@@ -1,5 +1,47 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of a SpatialData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Import dependencies"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
@@ -22,30 +64,6 @@
")"
]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "SFPL",
- "metadata": {},
- "outputs": [],
- "source": [
- "from spatialdata import (\n",
- " read_zarr,\n",
- " rasterize_bins,\n",
- " rasterize_bins_link_table_to_labels\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "iLit",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- },
{
"cell_type": "code",
"execution_count": null,
@@ -59,54 +77,109 @@
]
},
{
- "cell_type": "markdown",
- "id": "Hbol",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
"metadata": {},
+ "outputs": [],
"source": [
- "# Vitessce Widget Tutorial"
+ "if not isdir(spatialdata_filepath):\n",
+ " if not isfile(zip_filepath):\n",
+ " os.makedirs(data_dir, exist_ok=True)\n",
+ " urlretrieve('https://s3.embl.de/spatialdata/spatialdata-sandbox/visium_hd_3.0.0_io.zip', zip_filepath)\n",
+ " with zipfile.ZipFile(zip_filepath,\"r\") as zip_ref:\n",
+ " zip_ref.extractall(data_dir)\n",
+ " os.rename(join(data_dir, \"data.zarr\"), spatialdata_filepath)"
]
},
{
"cell_type": "markdown",
"id": "Xref",
- "metadata": {},
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"## Rasterize bins\n",
"Reference: https://spatialdata.scverse.org/en/stable/tutorials/notebooks/notebooks/examples/technology_visium_hd.html#performant-on-the-fly-data-rasterization"
]
},
{
- "cell_type": "markdown",
- "id": "MJUe",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
"metadata": {},
+ "outputs": [],
"source": [
- "# Visualization of a SpatialData object"
+ "from spatialdata import (\n",
+ " read_zarr,\n",
+ " rasterize_bins,\n",
+ " rasterize_bins_link_table_to_labels\n",
+ ")"
]
},
{
- "cell_type": "markdown",
- "id": "vblA",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
"metadata": {},
+ "outputs": [],
"source": [
- "## Import dependencies"
+ "sdata = read_zarr(spatialdata_filepath)\n",
+ "\n",
+ "for bin_size in [\"016\", \"008\", \"002\"]:\n",
+ " # rasterize_bins() requires a compresed sparse column (csc) matrix\n",
+ " sdata.tables[f\"square_{bin_size}um\"].X = sdata.tables[f\"square_{bin_size}um\"].X.tocsc()\n",
+ " rasterized = rasterize_bins(\n",
+ " sdata,\n",
+ " f\"Visium_HD_Mouse_Small_Intestine_square_{bin_size}um\",\n",
+ " f\"square_{bin_size}um\",\n",
+ " \"array_col\",\n",
+ " \"array_row\",\n",
+ " # We want to rasterize to a Labels element, rather than an Image element.\n",
+ " return_region_as_labels=True\n",
+ " )\n",
+ " sdata[f\"rasterized_{bin_size}um\"] = rasterized\n",
+ " rasterize_bins_link_table_to_labels(\n",
+ " sdata,\n",
+ " table_name=f\"square_{bin_size}um\",\n",
+ " rasterized_labels_name=f\"rasterized_{bin_size}um\",\n",
+ " )\n",
+ " try:\n",
+ " sdata.write_element(f\"rasterized_{bin_size}um\")\n",
+ " except:\n",
+ " pass\n",
+ "\n",
+ "sdata"
]
},
{
- "cell_type": "markdown",
- "id": "Kclp",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
"metadata": {},
+ "outputs": [],
"source": [
- "## Configure Vitessce\n",
- "\n",
- "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
+ "sdata"
]
},
{
"cell_type": "markdown",
- "id": "Hstk",
- "metadata": {},
+ "id": "Kclp",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "### Render the widget"
+ "## Configure Vitessce\n",
+ "\n",
+ "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
]
},
{
@@ -163,54 +236,11 @@
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "PKri",
- "metadata": {},
- "outputs": [],
- "source": [
- "if not isdir(spatialdata_filepath):\n",
- " if not isfile(zip_filepath):\n",
- " os.makedirs(data_dir, exist_ok=True)\n",
- " urlretrieve('https://s3.embl.de/spatialdata/spatialdata-sandbox/visium_hd_3.0.0_io.zip', zip_filepath)\n",
- " with zipfile.ZipFile(zip_filepath,\"r\") as zip_ref:\n",
- " zip_ref.extractall(data_dir)\n",
- " os.rename(join(data_dir, \"data.zarr\"), spatialdata_filepath)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "BYtC",
+ "cell_type": "markdown",
+ "id": "Hstk",
"metadata": {},
- "outputs": [],
"source": [
- "sdata = read_zarr(spatialdata_filepath)\n",
- "\n",
- "for bin_size in [\"016\", \"008\", \"002\"]:\n",
- " # rasterize_bins() requires a compresed sparse column (csc) matrix\n",
- " sdata.tables[f\"square_{bin_size}um\"].X = sdata.tables[f\"square_{bin_size}um\"].X.tocsc()\n",
- " rasterized = rasterize_bins(\n",
- " sdata,\n",
- " f\"Visium_HD_Mouse_Small_Intestine_square_{bin_size}um\",\n",
- " f\"square_{bin_size}um\",\n",
- " \"array_col\",\n",
- " \"array_row\",\n",
- " # We want to rasterize to a Labels element, rather than an Image element.\n",
- " return_region_as_labels=True\n",
- " )\n",
- " sdata[f\"rasterized_{bin_size}um\"] = rasterized\n",
- " rasterize_bins_link_table_to_labels(\n",
- " sdata,\n",
- " table_name=f\"square_{bin_size}um\",\n",
- " rasterized_labels_name=f\"rasterized_{bin_size}um\",\n",
- " )\n",
- " try:\n",
- " sdata.write_element(f\"rasterized_{bin_size}um\")\n",
- " except:\n",
- " pass\n",
- "\n",
- "sdata"
+ "### Render the widget"
]
},
{
@@ -227,11 +257,11 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "RGSE",
+ "id": "iLit",
"metadata": {},
"outputs": [],
"source": [
- "sdata"
+ "import marimo as mo"
]
}
],
diff --git a/docs/notebooks/__ipynb__/web_app_brain.ipynb b/docs/notebooks/__ipynb__/web_app_brain.ipynb
index 00ae949b..5ef1205f 100644
--- a/docs/notebooks/__ipynb__/web_app_brain.ipynb
+++ b/docs/notebooks/__ipynb__/web_app_brain.ipynb
@@ -1,5 +1,49 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Vitessce Web App Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of single-cell RNA seq data using vitessce.io"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the classes and functions that we will be using from the corresponding packages."
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
@@ -22,23 +66,19 @@
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "ulZA",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Hstk",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', description='COVID-19 Healthy Donor Brain')"
+ "## 2. Download the data\n",
+ "\n",
+ "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
]
},
{
@@ -55,28 +95,40 @@
},
{
"cell_type": "markdown",
- "id": "emfo",
- "metadata": {},
+ "id": "Xref",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "### 4.1. Instantiate a `VitessceConfig` object\n",
+ "## 3. Load the data\n",
"\n",
- "Use the `VitessceConfig(name, description)` constructor to create an instance."
+ "Note: this function may print a `FutureWarning`"
]
},
{
- "cell_type": "markdown",
- "id": "lEQa",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
"metadata": {},
+ "outputs": [],
"source": [
- "## 2. Download the data\n",
- "\n",
- "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
+ "adata = read_h5ad(adata_filepath)"
]
},
{
"cell_type": "markdown",
"id": "BYtC",
- "metadata": {},
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"## 3.1. Preprocess the Data For Visualization\n",
"\n",
@@ -84,75 +136,75 @@
]
},
{
- "cell_type": "markdown",
- "id": "vblA",
- "metadata": {},
- "source": [
- "## 1. Import dependencies\n",
- "\n",
- "We need to import the classes and functions that we will be using from the corresponding packages."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Vxnm",
- "metadata": {},
- "source": [
- "## 5. Launch the web application\n",
- "\n",
- "The `vc.web_app()` method serves the processed data locally and opens a web browser to `http://vitessce.io/?url={config_as_json}`"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {},
- "source": [
- "# Visualization of single-cell RNA seq data using vitessce.io"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Xref",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
"metadata": {},
+ "outputs": [],
"source": [
- "## 3. Load the data\n",
- "\n",
- "Note: this function may print a `FutureWarning`"
+ "top_dispersion = adata.var[\"dispersions_norm\"][\n",
+ " sorted(\n",
+ " range(len(adata.var[\"dispersions_norm\"])),\n",
+ " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
+ " )[-51:][0]\n",
+ "]\n",
+ "adata.var[\"top_highly_variable\"] = (\n",
+ " adata.var[\"dispersions_norm\"] > top_dispersion\n",
+ ")"
]
},
{
"cell_type": "markdown",
- "id": "qnkX",
- "metadata": {},
+ "id": "Kclp",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "### 4.4. Define the visualization layout\n",
+ "## 4. Create the Vitessce widget configuration\n",
"\n",
- "The `vc.layout(view_concat)` method allows us to specify how our views will be arranged in the layout grid in the widget. The `|` and `/` characters are magic syntax for `hconcat(v1, v2)` and `vconcat(v1, v2)`, respectively."
+ "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
]
},
{
"cell_type": "markdown",
- "id": "Kclp",
- "metadata": {},
+ "id": "emfo",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## 4. Create the Vitessce widget configuration\n",
+ "### 4.1. Instantiate a `VitessceConfig` object\n",
"\n",
- "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
+ "Use the `VitessceConfig(name, description)` constructor to create an instance."
]
},
{
- "cell_type": "markdown",
- "id": "Hbol",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Hstk",
"metadata": {},
+ "outputs": [],
"source": [
- "# Vitessce Web App Tutorial"
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', description='COVID-19 Healthy Donor Brain')"
]
},
{
"cell_type": "markdown",
"id": "nWHF",
- "metadata": {},
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"### 4.2. Add a dataset to the `VitessceConfig` instance\n",
"\n",
@@ -163,10 +215,35 @@
"Dataset wrapper classes may require additional parameters to resolve ambiguities. For instance, `AnnData` objects may store multiple clusterings or cell type annotation columns in the `adata.obs` dataframe. We can use the parameter `cell_set_obs_cols` to tell Vitessce which columns of the `obs` dataframe correspond to cell sets."
]
},
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "iLit",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
+ " adata,\n",
+ " obs_embedding_paths=[\"obsm/X_umap\"],\n",
+ " obs_embedding_names=[\"UMAP\"],\n",
+ " obs_set_paths=[\"obs/CellType\"],\n",
+ " obs_set_names=[\"Cell Type\"],\n",
+ " obs_feature_matrix_path=\"X\",\n",
+ " feature_filter_path=\"var/top_highly_variable\"\n",
+ " )\n",
+ ")"
+ ]
+ },
{
"cell_type": "markdown",
"id": "ZHCJ",
- "metadata": {},
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"### 4.3. Add visualizations to the `VitessceConfig` instance\n",
"\n",
@@ -180,81 +257,76 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "DnEU",
+ "id": "ROlb",
"metadata": {},
"outputs": [],
"source": [
- "vc.web_app()"
+ "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
+ "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
+ "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
+ "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)"
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "SFPL",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "qnkX",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "adata = read_h5ad(adata_filepath)"
+ "### 4.4. Define the visualization layout\n",
+ "\n",
+ "The `vc.layout(view_concat)` method allows us to specify how our views will be arranged in the layout grid in the widget. The `|` and `/` characters are magic syntax for `hconcat(v1, v2)` and `vconcat(v1, v2)`, respectively."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "iLit",
+ "id": "TqIu",
"metadata": {},
"outputs": [],
"source": [
- "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
- " adata,\n",
- " obs_embedding_paths=[\"obsm/X_umap\"],\n",
- " obs_embedding_names=[\"UMAP\"],\n",
- " obs_set_paths=[\"obs/CellType\"],\n",
- " obs_set_names=[\"Cell Type\"],\n",
- " obs_feature_matrix_path=\"X\",\n",
- " feature_filter_path=\"var/top_highly_variable\"\n",
- " )\n",
- ")"
+ "vc.layout((scatterplot | cell_sets) / (heatmap | genes));"
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "RGSE",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "Vxnm",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "top_dispersion = adata.var[\"dispersions_norm\"][\n",
- " sorted(\n",
- " range(len(adata.var[\"dispersions_norm\"])),\n",
- " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
- " )[-51:][0]\n",
- "]\n",
- "adata.var[\"top_highly_variable\"] = (\n",
- " adata.var[\"dispersions_norm\"] > top_dispersion\n",
- ")"
+ "## 5. Launch the web application\n",
+ "\n",
+ "The `vc.web_app()` method serves the processed data locally and opens a web browser to `http://vitessce.io/?url={config_as_json}`"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "ROlb",
+ "id": "DnEU",
"metadata": {},
"outputs": [],
"source": [
- "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
- "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
- "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
- "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)"
+ "vc.web_app()"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "TqIu",
+ "id": "ulZA",
"metadata": {},
"outputs": [],
"source": [
- "vc.layout((scatterplot | cell_sets) / (heatmap | genes));"
+ "import marimo as mo"
]
}
],
diff --git a/docs/notebooks/__ipynb__/widget_anndata_with_image.ipynb b/docs/notebooks/__ipynb__/widget_anndata_with_image.ipynb
index f2934064..64747b59 100644
--- a/docs/notebooks/__ipynb__/widget_anndata_with_image.ipynb
+++ b/docs/notebooks/__ipynb__/widget_anndata_with_image.ipynb
@@ -1,9 +1,37 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of AnnData object containing an image in `uns`"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "Note: This approach to storing images within AnnData objects is no longer recommended now that [SpatialData](https://spatialdata.scverse.org/en/stable/) has been introduced."
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "bkHC",
+ "id": "vblA",
"metadata": {},
"outputs": [],
"source": [
@@ -21,17 +49,7 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "BYtC",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "lEQa",
+ "id": "bkHC",
"metadata": {},
"outputs": [],
"source": [
@@ -39,34 +57,10 @@
"output_adata = join(\"data\", \"V1_Human_Lymph_Node.anndata.zarr\")"
]
},
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {},
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "vblA",
- "metadata": {},
- "source": [
- "Note: This approach to storing images within AnnData objects is no longer recommended now that [SpatialData](https://spatialdata.scverse.org/en/stable/) has been introduced."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {},
- "source": [
- "# Visualization of AnnData object containing an image in `uns`"
- ]
- },
{
"cell_type": "code",
"execution_count": null,
- "id": "PKri",
+ "id": "lEQa",
"metadata": {},
"outputs": [],
"source": [
@@ -88,7 +82,7 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "Xref",
+ "id": "PKri",
"metadata": {},
"outputs": [],
"source": [
@@ -113,13 +107,23 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "SFPL",
+ "id": "Xref",
"metadata": {},
"outputs": [],
"source": [
"vw = vc.widget()\n",
"vw"
]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
}
],
"metadata": {},
diff --git a/docs/notebooks/__ipynb__/widget_brain.ipynb b/docs/notebooks/__ipynb__/widget_brain.ipynb
index 9e99cad8..a0ac732f 100644
--- a/docs/notebooks/__ipynb__/widget_brain.ipynb
+++ b/docs/notebooks/__ipynb__/widget_brain.ipynb
@@ -1,9 +1,39 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of single-cell RNA seq data"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the classes and functions that we will be using from the corresponding packages."
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "bkHC",
+ "id": "vblA",
"metadata": {},
"outputs": [],
"source": [
@@ -26,29 +56,25 @@
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "Pvdt",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "iLit",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', description='COVID-19 Healthy Donor Brain')"
+ "## 2. Download the data\n",
+ "\n",
+ "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "PKri",
+ "id": "lEQa",
"metadata": {},
"outputs": [],
"source": [
@@ -60,56 +86,74 @@
},
{
"cell_type": "markdown",
- "id": "qnkX",
- "metadata": {},
+ "id": "PKri",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "### 4.3. Add visualizations to the `VitessceConfig` instance\n",
- "\n",
- "Now that we have added a dataset, we can configure visualizations. The `.add_view` method adds a view (i.e. visualization or controller component) to the configuration.\n",
- "\n",
- "The `Component` enum class (which we have imported as `cm` here) can be used to fill in the `component_type` parameter.\n",
+ "## 3. Load the data\n",
"\n",
- "For convenience, the `SCATTERPLOT` component type takes the extra `mapping` keyword argument, which specifies which embedding should be used for mapping cells to (x,y) points on the plot."
+ "Note: this function may print a `FutureWarning`"
]
},
{
- "cell_type": "markdown",
- "id": "Vxnm",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
"metadata": {},
+ "outputs": [],
"source": [
- "### 4.4. Define the visualization layout\n",
- "\n",
- "The `vc.layout(view_concat)` method allows us to specify how our views will be arranged in the layout grid in the widget. The `|` and `/` characters are magic syntax for `hconcat(v1, v2)` and `vconcat(v1, v2)`, respectively."
+ "adata = read_h5ad(adata_filepath)"
]
},
{
"cell_type": "markdown",
- "id": "ZHCJ",
- "metadata": {},
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "### 4.2. Add a dataset to the `VitessceConfig` instance\n",
- "\n",
- "In Vitessce, a dataset is a container for one file per data type. The `.add_dataset(name)` method on the `vc` instance sets up and returns a new dataset instance.\n",
- "\n",
- "Then, we can call the dataset's `.add_object(wrapper_object)` method to attach a \"data wrapper\" instance to our new dataset. For example, the `AnnDataWrapper` helps to configure AnnData Zarr stores for use in the Vitessce configuration.\n",
+ "## 3.1. Preprocess the Data For Visualization\n",
"\n",
- "Dataset wrapper classes may require additional parameters to resolve ambiguities. For instance, `AnnData` objects may store multiple clusterings or cell type annotation columns in the `adata.obs` dataframe. We can use the parameter `obs_set_paths` to tell Vitessce that certain columns of the `obs` dataframe correspond to cell type annotations or cell clusterings."
+ "This dataset contains 25,587 genes. We prepare to visualize the top 50 highly variable genes for the heatmap as ranked by dispersion norm, although one may use any boolean array filter for the heatmap."
]
},
{
- "cell_type": "markdown",
- "id": "lEQa",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
"metadata": {},
+ "outputs": [],
"source": [
- "## 2. Download the data\n",
- "\n",
- "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
+ "top_dispersion = adata.var[\"dispersions_norm\"][\n",
+ " sorted(\n",
+ " range(len(adata.var[\"dispersions_norm\"])),\n",
+ " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
+ " )[-51:][0]\n",
+ "]\n",
+ "adata.var[\"top_highly_variable\"] = (\n",
+ " adata.var[\"dispersions_norm\"] > top_dispersion\n",
+ ")"
]
},
{
"cell_type": "markdown",
- "id": "Kclp",
- "metadata": {},
+ "id": "RGSE",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"## 3.2 Save the Data to Zarr store\n",
"\n",
@@ -117,173 +161,193 @@
]
},
{
- "cell_type": "markdown",
- "id": "vblA",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Kclp",
"metadata": {},
+ "outputs": [],
"source": [
- "## 1. Import dependencies\n",
- "\n",
- "We need to import the classes and functions that we will be using from the corresponding packages."
+ "zarr_filepath = join('data', 'habib17.processed.zarr')\n",
+ "if not isdir(zarr_filepath):\n",
+ " adata_1 = optimize_adata(adata, obs_cols=['CellType'], obsm_keys=['X_umap'], optimize_X=True, var_cols=['top_highly_variable'])\n",
+ " adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])"
]
},
{
"cell_type": "markdown",
- "id": "ulZA",
- "metadata": {},
+ "id": "emfo",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## 5. Create the widget\n",
+ "## 4. Create the Vitessce widget configuration\n",
"\n",
- "The `vc.widget()` method returns the configured widget instance."
+ "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
]
},
{
"cell_type": "markdown",
- "id": "MJUe",
- "metadata": {},
+ "id": "Hstk",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "# Visualization of single-cell RNA seq data"
+ "### 4.1. Instantiate a `VitessceConfig` object\n",
+ "\n",
+ "Use the `VitessceConfig` constructor to create an instance."
]
},
{
- "cell_type": "markdown",
- "id": "Hbol",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "nWHF",
"metadata": {},
+ "outputs": [],
"source": [
- "# Vitessce Widget Tutorial"
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', description='COVID-19 Healthy Donor Brain')"
]
},
{
"cell_type": "markdown",
- "id": "BYtC",
- "metadata": {},
+ "id": "iLit",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## 3.1. Preprocess the Data For Visualization\n",
+ "### 4.2. Add a dataset to the `VitessceConfig` instance\n",
"\n",
- "This dataset contains 25,587 genes. We prepare to visualize the top 50 highly variable genes for the heatmap as ranked by dispersion norm, although one may use any boolean array filter for the heatmap."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "nWHF",
- "metadata": {},
- "source": [
- "### 4.1. Instantiate a `VitessceConfig` object\n",
+ "In Vitessce, a dataset is a container for one file per data type. The `.add_dataset(name)` method on the `vc` instance sets up and returns a new dataset instance.\n",
"\n",
- "Use the `VitessceConfig` constructor to create an instance."
+ "Then, we can call the dataset's `.add_object(wrapper_object)` method to attach a \"data wrapper\" instance to our new dataset. For example, the `AnnDataWrapper` helps to configure AnnData Zarr stores for use in the Vitessce configuration.\n",
+ "\n",
+ "Dataset wrapper classes may require additional parameters to resolve ambiguities. For instance, `AnnData` objects may store multiple clusterings or cell type annotation columns in the `adata.obs` dataframe. We can use the parameter `obs_set_paths` to tell Vitessce that certain columns of the `obs` dataframe correspond to cell type annotations or cell clusterings."
]
},
{
- "cell_type": "markdown",
- "id": "Xref",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ZHCJ",
"metadata": {},
+ "outputs": [],
"source": [
- "## 3. Load the data\n",
- "\n",
- "Note: this function may print a `FutureWarning`"
+ "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
+ " adata_path=zarr_filepath,\n",
+ " obs_embedding_paths=[\"obsm/X_umap\"],\n",
+ " obs_embedding_names=[\"UMAP\"],\n",
+ " obs_set_paths=[\"obs/CellType\"],\n",
+ " obs_set_names=[\"Cell Type\"],\n",
+ " obs_feature_matrix_path=\"X\",\n",
+ " initial_feature_filter_path=\"var/top_highly_variable\"\n",
+ " )\n",
+ ")"
]
},
{
"cell_type": "markdown",
- "id": "Hstk",
- "metadata": {},
+ "id": "ROlb",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## 4. Create the Vitessce widget configuration\n",
+ "### 4.3. Add visualizations to the `VitessceConfig` instance\n",
"\n",
- "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "ecfG",
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
+ "Now that we have added a dataset, we can configure visualizations. The `.add_view` method adds a view (i.e. visualization or controller component) to the configuration.\n",
+ "\n",
+ "The `Component` enum class (which we have imported as `cm` here) can be used to fill in the `component_type` parameter.\n",
+ "\n",
+ "For convenience, the `SCATTERPLOT` component type takes the extra `mapping` keyword argument, which specifies which embedding should be used for mapping cells to (x,y) points on the plot."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "SFPL",
+ "id": "qnkX",
"metadata": {},
"outputs": [],
"source": [
- "adata = read_h5ad(adata_filepath)"
+ "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
+ "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
+ "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
+ "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)"
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "RGSE",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "TqIu",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "top_dispersion = adata.var[\"dispersions_norm\"][\n",
- " sorted(\n",
- " range(len(adata.var[\"dispersions_norm\"])),\n",
- " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
- " )[-51:][0]\n",
- "]\n",
- "adata.var[\"top_highly_variable\"] = (\n",
- " adata.var[\"dispersions_norm\"] > top_dispersion\n",
- ")"
+ "### 4.4. Define the visualization layout\n",
+ "\n",
+ "The `vc.layout(view_concat)` method allows us to specify how our views will be arranged in the layout grid in the widget. The `|` and `/` characters are magic syntax for `hconcat(v1, v2)` and `vconcat(v1, v2)`, respectively."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "emfo",
+ "id": "Vxnm",
"metadata": {},
"outputs": [],
"source": [
- "zarr_filepath = join('data', 'habib17.processed.zarr')\n",
- "if not isdir(zarr_filepath):\n",
- " adata_1 = optimize_adata(adata, obs_cols=['CellType'], obsm_keys=['X_umap'], optimize_X=True, var_cols=['top_highly_variable'])\n",
- " adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])"
+ "vc.layout((scatterplot | cell_sets) / (heatmap | genes));"
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "ROlb",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "DnEU",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
- " adata_path=zarr_filepath,\n",
- " obs_embedding_paths=[\"obsm/X_umap\"],\n",
- " obs_embedding_names=[\"UMAP\"],\n",
- " obs_set_paths=[\"obs/CellType\"],\n",
- " obs_set_names=[\"Cell Type\"],\n",
- " obs_feature_matrix_path=\"X\",\n",
- " initial_feature_filter_path=\"var/top_highly_variable\"\n",
- " )\n",
- ")"
+ "## 5. Create the widget\n",
+ "\n",
+ "The `vc.widget()` method returns the configured widget instance."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "TqIu",
+ "id": "ulZA",
"metadata": {},
"outputs": [],
"source": [
- "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
- "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
- "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
- "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)"
+ "vw = vc.widget()\n",
+ "vw"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "DnEU",
+ "id": "ecfG",
"metadata": {},
"outputs": [],
"source": [
- "vc.layout((scatterplot | cell_sets) / (heatmap | genes));"
+ "import marimo as mo"
]
}
],
diff --git a/docs/notebooks/__ipynb__/widget_brain_h5ad.ipynb b/docs/notebooks/__ipynb__/widget_brain_h5ad.ipynb
index 9a5879a5..b4f56631 100644
--- a/docs/notebooks/__ipynb__/widget_brain_h5ad.ipynb
+++ b/docs/notebooks/__ipynb__/widget_brain_h5ad.ipynb
@@ -1,9 +1,23 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of single-cell RNA seq data from H5AD file"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "vblA",
+ "id": "MJUe",
"metadata": {},
"outputs": [],
"source": [
@@ -26,29 +40,33 @@
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "lEQa",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "h5_url = \"https://datasets.cellxgene.cziscience.com/84df8fa1-ab53-43c9-a439-95dcb9148265.h5ad\""
+ "## 0. Download data"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "Hstk",
+ "id": "bkHC",
"metadata": {},
"outputs": [],
"source": [
- "import marimo as mo"
+ "h5_url = \"https://datasets.cellxgene.cziscience.com/84df8fa1-ab53-43c9-a439-95dcb9148265.h5ad\""
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "PKri",
+ "id": "lEQa",
"metadata": {},
"outputs": [],
"source": [
@@ -58,10 +76,26 @@
" urlretrieve(h5_url, adata_filepath)"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "PKri",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Create a Reference Spec JSON file for the H5AD file\n",
+ "\n",
+ "In order for Vitessce to load H5AD files, we also need to provide a corresponding [Reference Spec](https://fsspec.github.io/kerchunk/spec.html) JSON file which contains mappings between AnnData object keys and the byte offsets at which those AnnData object values begin within the H5AD file binary contents."
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "SFPL",
+ "id": "Xref",
"metadata": {},
"outputs": [],
"source": [
@@ -74,58 +108,22 @@
},
{
"cell_type": "markdown",
- "id": "BYtC",
- "metadata": {},
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"## 2. Create the Vitessce widget configuration"
]
},
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {},
- "source": [
- "# Visualization of single-cell RNA seq data from H5AD file"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Xref",
- "metadata": {},
- "source": [
- "## 1. Create a Reference Spec JSON file for the H5AD file\n",
- "\n",
- "In order for Vitessce to load H5AD files, we also need to provide a corresponding [Reference Spec](https://fsspec.github.io/kerchunk/spec.html) JSON file which contains mappings between AnnData object keys and the byte offsets at which those AnnData object values begin within the H5AD file binary contents."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "bkHC",
- "metadata": {},
- "source": [
- "## 0. Download data"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {},
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Kclp",
- "metadata": {},
- "source": [
- "## 3. Create the widget"
- ]
- },
{
"cell_type": "code",
"execution_count": null,
- "id": "RGSE",
+ "id": "BYtC",
"metadata": {},
"outputs": [],
"source": [
@@ -150,16 +148,40 @@
"vc.layout((scatterplot | cell_sets) / (cell_set_sizes | genes));"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "RGSE",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 3. Create the widget"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "emfo",
+ "id": "Kclp",
"metadata": {},
"outputs": [],
"source": [
"vw = vc.widget()\n",
"vw"
]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "emfo",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
}
],
"metadata": {},
diff --git a/docs/notebooks/__ipynb__/widget_brain_with_base_dir.ipynb b/docs/notebooks/__ipynb__/widget_brain_with_base_dir.ipynb
index eafbb348..0f03d764 100644
--- a/docs/notebooks/__ipynb__/widget_brain_with_base_dir.ipynb
+++ b/docs/notebooks/__ipynb__/widget_brain_with_base_dir.ipynb
@@ -1,9 +1,39 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Configure relative to a base_dir"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the classes and functions that we will be using from the corresponding packages."
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "bkHC",
+ "id": "vblA",
"metadata": {},
"outputs": [],
"source": [
@@ -25,10 +55,26 @@
")"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 2. Define a `base_dir`\n",
+ "\n",
+ "We will define a `base_dir` inside which our data will live. We will provide this to `VitessceConfig` in order to construct a configuration that contains URL paths relative to this directory."
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "PKri",
+ "id": "lEQa",
"metadata": {},
"outputs": [],
"source": [
@@ -36,19 +82,25 @@
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "xXTn",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "PKri",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "import marimo as mo"
+ "## 3. Download the data\n",
+ "\n",
+ "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "SFPL",
+ "id": "Xref",
"metadata": {},
"outputs": [],
"source": [
@@ -59,112 +111,150 @@
" urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)"
]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "ROlb",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', base_dir=BASE_DIR)"
- ]
- },
{
"cell_type": "markdown",
- "id": "Xref",
- "metadata": {},
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## 3. Download the data\n",
+ "## 4. Load the data\n",
"\n",
- "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
+ "Note: this function may print a `FutureWarning`"
]
},
{
- "cell_type": "markdown",
- "id": "ZHCJ",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
"metadata": {},
+ "outputs": [],
"source": [
- "### 5.1. Instantiate a `VitessceConfig` object\n",
- "\n",
- "Use the `VitessceConfig` constructor to create an instance. In this case, we want to construct our configuration using local data that is relative to a particular directory, so we provide the `base_dir` parameter.\n",
- "\n",
- "Note: This `base_dir` parameter is optional. When it is omitted, local data paths are assumed to be relative to the current working directory."
+ "adata = read_h5ad(adata_filepath)"
]
},
{
"cell_type": "markdown",
- "id": "BYtC",
- "metadata": {},
+ "id": "RGSE",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## 4. Load the data\n",
+ "## 4.1. Preprocess the Data For Visualization\n",
"\n",
- "Note: this function may print a `FutureWarning`"
+ "This dataset contains 25,587 genes. We prepare to visualize the top 50 highly variable genes for the heatmap as ranked by dispersion norm, although one may use any boolean array filter for the heatmap."
]
},
{
- "cell_type": "markdown",
- "id": "aLJB",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Kclp",
"metadata": {},
+ "outputs": [],
"source": [
- "## 7. Check the URLs in the configuration\n",
- "\n",
- "We can check that the data URLs in the configuration respected the specified `base_dir`."
+ "top_dispersion = adata.var[\"dispersions_norm\"][\n",
+ " sorted(\n",
+ " range(len(adata.var[\"dispersions_norm\"])),\n",
+ " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
+ " )[-51:][0]\n",
+ "]\n",
+ "adata.var[\"top_highly_variable\"] = (\n",
+ " adata.var[\"dispersions_norm\"] > top_dispersion\n",
+ ")"
]
},
{
"cell_type": "markdown",
- "id": "Hbol",
- "metadata": {},
+ "id": "emfo",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "# Vitessce Widget Tutorial"
+ "## 4.2 Save the Data to Zarr store\n",
+ "\n",
+ "We want to convert the original `h5ad` file to a [Zarr](https://zarr.readthedocs.io/en/stable/) store, which Vitessce is able to load. We can use the `optimize_adata` function to ensure that all arrays and dataframe columns that we intend to use in our visualization are in the optimal format to be loaded by Vitessce. This function will cast arrays to numerical data types that take up less space (as long as the values allow). Note: unused arrays and columns (i.e., not specified in any of the parameters to `optimize_adata`) will not be copied into the new AnnData object."
]
},
{
- "cell_type": "markdown",
- "id": "Pvdt",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Hstk",
"metadata": {},
+ "outputs": [],
"source": [
- "## 6. Create the widget\n",
- "\n",
- "The `vc.widget()` method returns the configured widget instance."
+ "zarr_relative_filepath = 'habib17.processed.zarr'\n",
+ "zarr_filepath = join(BASE_DIR, zarr_relative_filepath)\n",
+ "if not isdir(zarr_filepath):\n",
+ " adata_1 = optimize_adata(adata, obs_cols=['CellType'], obsm_keys=['X_umap'], optimize_X=True, var_cols=['top_highly_variable'])\n",
+ " adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])"
]
},
{
"cell_type": "markdown",
- "id": "MJUe",
- "metadata": {},
+ "id": "nWHF",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "# Configure relative to a base_dir"
+ "## 5. Create the Vitessce widget configuration\n",
+ "\n",
+ "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
]
},
{
"cell_type": "markdown",
- "id": "Vxnm",
- "metadata": {},
+ "id": "iLit",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "### 5.3. Add visualizations to the `VitessceConfig` instance\n",
- "\n",
- "Now that we have added a dataset, we can configure visualizations. The `.add_view` method adds a view (i.e. visualization or controller component) to the configuration.\n",
+ "### 5.1. Instantiate a `VitessceConfig` object\n",
"\n",
- "The `Component` enum class (which we have imported as `cm` here) can be used to fill in the `component_type` parameter.\n",
+ "Use the `VitessceConfig` constructor to create an instance. In this case, we want to construct our configuration using local data that is relative to a particular directory, so we provide the `base_dir` parameter.\n",
"\n",
- "For convenience, the `SCATTERPLOT` component type takes the extra `mapping` keyword argument, which specifies which embedding should be used for mapping cells to (x,y) points on the plot."
+ "Note: This `base_dir` parameter is optional. When it is omitted, local data paths are assumed to be relative to the current working directory."
]
},
{
- "cell_type": "markdown",
- "id": "Kclp",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ZHCJ",
"metadata": {},
+ "outputs": [],
"source": [
- "## 4.1. Preprocess the Data For Visualization\n",
- "\n",
- "This dataset contains 25,587 genes. We prepare to visualize the top 50 highly variable genes for the heatmap as ranked by dispersion norm, although one may use any boolean array filter for the heatmap."
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', base_dir=BASE_DIR)"
]
},
{
"cell_type": "markdown",
- "id": "qnkX",
- "metadata": {},
+ "id": "ROlb",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"### 5.2. Add a dataset to the `VitessceConfig` instance\n",
"\n",
@@ -176,159 +266,145 @@
]
},
{
- "cell_type": "markdown",
- "id": "lEQa",
- "metadata": {},
- "source": [
- "## 2. Define a `base_dir`\n",
- "\n",
- "We will define a `base_dir` inside which our data will live. We will provide this to `VitessceConfig` in order to construct a configuration that contains URL paths relative to this directory."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Hstk",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "qnkX",
"metadata": {},
+ "outputs": [],
"source": [
- "## 4.2 Save the Data to Zarr store\n",
- "\n",
- "We want to convert the original `h5ad` file to a [Zarr](https://zarr.readthedocs.io/en/stable/) store, which Vitessce is able to load. We can use the `optimize_adata` function to ensure that all arrays and dataframe columns that we intend to use in our visualization are in the optimal format to be loaded by Vitessce. This function will cast arrays to numerical data types that take up less space (as long as the values allow). Note: unused arrays and columns (i.e., not specified in any of the parameters to `optimize_adata`) will not be copied into the new AnnData object."
+ "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
+ " adata_path=zarr_relative_filepath, # Relative to BASE_DIR (because we specified base_dir in the VitessceConfig constructor)\n",
+ " obs_embedding_paths=[\"obsm/X_umap\"],\n",
+ " obs_embedding_names=[\"UMAP\"],\n",
+ " obs_set_paths=[\"obs/CellType\"],\n",
+ " obs_set_names=[\"Cell Type\"],\n",
+ " obs_feature_matrix_path=\"X\",\n",
+ " initial_feature_filter_path=\"var/top_highly_variable\"\n",
+ " )\n",
+ ")"
]
},
{
"cell_type": "markdown",
- "id": "ulZA",
- "metadata": {},
+ "id": "TqIu",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "### 5.4. Define the visualization layout\n",
+ "### 5.3. Add visualizations to the `VitessceConfig` instance\n",
"\n",
- "The `vc.layout(view_concat)` method allows us to specify how our views will be arranged in the layout grid in the widget. The `|` and `/` characters are magic syntax for `hconcat(v1, v2)` and `vconcat(v1, v2)`, respectively."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "vblA",
- "metadata": {},
- "source": [
- "## 1. Import dependencies\n",
+ "Now that we have added a dataset, we can configure visualizations. The `.add_view` method adds a view (i.e. visualization or controller component) to the configuration.\n",
"\n",
- "We need to import the classes and functions that we will be using from the corresponding packages."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "iLit",
- "metadata": {},
- "source": [
- "## 5. Create the Vitessce widget configuration\n",
+ "The `Component` enum class (which we have imported as `cm` here) can be used to fill in the `component_type` parameter.\n",
"\n",
- "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
+ "For convenience, the `SCATTERPLOT` component type takes the extra `mapping` keyword argument, which specifies which embedding should be used for mapping cells to (x,y) points on the plot."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "RGSE",
+ "id": "Vxnm",
"metadata": {},
"outputs": [],
"source": [
- "adata = read_h5ad(adata_filepath)"
+ "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
+ "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
+ "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
+ "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)"
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "nHfw",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "DnEU",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "config_dict = vc.to_dict(base_url=BASE_URL_PLACEHOLDER)\n",
- "config_dict"
+ "### 5.4. Define the visualization layout\n",
+ "\n",
+ "The `vc.layout(view_concat)` method allows us to specify how our views will be arranged in the layout grid in the widget. The `|` and `/` characters are magic syntax for `hconcat(v1, v2)` and `vconcat(v1, v2)`, respectively."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "ZBYS",
+ "id": "ulZA",
"metadata": {},
"outputs": [],
"source": [
- "vw = vc.widget()\n",
- "vw"
+ "vc.layout((scatterplot | cell_sets) / (heatmap | genes));"
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "nWHF",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "ecfG",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "zarr_relative_filepath = 'habib17.processed.zarr'\n",
- "zarr_filepath = join(BASE_DIR, zarr_relative_filepath)\n",
- "if not isdir(zarr_filepath):\n",
- " adata_1 = optimize_adata(adata, obs_cols=['CellType'], obsm_keys=['X_umap'], optimize_X=True, var_cols=['top_highly_variable'])\n",
- " adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])"
+ "## 6. Create the widget\n",
+ "\n",
+ "The `vc.widget()` method returns the configured widget instance."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "emfo",
+ "id": "Pvdt",
"metadata": {},
"outputs": [],
"source": [
- "top_dispersion = adata.var[\"dispersions_norm\"][\n",
- " sorted(\n",
- " range(len(adata.var[\"dispersions_norm\"])),\n",
- " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
- " )[-51:][0]\n",
- "]\n",
- "adata.var[\"top_highly_variable\"] = (\n",
- " adata.var[\"dispersions_norm\"] > top_dispersion\n",
- ")"
+ "vw = vc.widget()\n",
+ "vw"
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "TqIu",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "ZBYS",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
- " adata_path=zarr_relative_filepath, # Relative to BASE_DIR (because we specified base_dir in the VitessceConfig constructor)\n",
- " obs_embedding_paths=[\"obsm/X_umap\"],\n",
- " obs_embedding_names=[\"UMAP\"],\n",
- " obs_set_paths=[\"obs/CellType\"],\n",
- " obs_set_names=[\"Cell Type\"],\n",
- " obs_feature_matrix_path=\"X\",\n",
- " initial_feature_filter_path=\"var/top_highly_variable\"\n",
- " )\n",
- ")"
+ "## 7. Check the URLs in the configuration\n",
+ "\n",
+ "We can check that the data URLs in the configuration respected the specified `base_dir`."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "DnEU",
+ "id": "aLJB",
"metadata": {},
"outputs": [],
"source": [
- "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
- "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
- "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
- "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)"
+ "config_dict = vc.to_dict(base_url=BASE_URL_PLACEHOLDER)\n",
+ "config_dict"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "ecfG",
+ "id": "nHfw",
"metadata": {},
"outputs": [],
"source": [
- "vc.layout((scatterplot | cell_sets) / (heatmap | genes));"
+ "import marimo as mo"
]
}
],
diff --git a/docs/notebooks/__ipynb__/widget_brain_with_quality_metric.ipynb b/docs/notebooks/__ipynb__/widget_brain_with_quality_metric.ipynb
index 7fdbf62b..2f4f3cbe 100644
--- a/docs/notebooks/__ipynb__/widget_brain_with_quality_metric.ipynb
+++ b/docs/notebooks/__ipynb__/widget_brain_with_quality_metric.ipynb
@@ -1,9 +1,39 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of single-cell RNA seq data"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the classes and functions that we will be using from the corresponding packages."
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "bkHC",
+ "id": "vblA",
"metadata": {},
"outputs": [],
"source": [
@@ -26,19 +56,25 @@
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "ZHCJ",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "import marimo as mo"
+ "## 2. Download the data\n",
+ "\n",
+ "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "PKri",
+ "id": "lEQa",
"metadata": {},
"outputs": [],
"source": [
@@ -50,56 +86,14 @@
},
{
"cell_type": "markdown",
- "id": "lEQa",
- "metadata": {},
- "source": [
- "## 2. Download the data\n",
- "\n",
- "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "BYtC",
- "metadata": {},
- "source": [
- "## 3.1. Preprocess the Data For Visualization\n",
- "\n",
- "This dataset contains 25,587 genes. We prepare to visualize the top 50 highly variable genes for the heatmap as ranked by dispersion norm, although one may use any boolean array filter for the heatmap."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "nWHF",
- "metadata": {},
- "source": [
- "## 5. Create the widget"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Kclp",
- "metadata": {},
- "source": [
- "## 3.2 Save the Data to Zarr store\n",
- "\n",
- "We want to convert the original `h5ad` file to a [Zarr](https://zarr.readthedocs.io/en/stable/) store, which Vitessce is able to load. We can use the `optimize_adata` function to ensure that all arrays and dataframe columns that we intend to use in our visualization are in the optimal format to be loaded by Vitessce. This function will cast arrays to numerical data types that take up less space (as long as the values allow). Note: unused arrays and columns (i.e., not specified in any of the parameters to `optimize_adata`) will not be copied into the new AnnData object."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "vblA",
- "metadata": {},
- "source": [
- "## 1. Import dependencies\n",
- "\n",
- "We need to import the classes and functions that we will be using from the corresponding packages."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Xref",
- "metadata": {},
+ "id": "PKri",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"## 3. Load the data\n",
"\n",
@@ -107,35 +101,35 @@
]
},
{
- "cell_type": "markdown",
- "id": "MJUe",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
"metadata": {},
+ "outputs": [],
"source": [
- "# Visualization of single-cell RNA seq data"
+ "adata = read_h5ad(adata_filepath)"
]
},
{
"cell_type": "markdown",
- "id": "Hbol",
- "metadata": {},
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
"id": "SFPL",
- "metadata": {},
- "outputs": [],
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "adata = read_h5ad(adata_filepath)"
+ "## 3.1. Preprocess the Data For Visualization\n",
+ "\n",
+ "This dataset contains 25,587 genes. We prepare to visualize the top 50 highly variable genes for the heatmap as ranked by dispersion norm, although one may use any boolean array filter for the heatmap."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "RGSE",
+ "id": "BYtC",
"metadata": {},
"outputs": [],
"source": [
@@ -150,10 +144,26 @@
")"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "RGSE",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 3.2 Save the Data to Zarr store\n",
+ "\n",
+ "We want to convert the original `h5ad` file to a [Zarr](https://zarr.readthedocs.io/en/stable/) store, which Vitessce is able to load. We can use the `optimize_adata` function to ensure that all arrays and dataframe columns that we intend to use in our visualization are in the optimal format to be loaded by Vitessce. This function will cast arrays to numerical data types that take up less space (as long as the values allow). Note: unused arrays and columns (i.e., not specified in any of the parameters to `optimize_adata`) will not be copied into the new AnnData object."
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "emfo",
+ "id": "Kclp",
"metadata": {},
"outputs": [],
"source": [
@@ -165,7 +175,7 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "Hstk",
+ "id": "emfo",
"metadata": {},
"outputs": [],
"source": [
@@ -229,16 +239,40 @@
"vc.layout((scatterplot | (cell_sets / genes)) / (scatterplot_2 | histogram));"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "Hstk",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 5. Create the widget"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "iLit",
+ "id": "nWHF",
"metadata": {},
"outputs": [],
"source": [
"vw = vc.widget()\n",
"vw"
]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "iLit",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
}
],
"metadata": {},
diff --git a/docs/notebooks/__ipynb__/widget_from_dict.ipynb b/docs/notebooks/__ipynb__/widget_from_dict.ipynb
index 93ace24b..8ebcc7e5 100644
--- a/docs/notebooks/__ipynb__/widget_from_dict.ipynb
+++ b/docs/notebooks/__ipynb__/widget_from_dict.ipynb
@@ -1,95 +1,111 @@
{
"cells": [
{
- "cell_type": "code",
- "execution_count": null,
- "id": "bkHC",
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import VitessceConfig"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "PKri",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "from example_configs import dries as dries_config"
+ "# Using an existing view config dict"
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "BYtC",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "import marimo as mo"
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the `VitessceConfig` class."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "SFPL",
+ "id": "vblA",
"metadata": {},
"outputs": [],
"source": [
- "vc = VitessceConfig.from_dict(dries_config)\n",
- "vw = vc.widget()\n",
- "vw"
+ "from vitessce import VitessceConfig"
]
},
{
"cell_type": "markdown",
- "id": "Xref",
- "metadata": {},
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## 3. Create the Vitessce widget\n",
+ "## 2. Import config of interest as a dict\n",
"\n",
- "Create the widget by creating a new config instance using the `VitessceConfig.from_dict` static method, then calling the config's `.widget()` method.\n",
+ "The Vitessce config at its lowest level is a JSON object or a Python `dict` that specifies a layout for the Vitessce components will be rendered in the widget. These components may be scatterplots, spatial plots, heatmaps, or control components. The config also describes the datasets and files that will be visualized.\n",
"\n",
- "Render the widget by placing the widget variable on its own line at the end of the notebook cell."
+ "The `vitessce` package provides helper functions and classes to simplify the process of defining Vitessce configs. Those functions are demonstrated in the other notebooks. The helper functions are intended to make visualization of local datasets easy. However, in this case, we are importing a config that has been pre-defined in the file `example_configs.py`, in which the dataset being visualized is stored remotely in AWS S3 (rather than locally)."
]
},
{
- "cell_type": "markdown",
- "id": "Hbol",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
"metadata": {},
+ "outputs": [],
"source": [
- "# Vitessce Widget Tutorial"
+ "from example_configs import dries as dries_config"
]
},
{
"cell_type": "markdown",
- "id": "lEQa",
- "metadata": {},
+ "id": "PKri",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## 2. Import config of interest as a dict\n",
+ "## 3. Create the Vitessce widget\n",
"\n",
- "The Vitessce config at its lowest level is a JSON object or a Python `dict` that specifies a layout for the Vitessce components will be rendered in the widget. These components may be scatterplots, spatial plots, heatmaps, or control components. The config also describes the datasets and files that will be visualized.\n",
+ "Create the widget by creating a new config instance using the `VitessceConfig.from_dict` static method, then calling the config's `.widget()` method.\n",
"\n",
- "The `vitessce` package provides helper functions and classes to simplify the process of defining Vitessce configs. Those functions are demonstrated in the other notebooks. The helper functions are intended to make visualization of local datasets easy. However, in this case, we are importing a config that has been pre-defined in the file `example_configs.py`, in which the dataset being visualized is stored remotely in AWS S3 (rather than locally)."
+ "Render the widget by placing the widget variable on its own line at the end of the notebook cell."
]
},
{
- "cell_type": "markdown",
- "id": "MJUe",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
"metadata": {},
+ "outputs": [],
"source": [
- "# Using an existing view config dict"
+ "vc = VitessceConfig.from_dict(dries_config)\n",
+ "vw = vc.widget()\n",
+ "vw"
]
},
{
- "cell_type": "markdown",
- "id": "vblA",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
"metadata": {},
+ "outputs": [],
"source": [
- "## 1. Import dependencies\n",
- "\n",
- "We need to import the `VitessceConfig` class."
+ "import marimo as mo"
]
}
],
diff --git a/docs/notebooks/__ipynb__/widget_genomic_profiles.ipynb b/docs/notebooks/__ipynb__/widget_genomic_profiles.ipynb
index 7965bdbe..8d4d91fc 100644
--- a/docs/notebooks/__ipynb__/widget_genomic_profiles.ipynb
+++ b/docs/notebooks/__ipynb__/widget_genomic_profiles.ipynb
@@ -1,9 +1,39 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of genomic profiles"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the classes and functions that we will be using from the corresponding packages."
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "bkHC",
+ "id": "vblA",
"metadata": {},
"outputs": [],
"source": [
@@ -25,30 +55,25 @@
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "ROlb",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "RGSE",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "multivec_zarr_path = join(\"data\", \"HBM485.TBWH.322.multivec.zarr\")\n",
- "adata_zarr_path = join(\"data\", \"HBM485.TBWH.322.adata.zarr\")"
+ "## 2. Load the data\n",
+ "\n",
+ "In this step, we load the raw data that has been downloaded from the HuBMAP portal https://portal.hubmapconsortium.org/browse/dataset/210d118a14c8624b6bb9610a9062656e"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "PKri",
+ "id": "lEQa",
"metadata": {},
"outputs": [],
"source": [
@@ -60,73 +85,103 @@
},
{
"cell_type": "markdown",
- "id": "iLit",
- "metadata": {},
+ "id": "PKri",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## 5. Create the widget"
+ "## 3. Convert the data to Vitessce-compatible formats\n",
+ "\n",
+ "Vitessce can load AnnData objects saved to Zarr formats efficiently."
]
},
{
- "cell_type": "markdown",
- "id": "lEQa",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
"metadata": {},
+ "outputs": [],
"source": [
- "## 2. Load the data\n",
- "\n",
- "In this step, we load the raw data that has been downloaded from the HuBMAP portal https://portal.hubmapconsortium.org/browse/dataset/210d118a14c8624b6bb9610a9062656e"
+ "# The genome assembly is GRCh38 but the chromosome names in the bin names do not start with the \"chr\" prefix.\n",
+ "# This is incompatible with the chromosome names from `negspy`, so we need to append the prefix.\n",
+ "bins_df[\"interval\"] = bins_df[\"interval\"].apply(lambda x: \"chr\" + x)"
]
},
{
- "cell_type": "markdown",
- "id": "Hbol",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
"metadata": {},
+ "outputs": [],
"source": [
- "# Vitessce Widget Tutorial"
+ "obs = clusters_df[[\"cluster\"]]\n",
+ "obs[\"cluster\"] = obs[\"cluster\"].astype(str)\n",
+ "obsm = { \"X_umap\": clusters_df[[\"umap.1\", \"umap.2\"]].values }\n",
+ "adata = AnnData(X=mtx, obs=obs, var=bins_df, obsm=obsm)\n",
+ "adata"
]
},
{
- "cell_type": "markdown",
- "id": "Hstk",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
"metadata": {},
+ "outputs": [],
"source": [
- "## 4. Make a Vitessce configuration\n",
- "\n",
- "We need to tell Vitessce about the data that we want to load and the visualization components that we want to include in the widget.\n",
- "For this dataset, we want to add the `GENOMIC_PROFILES` component, which renders genome browser tracks with [HiGlass](http://higlass.io)."
+ "multivec_zarr_path = join(\"data\", \"HBM485.TBWH.322.multivec.zarr\")\n",
+ "adata_zarr_path = join(\"data\", \"HBM485.TBWH.322.adata.zarr\")"
]
},
{
- "cell_type": "markdown",
- "id": "Xref",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
"metadata": {},
+ "outputs": [],
"source": [
- "## 3. Convert the data to Vitessce-compatible formats\n",
- "\n",
- "Vitessce can load AnnData objects saved to Zarr formats efficiently."
+ "# Sort cluster IDs\n",
+ "cluster_ids = obs[\"cluster\"].unique().tolist()\n",
+ "cluster_ids.sort(key=int)\n",
+ "# Save genomic profiles to multivec-zarr format.\n",
+ "adata_to_multivec_zarr(adata, multivec_zarr_path, obs_set_col=\"cluster\", obs_set_name=\"Cluster\", obs_set_vals=cluster_ids)"
]
},
{
- "cell_type": "markdown",
- "id": "MJUe",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Kclp",
"metadata": {},
+ "outputs": [],
"source": [
- "# Visualization of genomic profiles"
+ "# Save anndata object to AnnData-Zarr format.\n",
+ "adata.write_zarr(adata_zarr_path)"
]
},
{
"cell_type": "markdown",
- "id": "vblA",
- "metadata": {},
+ "id": "emfo",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## 1. Import dependencies\n",
+ "## 4. Make a Vitessce configuration\n",
"\n",
- "We need to import the classes and functions that we will be using from the corresponding packages."
+ "We need to tell Vitessce about the data that we want to load and the visualization components that we want to include in the widget.\n",
+ "For this dataset, we want to add the `GENOMIC_PROFILES` component, which renders genome browser tracks with [HiGlass](http://higlass.io)."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "nWHF",
+ "id": "Hstk",
"metadata": {},
"outputs": [],
"source": [
@@ -149,35 +204,23 @@
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "SFPL",
- "metadata": {},
- "outputs": [],
- "source": [
- "# The genome assembly is GRCh38 but the chromosome names in the bin names do not start with the \"chr\" prefix.\n",
- "# This is incompatible with the chromosome names from `negspy`, so we need to append the prefix.\n",
- "bins_df[\"interval\"] = bins_df[\"interval\"].apply(lambda x: \"chr\" + x)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "BYtC",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "nWHF",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "obs = clusters_df[[\"cluster\"]]\n",
- "obs[\"cluster\"] = obs[\"cluster\"].astype(str)\n",
- "obsm = { \"X_umap\": clusters_df[[\"umap.1\", \"umap.2\"]].values }\n",
- "adata = AnnData(X=mtx, obs=obs, var=bins_df, obsm=obsm)\n",
- "adata"
+ "## 5. Create the widget"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "ZHCJ",
+ "id": "iLit",
"metadata": {},
"outputs": [],
"source": [
@@ -188,26 +231,11 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "Kclp",
- "metadata": {},
- "outputs": [],
- "source": [
- "# Sort cluster IDs\n",
- "cluster_ids = obs[\"cluster\"].unique().tolist()\n",
- "cluster_ids.sort(key=int)\n",
- "# Save genomic profiles to multivec-zarr format.\n",
- "adata_to_multivec_zarr(adata, multivec_zarr_path, obs_set_col=\"cluster\", obs_set_name=\"Cluster\", obs_set_vals=cluster_ids)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "emfo",
+ "id": "ZHCJ",
"metadata": {},
"outputs": [],
"source": [
- "# Save anndata object to AnnData-Zarr format.\n",
- "adata.write_zarr(adata_zarr_path)"
+ "import marimo as mo"
]
}
],
diff --git a/docs/notebooks/__ipynb__/widget_imaging.ipynb b/docs/notebooks/__ipynb__/widget_imaging.ipynb
index 3102a8f4..fbbe59d9 100644
--- a/docs/notebooks/__ipynb__/widget_imaging.ipynb
+++ b/docs/notebooks/__ipynb__/widget_imaging.ipynb
@@ -1,9 +1,24 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of Multi-Modal Imaging Data\n",
+ "We visualize IMS, PAS, and AF imaging data overlaid from the Spraggins Lab of the Biomolecular Multimodal Imaging Center (BIOMC) at Vanderbilt University, uploaded to the HuBMAP data portal."
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "vblA",
+ "id": "MJUe",
"metadata": {},
"outputs": [],
"source": [
@@ -18,19 +33,24 @@
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "SFPL",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "import marimo as mo"
+ "## 1. Configure Vitessce\n",
+ "Set up the images from the three different assays, with the `use_physical_size_scaling` set to `True` so that the IMS image scales to the other images based on their physical sizes."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "lEQa",
+ "id": "bkHC",
"metadata": {},
"outputs": [],
"source": [
@@ -54,36 +74,27 @@
},
{
"cell_type": "markdown",
- "id": "MJUe",
- "metadata": {},
- "source": [
- "# Visualization of Multi-Modal Imaging Data\n",
- "We visualize IMS, PAS, and AF imaging data overlaid from the Spraggins Lab of the Biomolecular Multimodal Imaging Center (BIOMC) at Vanderbilt University, uploaded to the HuBMAP data portal."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {},
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "bkHC",
- "metadata": {},
+ "id": "lEQa",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## 1. Configure Vitessce\n",
- "Set up the images from the three different assays, with the `use_physical_size_scaling` set to `True` so that the IMS image scales to the other images based on their physical sizes."
+ "## 2. Create the Vitessce widget"
]
},
{
- "cell_type": "markdown",
+ "cell_type": "code",
+ "execution_count": null,
"id": "PKri",
"metadata": {},
+ "outputs": [],
"source": [
- "## 2. Create the Vitessce widget"
+ "vw = vc.widget()\n",
+ "vw"
]
},
{
@@ -93,8 +104,7 @@
"metadata": {},
"outputs": [],
"source": [
- "vw = vc.widget()\n",
- "vw"
+ "import marimo as mo"
]
}
],
diff --git a/docs/notebooks/__ipynb__/widget_imaging_beta.ipynb b/docs/notebooks/__ipynb__/widget_imaging_beta.ipynb
index f5081e74..9b116c80 100644
--- a/docs/notebooks/__ipynb__/widget_imaging_beta.ipynb
+++ b/docs/notebooks/__ipynb__/widget_imaging_beta.ipynb
@@ -1,9 +1,24 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of Multi-Modal Imaging Data\n",
+ "We visualize IMS, PAS, and AF imaging data overlaid from the Spraggins Lab of the Biomolecular Multimodal Imaging Center (BIOMC) at Vanderbilt University, uploaded to the HuBMAP data portal."
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "vblA",
+ "id": "MJUe",
"metadata": {},
"outputs": [],
"source": [
@@ -19,19 +34,24 @@
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "SFPL",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "import marimo as mo"
+ "## 1. Configure Vitessce\n",
+ "Set up the images from the three different assays, with the `use_physical_size_scaling` set to `True` so that the IMS image scales to the other images based on their physical sizes."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "lEQa",
+ "id": "bkHC",
"metadata": {},
"outputs": [],
"source": [
@@ -92,36 +112,27 @@
},
{
"cell_type": "markdown",
- "id": "bkHC",
- "metadata": {},
- "source": [
- "## 1. Configure Vitessce\n",
- "Set up the images from the three different assays, with the `use_physical_size_scaling` set to `True` so that the IMS image scales to the other images based on their physical sizes."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {},
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "PKri",
- "metadata": {},
+ "id": "lEQa",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"## 2. Create the Vitessce widget"
]
},
{
- "cell_type": "markdown",
- "id": "MJUe",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
"metadata": {},
+ "outputs": [],
"source": [
- "# Visualization of Multi-Modal Imaging Data\n",
- "We visualize IMS, PAS, and AF imaging data overlaid from the Spraggins Lab of the Biomolecular Multimodal Imaging Center (BIOMC) at Vanderbilt University, uploaded to the HuBMAP data portal."
+ "vw = vc.widget(custom_js_url='http://localhost:8000/packages/main/prod/dist/index.min.js')\n",
+ "vw"
]
},
{
@@ -131,8 +142,7 @@
"metadata": {},
"outputs": [],
"source": [
- "vw = vc.widget(custom_js_url='http://localhost:8000/packages/main/prod/dist/index.min.js')\n",
- "vw"
+ "import marimo as mo"
]
}
],
diff --git a/docs/notebooks/__ipynb__/widget_imaging_segmentation.ipynb b/docs/notebooks/__ipynb__/widget_imaging_segmentation.ipynb
index 212893b4..69eed98b 100644
--- a/docs/notebooks/__ipynb__/widget_imaging_segmentation.ipynb
+++ b/docs/notebooks/__ipynb__/widget_imaging_segmentation.ipynb
@@ -1,9 +1,24 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of Segmentation Bitmask\n",
+ "We visualize raw imaging data + a segmentation bitmask the [MCMicro piplene](https://mcmicro.org/) - see https://www.biorxiv.org/content/10.1101/2021.03.15.435473v1.full and specifically [Figure S1](https://www.google.com/url?q=https://www.biorxiv.org/content/10.1101/2021.03.15.435473v1.full%23F3&sa=D&source=editors&ust=1623173627976000&usg=AOvVaw3JkzCxYyE86q8jxfNCgShh)"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "vblA",
+ "id": "MJUe",
"metadata": {},
"outputs": [],
"source": [
@@ -18,19 +33,24 @@
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "SFPL",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "import marimo as mo"
+ "## 1. Configure Vitessce\n",
+ "Set up the two images, already pyramidal from the [bioformats2raw + raw2ometiff pipeline](https://github.com/hms-dbmi/viv/tree/master/tutorial), labeling the segmentation \"on top\" as the bitmask and the other as simply the image data."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "lEQa",
+ "id": "bkHC",
"metadata": {},
"outputs": [],
"source": [
@@ -51,36 +71,27 @@
},
{
"cell_type": "markdown",
- "id": "PKri",
- "metadata": {},
+ "id": "lEQa",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"## 2. Create the Vitessce widget"
]
},
{
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {},
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "bkHC",
- "metadata": {},
- "source": [
- "## 1. Configure Vitessce\n",
- "Set up the two images, already pyramidal from the [bioformats2raw + raw2ometiff pipeline](https://github.com/hms-dbmi/viv/tree/master/tutorial), labeling the segmentation \"on top\" as the bitmask and the other as simply the image data."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
"metadata": {},
+ "outputs": [],
"source": [
- "# Visualization of Segmentation Bitmask\n",
- "We visualize raw imaging data + a segmentation bitmask the [MCMicro piplene](https://mcmicro.org/) - see https://www.biorxiv.org/content/10.1101/2021.03.15.435473v1.full and specifically [Figure S1](https://www.google.com/url?q=https://www.biorxiv.org/content/10.1101/2021.03.15.435473v1.full%23F3&sa=D&source=editors&ust=1623173627976000&usg=AOvVaw3JkzCxYyE86q8jxfNCgShh)"
+ "vw = vc.widget()\n",
+ "vw"
]
},
{
@@ -90,8 +101,7 @@
"metadata": {},
"outputs": [],
"source": [
- "vw = vc.widget()\n",
- "vw"
+ "import marimo as mo"
]
}
],
diff --git a/docs/notebooks/__ipynb__/widget_loom.ipynb b/docs/notebooks/__ipynb__/widget_loom.ipynb
index 024d4971..b6a86875 100644
--- a/docs/notebooks/__ipynb__/widget_loom.ipynb
+++ b/docs/notebooks/__ipynb__/widget_loom.ipynb
@@ -1,9 +1,37 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of a Loom file"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Import dependencies"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "bkHC",
+ "id": "vblA",
"metadata": {},
"outputs": [],
"source": [
@@ -27,19 +55,25 @@
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "qnkX",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "import marimo as mo"
+ "## 2. Download data\n",
+ "\n",
+ "Download `osmFISH_SScortex_mouse_all_cells.loom` from http://loom.linnarssonlab.org/."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "PKri",
+ "id": "lEQa",
"metadata": {},
"outputs": [],
"source": [
@@ -51,102 +85,74 @@
},
{
"cell_type": "markdown",
- "id": "BYtC",
- "metadata": {},
- "source": [
- "Generate pseudo-segmentations as diamond-shaped polygons centered on the spatial coordinate of each cell, and store in `adata.obsm[\"segmentations\"]`"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "vblA",
- "metadata": {},
- "source": [
- "## 1. Import dependencies"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Xref",
- "metadata": {},
+ "id": "PKri",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"## 3. Open Loom file with AnnData's read_loom"
]
},
{
- "cell_type": "markdown",
- "id": "Kclp",
- "metadata": {},
- "source": [
- "Save the AnnData object to a Zarr store:"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {},
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "lEQa",
- "metadata": {},
- "source": [
- "## 2. Download data\n",
- "\n",
- "Download `osmFISH_SScortex_mouse_all_cells.loom` from http://loom.linnarssonlab.org/."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
"metadata": {},
+ "outputs": [],
"source": [
- "# Visualization of a Loom file"
+ "adata = read_loom(loom_filepath, obsm_names={\"tSNE\": [\"_tSNE_1\", \"_tSNE_2\"], \"spatial\": [\"X\", \"Y\"]})"
]
},
{
"cell_type": "markdown",
- "id": "Hstk",
- "metadata": {},
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## 4. Configure Vitessce\n",
- "\n",
- "Create a Vitessce view config."
+ "Generate pseudo-segmentations as diamond-shaped polygons centered on the spatial coordinate of each cell, and store in `adata.obsm[\"segmentations\"]`"
]
},
{
- "cell_type": "markdown",
- "id": "ZHCJ",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
"metadata": {},
+ "outputs": [],
"source": [
- "A widget can be created with the `.widget()` method on the config instance."
+ "num_cells = adata.obs.shape[0]\n",
+ "adata.obsm[\"segmentations\"] = np.zeros((num_cells, 4, 2))\n",
+ "radius = 100\n",
+ "for i in range(num_cells):\n",
+ " adata.obsm[\"segmentations\"][i, :, :] = to_diamond(adata.obsm['spatial'][i, 0], adata.obsm['spatial'][i, 1], radius)"
]
},
{
"cell_type": "markdown",
- "id": "iLit",
- "metadata": {},
- "source": [
- "## 5. Render the widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "SFPL",
- "metadata": {},
- "outputs": [],
+ "id": "RGSE",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "adata = read_loom(loom_filepath, obsm_names={\"tSNE\": [\"_tSNE_1\", \"_tSNE_2\"], \"spatial\": [\"X\", \"Y\"]})"
+ "Save the AnnData object to a Zarr store:"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "emfo",
+ "id": "Kclp",
"metadata": {},
"outputs": [],
"source": [
@@ -157,23 +163,25 @@
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "RGSE",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "emfo",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "num_cells = adata.obs.shape[0]\n",
- "adata.obsm[\"segmentations\"] = np.zeros((num_cells, 4, 2))\n",
- "radius = 100\n",
- "for i in range(num_cells):\n",
- " adata.obsm[\"segmentations\"][i, :, :] = to_diamond(adata.obsm['spatial'][i, 0], adata.obsm['spatial'][i, 1], radius)"
+ "## 4. Configure Vitessce\n",
+ "\n",
+ "Create a Vitessce view config."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "nWHF",
+ "id": "Hstk",
"metadata": {},
"outputs": [],
"source": [
@@ -196,16 +204,54 @@
"vc.layout(spatial | (tsne / cell_sets));"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "nWHF",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 5. Render the widget"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "iLit",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "A widget can be created with the `.widget()` method on the config instance."
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "ROlb",
+ "id": "ZHCJ",
"metadata": {},
"outputs": [],
"source": [
"vw = vc.widget()\n",
"vw"
]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ROlb",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
}
],
"metadata": {},
diff --git a/docs/notebooks/__ipynb__/widget_modify_config.ipynb b/docs/notebooks/__ipynb__/widget_modify_config.ipynb
index fd8608e2..a2a5363a 100644
--- a/docs/notebooks/__ipynb__/widget_modify_config.ipynb
+++ b/docs/notebooks/__ipynb__/widget_modify_config.ipynb
@@ -1,9 +1,23 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Programmatic modification of widget configuration"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "vblA",
+ "id": "MJUe",
"metadata": {},
"outputs": [],
"source": [
@@ -24,17 +38,7 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "SFPL",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "bkHC",
+ "id": "vblA",
"metadata": {},
"outputs": [],
"source": [
@@ -67,19 +71,14 @@
]
},
{
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {},
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
"metadata": {},
+ "outputs": [],
"source": [
- "# Programmatic modification of widget configuration"
+ "vw = vc.widget(remount_on_uid_change=False)\n",
+ "vw"
]
},
{
@@ -89,14 +88,15 @@
"metadata": {},
"outputs": [],
"source": [
- "vw = vc.widget(remount_on_uid_change=False)\n",
- "vw"
+ "# Inspect the current configuration value.\n",
+ "# This is a dict in the JSON-based format https://vitessce.io/docs/view-config-json/\n",
+ "vw.config"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "Xref",
+ "id": "PKri",
"metadata": {},
"outputs": [],
"source": [
@@ -131,13 +131,11 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "PKri",
+ "id": "Xref",
"metadata": {},
"outputs": [],
"source": [
- "# Inspect the current configuration value.\n",
- "# This is a dict in the JSON-based format https://vitessce.io/docs/view-config-json/\n",
- "vw.config"
+ "import marimo as mo"
]
}
],
diff --git a/docs/notebooks/__ipynb__/widget_neuroglancer.ipynb b/docs/notebooks/__ipynb__/widget_neuroglancer.ipynb
index 122c936a..a7577622 100644
--- a/docs/notebooks/__ipynb__/widget_neuroglancer.ipynb
+++ b/docs/notebooks/__ipynb__/widget_neuroglancer.ipynb
@@ -1,9 +1,23 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Example usage of Neuroglancer view"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "vblA",
+ "id": "MJUe",
"metadata": {},
"outputs": [],
"source": [
@@ -22,19 +36,23 @@
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "SFPL",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "import marimo as mo"
+ "## 1. Configure Vitessce"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "lEQa",
+ "id": "bkHC",
"metadata": {},
"outputs": [],
"source": [
@@ -167,34 +185,27 @@
},
{
"cell_type": "markdown",
- "id": "PKri",
- "metadata": {},
+ "id": "lEQa",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"## 2. Create the Vitessce widget"
]
},
{
- "cell_type": "markdown",
- "id": "bkHC",
- "metadata": {},
- "source": [
- "## 1. Configure Vitessce"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {},
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
"metadata": {},
+ "outputs": [],
"source": [
- "# Example usage of Neuroglancer view"
+ "vw = vc.widget()\n",
+ "vw"
]
},
{
@@ -204,8 +215,7 @@
"metadata": {},
"outputs": [],
"source": [
- "vw = vc.widget()\n",
- "vw"
+ "import marimo as mo"
]
}
],
diff --git a/docs/notebooks/__ipynb__/widget_pbmc.ipynb b/docs/notebooks/__ipynb__/widget_pbmc.ipynb
index 53ab9e82..edef6265 100644
--- a/docs/notebooks/__ipynb__/widget_pbmc.ipynb
+++ b/docs/notebooks/__ipynb__/widget_pbmc.ipynb
@@ -1,9 +1,39 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of 3k PBMC reference"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the classes and functions that we will be using from the corresponding packages."
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "bkHC",
+ "id": "vblA",
"metadata": {},
"outputs": [],
"source": [
@@ -26,19 +56,25 @@
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "iLit",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "import marimo as mo"
+ "## 2. Download the dataset\n",
+ "\n",
+ "Download `pbmc3k_final.h5ad` from https://seurat.nygenome.org/pbmc3k_final.h5ad"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "PKri",
+ "id": "lEQa",
"metadata": {},
"outputs": [],
"source": [
@@ -50,44 +86,67 @@
},
{
"cell_type": "markdown",
- "id": "MJUe",
- "metadata": {},
+ "id": "PKri",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "# Visualization of 3k PBMC reference"
+ "## 3. Load the dataset\n",
+ "\n",
+ "Load the dataset using AnnData's `read_h5ad` function."
]
},
{
- "cell_type": "markdown",
- "id": "vblA",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
"metadata": {},
+ "outputs": [],
"source": [
- "## 1. Import dependencies\n",
- "\n",
- "We need to import the classes and functions that we will be using from the corresponding packages."
+ "adata = read_h5ad(adata_filepath)"
]
},
{
"cell_type": "markdown",
- "id": "lEQa",
- "metadata": {},
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## 2. Download the dataset\n",
- "\n",
- "Download `pbmc3k_final.h5ad` from https://seurat.nygenome.org/pbmc3k_final.h5ad"
+ "## 3.1 Save the AnnData object to Zarr"
]
},
{
- "cell_type": "markdown",
+ "cell_type": "code",
+ "execution_count": null,
"id": "BYtC",
"metadata": {},
+ "outputs": [],
"source": [
- "## 3.1 Save the AnnData object to Zarr"
+ "zarr_filepath = join('data', 'pbmc3k_final.zarr')\n",
+ "if not isdir(zarr_filepath):\n",
+ " adata_1 = optimize_adata(adata, obs_cols=['leiden'], obsm_keys=['X_umap', 'X_pca'], optimize_X=True)\n",
+ " adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])"
]
},
{
"cell_type": "markdown",
- "id": "Kclp",
- "metadata": {},
+ "id": "RGSE",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"## 4. Create a Vitessce view config\n",
"\n",
@@ -96,59 +155,10 @@
"For more details about how to configure data depending on where the files are located relative to the notebook execution, see https://python-docs.vitessce.io/data_options.html."
]
},
- {
- "cell_type": "markdown",
- "id": "Hstk",
- "metadata": {},
- "source": [
- "## 5. Create the Vitessce widget"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Xref",
- "metadata": {},
- "source": [
- "## 3. Load the dataset\n",
- "\n",
- "Load the dataset using AnnData's `read_h5ad` function."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {},
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
{
"cell_type": "code",
"execution_count": null,
- "id": "SFPL",
- "metadata": {},
- "outputs": [],
- "source": [
- "adata = read_h5ad(adata_filepath)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "RGSE",
- "metadata": {},
- "outputs": [],
- "source": [
- "zarr_filepath = join('data', 'pbmc3k_final.zarr')\n",
- "if not isdir(zarr_filepath):\n",
- " adata_1 = optimize_adata(adata, obs_cols=['leiden'], obsm_keys=['X_umap', 'X_pca'], optimize_X=True)\n",
- " adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "emfo",
+ "id": "Kclp",
"metadata": {},
"outputs": [],
"source": [
@@ -171,16 +181,40 @@
"vc.layout((umap / pca) | ((cell_sets | genes) / heatmap));"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "emfo",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 5. Create the Vitessce widget"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "nWHF",
+ "id": "Hstk",
"metadata": {},
"outputs": [],
"source": [
"vw = vc.widget()\n",
"vw"
]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "nWHF",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
}
],
"metadata": {},
diff --git a/docs/notebooks/__ipynb__/widget_pbmc_remote.ipynb b/docs/notebooks/__ipynb__/widget_pbmc_remote.ipynb
index 0cf0f95b..c21d07ec 100644
--- a/docs/notebooks/__ipynb__/widget_pbmc_remote.ipynb
+++ b/docs/notebooks/__ipynb__/widget_pbmc_remote.ipynb
@@ -1,9 +1,39 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of 3k PBMC reference from Remote Zarr Store"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the classes and functions that we will be using from the corresponding packages."
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "bkHC",
+ "id": "vblA",
"metadata": {},
"outputs": [],
"source": [
@@ -21,10 +51,26 @@
")"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 2. Set the URL for the Remote Dataset\n",
+ "\n",
+ "For this example, we already have uploaded the `pbmc3k` dataset as a zarr store from the [scanpy docs](https://scanpy.readthedocs.io/en/stable/api/scanpy.datasets.pbmc3k.html) to the cloud."
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "PKri",
+ "id": "lEQa",
"metadata": {},
"outputs": [],
"source": [
@@ -32,19 +78,25 @@
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "emfo",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "PKri",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "import marimo as mo"
+ "## 3. Create a Vitessce view config\n",
+ "\n",
+ "Define the data and views you would like to include in the widget."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "SFPL",
+ "id": "Xref",
"metadata": {},
"outputs": [],
"source": [
@@ -62,64 +114,41 @@
},
{
"cell_type": "markdown",
- "id": "lEQa",
- "metadata": {},
- "source": [
- "## 2. Set the URL for the Remote Dataset\n",
- "\n",
- "For this example, we already have uploaded the `pbmc3k` dataset as a zarr store from the [scanpy docs](https://scanpy.readthedocs.io/en/stable/api/scanpy.datasets.pbmc3k.html) to the cloud."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Xref",
- "metadata": {},
- "source": [
- "## 3. Create a Vitessce view config\n",
- "\n",
- "Define the data and views you would like to include in the widget."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {},
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {},
- "source": [
- "# Visualization of 3k PBMC reference from Remote Zarr Store"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "BYtC",
- "metadata": {},
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"## 4. Create the Vitessce widget"
]
},
{
"cell_type": "markdown",
- "id": "RGSE",
- "metadata": {},
+ "id": "BYtC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"A widget can be created with the `.widget()` method on the config instance. Here, the `proxy=True` parameter allows this widget to be used in a cloud notebook environment, such as Binder."
]
},
{
- "cell_type": "markdown",
- "id": "vblA",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
"metadata": {},
+ "outputs": [],
"source": [
- "## 1. Import dependencies\n",
- "\n",
- "We need to import the classes and functions that we will be using from the corresponding packages."
+ "vw = vc.widget()\n",
+ "vw"
]
},
{
@@ -129,8 +158,7 @@
"metadata": {},
"outputs": [],
"source": [
- "vw = vc.widget()\n",
- "vw"
+ "import marimo as mo"
]
}
],
diff --git a/docs/notebooks/__ipynb__/widget_plugin_custom.ipynb b/docs/notebooks/__ipynb__/widget_plugin_custom.ipynb
index 84733619..e2b99f84 100644
--- a/docs/notebooks/__ipynb__/widget_plugin_custom.ipynb
+++ b/docs/notebooks/__ipynb__/widget_plugin_custom.ipynb
@@ -1,9 +1,23 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Vitessce custom plugin definition"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "vblA",
+ "id": "MJUe",
"metadata": {},
"outputs": [],
"source": [
@@ -21,17 +35,7 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "SFPL",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "bkHC",
+ "id": "vblA",
"metadata": {},
"outputs": [],
"source": [
@@ -117,7 +121,7 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "lEQa",
+ "id": "bkHC",
"metadata": {},
"outputs": [],
"source": [
@@ -141,26 +145,27 @@
},
{
"cell_type": "markdown",
- "id": "PKri",
- "metadata": {},
+ "id": "lEQa",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"## 2. Create the Vitessce widget"
]
},
{
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {},
- "source": [
- "# Vitessce custom plugin definition"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Hbol",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
"metadata": {},
+ "outputs": [],
"source": [
- "# Vitessce Widget Tutorial"
+ "vw = vc.widget(plugins=[ChatPlugin()])\n",
+ "vw"
]
},
{
@@ -170,8 +175,7 @@
"metadata": {},
"outputs": [],
"source": [
- "vw = vc.widget(plugins=[ChatPlugin()])\n",
- "vw"
+ "import marimo as mo"
]
}
],
diff --git a/docs/notebooks/__ipynb__/widget_plugin_demo.ipynb b/docs/notebooks/__ipynb__/widget_plugin_demo.ipynb
index cb6b0492..4ab1b120 100644
--- a/docs/notebooks/__ipynb__/widget_plugin_demo.ipynb
+++ b/docs/notebooks/__ipynb__/widget_plugin_demo.ipynb
@@ -1,9 +1,37 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Vitessce plugin usage demo"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "We visualize IMS, PAS, and AF imaging data overlaid from the Spraggins Lab of the Biomolecular Multimodal Imaging Center (BIOMC) at Vanderbilt University, uploaded to the HuBMAP data portal."
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "bkHC",
+ "id": "vblA",
"metadata": {},
"outputs": [],
"source": [
@@ -20,7 +48,7 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "lEQa",
+ "id": "bkHC",
"metadata": {},
"outputs": [],
"source": [
@@ -28,19 +56,24 @@
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "RGSE",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "import marimo as mo"
+ "## 1. Configure Vitessce\n",
+ "Set up the images from the three different assays, with the `use_physical_size_scaling` set to `True` so that the IMS image scales to the other images based on their physical sizes."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "Xref",
+ "id": "PKri",
"metadata": {},
"outputs": [],
"source": [
@@ -64,43 +97,27 @@
},
{
"cell_type": "markdown",
- "id": "PKri",
- "metadata": {},
- "source": [
- "## 1. Configure Vitessce\n",
- "Set up the images from the three different assays, with the `use_physical_size_scaling` set to `True` so that the IMS image scales to the other images based on their physical sizes."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "SFPL",
- "metadata": {},
+ "id": "Xref",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"## 2. Create the Vitessce widget"
]
},
{
- "cell_type": "markdown",
- "id": "vblA",
- "metadata": {},
- "source": [
- "We visualize IMS, PAS, and AF imaging data overlaid from the Spraggins Lab of the Biomolecular Multimodal Imaging Center (BIOMC) at Vanderbilt University, uploaded to the HuBMAP data portal."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {},
- "source": [
- "# Vitessce plugin usage demo"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Hbol",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
"metadata": {},
+ "outputs": [],
"source": [
- "# Vitessce Widget Tutorial"
+ "vw = vc.widget(plugins=[DemoPlugin()])\n",
+ "vw"
]
},
{
@@ -110,8 +127,7 @@
"metadata": {},
"outputs": [],
"source": [
- "vw = vc.widget(plugins=[DemoPlugin()])\n",
- "vw"
+ "import marimo as mo"
]
}
],
diff --git a/docs/notebooks/__ipynb__/widget_segmentations_beta.ipynb b/docs/notebooks/__ipynb__/widget_segmentations_beta.ipynb
index 582d924a..4354b1b2 100644
--- a/docs/notebooks/__ipynb__/widget_segmentations_beta.ipynb
+++ b/docs/notebooks/__ipynb__/widget_segmentations_beta.ipynb
@@ -1,9 +1,23 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of OME-TIFF images and segmentation masks"
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "vblA",
+ "id": "MJUe",
"metadata": {},
"outputs": [],
"source": [
@@ -23,17 +37,7 @@
{
"cell_type": "code",
"execution_count": null,
- "id": "PKri",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "bkHC",
+ "id": "vblA",
"metadata": {},
"outputs": [],
"source": [
@@ -66,19 +70,14 @@
]
},
{
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {},
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
"metadata": {},
+ "outputs": [],
"source": [
- "# Visualization of OME-TIFF images and segmentation masks"
+ "vw = vc.widget()\n",
+ "vw"
]
},
{
@@ -88,8 +87,7 @@
"metadata": {},
"outputs": [],
"source": [
- "vw = vc.widget()\n",
- "vw"
+ "import marimo as mo"
]
}
],
diff --git a/docs/notebooks/__ipynb__/widget_shortcut.ipynb b/docs/notebooks/__ipynb__/widget_shortcut.ipynb
index f80c8de7..68e38c52 100644
--- a/docs/notebooks/__ipynb__/widget_shortcut.ipynb
+++ b/docs/notebooks/__ipynb__/widget_shortcut.ipynb
@@ -1,9 +1,39 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# The from_object shortcut"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "Import the functions and classes that we will be using."
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "bkHC",
+ "id": "vblA",
"metadata": {},
"outputs": [],
"source": [
@@ -22,29 +52,25 @@
]
},
{
- "cell_type": "code",
- "execution_count": null,
- "id": "Hstk",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "SFPL",
- "metadata": {},
- "outputs": [],
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "adata = read_h5ad(join(\"data\", \"habib17.processed.h5ad\"))"
+ "## 2. Download the data\n",
+ "\n",
+ "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "PKri",
+ "id": "lEQa",
"metadata": {},
"outputs": [],
"source": [
@@ -55,68 +81,46 @@
},
{
"cell_type": "markdown",
- "id": "BYtC",
- "metadata": {},
- "source": [
- "## 3.1. Preprocess the Data For Visualization"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Xref",
- "metadata": {},
+ "id": "PKri",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
"## 3. Load the data"
]
},
{
- "cell_type": "markdown",
- "id": "Kclp",
- "metadata": {},
- "source": [
- "With one line of code, you may create a Vitessce widget based on an automatically inferred configuration."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {},
- "source": [
- "# The from_object shortcut"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {},
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "lEQa",
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
"metadata": {},
+ "outputs": [],
"source": [
- "## 2. Download the data\n",
- "\n",
- "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
+ "adata = read_h5ad(join(\"data\", \"habib17.processed.h5ad\"))"
]
},
{
"cell_type": "markdown",
- "id": "vblA",
- "metadata": {},
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
"source": [
- "## 1. Import dependencies\n",
- "\n",
- "Import the functions and classes that we will be using."
+ "## 3.1. Preprocess the Data For Visualization"
]
},
{
"cell_type": "code",
"execution_count": null,
- "id": "RGSE",
+ "id": "BYtC",
"metadata": {},
"outputs": [],
"source": [
@@ -131,10 +135,24 @@
")"
]
},
+ {
+ "cell_type": "markdown",
+ "id": "RGSE",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "With one line of code, you may create a Vitessce widget based on an automatically inferred configuration."
+ ]
+ },
{
"cell_type": "code",
"execution_count": null,
- "id": "emfo",
+ "id": "Kclp",
"metadata": {},
"outputs": [],
"source": [
@@ -149,6 +167,16 @@
"), schema_version=\"1.0.15\").widget(height=800)\n",
"vw"
]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "emfo",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import marimo as mo"
+ ]
}
],
"metadata": {},
diff --git a/docs/notebooks/cellbrowser_to_vitessce_config_conversion.mo.py b/docs/notebooks/cellbrowser_to_vitessce_config_conversion.mo.py
index 157ee36d..a4ffe018 100644
--- a/docs/notebooks/cellbrowser_to_vitessce_config_conversion.mo.py
+++ b/docs/notebooks/cellbrowser_to_vitessce_config_conversion.mo.py
@@ -4,6 +4,12 @@
app = marimo.App()
+@app.cell
+def _():
+ import marimo as mo
+ return (mo,)
+
+
@app.cell(hide_code=True)
def _(mo):
mo.md(
@@ -66,12 +72,6 @@ def _(mo):
return
-@app.cell
-def _():
- ## 3. Convert UCSC Cell Browser project to a Vitessce view config
- return
-
-
@app.cell
def _(convert_cell_browser_project_to_anndata):
# Example run, coverting "adultPancreas" project:
@@ -139,11 +139,5 @@ def _(vc):
return
-@app.cell
-def _():
- import marimo as mo
- return (mo,)
-
-
if __name__ == "__main__":
app.run()
diff --git a/docs/notebooks/data_conversion.mo.py b/docs/notebooks/data_conversion.mo.py
index d1a94e09..956bcf45 100644
--- a/docs/notebooks/data_conversion.mo.py
+++ b/docs/notebooks/data_conversion.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Data Preparation Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/data_export_files.mo.py b/docs/notebooks/data_export_files.mo.py
index a3f3d968..ad827c86 100644
--- a/docs/notebooks/data_export_files.mo.py
+++ b/docs/notebooks/data_export_files.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Data Preparation Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/data_export_s3.mo.py b/docs/notebooks/data_export_s3.mo.py
index 189f3fc4..a070ae92 100644
--- a/docs/notebooks/data_export_s3.mo.py
+++ b/docs/notebooks/data_export_s3.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Data Preparation Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/page_mode_comparative.mo.py b/docs/notebooks/page_mode_comparative.mo.py
index 0f350132..6440a387 100644
--- a/docs/notebooks/page_mode_comparative.mo.py
+++ b/docs/notebooks/page_mode_comparative.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/page_mode_example.mo.py b/docs/notebooks/page_mode_example.mo.py
index 0f117780..1ff38f0f 100644
--- a/docs/notebooks/page_mode_example.mo.py
+++ b/docs/notebooks/page_mode_example.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/spatial_data.mo.py b/docs/notebooks/spatial_data.mo.py
index 7b0cc4bb..413791ec 100644
--- a/docs/notebooks/spatial_data.mo.py
+++ b/docs/notebooks/spatial_data.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/spatial_data_blobs.mo.py b/docs/notebooks/spatial_data_blobs.mo.py
index ff4d6b94..cc8d23ee 100644
--- a/docs/notebooks/spatial_data_blobs.mo.py
+++ b/docs/notebooks/spatial_data_blobs.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/spatial_data_kpmp_vis.mo.py b/docs/notebooks/spatial_data_kpmp_vis.mo.py
index bc51784a..43db087f 100644
--- a/docs/notebooks/spatial_data_kpmp_vis.mo.py
+++ b/docs/notebooks/spatial_data_kpmp_vis.mo.py
@@ -8,7 +8,7 @@
def _(mo):
mo.md(
r"""
- # Vitessce Widget Tutorial
+ # Visualization of a SpatialData object
"""
)
return
diff --git a/docs/notebooks/spatial_data_merfish.mo.py b/docs/notebooks/spatial_data_merfish.mo.py
index 94081dec..42645033 100644
--- a/docs/notebooks/spatial_data_merfish.mo.py
+++ b/docs/notebooks/spatial_data_merfish.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/spatial_data_merfish_2.mo.py b/docs/notebooks/spatial_data_merfish_2.mo.py
index 4c7781d4..76b0160f 100644
--- a/docs/notebooks/spatial_data_merfish_2.mo.py
+++ b/docs/notebooks/spatial_data_merfish_2.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/spatial_data_mouseliver.mo.py b/docs/notebooks/spatial_data_mouseliver.mo.py
index f5e690cf..cf8d2e29 100644
--- a/docs/notebooks/spatial_data_mouseliver.mo.py
+++ b/docs/notebooks/spatial_data_mouseliver.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/spatial_data_mouseliver_remote.mo.py b/docs/notebooks/spatial_data_mouseliver_remote.mo.py
index 69119bc8..4e9dba66 100644
--- a/docs/notebooks/spatial_data_mouseliver_remote.mo.py
+++ b/docs/notebooks/spatial_data_mouseliver_remote.mo.py
@@ -1,26 +1,18 @@
import marimo
__generated_with = "0.13.15"
-app = marimo.App()
+app = marimo.App(width="full")
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
+ mo.md(r"""# Vitessce Widget Tutorial""")
return
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- # Visualization of a SpatialData object and individual Spatial Elements, remote data
- """
- )
+ mo.md(r"""# Visualization of a SpatialData object and individual Spatial Elements, remote data""")
return
@@ -28,11 +20,11 @@ def _(mo):
def _(mo):
mo.md(
r"""
- This notebook explains how to create interactive visualizations of data that are accessible remotely.
+ This notebook explains how to create interactive visualizations of data that are accessible remotely.
- We progress through different visualization tasks, first demonstrating how Vitessce facilitates integrated imaging and spatial single-cell visualizations, then demonstrating visualization of non-spatial and image-only datasets.
- """
+ We progress through different visualization tasks, first demonstrating how Vitessce facilitates integrated imaging and spatial single-cell visualizations, then demonstrating visualization of non-spatial and image-only datasets.
+ """
)
return
@@ -41,36 +33,28 @@ def _(mo):
def _(mo):
mo.md(
r"""
-
- """
+
+ """
)
return
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- ## Utility dependencies
- """
- )
+ mo.md(r"""## Utility dependencies""")
return
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- First, we import utility dependencies which will be used to download the example dataset and manipulate file paths, zip files, and JSON files.
- """
- )
+ mo.md(r"""First, we import utility dependencies which will be used to download the example dataset and manipulate file paths, zip files, and JSON files.""")
return
@@ -86,11 +70,7 @@ def _():
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- ## Dependencies for Vitessce
- """
- )
+ mo.md(r"""## Dependencies for Vitessce""")
return
@@ -98,17 +78,17 @@ def _(mo):
def _(mo):
mo.md(
r"""
- Here, we import classes and functions from the `vitessce` Python package.
- This package includes not only APIs for [visualization configuration](https://python-docs.vitessce.io/api_config.html) but also [helper functions](https://python-docs.vitessce.io/api_data.html#vitessce-data-utils) for basic data transformation tasks.
- To specify mappings between data fields and visualization properties, the package contains [classes](https://python-docs.vitessce.io/api_data.html#module-vitessce.wrappers) which wrap standard single-cell data structures stored in formats including [AnnData](https://doi.org/10.1101/2021.12.16.473007), [SpatialData](https://doi.org/10.1038/s41592-024-02212-x), [OME-TIFF](https://doi.org/10.1007/978-3-030-23937-4_1), and [OME-Zarr](https://doi.org/10.1038/s41592-021-01326-w):
-
- - [AnnDataWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.AnnDataWrapper)
- - [ImageOmeTiffWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ImageOmeTiffWrapper)
- - [ImageOmeZarrWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ImageOmeZarrWrapper)
- - [ObsSegmentationsOmeTiffWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ObsSegmentationsOmeTiffWrapper)
- - [ObsSegmentationsOmeZarrWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ObsSegmentationsOmeZarrWrapper)
- - [SpatialDataWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.SpatialDataWrapper)
- """
+ Here, we import classes and functions from the `vitessce` Python package.
+ This package includes not only APIs for [visualization configuration](https://python-docs.vitessce.io/api_config.html) but also [helper functions](https://python-docs.vitessce.io/api_data.html#vitessce-data-utils) for basic data transformation tasks.
+ To specify mappings between data fields and visualization properties, the package contains [classes](https://python-docs.vitessce.io/api_data.html#module-vitessce.wrappers) which wrap standard single-cell data structures stored in formats including [AnnData](https://doi.org/10.1101/2021.12.16.473007), [SpatialData](https://doi.org/10.1038/s41592-024-02212-x), [OME-TIFF](https://doi.org/10.1007/978-3-030-23937-4_1), and [OME-Zarr](https://doi.org/10.1038/s41592-021-01326-w):
+
+ - [AnnDataWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.AnnDataWrapper)
+ - [ImageOmeTiffWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ImageOmeTiffWrapper)
+ - [ImageOmeZarrWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ImageOmeZarrWrapper)
+ - [ObsSegmentationsOmeTiffWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ObsSegmentationsOmeTiffWrapper)
+ - [ObsSegmentationsOmeZarrWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ObsSegmentationsOmeZarrWrapper)
+ - [SpatialDataWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.SpatialDataWrapper)
+ """
)
return
@@ -153,21 +133,17 @@ def _():
def _(mo):
mo.md(
r"""
- In this blog post, we perform basic data transformation tasks to save individual elements of an integrated SpatialData object to separate files in AnnData, OME-TIFF, and OME-Zarr formats.
- To perform these data transformations, we import the following dependencies.
- In general, you will typically not need to import all of these dependencies, either because you are only working with data in one of these formats, or because the data you intend to visualize is already saved to a file or directory.
- """
+ In this blog post, we perform basic data transformation tasks to save individual elements of an integrated SpatialData object to separate files in AnnData, OME-TIFF, and OME-Zarr formats.
+ To perform these data transformations, we import the following dependencies.
+ In general, you will typically not need to import all of these dependencies, either because you are only working with data in one of these formats, or because the data you intend to visualize is already saved to a file or directory.
+ """
)
return
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- ## Download example dataset
- """
- )
+ mo.md(r"""## Download example dataset""")
return
@@ -175,10 +151,10 @@ def _(mo):
def _(mo):
mo.md(
r"""
- We download a mouse liver dataset which serves as a SpatialData [example dataset](https://github.com/scverse/spatialdata-notebooks/blob/main/notebooks/examples/transformations.ipynb).
+ We download a mouse liver dataset which serves as a SpatialData [example dataset](https://github.com/scverse/spatialdata-notebooks/blob/main/notebooks/examples/transformations.ipynb).
- This dataset was generated by [Guilliams et al.](https://doi.org/10.1016/j.cell.2021.12.018) and processed using [SPArrOW](https://doi.org/10.1101/2024.07.04.601829) during the SpatialData [developer workshop](https://doi.org/10.37044/osf.io/8ck3e) in 2024.
- """
+ This dataset was generated by [Guilliams et al.](https://doi.org/10.1016/j.cell.2021.12.018) and processed using [SPArrOW](https://doi.org/10.1101/2024.07.04.601829) during the SpatialData [developer workshop](https://doi.org/10.37044/osf.io/8ck3e) in 2024.
+ """
)
return
@@ -214,11 +190,7 @@ def _(base_url):
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- ## Visualization of a SpatialData object
- """
- )
+ mo.md(r"""## Visualization of a SpatialData object""")
return
@@ -226,15 +198,15 @@ def _(mo):
def _(mo):
mo.md(
r"""
- SpatialData objects are the most complex type of data structure we will work with in this blog post.
- SpatialData objects function as contains for multiple types of Spatial Elements:
-
- - Tables (each table is represented as an AnnData object)
- - Points (e.g., coordinates of transcripts from FISH-based experiments)
- - Shapes (vector-based shapes such as polygons and circles)
- - Labels (label images, i.e., segmentation bitmasks; each label image is stored using OME-Zarr)
- - Images (microscopy images; each image is stored using OME-Zarr)
- """
+ SpatialData objects are the most complex type of data structure we will work with in this blog post.
+ SpatialData objects function as contains for multiple types of Spatial Elements:
+
+ - Tables (each table is represented as an AnnData object)
+ - Points (e.g., coordinates of transcripts from FISH-based experiments)
+ - Shapes (vector-based shapes such as polygons and circles)
+ - Labels (label images, i.e., segmentation bitmasks; each label image is stored using OME-Zarr)
+ - Images (microscopy images; each image is stored using OME-Zarr)
+ """
)
return
@@ -243,11 +215,11 @@ def _(mo):
def _(mo):
mo.md(
r"""
- ## Configure Vitessce
+ ## Configure Vitessce
- Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views.
- To visualize data stored in a SpatialData object, we use the `SpatialDataWrapper` class and specify the paths (relative to the root of the Zarr [directory store](https://zarr.readthedocs.io/en/v2.18.5/api/storage.html#zarr.storage.DirectoryStore)) to different spatial elements of interest.
- """
+ Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views.
+ To visualize data stored in a SpatialData object, we use the `SpatialDataWrapper` class and specify the paths (relative to the root of the Zarr [directory store](https://zarr.readthedocs.io/en/v2.18.5/api/storage.html#zarr.storage.DirectoryStore)) to different spatial elements of interest.
+ """
)
return
@@ -280,28 +252,20 @@ def _(
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- ### Render the widget
- """
- )
+ mo.md(r"""### Render the widget""")
return
@app.cell
def _(vc):
- _vw = vc.widget()
+ _vw = vc.widget(height=900)
_vw
return
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- ## Extract AnnData object from SpatialData object
- """
- )
+ mo.md(r"""## Extract AnnData object from SpatialData object""")
return
@@ -309,9 +273,9 @@ def _(mo):
def _(mo):
mo.md(
r"""
- The above example demonstrates how to visualize a spatial 'omics dataset containing not only single-cell information (e.g., a cell-by-gene expression matrix, cell type annotations) but also an image and cell segmentations.
- To demonstrate how to use Vitessce to visualize data from a (non-spatial) single-cell experiment, we will extract this information from the SpatialData object and save it to a simpler [AnnData](https://anndata.readthedocs.io/) object (ignoring the imaging and spatially-resolved elements).
- """
+ The above example demonstrates how to visualize a spatial 'omics dataset containing not only single-cell information (e.g., a cell-by-gene expression matrix, cell type annotations) but also an image and cell segmentations.
+ To demonstrate how to use Vitessce to visualize data from a (non-spatial) single-cell experiment, we will extract this information from the SpatialData object and save it to a simpler [AnnData](https://anndata.readthedocs.io/) object (ignoring the imaging and spatially-resolved elements).
+ """
)
return
@@ -320,11 +284,11 @@ def _(mo):
def _(mo):
mo.md(
r"""
- As Zarr-formatted data can be easily visualized by Vitessce, we recommend saving the AnnData object to a Zarr store using the [write_zarr](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_zarr.html) method.
- Optionally, the shape of array chunks (for the AnnData `X` array) can be specified as a parameter, to optimize performance based on data access patterns.
- For example, a common pattern is to visualize data across all cells for one gene.
- To support such a pattern, the chunk shape can be specified as follows, `(total number of cells, small number of genes)`, resulting in tall-and-skinny array chunks.
- """
+ As Zarr-formatted data can be easily visualized by Vitessce, we recommend saving the AnnData object to a Zarr store using the [write_zarr](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_zarr.html) method.
+ Optionally, the shape of array chunks (for the AnnData `X` array) can be specified as a parameter, to optimize performance based on data access patterns.
+ For example, a common pattern is to visualize data across all cells for one gene.
+ To support such a pattern, the chunk shape can be specified as follows, `(total number of cells, small number of genes)`, resulting in tall-and-skinny array chunks.
+ """
)
return
@@ -333,40 +297,28 @@ def _(mo):
def _(mo):
mo.md(
r"""
- Alternatively, your AnnData object may already be stored using the H5AD (HDF5-based) format.
- To demonstrate this scenario, we save the object using the [write_h5ad](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_h5ad.html) method.
- """
+ Alternatively, your AnnData object may already be stored using the H5AD (HDF5-based) format.
+ To demonstrate this scenario, we save the object using the [write_h5ad](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_h5ad.html) method.
+ """
)
return
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- To read H5AD-formatted data, Vitessce requires an accompanying JSON [references specification](https://fsspec.github.io/kerchunk/spec.html) file, which can be constructed using the `generate_h5ad_ref_spec` utility function.
- """
- )
+ mo.md(r"""To read H5AD-formatted data, Vitessce requires an accompanying JSON [references specification](https://fsspec.github.io/kerchunk/spec.html) file, which can be constructed using the `generate_h5ad_ref_spec` utility function.""")
return
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- ## Visualization of an AnnData object
- """
- )
+ mo.md(r"""## Visualization of an AnnData object""")
return
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- ### Zarr-based AnnData
- """
- )
+ mo.md(r"""### Zarr-based AnnData""")
return
@@ -392,11 +344,7 @@ def _(vc_1):
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- ### H5AD-based AnnData
- """
- )
+ mo.md(r"""### H5AD-based AnnData""")
return
@@ -428,21 +376,13 @@ def _(vc_2):
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- ## Visualization of an image file
- """
- )
+ mo.md(r"""## Visualization of an image file""")
return
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- ### OME-Zarr image
- """
- )
+ mo.md(r"""### OME-Zarr image""")
return
@@ -481,11 +421,7 @@ def _(vc_3):
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- ### OME-TIFF image
- """
- )
+ mo.md(r"""### OME-TIFF image""")
return
@@ -519,33 +455,33 @@ def _(vc_4):
def _(mo):
mo.md(
r"""
- ## Data location options
+ ## Data location options
- Vitessce can visualize data [not only stored](https://python-docs.vitessce.io/data_options.html) locally (referenced using local file or directory paths) but also stored remotely (referenced using absolute URL paths).
- Depending on whether the Python kernel running the Jupyter process is running locally versus remotely (e.g., on a cluster or cloud platform such as Google Colab), certain data locations may be challenging to access from the machine running the Jupyter notebook frontend (i.e., the machine on which the web browser used to view the notebook is installed).
+ Vitessce can visualize data [not only stored](https://python-docs.vitessce.io/data_options.html) locally (referenced using local file or directory paths) but also stored remotely (referenced using absolute URL paths).
+ Depending on whether the Python kernel running the Jupyter process is running locally versus remotely (e.g., on a cluster or cloud platform such as Google Colab), certain data locations may be challenging to access from the machine running the Jupyter notebook frontend (i.e., the machine on which the web browser used to view the notebook is installed).
- To provide data via one of these alternative mechanisms, use parameters with the following suffices when instantiating the data wrapper classes.
+ To provide data via one of these alternative mechanisms, use parameters with the following suffices when instantiating the data wrapper classes.
- - `_path`: Local file or directory
- - `_url`: Remote file or directory
- - `_store`: Zarr-store-accessible (for zarr-based formats)
- - `_artifact`: Lamin artifact
+ - `_path`: Local file or directory
+ - `_url`: Remote file or directory
+ - `_store`: Zarr-store-accessible (for zarr-based formats)
+ - `_artifact`: Lamin artifact
- For example, `adata_path` can be exchanged for one of the following options.
+ For example, `adata_path` can be exchanged for one of the following options.
- ```diff
- AnnDataWrapper(
- - adata_path="./mouse_liver.spatialdata.zarr",
- + adata_url="https://example.com/mouse_liver.spatialdata.zarr", # Absolute URL
- + adata_store="./mouse_liver.spatialdata.zarr", # String interpreted as root of DirectoryStore
- + adata_store=zarr.DirectoryStore("./mouse_liver.spatialdata.zarr"), # Instance of zarr.storage
- + adata_artifact=adata_zarr_artifact, # Instance of ln.Artifact
- ...
- ```
+ ```diff
+ AnnDataWrapper(
+ - adata_path="./mouse_liver.spatialdata.zarr",
+ + adata_url="https://example.com/mouse_liver.spatialdata.zarr", # Absolute URL
+ + adata_store="./mouse_liver.spatialdata.zarr", # String interpreted as root of DirectoryStore
+ + adata_store=zarr.DirectoryStore("./mouse_liver.spatialdata.zarr"), # Instance of zarr.storage
+ + adata_artifact=adata_zarr_artifact, # Instance of ln.Artifact
+ ...
+ ```
- Note that the `_store` options are only available for Zarr-based formats, such as AnnDataWrapper, SpatialDataWrapper, and ImageOmeZarrWrapper.
- Further, when multiple files are required, such as both `adata_path` and `ref_path` (for the JSON reference specification file accompanying an H5AD file) or `img_path` and `offsets_path`, multiple parameter suffices may need to be changed.
- """
+ Note that the `_store` options are only available for Zarr-based formats, such as AnnDataWrapper, SpatialDataWrapper, and ImageOmeZarrWrapper.
+ Further, when multiple files are required, such as both `adata_path` and `ref_path` (for the JSON reference specification file accompanying an H5AD file) or `img_path` and `offsets_path`, multiple parameter suffices may need to be changed.
+ """
)
return
diff --git a/docs/notebooks/spatial_data_visium_hd.mo.py b/docs/notebooks/spatial_data_visium_hd.mo.py
index 86bf1b76..10b11750 100644
--- a/docs/notebooks/spatial_data_visium_hd.mo.py
+++ b/docs/notebooks/spatial_data_visium_hd.mo.py
@@ -1,37 +1,24 @@
import marimo
__generated_with = "0.13.15"
-app = marimo.App()
+app = marimo.App(width="full")
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
+ mo.md(r"""# Vitessce Widget Tutorial""")
return
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- # Visualization of a SpatialData object
- """
- )
+ mo.md(r"""# Visualization of a SpatialData object""")
return
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- ## Import dependencies
-
- """
- )
+ mo.md(r"""## Import dependencies""")
return
@@ -99,9 +86,9 @@ def _(
def _(mo):
mo.md(
r"""
- ## Rasterize bins
- Reference: https://spatialdata.scverse.org/en/stable/tutorials/notebooks/notebooks/examples/technology_visium_hd.html#performant-on-the-fly-data-rasterization
- """
+ ## Rasterize bins
+ Reference: https://spatialdata.scverse.org/en/stable/tutorials/notebooks/notebooks/examples/technology_visium_hd.html#performant-on-the-fly-data-rasterization
+ """
)
return
@@ -117,14 +104,14 @@ def _():
@app.cell
-def _(read_zarr, spatialdata_filepath):
+def _(
+ rasterize_bins,
+ rasterize_bins_link_table_to_labels,
+ read_zarr,
+ spatialdata_filepath,
+):
sdata = read_zarr(spatialdata_filepath)
- sdata
- return (sdata,)
-
-@app.cell
-def _(rasterize_bins, rasterize_bins_link_table_to_labels, sdata):
for bin_size in ["016", "008", "002"]:
# rasterize_bins() requires a compresed sparse column (csc) matrix
sdata.tables[f"square_{bin_size}um"].X = sdata.tables[f"square_{bin_size}um"].X.tocsc()
@@ -143,8 +130,13 @@ def _(rasterize_bins, rasterize_bins_link_table_to_labels, sdata):
table_name=f"square_{bin_size}um",
rasterized_labels_name=f"rasterized_{bin_size}um",
)
- sdata.write_element(f"rasterized_{bin_size}um")
- return
+ try:
+ sdata.write_element(f"rasterized_{bin_size}um")
+ except:
+ pass
+
+ sdata
+ return (sdata,)
@app.cell
@@ -157,10 +149,10 @@ def _(sdata):
def _(mo):
mo.md(
r"""
- ## Configure Vitessce
+ ## Configure Vitessce
- Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views.
- """
+ Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views.
+ """
)
return
@@ -221,13 +213,9 @@ def _(
return (vc,)
-@app.cell(hide_code=True)
+@app.cell
def _(mo):
- mo.md(
- r"""
- ### Render the widget
- """
- )
+ mo.md(r"""### Render the widget""")
return
diff --git a/docs/notebooks/widget_anndata_with_image.mo.py b/docs/notebooks/widget_anndata_with_image.mo.py
index c02776e3..2e8a042e 100644
--- a/docs/notebooks/widget_anndata_with_image.mo.py
+++ b/docs/notebooks/widget_anndata_with_image.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/widget_brain.mo.py b/docs/notebooks/widget_brain.mo.py
index 0d7e6ffd..b1c4b00a 100644
--- a/docs/notebooks/widget_brain.mo.py
+++ b/docs/notebooks/widget_brain.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/widget_brain_h5ad.mo.py b/docs/notebooks/widget_brain_h5ad.mo.py
index 6386f489..1ca6402b 100644
--- a/docs/notebooks/widget_brain_h5ad.mo.py
+++ b/docs/notebooks/widget_brain_h5ad.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/widget_brain_with_base_dir.mo.py b/docs/notebooks/widget_brain_with_base_dir.mo.py
index deae6013..e64eab5a 100644
--- a/docs/notebooks/widget_brain_with_base_dir.mo.py
+++ b/docs/notebooks/widget_brain_with_base_dir.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/widget_brain_with_quality_metric.mo.py b/docs/notebooks/widget_brain_with_quality_metric.mo.py
index 5b3dfae1..6ea720a8 100644
--- a/docs/notebooks/widget_brain_with_quality_metric.mo.py
+++ b/docs/notebooks/widget_brain_with_quality_metric.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/widget_from_dict.mo.py b/docs/notebooks/widget_from_dict.mo.py
index a55c97e1..a9dd44ec 100644
--- a/docs/notebooks/widget_from_dict.mo.py
+++ b/docs/notebooks/widget_from_dict.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/widget_genomic_profiles.mo.py b/docs/notebooks/widget_genomic_profiles.mo.py
index 592bf698..2c5bffce 100644
--- a/docs/notebooks/widget_genomic_profiles.mo.py
+++ b/docs/notebooks/widget_genomic_profiles.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/widget_imaging.mo.py b/docs/notebooks/widget_imaging.mo.py
index ea18dd11..744a5e48 100644
--- a/docs/notebooks/widget_imaging.mo.py
+++ b/docs/notebooks/widget_imaging.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/widget_imaging_beta.mo.py b/docs/notebooks/widget_imaging_beta.mo.py
index 4fde5426..547bb0f8 100644
--- a/docs/notebooks/widget_imaging_beta.mo.py
+++ b/docs/notebooks/widget_imaging_beta.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/widget_imaging_segmentation.mo.py b/docs/notebooks/widget_imaging_segmentation.mo.py
index 532bb71c..4d4b2177 100644
--- a/docs/notebooks/widget_imaging_segmentation.mo.py
+++ b/docs/notebooks/widget_imaging_segmentation.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/widget_loom.mo.py b/docs/notebooks/widget_loom.mo.py
index eb879421..a9ff13f7 100644
--- a/docs/notebooks/widget_loom.mo.py
+++ b/docs/notebooks/widget_loom.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/widget_modify_config.mo.py b/docs/notebooks/widget_modify_config.mo.py
index 915d2938..3146e2e2 100644
--- a/docs/notebooks/widget_modify_config.mo.py
+++ b/docs/notebooks/widget_modify_config.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/widget_neuroglancer.mo.py b/docs/notebooks/widget_neuroglancer.mo.py
index 08a5083e..bdb4ad4f 100644
--- a/docs/notebooks/widget_neuroglancer.mo.py
+++ b/docs/notebooks/widget_neuroglancer.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/widget_on_colab.mo.py b/docs/notebooks/widget_on_colab.mo.py
index b2be2ad3..15b008d3 100644
--- a/docs/notebooks/widget_on_colab.mo.py
+++ b/docs/notebooks/widget_on_colab.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/widget_pbmc.mo.py b/docs/notebooks/widget_pbmc.mo.py
index 14bee94e..77b4e711 100644
--- a/docs/notebooks/widget_pbmc.mo.py
+++ b/docs/notebooks/widget_pbmc.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/widget_pbmc_remote.mo.py b/docs/notebooks/widget_pbmc_remote.mo.py
index fbe9da5a..81024869 100644
--- a/docs/notebooks/widget_pbmc_remote.mo.py
+++ b/docs/notebooks/widget_pbmc_remote.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/widget_plugin_custom.mo.py b/docs/notebooks/widget_plugin_custom.mo.py
index bc24ea8c..4e605257 100644
--- a/docs/notebooks/widget_plugin_custom.mo.py
+++ b/docs/notebooks/widget_plugin_custom.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/widget_plugin_demo.mo.py b/docs/notebooks/widget_plugin_demo.mo.py
index 7911b86f..be7de441 100644
--- a/docs/notebooks/widget_plugin_demo.mo.py
+++ b/docs/notebooks/widget_plugin_demo.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/widget_plugin_spatial-query.mo.py b/docs/notebooks/widget_plugin_spatial-query.mo.py
index 4ae7ecce..a54feca0 100644
--- a/docs/notebooks/widget_plugin_spatial-query.mo.py
+++ b/docs/notebooks/widget_plugin_spatial-query.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/widget_segmentations_beta.mo.py b/docs/notebooks/widget_segmentations_beta.mo.py
index 9f293f56..93d45102 100644
--- a/docs/notebooks/widget_segmentations_beta.mo.py
+++ b/docs/notebooks/widget_segmentations_beta.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/docs/notebooks/widget_shortcut.mo.py b/docs/notebooks/widget_shortcut.mo.py
index c3f7b970..1ea334ea 100644
--- a/docs/notebooks/widget_shortcut.mo.py
+++ b/docs/notebooks/widget_shortcut.mo.py
@@ -4,16 +4,6 @@
app = marimo.App()
-@app.cell(hide_code=True)
-def _(mo):
- mo.md(
- r"""
- # Vitessce Widget Tutorial
- """
- )
- return
-
-
@app.cell(hide_code=True)
def _(mo):
mo.md(
diff --git a/pyproject.toml b/pyproject.toml
index a8f51a19..a971207c 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -90,7 +90,7 @@ linting = []
notebook = [
'spatialdata>=0.3.0',
'dask[dataframe]==2024.11.1',
- 'marimo',
+ 'marimo>=0.14.16',
'starlette>=0.42.0',
'tqdm>=4.1.0',
]
diff --git a/scripts/convert_mo_to_ipynb.sh b/scripts/convert_mo_to_ipynb.sh
index 7aed1a0d..72cf47ec 100644
--- a/scripts/convert_mo_to_ipynb.sh
+++ b/scripts/convert_mo_to_ipynb.sh
@@ -2,7 +2,14 @@ cd docs/notebooks
for file in *.mo.py; do
echo "Converting $file to ${file%.mo.py}.ipynb"
- uv run marimo export ipynb —-sort=top-down --force --output "__ipynb__/${file%.mo.py}.ipynb" "$file"
+ uv run marimo export ipynb "$file" --output "__ipynb__/${file%.mo.py}.ipynb" —-sort top-down --force
done
+# Uncomment the following lines if you want to use the list of existing .ipynb files in __ipynb__ directory for conversion
+#for file in __ipynb__/*.ipynb; do
+# FILENAME=$(basename "${file%.ipynb}")
+# echo "Converting ${FILENAME}.mo.py to ${FILENAME}.ipynb"
+# uv run marimo export ipynb "${FILENAME}.mo.py" --output "__ipynb__/${FILENAME}.ipynb" --sort top-down --force
+#done
+
cp example_configs.py "__ipynb__/example_configs.py"
\ No newline at end of file
From 42931a977b8cfcbd4376411de2a2a5a0e1c4d9d5 Mon Sep 17 00:00:00 2001
From: Mark Keller <7525285+keller-mark@users.noreply.github.com>
Date: Fri, 8 Aug 2025 12:39:02 -0400
Subject: [PATCH 07/10] Fix syntax highlighting via nbsphinx
---
docs/conf.py | 33 ++++++++++++++++++++++++++++++++-
1 file changed, 32 insertions(+), 1 deletion(-)
diff --git a/docs/conf.py b/docs/conf.py
index d14b41ab..229933a5 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -3,6 +3,7 @@
import sys
import glob
from os.path import join
+import json
import vitessce
@@ -123,9 +124,39 @@ def find_source():
# -- Strip notebook output -------------------------------------------------
-for filename in glob.glob(join('notebooks', '*.ipynb'), recursive=True):
+for filename in glob.glob(join('notebooks', "__ipynb__", '*.ipynb'), recursive=True):
ntbk = nbclean.NotebookCleaner(filename)
ntbk.clear('stderr')
ntbk.clear('output')
ntbk.remove_cells(empty=True)
+ ntbk.remove_cells(search_text="import marimo as mo")
ntbk.save(filename)
+
+ # Add missing metadata, to enable the code to be interpreted as Python code
+ # for syntax highlighting when rendered by nbsphinx.
+ with open(filename, 'r') as f:
+ ntbk_json = json.load(f)
+ with open(filename, 'w') as f:
+ if len(ntbk_json['metadata']) == 0:
+ # If the metadata is empty, we add the default metadata.
+ # This is needed for nbsphinx to render the notebook correctly.
+ ntbk_json['metadata'] = {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
+ }
+ }
+ json.dump(ntbk_json, f, indent=2)
From 1c92e7cac13b5abe4bb9659fa9f5cca7abf06b2e Mon Sep 17 00:00:00 2001
From: Mark Keller <7525285+keller-mark@users.noreply.github.com>
Date: Fri, 8 Aug 2025 12:40:21 -0400
Subject: [PATCH 08/10] Add metadata
---
...rowser_to_vitessce_config_conversion.ipynb | 364 ++--
.../__ipynb__/config_to_python.ipynb | 416 ++--
.../notebooks/__ipynb__/data_conversion.ipynb | 206 +-
.../__ipynb__/data_export_files.ipynb | 536 ++---
docs/notebooks/__ipynb__/data_export_s3.ipynb | 526 ++---
.../__ipynb__/page_mode_comparative.ipynb | 996 ++++-----
.../__ipynb__/page_mode_example.ipynb | 436 ++--
docs/notebooks/__ipynb__/spatial_data.ipynb | 360 ++--
.../__ipynb__/spatial_data_blobs.ipynb | 424 ++--
.../__ipynb__/spatial_data_kpmp_vis.ipynb | 946 ++++-----
.../__ipynb__/spatial_data_merfish.ipynb | 418 ++--
.../__ipynb__/spatial_data_merfish_2.ipynb | 362 ++--
.../__ipynb__/spatial_data_mouseliver.ipynb | 1786 +++++++++--------
.../spatial_data_mouseliver_remote.ipynb | 1352 ++++++-------
.../__ipynb__/spatial_data_visium_hd.ipynb | 542 ++---
docs/notebooks/__ipynb__/web_app_brain.ipynb | 672 ++++---
.../__ipynb__/widget_anndata_with_image.ipynb | 264 +--
docs/notebooks/__ipynb__/widget_brain.ipynb | 714 +++----
.../__ipynb__/widget_brain_h5ad.ipynb | 380 ++--
.../widget_brain_with_base_dir.ipynb | 828 ++++----
.../widget_brain_with_quality_metric.ipynb | 562 +++---
.../__ipynb__/widget_from_dict.ipynb | 230 ++-
.../__ipynb__/widget_genomic_profiles.ipynb | 490 ++---
docs/notebooks/__ipynb__/widget_imaging.ipynb | 228 ++-
.../__ipynb__/widget_imaging_beta.ipynb | 304 +--
.../widget_imaging_segmentation.ipynb | 222 +-
docs/notebooks/__ipynb__/widget_loom.ipynb | 520 ++---
.../__ipynb__/widget_modify_config.ipynb | 292 +--
.../__ipynb__/widget_neuroglancer.ipynb | 450 +++--
docs/notebooks/__ipynb__/widget_pbmc.ipynb | 446 ++--
.../__ipynb__/widget_pbmc_remote.ipynb | 336 ++--
.../__ipynb__/widget_plugin_custom.ipynb | 370 ++--
.../__ipynb__/widget_plugin_demo.ipynb | 274 +--
.../__ipynb__/widget_segmentations_beta.ipynb | 196 +-
.../notebooks/__ipynb__/widget_shortcut.ipynb | 370 ++--
35 files changed, 9049 insertions(+), 8769 deletions(-)
diff --git a/docs/notebooks/__ipynb__/cellbrowser_to_vitessce_config_conversion.ipynb b/docs/notebooks/__ipynb__/cellbrowser_to_vitessce_config_conversion.ipynb
index df25ea7c..31abf63b 100644
--- a/docs/notebooks/__ipynb__/cellbrowser_to_vitessce_config_conversion.ipynb
+++ b/docs/notebooks/__ipynb__/cellbrowser_to_vitessce_config_conversion.ipynb
@@ -1,182 +1,190 @@
{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Hbol",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "# Load UCSC Cell Browser project in Vitessce"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "vblA",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "This notebook shows you how to use the `convert_cell_browser_project_to_anndata` function, which allows you to take an existing project, published in https://cells.ucsc.edu/ and:\n",
- "1. Convert it into the AnnData format that is supported by Vitessce\n",
- "2. Save the AnnData object as a Zarr store\n",
- "3. Configure Vitessce with the AnnData-Zarr store\n",
- "4. Render a Vitessce widget based on the config (step 3) directly in the notebook.\n",
- "\n",
- "The dataset that you choose to convert needs to be a valid UCSC Cell Browser \"project\", accessible from https://cells.ucsc.edu/, with a configuration available in https://github.com/ucscGenomeBrowser/cellbrowser-confs\n",
- "\n",
- "The `convert_cell_browser_project_to_anndata` function takes the name of that project as an input. For example, to convert this project, https://cells.ucsc.edu/?ds=adultPancreas, you will neeed to pass `\"adultPancreas\"` as the project name."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "bkHC",
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "import json\n",
- "from os.path import join\n",
- "from vitessce import (\n",
- " convert_cell_browser_project_to_anndata,\n",
- " AnnDataWrapper,\n",
- " VitessceConfig,\n",
- ")\n",
- "from vitessce.data_utils import VAR_CHUNK_SIZE"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "lEQa",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 1. Convert UCSC Cell Browser project to a format that is supported by Vitessce\n",
- "#### Output:\n",
- "An AnnData object"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "PKri",
- "metadata": {},
- "outputs": [],
- "source": [
- "# Example run, coverting \"adultPancreas\" project:\n",
- "adata = convert_cell_browser_project_to_anndata(project_name=\"adultPancreas\", keep_only_marker_genes=True)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Xref",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Load UCSC Cell Browser project in Vitessce"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "This notebook shows you how to use the `convert_cell_browser_project_to_anndata` function, which allows you to take an existing project, published in https://cells.ucsc.edu/ and:\n",
+ "1. Convert it into the AnnData format that is supported by Vitessce\n",
+ "2. Save the AnnData object as a Zarr store\n",
+ "3. Configure Vitessce with the AnnData-Zarr store\n",
+ "4. Render a Vitessce widget based on the config (step 3) directly in the notebook.\n",
+ "\n",
+ "The dataset that you choose to convert needs to be a valid UCSC Cell Browser \"project\", accessible from https://cells.ucsc.edu/, with a configuration available in https://github.com/ucscGenomeBrowser/cellbrowser-confs\n",
+ "\n",
+ "The `convert_cell_browser_project_to_anndata` function takes the name of that project as an input. For example, to convert this project, https://cells.ucsc.edu/?ds=adultPancreas, you will neeed to pass `\"adultPancreas\"` as the project name."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "import json\n",
+ "from os.path import join\n",
+ "from vitessce import (\n",
+ " convert_cell_browser_project_to_anndata,\n",
+ " AnnDataWrapper,\n",
+ " VitessceConfig,\n",
+ ")\n",
+ "from vitessce.data_utils import VAR_CHUNK_SIZE"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Convert UCSC Cell Browser project to a format that is supported by Vitessce\n",
+ "#### Output:\n",
+ "An AnnData object"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Example run, coverting \"adultPancreas\" project:\n",
+ "adata = convert_cell_browser_project_to_anndata(project_name=\"adultPancreas\", keep_only_marker_genes=True)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Xref",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 2. Save the AnnData object as a Zarr store"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "zarr_filepath = join(\"data\", \"out.adata.zarr\")\n",
+ "os.makedirs(os.path.dirname(zarr_filepath), exist_ok=True)\n",
+ "adata.write_zarr(zarr_filepath, chunks=[adata.shape[0], VAR_CHUNK_SIZE])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "BYtC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 3. Configure Vitessce with the AnnData-Zarr store"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "anndata_wrapper_inst = AnnDataWrapper(\n",
+ " adata_path=zarr_filepath,\n",
+ " obs_feature_matrix_path=\"X\",\n",
+ " obs_embedding_paths=[\"obsm/X_tsne\"],\n",
+ " obs_embedding_names=[\"t-SNE\"],\n",
+ " obs_set_paths=[\"obs/cluster\", \"obs/age\"],\n",
+ " obs_set_names=[\"cluster\", \"age\"],\n",
+ ")\n",
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name=\"Vitessce configuration for CellBrowser project adultPancreas\")\n",
+ "anndata_wrapper_inst.auto_view_config(vc)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Kclp",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 4. Render the Vitessce widget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "emfo",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
}
- },
- "source": [
- "## 2. Save the AnnData object as a Zarr store"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "SFPL",
- "metadata": {},
- "outputs": [],
- "source": [
- "zarr_filepath = join(\"data\", \"out.adata.zarr\")\n",
- "os.makedirs(os.path.dirname(zarr_filepath), exist_ok=True)\n",
- "adata.write_zarr(zarr_filepath, chunks=[adata.shape[0], VAR_CHUNK_SIZE])"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "BYtC",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 3. Configure Vitessce with the AnnData-Zarr store"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "RGSE",
- "metadata": {},
- "outputs": [],
- "source": [
- "anndata_wrapper_inst = AnnDataWrapper(\n",
- " adata_path=zarr_filepath,\n",
- " obs_feature_matrix_path=\"X\",\n",
- " obs_embedding_paths=[\"obsm/X_tsne\"],\n",
- " obs_embedding_names=[\"t-SNE\"],\n",
- " obs_set_paths=[\"obs/cluster\", \"obs/age\"],\n",
- " obs_set_names=[\"cluster\", \"age\"],\n",
- ")\n",
- "vc = VitessceConfig(schema_version=\"1.0.15\", name=\"Vitessce configuration for CellBrowser project adultPancreas\")\n",
- "anndata_wrapper_inst.auto_view_config(vc)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Kclp",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "## 4. Render the Vitessce widget"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "emfo",
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/config_to_python.ipynb b/docs/notebooks/__ipynb__/config_to_python.ipynb
index 672f44c4..084378cf 100644
--- a/docs/notebooks/__ipynb__/config_to_python.ipynb
+++ b/docs/notebooks/__ipynb__/config_to_python.ipynb
@@ -1,208 +1,216 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Generate Python code to reconstruct a VitessceConfig instance"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "MJUe",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import VitessceConfig, VitessceChainableConfig, VitessceConfigDatasetFile"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from example_configs import dries as dries_config"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Load a view config from a dict representation"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig.from_dict(dries_config)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "PKri",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Print to JSON"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import json\n",
+ "print(json.dumps(vc.to_dict(), indent=2))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Print to Python\n",
+ "\n",
+ "The `vc.to_python` function generates formatted Python code which can be used to re-generate the `vc` instance."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "imports, code = vc.to_python()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "RGSE",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "The first value returned is a list of classes used by the code snippet."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Kclp",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "imports"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "emfo",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "print(code)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hstk",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "The second value is the code snippet. When evaluated, the result will be a new `VitessceConfig` instance."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "nWHF",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Evaluate the code and render a Vitessce widget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "iLit",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "reconstructed_vc = eval(code)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ZHCJ",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "reconstructed_vc.widget()"
+ ]
}
- },
- "source": [
- "# Generate Python code to reconstruct a VitessceConfig instance"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "MJUe",
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import VitessceConfig, VitessceChainableConfig, VitessceConfigDatasetFile"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "vblA",
- "metadata": {},
- "outputs": [],
- "source": [
- "from example_configs import dries as dries_config"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "bkHC",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Load a view config from a dict representation"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "lEQa",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig.from_dict(dries_config)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "PKri",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Print to JSON"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "import json\n",
- "print(json.dumps(vc.to_dict(), indent=2))"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "SFPL",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Print to Python\n",
- "\n",
- "The `vc.to_python` function generates formatted Python code which can be used to re-generate the `vc` instance."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "BYtC",
- "metadata": {},
- "outputs": [],
- "source": [
- "imports, code = vc.to_python()"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "RGSE",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "The first value returned is a list of classes used by the code snippet."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Kclp",
- "metadata": {},
- "outputs": [],
- "source": [
- "imports"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "emfo",
- "metadata": {},
- "outputs": [],
- "source": [
- "print(code)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Hstk",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "The second value is the code snippet. When evaluated, the result will be a new `VitessceConfig` instance."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "nWHF",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "## Evaluate the code and render a Vitessce widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "iLit",
- "metadata": {},
- "outputs": [],
- "source": [
- "reconstructed_vc = eval(code)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "ZHCJ",
- "metadata": {},
- "outputs": [],
- "source": [
- "reconstructed_vc.widget()"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "ROlb",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/data_conversion.ipynb b/docs/notebooks/__ipynb__/data_conversion.ipynb
index 0490c213..bb1c6f96 100644
--- a/docs/notebooks/__ipynb__/data_conversion.ipynb
+++ b/docs/notebooks/__ipynb__/data_conversion.ipynb
@@ -1,103 +1,111 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Convert data manually"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "When running the Vitessce widget, data is converted on-the-fly into formats that the Vitessce JavaScript component can render.\n",
+ "The converted data is stored in temporary files, preventing long-term use of the converted files.\n",
+ "\n",
+ "However, the data conversion utilities used by the widget are exposed so that their outputs can be saved to regular files.\n",
+ "This allows the files to be saved for future use with the Vitessce web application by serving the files locally or moving the files onto an object storage system such as AWS S3 (for long-term storage and data sharing).\n",
+ "\n",
+ "This notebook demonstrates how to save the processed outputs of the `AnnDataWrapper` and `SnapWrapper` classes."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import SnapWrapper\n",
+ "from os.path import join\n",
+ "from scipy.io import mmread\n",
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "import json"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "mtx = mmread(join('data', 'snapatac', 'filtered_cell_by_bin.mtx'))\n",
+ "barcodes_df = pd.read_csv(join('data', 'snapatac', 'barcodes.txt'), header=None)\n",
+ "bins_df = pd.read_csv(join('data', 'snapatac', 'bins.txt'), header=None)\n",
+ "clusters_df = pd.read_csv(join('data', 'snapatac', 'umap_coords_clusters.csv'), index_col=0)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "zarr_filepath = join('data', 'snapatac', 'out.snap.multires.zarr')\n",
+ "\n",
+ "w = SnapWrapper(mtx, barcodes_df, bins_df, clusters_df)\n",
+ "\n",
+ "cells_json = w.create_cells_json()\n",
+ "cell_sets_json = w.create_cell_sets_json()\n",
+ "\n",
+ "with open(join('data', 'snapatac', 'out.cells.json'), 'w') as f:\n",
+ " json.dump(cells_json, f)\n",
+ "\n",
+ "with open(join('data', 'snapatac', 'out.cell-sets.json'), 'w') as f:\n",
+ " json.dump(cell_sets_json, f)\n",
+ "\n",
+ "\n",
+ "w.create_genomic_multivec_zarr(zarr_filepath)"
+ ]
}
- },
- "source": [
- "# Convert data manually"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "When running the Vitessce widget, data is converted on-the-fly into formats that the Vitessce JavaScript component can render.\n",
- "The converted data is stored in temporary files, preventing long-term use of the converted files.\n",
- "\n",
- "However, the data conversion utilities used by the widget are exposed so that their outputs can be saved to regular files.\n",
- "This allows the files to be saved for future use with the Vitessce web application by serving the files locally or moving the files onto an object storage system such as AWS S3 (for long-term storage and data sharing).\n",
- "\n",
- "This notebook demonstrates how to save the processed outputs of the `AnnDataWrapper` and `SnapWrapper` classes."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "vblA",
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import SnapWrapper\n",
- "from os.path import join\n",
- "from scipy.io import mmread\n",
- "import pandas as pd\n",
- "import numpy as np\n",
- "import json"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "bkHC",
- "metadata": {},
- "outputs": [],
- "source": [
- "mtx = mmread(join('data', 'snapatac', 'filtered_cell_by_bin.mtx'))\n",
- "barcodes_df = pd.read_csv(join('data', 'snapatac', 'barcodes.txt'), header=None)\n",
- "bins_df = pd.read_csv(join('data', 'snapatac', 'bins.txt'), header=None)\n",
- "clusters_df = pd.read_csv(join('data', 'snapatac', 'umap_coords_clusters.csv'), index_col=0)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "lEQa",
- "metadata": {},
- "outputs": [],
- "source": [
- "zarr_filepath = join('data', 'snapatac', 'out.snap.multires.zarr')\n",
- "\n",
- "w = SnapWrapper(mtx, barcodes_df, bins_df, clusters_df)\n",
- "\n",
- "cells_json = w.create_cells_json()\n",
- "cell_sets_json = w.create_cell_sets_json()\n",
- "\n",
- "with open(join('data', 'snapatac', 'out.cells.json'), 'w') as f:\n",
- " json.dump(cells_json, f)\n",
- "\n",
- "with open(join('data', 'snapatac', 'out.cell-sets.json'), 'w') as f:\n",
- " json.dump(cell_sets_json, f)\n",
- "\n",
- "\n",
- "w.create_genomic_multivec_zarr(zarr_filepath)"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "PKri",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/data_export_files.ipynb b/docs/notebooks/__ipynb__/data_export_files.ipynb
index 97827fc1..e5a282b2 100644
--- a/docs/notebooks/__ipynb__/data_export_files.ipynb
+++ b/docs/notebooks/__ipynb__/data_export_files.ipynb
@@ -1,268 +1,276 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Export data to local files"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the classes and functions that we will be using from the corresponding packages."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "import json\n",
+ "from urllib.parse import quote_plus\n",
+ "from os.path import join, isfile, isdir\n",
+ "from urllib.request import urlretrieve\n",
+ "from anndata import read_h5ad\n",
+ "import scanpy as sc\n",
+ "\n",
+ "from vitessce import (\n",
+ " VitessceWidget,\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " AnnDataWrapper,\n",
+ ")\n",
+ "from vitessce.data_utils import (\n",
+ " optimize_adata,\n",
+ " VAR_CHUNK_SIZE,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 2. Download and process data\n",
+ "\n",
+ "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata_filepath = join(\"data\", \"habib17.processed.h5ad\")\n",
+ "if not isfile(adata_filepath):\n",
+ " os.makedirs(\"data\", exist_ok=True)\n",
+ " urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)\n",
+ "\n",
+ "adata = read_h5ad(adata_filepath)\n",
+ "top_dispersion = adata.var[\"dispersions_norm\"][\n",
+ " sorted(\n",
+ " range(len(adata.var[\"dispersions_norm\"])),\n",
+ " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
+ " )[-51:][0]\n",
+ "]\n",
+ "adata.var[\"top_highly_variable\"] = (\n",
+ " adata.var[\"dispersions_norm\"] > top_dispersion\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "zarr_filepath = join('data', 'habib17.processed.zarr')\n",
+ "if not isdir(zarr_filepath):\n",
+ " adata_1 = optimize_adata(adata, obs_cols=['CellType'], obsm_keys=['X_umap'], var_cols=['top_highly_variable'], optimize_X=True)\n",
+ " adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Xref",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 3. Create the Vitessce configuration"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "Set up the configuration by adding the views and datasets of interest."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', description='COVID-19 Healthy Donor Brain')\n",
+ "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
+ " adata_path=zarr_filepath,\n",
+ " obs_embedding_paths=[\"obsm/X_umap\"],\n",
+ " obs_embedding_names=[\"UMAP\"],\n",
+ " obs_set_paths=[\"obs/CellType\"],\n",
+ " obs_set_names=[\"Cell Type\"],\n",
+ " obs_feature_matrix_path=\"X\",\n",
+ " feature_filter_path=\"var/top_highly_variable\"\n",
+ "))\n",
+ "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"X_umap\")\n",
+ "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
+ "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
+ "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)\n",
+ "vc.layout((scatterplot | (cell_sets / genes)) / heatmap);"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "RGSE",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 4. Export files to a local directory\n",
+ "\n",
+ "The `.export(to='files')` method on the view config instance will export files to the specified directory `out_dir`. The `base_url` parameter is required so that the file URLs in the view config point to the location where you ultimately intend to serve the files."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Kclp",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "config_dict = vc.export(to='files', base_url='http://localhost:3000', out_dir='./test')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "emfo",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 5. Serve the files"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hstk",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "Now that the files have been saved to the `./test` directory, they can be served by any static web server.\n",
+ "\n",
+ "If you would like to serve the files locally, we recommend [http-server](https://github.com/http-party/http-server) which can be installed with NPM or Homebrew:\n",
+ "```sh\n",
+ "cd test\n",
+ "http-server ./ --cors -p 3000\n",
+ "```"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "nWHF",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 6. View on vitessce.io\n",
+ "\n",
+ "The returned view config dict can be converted to a URL, and if the files are served on the internet (rather than locally), this URL can be used to share the interactive visualizations with colleagues."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "iLit",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vitessce_url = \"http://vitessce.io/?url=data:,\" + quote_plus(json.dumps(config_dict))\n",
+ "import webbrowser\n",
+ "webbrowser.open(vitessce_url)"
+ ]
}
- },
- "source": [
- "# Export data to local files"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 1. Import dependencies\n",
- "\n",
- "We need to import the classes and functions that we will be using from the corresponding packages."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "vblA",
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "import json\n",
- "from urllib.parse import quote_plus\n",
- "from os.path import join, isfile, isdir\n",
- "from urllib.request import urlretrieve\n",
- "from anndata import read_h5ad\n",
- "import scanpy as sc\n",
- "\n",
- "from vitessce import (\n",
- " VitessceWidget,\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " AnnDataWrapper,\n",
- ")\n",
- "from vitessce.data_utils import (\n",
- " optimize_adata,\n",
- " VAR_CHUNK_SIZE,\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "bkHC",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "## 2. Download and process data\n",
- "\n",
- "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "lEQa",
- "metadata": {},
- "outputs": [],
- "source": [
- "adata_filepath = join(\"data\", \"habib17.processed.h5ad\")\n",
- "if not isfile(adata_filepath):\n",
- " os.makedirs(\"data\", exist_ok=True)\n",
- " urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)\n",
- "\n",
- "adata = read_h5ad(adata_filepath)\n",
- "top_dispersion = adata.var[\"dispersions_norm\"][\n",
- " sorted(\n",
- " range(len(adata.var[\"dispersions_norm\"])),\n",
- " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
- " )[-51:][0]\n",
- "]\n",
- "adata.var[\"top_highly_variable\"] = (\n",
- " adata.var[\"dispersions_norm\"] > top_dispersion\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "PKri",
- "metadata": {},
- "outputs": [],
- "source": [
- "zarr_filepath = join('data', 'habib17.processed.zarr')\n",
- "if not isdir(zarr_filepath):\n",
- " adata_1 = optimize_adata(adata, obs_cols=['CellType'], obsm_keys=['X_umap'], var_cols=['top_highly_variable'], optimize_X=True)\n",
- " adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Xref",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 3. Create the Vitessce configuration"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "SFPL",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "Set up the configuration by adding the views and datasets of interest."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "BYtC",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', description='COVID-19 Healthy Donor Brain')\n",
- "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
- " adata_path=zarr_filepath,\n",
- " obs_embedding_paths=[\"obsm/X_umap\"],\n",
- " obs_embedding_names=[\"UMAP\"],\n",
- " obs_set_paths=[\"obs/CellType\"],\n",
- " obs_set_names=[\"Cell Type\"],\n",
- " obs_feature_matrix_path=\"X\",\n",
- " feature_filter_path=\"var/top_highly_variable\"\n",
- "))\n",
- "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"X_umap\")\n",
- "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
- "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
- "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)\n",
- "vc.layout((scatterplot | (cell_sets / genes)) / heatmap);"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "RGSE",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 4. Export files to a local directory\n",
- "\n",
- "The `.export(to='files')` method on the view config instance will export files to the specified directory `out_dir`. The `base_url` parameter is required so that the file URLs in the view config point to the location where you ultimately intend to serve the files."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Kclp",
- "metadata": {},
- "outputs": [],
- "source": [
- "config_dict = vc.export(to='files', base_url='http://localhost:3000', out_dir='./test')"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "emfo",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 5. Serve the files"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Hstk",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "Now that the files have been saved to the `./test` directory, they can be served by any static web server.\n",
- "\n",
- "If you would like to serve the files locally, we recommend [http-server](https://github.com/http-party/http-server) which can be installed with NPM or Homebrew:\n",
- "```sh\n",
- "cd test\n",
- "http-server ./ --cors -p 3000\n",
- "```"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "nWHF",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 6. View on vitessce.io\n",
- "\n",
- "The returned view config dict can be converted to a URL, and if the files are served on the internet (rather than locally), this URL can be used to share the interactive visualizations with colleagues."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "iLit",
- "metadata": {},
- "outputs": [],
- "source": [
- "vitessce_url = \"http://vitessce.io/?url=data:,\" + quote_plus(json.dumps(config_dict))\n",
- "import webbrowser\n",
- "webbrowser.open(vitessce_url)"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "ZHCJ",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/data_export_s3.ipynb b/docs/notebooks/__ipynb__/data_export_s3.ipynb
index a6ffc19f..5ed073d9 100644
--- a/docs/notebooks/__ipynb__/data_export_s3.ipynb
+++ b/docs/notebooks/__ipynb__/data_export_s3.ipynb
@@ -1,263 +1,271 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Export data to AWS S3"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the classes and functions that we will be using from the corresponding packages."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "import boto3\n",
+ "import json\n",
+ "from urllib.parse import quote_plus\n",
+ "from os.path import join, isfile, isdir\n",
+ "from urllib.request import urlretrieve\n",
+ "from anndata import read_h5ad\n",
+ "import scanpy as sc\n",
+ "\n",
+ "from vitessce import (\n",
+ " VitessceWidget,\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " AnnDataWrapper,\n",
+ ")\n",
+ "from vitessce.data_utils import (\n",
+ " optimize_adata,\n",
+ " VAR_CHUNK_SIZE,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 2. Download and process data\n",
+ "\n",
+ "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata_filepath = join(\"data\", \"habib17.processed.h5ad\")\n",
+ "if not isfile(adata_filepath):\n",
+ " os.makedirs(\"data\", exist_ok=True)\n",
+ " urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)\n",
+ "\n",
+ "adata = read_h5ad(adata_filepath)\n",
+ "top_dispersion = adata.var[\"dispersions_norm\"][\n",
+ " sorted(\n",
+ " range(len(adata.var[\"dispersions_norm\"])),\n",
+ " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
+ " )[-51:][0]\n",
+ "]\n",
+ "adata.var[\"top_highly_variable\"] = (\n",
+ " adata.var[\"dispersions_norm\"] > top_dispersion\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "zarr_filepath = join('data', 'habib17.processed.zarr')\n",
+ "if not isdir(zarr_filepath):\n",
+ " adata_1 = optimize_adata(adata, obs_cols=['CellType'], obsm_keys=['X_umap'], var_cols=['top_highly_variable'], optimize_X=True)\n",
+ " adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Xref",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 3. Create the Vitessce configuration"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "Set up the configuration by adding the views and datasets of interest."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', description='COVID-19 Healthy Donor Brain')\n",
+ "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
+ " adata_path=zarr_filepath,\n",
+ " obs_embedding_paths=[\"obsm/X_umap\"],\n",
+ " obs_embedding_names=[\"UMAP\"],\n",
+ " obs_set_paths=[\"obs/CellType\"],\n",
+ " obs_set_names=[\"Cell Type\"],\n",
+ " obs_feature_matrix_path=\"X\",\n",
+ " feature_filter_path=\"var/top_highly_variable\"\n",
+ "))\n",
+ "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
+ "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
+ "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
+ "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)\n",
+ "vc.layout((scatterplot | (cell_sets / genes)) / heatmap);"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "RGSE",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 4. Create a `boto3` resource with S3 credentials"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Kclp",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "s3 = boto3.resource(\n",
+ " service_name='s3',\n",
+ " aws_access_key_id=os.environ['VITESSCE_S3_ACCESS_KEY_ID'],\n",
+ " aws_secret_access_key=os.environ['VITESSCE_S3_SECRET_ACCESS_KEY'],\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "emfo",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 5. Upload files to S3\n",
+ "\n",
+ "The `.export(to='S3')` method on the view config instance will upload all data objects to the specified bucket. Then, the processed view config will be returned as a `dict`, with the file URLs filled in, pointing to the S3 bucket files. For more information about configuring the S3 bucket so that files are accessible over the internet, visit the \"Hosting Data\" page of our core documentation site."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Hstk",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "config_dict = vc.export(to='S3', s3=s3, bucket_name='vitessce-export-examples', prefix='test')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "nWHF",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 6. View on vitessce.io\n",
+ "\n",
+ "The returned view config dict can be converted to a URL, and can be used to share the interactive visualizations with colleagues."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "iLit",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vitessce_url = \"http://vitessce.io/?url=data:,\" + quote_plus(json.dumps(config_dict))\n",
+ "import webbrowser\n",
+ "webbrowser.open(vitessce_url)"
+ ]
}
- },
- "source": [
- "# Export data to AWS S3"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 1. Import dependencies\n",
- "\n",
- "We need to import the classes and functions that we will be using from the corresponding packages."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "vblA",
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "import boto3\n",
- "import json\n",
- "from urllib.parse import quote_plus\n",
- "from os.path import join, isfile, isdir\n",
- "from urllib.request import urlretrieve\n",
- "from anndata import read_h5ad\n",
- "import scanpy as sc\n",
- "\n",
- "from vitessce import (\n",
- " VitessceWidget,\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " AnnDataWrapper,\n",
- ")\n",
- "from vitessce.data_utils import (\n",
- " optimize_adata,\n",
- " VAR_CHUNK_SIZE,\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "bkHC",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 2. Download and process data\n",
- "\n",
- "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "lEQa",
- "metadata": {},
- "outputs": [],
- "source": [
- "adata_filepath = join(\"data\", \"habib17.processed.h5ad\")\n",
- "if not isfile(adata_filepath):\n",
- " os.makedirs(\"data\", exist_ok=True)\n",
- " urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)\n",
- "\n",
- "adata = read_h5ad(adata_filepath)\n",
- "top_dispersion = adata.var[\"dispersions_norm\"][\n",
- " sorted(\n",
- " range(len(adata.var[\"dispersions_norm\"])),\n",
- " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
- " )[-51:][0]\n",
- "]\n",
- "adata.var[\"top_highly_variable\"] = (\n",
- " adata.var[\"dispersions_norm\"] > top_dispersion\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "PKri",
- "metadata": {},
- "outputs": [],
- "source": [
- "zarr_filepath = join('data', 'habib17.processed.zarr')\n",
- "if not isdir(zarr_filepath):\n",
- " adata_1 = optimize_adata(adata, obs_cols=['CellType'], obsm_keys=['X_umap'], var_cols=['top_highly_variable'], optimize_X=True)\n",
- " adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Xref",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 3. Create the Vitessce configuration"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "SFPL",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "Set up the configuration by adding the views and datasets of interest."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "BYtC",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', description='COVID-19 Healthy Donor Brain')\n",
- "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
- " adata_path=zarr_filepath,\n",
- " obs_embedding_paths=[\"obsm/X_umap\"],\n",
- " obs_embedding_names=[\"UMAP\"],\n",
- " obs_set_paths=[\"obs/CellType\"],\n",
- " obs_set_names=[\"Cell Type\"],\n",
- " obs_feature_matrix_path=\"X\",\n",
- " feature_filter_path=\"var/top_highly_variable\"\n",
- "))\n",
- "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
- "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
- "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
- "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)\n",
- "vc.layout((scatterplot | (cell_sets / genes)) / heatmap);"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "RGSE",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 4. Create a `boto3` resource with S3 credentials"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Kclp",
- "metadata": {},
- "outputs": [],
- "source": [
- "s3 = boto3.resource(\n",
- " service_name='s3',\n",
- " aws_access_key_id=os.environ['VITESSCE_S3_ACCESS_KEY_ID'],\n",
- " aws_secret_access_key=os.environ['VITESSCE_S3_SECRET_ACCESS_KEY'],\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "emfo",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 5. Upload files to S3\n",
- "\n",
- "The `.export(to='S3')` method on the view config instance will upload all data objects to the specified bucket. Then, the processed view config will be returned as a `dict`, with the file URLs filled in, pointing to the S3 bucket files. For more information about configuring the S3 bucket so that files are accessible over the internet, visit the \"Hosting Data\" page of our core documentation site."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Hstk",
- "metadata": {},
- "outputs": [],
- "source": [
- "config_dict = vc.export(to='S3', s3=s3, bucket_name='vitessce-export-examples', prefix='test')"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "nWHF",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 6. View on vitessce.io\n",
- "\n",
- "The returned view config dict can be converted to a URL, and can be used to share the interactive visualizations with colleagues."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "iLit",
- "metadata": {},
- "outputs": [],
- "source": [
- "vitessce_url = \"http://vitessce.io/?url=data:,\" + quote_plus(json.dumps(config_dict))\n",
- "import webbrowser\n",
- "webbrowser.open(vitessce_url)"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "ZHCJ",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/page_mode_comparative.ipynb b/docs/notebooks/__ipynb__/page_mode_comparative.ipynb
index 31ee589a..ec439c1a 100644
--- a/docs/notebooks/__ipynb__/page_mode_comparative.ipynb
+++ b/docs/notebooks/__ipynb__/page_mode_comparative.ipynb
@@ -1,498 +1,506 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of ComparativeData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Configure Vitessce"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from oxc_py import transform\n",
+ "from vitessce import VitessceConfig, hconcat, vconcat"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Configure the data and views"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Reference: https://github.com/vitessce/vitessce/blob/main/examples/configs/src/view-configs/kpmp-premiere.js"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "base_url = 'https://storage.googleapis.com/vitessce-demo-data/kpmp-jan-2025/kpmp_premiere_20250330.adata.zarr'"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.17\", name='Lake et al.')\n",
+ "\n",
+ "dataset = vc.add_dataset('lake_et_al').add_file(\n",
+ " file_type='comparisonMetadata.anndata.zarr',\n",
+ " url=base_url,\n",
+ " options={\n",
+ " \"path\": 'uns/comparison_metadata',\n",
+ " },\n",
+ " coordination_values={\n",
+ " \"obsType\": 'cell',\n",
+ " \"sampleType\": 'sample',\n",
+ " },\n",
+ ").add_file(\n",
+ " file_type='comparativeFeatureStats.anndata.zarr',\n",
+ " url=base_url,\n",
+ " options= {\n",
+ " \"metadataPath\": 'uns/comparison_metadata',\n",
+ " \"indexColumn\": 'names',\n",
+ " \"pValueColumn\": 'pvals_adj',\n",
+ " \"foldChangeColumn\": 'logfoldchanges',\n",
+ " \"pValueAdjusted\": True,\n",
+ " \"foldChangeTransformation\": 'log2',\n",
+ " },\n",
+ " coordination_values={\n",
+ " \"obsType\": 'cell',\n",
+ " \"sampleType\": 'sample',\n",
+ " \"featureType\": 'gene',\n",
+ " },\n",
+ ").add_file(\n",
+ " file_type= 'comparativeObsSetStats.anndata.zarr',\n",
+ " url= base_url,\n",
+ " options= {\n",
+ " \"metadataPath\": 'uns/comparison_metadata',\n",
+ " \"indexColumn\": 'Cell Type',\n",
+ " \"interceptExpectedSampleColumn\": 'Expected Sample_intercept',\n",
+ " \"effectExpectedSampleColumn\": 'Expected Sample_effect',\n",
+ " \"foldChangeColumn\": 'log2-fold change',\n",
+ " \"foldChangeTransformation\": 'log2',\n",
+ " \"isCredibleEffectColumn\": 'is_credible_effect',\n",
+ " },\n",
+ " coordination_values= {\n",
+ " \"obsType\": 'cell',\n",
+ " \"sampleType\": 'sample',\n",
+ " },\n",
+ ").add_file(\n",
+ " file_type='comparativeFeatureSetStats.anndata.zarr',\n",
+ " url=base_url,\n",
+ " options= {\n",
+ " \"metadataPath\": 'uns/comparison_metadata',\n",
+ " \"indexColumn\": 'pathway_name',\n",
+ " \"termColumn\": 'pathway_term',\n",
+ " \"pValueColumn\": 'pvals_adj',\n",
+ " \"pValueAdjusted\": True,\n",
+ " \"analysisType\": 'pertpy_hypergeometric',\n",
+ " \"featureSetLibrary\": 'Reactome_2022',\n",
+ " },\n",
+ " coordination_values= {\n",
+ " \"obsType\": 'cell',\n",
+ " \"featureType\": 'gene',\n",
+ " \"sampleType\": 'sample',\n",
+ " },\n",
+ ").add_file(\n",
+ " file_type='anndata.zarr',\n",
+ " url=base_url,\n",
+ " coordination_values={\n",
+ " \"obsType\": 'cell',\n",
+ " \"featureType\": 'gene',\n",
+ " \"featureValueType\": 'expression',\n",
+ " \"sampleType\": 'sample',\n",
+ " },\n",
+ " options={\n",
+ " \"obsFeatureMatrix\": {\n",
+ " \"path\": 'layers/pearson_residuals',\n",
+ " },\n",
+ " \"obsEmbedding\": [\n",
+ " {\n",
+ " \"path\": 'obsm/X_densmap',\n",
+ " \"embeddingType\": 'densMAP',\n",
+ " },\n",
+ " ],\n",
+ " \"obsSets\": [\n",
+ " {\n",
+ " \"name\": 'Cell Type',\n",
+ " \"path\": 'obs/cell_type',\n",
+ " },\n",
+ " {\n",
+ " \"name\": 'Subclass L1',\n",
+ " \"path\": 'obs/subclass_l1',\n",
+ " },\n",
+ " {\n",
+ " \"name\": 'Subclass L2',\n",
+ " \"path\": 'obs/subclass_l2',\n",
+ " },\n",
+ " {\n",
+ " \"name\": 'Donor ID',\n",
+ " \"path\": 'obs/donor_id',\n",
+ " },\n",
+ " ],\n",
+ " \"sampleEdges\": {\n",
+ " \"path\": 'obs/SampleID',\n",
+ " },\n",
+ " },\n",
+ ").add_file(\n",
+ " file_type='sampleSets.anndata.zarr',\n",
+ " url=f\"{base_url}/uns/__all__.samples\",\n",
+ " options={\n",
+ " \"sampleSets\": [\n",
+ " {\n",
+ " \"name\": 'Disease Type',\n",
+ " \"path\": 'diseasetype',\n",
+ " },\n",
+ " {\n",
+ " \"name\": 'Adjudicated Category',\n",
+ " \"path\": 'AdjudicatedCategory',\n",
+ " },\n",
+ " {\n",
+ " \"name\": 'Enrollment Category',\n",
+ " \"path\": 'EnrollmentCategory',\n",
+ " },\n",
+ " ],\n",
+ " },\n",
+ " coordination_values= {\n",
+ " \"sampleType\": 'sample',\n",
+ " },\n",
+ ")\n",
+ "\n",
+ "biomarkerSelect = vc.add_view('biomarkerSelect', dataset=dataset, uid='biomarker-select')\n",
+ "comparativeHeading = vc.add_view('comparativeHeading', dataset=dataset, uid='comparative-heading')\n",
+ "dualScatterplot = vc.add_view('dualScatterplot', dataset=dataset, uid='scatterplot')\n",
+ "obsSets = vc.add_view('obsSets', dataset=dataset, uid='cell-sets')\n",
+ "sampleSets = vc.add_view('sampleSetPairManager', dataset=dataset, uid='sample-sets')\n",
+ "obsSetSizes = vc.add_view('obsSetSizes', dataset=dataset)\n",
+ "featureList = vc.add_view('featureList', dataset=dataset)\n",
+ "violinPlots = vc.add_view('obsSetFeatureValueDistribution', dataset=dataset, uid='violin-plot')\n",
+ "dotPlot = vc.add_view('dotPlot', dataset=dataset, uid='dot-plot')\n",
+ "treemap = vc.add_view('treemap', dataset=dataset, uid='treemap')\n",
+ "volcanoPlot = vc.add_view('volcanoPlot', dataset=dataset, uid='volcano-plot')\n",
+ "volcanoPlotTable = vc.add_view('featureStatsTable', dataset=dataset, uid='volcano-plot-table')\n",
+ "obsSetCompositionBarPlot = vc.add_view('obsSetCompositionBarPlot', dataset=dataset, uid='sccoda-plot')\n",
+ "featureSetEnrichmentBarPlot = vc.add_view('featureSetEnrichmentBarPlot', dataset=dataset, uid='pathways-plot')\n",
+ "\n",
+ "[sampleSetScope_caseControl] = vc.add_coordination('sampleSetSelection')\n",
+ "sampleSetScope_caseControl.set_value([['Disease Type', 'CKD'], ['Disease Type', 'Reference']])\n",
+ "\n",
+ "[featureSelectionScope] = vc.add_coordination('featureSelection')\n",
+ "featureSelectionScope.set_value(['UMOD', 'NPHS2'])\n",
+ "\n",
+ "vc.link_views_by_dict([dualScatterplot], {\n",
+ " \"embeddingType\": 'densMAP',\n",
+ " \"embeddingContoursVisible\": True,\n",
+ " \"embeddingPointsVisible\": False,\n",
+ " \"embeddingObsSetLabelsVisible\": True,\n",
+ "}, meta=False);\n",
+ "\n",
+ "\n",
+ "vc.link_views([biomarkerSelect, dualScatterplot, obsSets, obsSetSizes, featureList, violinPlots, dotPlot, treemap, volcanoPlot, volcanoPlotTable, comparativeHeading, obsSetCompositionBarPlot, featureSetEnrichmentBarPlot, sampleSets], ['sampleType'], ['sample'])\n",
+ "\n",
+ "vc.link_views_by_dict([biomarkerSelect, dualScatterplot, obsSets, obsSetSizes, featureList, violinPlots, dotPlot, treemap, volcanoPlot, volcanoPlotTable, comparativeHeading, obsSetCompositionBarPlot, featureSetEnrichmentBarPlot, sampleSets], {\n",
+ " \"sampleSetSelection\": sampleSetScope_caseControl,\n",
+ " \"featureSelection\": featureSelectionScope,\n",
+ "}, meta=False)\n",
+ "\n",
+ "vc.link_views_by_dict([dualScatterplot, violinPlots, featureList, dotPlot], {\n",
+ " # \"featureSelection\": ['UMOD', 'NPHS2'], // , 'ENSG00000074803', 'ENSG00000164825'],\n",
+ " \"obsColorEncoding\": 'geneSelection',\n",
+ " \"featureValueColormap\": 'jet',\n",
+ " \"featureValueColormapRange\": [0, 0.25],\n",
+ " \"featureAggregationStrategy\": None,\n",
+ "}, meta=False)\n",
+ "\n",
+ "vc.layout(hconcat(\n",
+ " vconcat(dualScatterplot, biomarkerSelect, comparativeHeading, obsSets, obsSetSizes, featureList),\n",
+ " vconcat(treemap, featureSetEnrichmentBarPlot, violinPlots, dotPlot, obsSetCompositionBarPlot, sampleSets),\n",
+ " volcanoPlotTable,\n",
+ "));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Define the page layout"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "PAGE_ESM = transform(\"\"\"\n",
+ "import clsx from \"https://unpkg.com/clsx@1.1.1/dist/clsx.m.js\";\n",
+ "\n",
+ "function createPage(utilsForPages) {\n",
+ " const {\n",
+ " React,\n",
+ " usePageModeView,\n",
+ " } = utilsForPages;\n",
+ " function PageComponent(props) {\n",
+ " const BiomarkerSelect = usePageModeView('biomarker-select');\n",
+ " const ComparativeHeading = usePageModeView('comparative-heading');\n",
+ " const CellSets = usePageModeView('cell-sets');\n",
+ " const SampleSets = usePageModeView('sample-sets');\n",
+ " const DualScatterplot = usePageModeView('scatterplot');\n",
+ " const ViolinPlot = usePageModeView('violin-plot');\n",
+ " const DotPlot = usePageModeView('dot-plot');\n",
+ " const Treemap = usePageModeView('treemap');\n",
+ " const VolcanoPlot = usePageModeView('volcano-plot');\n",
+ " const VolcanoPlotTable = usePageModeView('volcano-plot-table');\n",
+ " const SccodaPlot = usePageModeView('sccoda-plot');\n",
+ " const PathwaysPlot = usePageModeView('pathways-plot');\n",
+ "\n",
+ "\n",
+ " return (\n",
+ " <>\n",
+ " \n",
+ " \n",
+ "
\n",
+ "
Comparative visualization of single-cell atlas data \n",
+ " \n",
+ " \n",
+ "
\n",
+ "\n",
+ " \n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
This view contains a treemap visualization to communicate cell type composition in each of the selected sample groups.
\n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
This view displays the results of a cell type composition analysis performed using the ScCODA algorithm (B\u00fcttner et al. 2021). Cell types with significantly different composition between the selected sample groups are displayed opaque while not-signficant results are displayed with transparent bars. The single outlined bar denotes the automatically-selected reference cell type.
\n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
This view displays differential expression test results, performed using the rank_genes_groups function from Scanpy (Wolf et al. 2018) with method "wilcoxon". The arrows on the bottom left and bottom right denote the direction of the effect. Click a point in the plot to select the corresponding gene. Note that differential expression tests have been run for each cell type separately, so the each gene can appear multiple times (once per cell type). If there are too many points on the plot, cell types can be selected to filter the points.
\n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
This view displays differential expression test results in tabular form. Click a row in the table to select the corresponding gene.
\n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
This view displays gene set enrichment test results based on the differential expression results. Gene set enrichment tests have been performed using Reactome 2022 pathway gene sets from BlitzGSEA (Lachmann et al. 2022) via the hypergeometric function of Pertpy (Heumos et al. 2024).
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
This view contains contour scatterplots which display the results of a density-preserving dimensionality reduction (Narayan et al. 2021). Contour opacities correspond to the shown percentile thresholds.
\n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
This dot plot view displays gene expression values per cell type and sample group for the selected biomarkers.
\n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ "
This violin plot view displays gene expression values per cell type and sample group for the selected biomarker.
\n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ " {/*
Neighborhood-level representations \n",
+ "
TODO \n",
+ "
Segmented instance-level representations \n",
+ "
TODO \n",
+ "
Image-level representations \n",
+ "
TODO \n",
+ "
Participant-level representations \n",
+ "
TODO */}\n",
+ "
\n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "\n",
+ "
\n",
+ " >\n",
+ " );\n",
+ " }\n",
+ " return PageComponent;\n",
+ "}\n",
+ "export default { createPage };\n",
+ "\"\"\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "RGSE",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Render page as widget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Kclp",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget(page_esm=PAGE_ESM, page_mode=True, height=4700, prevent_scroll=False)\n",
+ "vw"
+ ]
}
- },
- "source": [
- "# Visualization of ComparativeData object"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Configure Vitessce"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "vblA",
- "metadata": {},
- "outputs": [],
- "source": [
- "from oxc_py import transform\n",
- "from vitessce import VitessceConfig, hconcat, vconcat"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "bkHC",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "## Configure the data and views"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "lEQa",
- "metadata": {},
- "outputs": [],
- "source": [
- "# Reference: https://github.com/vitessce/vitessce/blob/main/examples/configs/src/view-configs/kpmp-premiere.js"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "PKri",
- "metadata": {},
- "outputs": [],
- "source": [
- "base_url = 'https://storage.googleapis.com/vitessce-demo-data/kpmp-jan-2025/kpmp_premiere_20250330.adata.zarr'"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.17\", name='Lake et al.')\n",
- "\n",
- "dataset = vc.add_dataset('lake_et_al').add_file(\n",
- " file_type='comparisonMetadata.anndata.zarr',\n",
- " url=base_url,\n",
- " options={\n",
- " \"path\": 'uns/comparison_metadata',\n",
- " },\n",
- " coordination_values={\n",
- " \"obsType\": 'cell',\n",
- " \"sampleType\": 'sample',\n",
- " },\n",
- ").add_file(\n",
- " file_type='comparativeFeatureStats.anndata.zarr',\n",
- " url=base_url,\n",
- " options= {\n",
- " \"metadataPath\": 'uns/comparison_metadata',\n",
- " \"indexColumn\": 'names',\n",
- " \"pValueColumn\": 'pvals_adj',\n",
- " \"foldChangeColumn\": 'logfoldchanges',\n",
- " \"pValueAdjusted\": True,\n",
- " \"foldChangeTransformation\": 'log2',\n",
- " },\n",
- " coordination_values={\n",
- " \"obsType\": 'cell',\n",
- " \"sampleType\": 'sample',\n",
- " \"featureType\": 'gene',\n",
- " },\n",
- ").add_file(\n",
- " file_type= 'comparativeObsSetStats.anndata.zarr',\n",
- " url= base_url,\n",
- " options= {\n",
- " \"metadataPath\": 'uns/comparison_metadata',\n",
- " \"indexColumn\": 'Cell Type',\n",
- " \"interceptExpectedSampleColumn\": 'Expected Sample_intercept',\n",
- " \"effectExpectedSampleColumn\": 'Expected Sample_effect',\n",
- " \"foldChangeColumn\": 'log2-fold change',\n",
- " \"foldChangeTransformation\": 'log2',\n",
- " \"isCredibleEffectColumn\": 'is_credible_effect',\n",
- " },\n",
- " coordination_values= {\n",
- " \"obsType\": 'cell',\n",
- " \"sampleType\": 'sample',\n",
- " },\n",
- ").add_file(\n",
- " file_type='comparativeFeatureSetStats.anndata.zarr',\n",
- " url=base_url,\n",
- " options= {\n",
- " \"metadataPath\": 'uns/comparison_metadata',\n",
- " \"indexColumn\": 'pathway_name',\n",
- " \"termColumn\": 'pathway_term',\n",
- " \"pValueColumn\": 'pvals_adj',\n",
- " \"pValueAdjusted\": True,\n",
- " \"analysisType\": 'pertpy_hypergeometric',\n",
- " \"featureSetLibrary\": 'Reactome_2022',\n",
- " },\n",
- " coordination_values= {\n",
- " \"obsType\": 'cell',\n",
- " \"featureType\": 'gene',\n",
- " \"sampleType\": 'sample',\n",
- " },\n",
- ").add_file(\n",
- " file_type='anndata.zarr',\n",
- " url=base_url,\n",
- " coordination_values={\n",
- " \"obsType\": 'cell',\n",
- " \"featureType\": 'gene',\n",
- " \"featureValueType\": 'expression',\n",
- " \"sampleType\": 'sample',\n",
- " },\n",
- " options={\n",
- " \"obsFeatureMatrix\": {\n",
- " \"path\": 'layers/pearson_residuals',\n",
- " },\n",
- " \"obsEmbedding\": [\n",
- " {\n",
- " \"path\": 'obsm/X_densmap',\n",
- " \"embeddingType\": 'densMAP',\n",
- " },\n",
- " ],\n",
- " \"obsSets\": [\n",
- " {\n",
- " \"name\": 'Cell Type',\n",
- " \"path\": 'obs/cell_type',\n",
- " },\n",
- " {\n",
- " \"name\": 'Subclass L1',\n",
- " \"path\": 'obs/subclass_l1',\n",
- " },\n",
- " {\n",
- " \"name\": 'Subclass L2',\n",
- " \"path\": 'obs/subclass_l2',\n",
- " },\n",
- " {\n",
- " \"name\": 'Donor ID',\n",
- " \"path\": 'obs/donor_id',\n",
- " },\n",
- " ],\n",
- " \"sampleEdges\": {\n",
- " \"path\": 'obs/SampleID',\n",
- " },\n",
- " },\n",
- ").add_file(\n",
- " file_type='sampleSets.anndata.zarr',\n",
- " url=f\"{base_url}/uns/__all__.samples\",\n",
- " options={\n",
- " \"sampleSets\": [\n",
- " {\n",
- " \"name\": 'Disease Type',\n",
- " \"path\": 'diseasetype',\n",
- " },\n",
- " {\n",
- " \"name\": 'Adjudicated Category',\n",
- " \"path\": 'AdjudicatedCategory',\n",
- " },\n",
- " {\n",
- " \"name\": 'Enrollment Category',\n",
- " \"path\": 'EnrollmentCategory',\n",
- " },\n",
- " ],\n",
- " },\n",
- " coordination_values= {\n",
- " \"sampleType\": 'sample',\n",
- " },\n",
- ")\n",
- "\n",
- "biomarkerSelect = vc.add_view('biomarkerSelect', dataset=dataset, uid='biomarker-select')\n",
- "comparativeHeading = vc.add_view('comparativeHeading', dataset=dataset, uid='comparative-heading')\n",
- "dualScatterplot = vc.add_view('dualScatterplot', dataset=dataset, uid='scatterplot')\n",
- "obsSets = vc.add_view('obsSets', dataset=dataset, uid='cell-sets')\n",
- "sampleSets = vc.add_view('sampleSetPairManager', dataset=dataset, uid='sample-sets')\n",
- "obsSetSizes = vc.add_view('obsSetSizes', dataset=dataset)\n",
- "featureList = vc.add_view('featureList', dataset=dataset)\n",
- "violinPlots = vc.add_view('obsSetFeatureValueDistribution', dataset=dataset, uid='violin-plot')\n",
- "dotPlot = vc.add_view('dotPlot', dataset=dataset, uid='dot-plot')\n",
- "treemap = vc.add_view('treemap', dataset=dataset, uid='treemap')\n",
- "volcanoPlot = vc.add_view('volcanoPlot', dataset=dataset, uid='volcano-plot')\n",
- "volcanoPlotTable = vc.add_view('featureStatsTable', dataset=dataset, uid='volcano-plot-table')\n",
- "obsSetCompositionBarPlot = vc.add_view('obsSetCompositionBarPlot', dataset=dataset, uid='sccoda-plot')\n",
- "featureSetEnrichmentBarPlot = vc.add_view('featureSetEnrichmentBarPlot', dataset=dataset, uid='pathways-plot')\n",
- "\n",
- "[sampleSetScope_caseControl] = vc.add_coordination('sampleSetSelection')\n",
- "sampleSetScope_caseControl.set_value([['Disease Type', 'CKD'], ['Disease Type', 'Reference']])\n",
- "\n",
- "[featureSelectionScope] = vc.add_coordination('featureSelection')\n",
- "featureSelectionScope.set_value(['UMOD', 'NPHS2'])\n",
- "\n",
- "vc.link_views_by_dict([dualScatterplot], {\n",
- " \"embeddingType\": 'densMAP',\n",
- " \"embeddingContoursVisible\": True,\n",
- " \"embeddingPointsVisible\": False,\n",
- " \"embeddingObsSetLabelsVisible\": True,\n",
- "}, meta=False);\n",
- "\n",
- "\n",
- "vc.link_views([biomarkerSelect, dualScatterplot, obsSets, obsSetSizes, featureList, violinPlots, dotPlot, treemap, volcanoPlot, volcanoPlotTable, comparativeHeading, obsSetCompositionBarPlot, featureSetEnrichmentBarPlot, sampleSets], ['sampleType'], ['sample'])\n",
- "\n",
- "vc.link_views_by_dict([biomarkerSelect, dualScatterplot, obsSets, obsSetSizes, featureList, violinPlots, dotPlot, treemap, volcanoPlot, volcanoPlotTable, comparativeHeading, obsSetCompositionBarPlot, featureSetEnrichmentBarPlot, sampleSets], {\n",
- " \"sampleSetSelection\": sampleSetScope_caseControl,\n",
- " \"featureSelection\": featureSelectionScope,\n",
- "}, meta=False)\n",
- "\n",
- "vc.link_views_by_dict([dualScatterplot, violinPlots, featureList, dotPlot], {\n",
- " # \"featureSelection\": ['UMOD', 'NPHS2'], // , 'ENSG00000074803', 'ENSG00000164825'],\n",
- " \"obsColorEncoding\": 'geneSelection',\n",
- " \"featureValueColormap\": 'jet',\n",
- " \"featureValueColormapRange\": [0, 0.25],\n",
- " \"featureAggregationStrategy\": None,\n",
- "}, meta=False)\n",
- "\n",
- "vc.layout(hconcat(\n",
- " vconcat(dualScatterplot, biomarkerSelect, comparativeHeading, obsSets, obsSetSizes, featureList),\n",
- " vconcat(treemap, featureSetEnrichmentBarPlot, violinPlots, dotPlot, obsSetCompositionBarPlot, sampleSets),\n",
- " volcanoPlotTable,\n",
- "));"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "SFPL",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Define the page layout"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "BYtC",
- "metadata": {},
- "outputs": [],
- "source": [
- "PAGE_ESM = transform(\"\"\"\n",
- "import clsx from \"https://unpkg.com/clsx@1.1.1/dist/clsx.m.js\";\n",
- "\n",
- "function createPage(utilsForPages) {\n",
- " const {\n",
- " React,\n",
- " usePageModeView,\n",
- " } = utilsForPages;\n",
- " function PageComponent(props) {\n",
- " const BiomarkerSelect = usePageModeView('biomarker-select');\n",
- " const ComparativeHeading = usePageModeView('comparative-heading');\n",
- " const CellSets = usePageModeView('cell-sets');\n",
- " const SampleSets = usePageModeView('sample-sets');\n",
- " const DualScatterplot = usePageModeView('scatterplot');\n",
- " const ViolinPlot = usePageModeView('violin-plot');\n",
- " const DotPlot = usePageModeView('dot-plot');\n",
- " const Treemap = usePageModeView('treemap');\n",
- " const VolcanoPlot = usePageModeView('volcano-plot');\n",
- " const VolcanoPlotTable = usePageModeView('volcano-plot-table');\n",
- " const SccodaPlot = usePageModeView('sccoda-plot');\n",
- " const PathwaysPlot = usePageModeView('pathways-plot');\n",
- "\n",
- "\n",
- " return (\n",
- " <>\n",
- " \n",
- " \n",
- "
\n",
- "
Comparative visualization of single-cell atlas data \n",
- " \n",
- " \n",
- "
\n",
- "\n",
- " \n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "
\n",
- "
This view contains a treemap visualization to communicate cell type composition in each of the selected sample groups.
\n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "
\n",
- "
\n",
- "
This view displays the results of a cell type composition analysis performed using the ScCODA algorithm (Büttner et al. 2021). Cell types with significantly different composition between the selected sample groups are displayed opaque while not-signficant results are displayed with transparent bars. The single outlined bar denotes the automatically-selected reference cell type.
\n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "
\n",
- "
\n",
- "
This view displays differential expression test results, performed using the rank_genes_groups function from Scanpy (Wolf et al. 2018) with method "wilcoxon". The arrows on the bottom left and bottom right denote the direction of the effect. Click a point in the plot to select the corresponding gene. Note that differential expression tests have been run for each cell type separately, so the each gene can appear multiple times (once per cell type). If there are too many points on the plot, cell types can be selected to filter the points.
\n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "
\n",
- "
\n",
- "
This view displays differential expression test results in tabular form. Click a row in the table to select the corresponding gene.
\n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "
\n",
- "
\n",
- "
This view displays gene set enrichment test results based on the differential expression results. Gene set enrichment tests have been performed using Reactome 2022 pathway gene sets from BlitzGSEA (Lachmann et al. 2022) via the hypergeometric function of Pertpy (Heumos et al. 2024).
\n",
- "
\n",
- "
\n",
- "
\n",
- "
\n",
- "
\n",
- "
This view contains contour scatterplots which display the results of a density-preserving dimensionality reduction (Narayan et al. 2021). Contour opacities correspond to the shown percentile thresholds.
\n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "
\n",
- "
\n",
- "
This dot plot view displays gene expression values per cell type and sample group for the selected biomarkers.
\n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "
\n",
- "
\n",
- "
This violin plot view displays gene expression values per cell type and sample group for the selected biomarker.
\n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- " {/*
Neighborhood-level representations \n",
- "
TODO \n",
- "
Segmented instance-level representations \n",
- "
TODO \n",
- "
Image-level representations \n",
- "
TODO \n",
- "
Participant-level representations \n",
- "
TODO */}\n",
- "
\n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "\n",
- "
\n",
- " >\n",
- " );\n",
- " }\n",
- " return PageComponent;\n",
- "}\n",
- "export default { createPage };\n",
- "\"\"\")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "RGSE",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Render page as widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Kclp",
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget(page_esm=PAGE_ESM, page_mode=True, height=4700, prevent_scroll=False)\n",
- "vw"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "emfo",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/page_mode_example.ipynb b/docs/notebooks/__ipynb__/page_mode_example.ipynb
index bc6f676d..86394336 100644
--- a/docs/notebooks/__ipynb__/page_mode_example.ipynb
+++ b/docs/notebooks/__ipynb__/page_mode_example.ipynb
@@ -1,218 +1,226 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Page mode example"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Configure Vitessce"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " AnnDataWrapper,\n",
+ " CsvWrapper,\n",
+ ")\n",
+ "from oxc_py import transform"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Configure the data and views"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "url = 'https://storage.googleapis.com/vitessce-demo-data/anndata-test/pbmc3k_processed.zarr'"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.17\", name='PBMC Reference')\n",
+ "dataset = vc.add_dataset(name='PBMC 3k').add_object(\n",
+ " AnnDataWrapper(\n",
+ " adata_url=url,\n",
+ " obs_set_paths=[\"obs/louvain\"],\n",
+ " obs_set_names=[\"Louvain\"],\n",
+ " obs_embedding_paths=[\"obsm/X_umap\", \"obsm/X_pca\"],\n",
+ " obs_embedding_names=[\"UMAP\", \"PCA\"],\n",
+ " obs_feature_matrix_path=\"X\"\n",
+ " )\n",
+ ")\n",
+ "\n",
+ "umap = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\", uid=\"scatterplot-umap\")\n",
+ "pca = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"PCA\", uid=\"scatterplot-pca\")\n",
+ "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset, uid=\"cell-sets\")\n",
+ "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset, uid=\"gene-list\")\n",
+ "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset, uid=\"heatmap\")\n",
+ "\n",
+ "vc.layout((umap / pca) | ((cell_sets | genes) / heatmap));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Xref",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Define the page layout"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "PAGE_ESM = transform(\"\"\"\n",
+ "function createPage(utilsForPages) {\n",
+ " const {\n",
+ " React,\n",
+ " usePageModeView,\n",
+ " } = utilsForPages;\n",
+ " function PageComponent(props) {\n",
+ " const ScatterplotUmap = usePageModeView('scatterplot-umap');\n",
+ " const ScatterplotPca = usePageModeView('scatterplot-pca');\n",
+ " const CellSets = usePageModeView('cell-sets');\n",
+ " const GeneList = usePageModeView('gene-list');\n",
+ " const Heatmap = usePageModeView('heatmap');\n",
+ "\n",
+ " return (\n",
+ " <>\n",
+ " \n",
+ " \n",
+ "
\n",
+ "
This is an arbitrary HTML element with custom CSS \n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
Another HTML element \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
\n",
+ "
\n",
+ " \n",
+ " \n",
+ "
\n",
+ "
\n",
+ "\n",
+ " >\n",
+ " );\n",
+ " }\n",
+ " return PageComponent;\n",
+ "}\n",
+ "export default { createPage };\n",
+ "\"\"\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "BYtC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Render page as widget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget(page_esm=PAGE_ESM, page_mode=True, height=1100)\n",
+ "vw"
+ ]
}
- },
- "source": [
- "# Page mode example"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Configure Vitessce"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "vblA",
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " AnnDataWrapper,\n",
- " CsvWrapper,\n",
- ")\n",
- "from oxc_py import transform"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "bkHC",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Configure the data and views"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "lEQa",
- "metadata": {},
- "outputs": [],
- "source": [
- "url = 'https://storage.googleapis.com/vitessce-demo-data/anndata-test/pbmc3k_processed.zarr'"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "PKri",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.17\", name='PBMC Reference')\n",
- "dataset = vc.add_dataset(name='PBMC 3k').add_object(\n",
- " AnnDataWrapper(\n",
- " adata_url=url,\n",
- " obs_set_paths=[\"obs/louvain\"],\n",
- " obs_set_names=[\"Louvain\"],\n",
- " obs_embedding_paths=[\"obsm/X_umap\", \"obsm/X_pca\"],\n",
- " obs_embedding_names=[\"UMAP\", \"PCA\"],\n",
- " obs_feature_matrix_path=\"X\"\n",
- " )\n",
- ")\n",
- "\n",
- "umap = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\", uid=\"scatterplot-umap\")\n",
- "pca = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"PCA\", uid=\"scatterplot-pca\")\n",
- "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset, uid=\"cell-sets\")\n",
- "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset, uid=\"gene-list\")\n",
- "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset, uid=\"heatmap\")\n",
- "\n",
- "vc.layout((umap / pca) | ((cell_sets | genes) / heatmap));"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Xref",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Define the page layout"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "SFPL",
- "metadata": {},
- "outputs": [],
- "source": [
- "PAGE_ESM = transform(\"\"\"\n",
- "function createPage(utilsForPages) {\n",
- " const {\n",
- " React,\n",
- " usePageModeView,\n",
- " } = utilsForPages;\n",
- " function PageComponent(props) {\n",
- " const ScatterplotUmap = usePageModeView('scatterplot-umap');\n",
- " const ScatterplotPca = usePageModeView('scatterplot-pca');\n",
- " const CellSets = usePageModeView('cell-sets');\n",
- " const GeneList = usePageModeView('gene-list');\n",
- " const Heatmap = usePageModeView('heatmap');\n",
- "\n",
- " return (\n",
- " <>\n",
- " \n",
- " \n",
- "
\n",
- "
This is an arbitrary HTML element with custom CSS \n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "
Another HTML element \n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "
\n",
- " \n",
- " \n",
- "
\n",
- "
\n",
- "\n",
- " >\n",
- " );\n",
- " }\n",
- " return PageComponent;\n",
- "}\n",
- "export default { createPage };\n",
- "\"\"\")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "BYtC",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "## Render page as widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "RGSE",
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget(page_esm=PAGE_ESM, page_mode=True, height=1100)\n",
- "vw"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Kclp",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/spatial_data.ipynb b/docs/notebooks/__ipynb__/spatial_data.ipynb
index c183933c..6e7dde80 100644
--- a/docs/notebooks/__ipynb__/spatial_data.ipynb
+++ b/docs/notebooks/__ipynb__/spatial_data.ipynb
@@ -1,180 +1,188 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of a SpatialData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Import dependencies"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from os.path import join, isfile, isdir\n",
+ "from urllib.request import urlretrieve\n",
+ "import zipfile\n",
+ "\n",
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " ViewType as vt,\n",
+ " CoordinationType as ct,\n",
+ " CoordinationLevel as CL,\n",
+ " SpatialDataWrapper,\n",
+ " get_initial_coordination_scope_prefix\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "data_dir = \"data\"\n",
+ "zip_filepath = join(data_dir, \"visium.spatialdata.zarr.zip\")\n",
+ "spatialdata_filepath = join(data_dir, \"visium.spatialdata.zarr\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "if not isdir(spatialdata_filepath):\n",
+ " if not isfile(zip_filepath):\n",
+ " os.makedirs(data_dir, exist_ok=True)\n",
+ " urlretrieve('https://s3.embl.de/spatialdata/spatialdata-sandbox/visium_associated_xenium_io.zip', zip_filepath)\n",
+ " with zipfile.ZipFile(zip_filepath,\"r\") as zip_ref:\n",
+ " zip_ref.extractall(data_dir)\n",
+ " os.rename(join(data_dir, \"data.zarr\"), spatialdata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "PKri",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Configure Vitessce\n",
+ "\n",
+ "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(\n",
+ " schema_version=\"1.0.18\",\n",
+ " name='Visium SpatialData Demo (visium_associated_xenium_io)',\n",
+ ")\n",
+ "# Add data to the configuration:\n",
+ "wrapper = SpatialDataWrapper(\n",
+ " sdata_path=spatialdata_filepath,\n",
+ " # The following paths are relative to the root of the SpatialData zarr store on-disk.\n",
+ " image_path=\"images/CytAssist_FFPE_Human_Breast_Cancer_full_image\",\n",
+ " table_path=\"tables/table\",\n",
+ " obs_feature_matrix_path=\"tables/table/X\",\n",
+ " obs_spots_path=\"shapes/CytAssist_FFPE_Human_Breast_Cancer\",\n",
+ " region=\"CytAssist_FFPE_Human_Breast_Cancer\",\n",
+ " coordinate_system=\"global\",\n",
+ " coordination_values={\n",
+ " # The following tells Vitessce to consider each observation as a \"spot\"\n",
+ " \"obsType\": \"spot\",\n",
+ " }\n",
+ ")\n",
+ "dataset = vc.add_dataset(name='Breast Cancer Visium').add_object(wrapper)\n",
+ "\n",
+ "# Add views (visualizations) to the configuration:\n",
+ "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
+ "feature_list = vc.add_view(vt.FEATURE_LIST, dataset=dataset)\n",
+ "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
+ "vc.link_views_by_dict([spatial, layer_controller], {\n",
+ " 'imageLayer': CL([{\n",
+ " 'photometricInterpretation': 'RGB',\n",
+ " }]),\n",
+ "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
+ "obs_sets = vc.add_view(vt.OBS_SETS, dataset=dataset)\n",
+ "vc.link_views([spatial, layer_controller, feature_list, obs_sets], ['obsType'], [wrapper.obs_type_label])\n",
+ "\n",
+ "# Layout the views\n",
+ "vc.layout(spatial | (feature_list / layer_controller / obs_sets));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### Render the widget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
}
- },
- "source": [
- "# Visualization of a SpatialData object"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Import dependencies"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "vblA",
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join, isfile, isdir\n",
- "from urllib.request import urlretrieve\n",
- "import zipfile\n",
- "\n",
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " ViewType as vt,\n",
- " CoordinationType as ct,\n",
- " CoordinationLevel as CL,\n",
- " SpatialDataWrapper,\n",
- " get_initial_coordination_scope_prefix\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "bkHC",
- "metadata": {},
- "outputs": [],
- "source": [
- "data_dir = \"data\"\n",
- "zip_filepath = join(data_dir, \"visium.spatialdata.zarr.zip\")\n",
- "spatialdata_filepath = join(data_dir, \"visium.spatialdata.zarr\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "lEQa",
- "metadata": {},
- "outputs": [],
- "source": [
- "if not isdir(spatialdata_filepath):\n",
- " if not isfile(zip_filepath):\n",
- " os.makedirs(data_dir, exist_ok=True)\n",
- " urlretrieve('https://s3.embl.de/spatialdata/spatialdata-sandbox/visium_associated_xenium_io.zip', zip_filepath)\n",
- " with zipfile.ZipFile(zip_filepath,\"r\") as zip_ref:\n",
- " zip_ref.extractall(data_dir)\n",
- " os.rename(join(data_dir, \"data.zarr\"), spatialdata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "PKri",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "## Configure Vitessce\n",
- "\n",
- "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(\n",
- " schema_version=\"1.0.18\",\n",
- " name='Visium SpatialData Demo (visium_associated_xenium_io)',\n",
- ")\n",
- "# Add data to the configuration:\n",
- "wrapper = SpatialDataWrapper(\n",
- " sdata_path=spatialdata_filepath,\n",
- " # The following paths are relative to the root of the SpatialData zarr store on-disk.\n",
- " image_path=\"images/CytAssist_FFPE_Human_Breast_Cancer_full_image\",\n",
- " table_path=\"tables/table\",\n",
- " obs_feature_matrix_path=\"tables/table/X\",\n",
- " obs_spots_path=\"shapes/CytAssist_FFPE_Human_Breast_Cancer\",\n",
- " region=\"CytAssist_FFPE_Human_Breast_Cancer\",\n",
- " coordinate_system=\"global\",\n",
- " coordination_values={\n",
- " # The following tells Vitessce to consider each observation as a \"spot\"\n",
- " \"obsType\": \"spot\",\n",
- " }\n",
- ")\n",
- "dataset = vc.add_dataset(name='Breast Cancer Visium').add_object(wrapper)\n",
- "\n",
- "# Add views (visualizations) to the configuration:\n",
- "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
- "feature_list = vc.add_view(vt.FEATURE_LIST, dataset=dataset)\n",
- "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " 'imageLayer': CL([{\n",
- " 'photometricInterpretation': 'RGB',\n",
- " }]),\n",
- "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
- "obs_sets = vc.add_view(vt.OBS_SETS, dataset=dataset)\n",
- "vc.link_views([spatial, layer_controller, feature_list, obs_sets], ['obsType'], [wrapper.obs_type_label])\n",
- "\n",
- "# Layout the views\n",
- "vc.layout(spatial | (feature_list / layer_controller / obs_sets));"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "SFPL",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "### Render the widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "BYtC",
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "RGSE",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/spatial_data_blobs.ipynb b/docs/notebooks/__ipynb__/spatial_data_blobs.ipynb
index 83d023ea..f80fd43d 100644
--- a/docs/notebooks/__ipynb__/spatial_data_blobs.ipynb
+++ b/docs/notebooks/__ipynb__/spatial_data_blobs.ipynb
@@ -1,212 +1,220 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of a SpatialData object, blobs example"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Import dependencies"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import spatialdata\n",
+ "from os.path import join"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "sdata = spatialdata.datasets.blobs()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "spatialdata_filepath = join(\"data\", \"blobs.spatialdata.zarr\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "sdata.write(spatialdata_filepath, overwrite=True)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " ViewType as vt,\n",
+ " CoordinationType as ct,\n",
+ " CoordinationLevel as CL,\n",
+ " SpatialDataWrapper,\n",
+ " get_initial_coordination_scope_prefix\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Configure Vitessce\n",
+ "\n",
+ "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(\n",
+ " schema_version=\"1.0.18\",\n",
+ " name='Visium SpatialData Demo (blobs)',\n",
+ ")\n",
+ "# Add data to the configuration:\n",
+ "wrapper = SpatialDataWrapper(\n",
+ " sdata_store=spatialdata_filepath,\n",
+ " # The following paths are relative to the root of the SpatialData zarr store on-disk.\n",
+ " image_path=\"images/blobs_image\",\n",
+ " obs_segmentations_path=\"labels/blobs_labels\",\n",
+ " coordinate_system=\"global\",\n",
+ " coordination_values={\n",
+ " \"obsType\": \"blob\",\n",
+ " \"fileUid\": \"my_unique_id\"\n",
+ " }\n",
+ ")\n",
+ "dataset = vc.add_dataset(name='Blobs').add_object(wrapper)\n",
+ "\n",
+ "# Add views (visualizations) to the configuration:\n",
+ "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
+ "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
+ "\n",
+ "vc.link_views_by_dict([spatial, layer_controller], {\n",
+ " 'imageLayer': CL([{\n",
+ " \"fileUid\": \"my_unique_id\",\n",
+ " 'photometricInterpretation': 'BlackIsZero',\n",
+ " 'spatialLayerOpacity': 0.9,\n",
+ " 'imageChannel': CL([\n",
+ " {\n",
+ " \"spatialTargetC\": 0,\n",
+ " \"spatialChannelColor\": [255, 0, 0],\n",
+ " \"spatialChannelOpacity\": 1.0\n",
+ " },\n",
+ " {\n",
+ " \"spatialTargetC\": 1,\n",
+ " \"spatialChannelColor\": [0, 255, 0],\n",
+ " \"spatialChannelOpacity\": 1.0\n",
+ " },\n",
+ " {\n",
+ " \"spatialTargetC\": 2,\n",
+ " \"spatialChannelColor\": [0, 0, 255],\n",
+ " \"spatialChannelOpacity\": 1.0\n",
+ " }\n",
+ " ])\n",
+ " }]),\n",
+ "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
+ "\n",
+ "vc.link_views_by_dict([spatial, layer_controller], {\n",
+ " 'segmentationLayer': CL([{\n",
+ " \"fileUid\": \"my_unique_id\",\n",
+ " 'segmentationChannel': CL([{\n",
+ " 'spatialChannelVisible': True,\n",
+ " 'obsType': 'blob',\n",
+ " }]),\n",
+ " }]),\n",
+ "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"obsSegmentations\"))\n",
+ "\n",
+ "# Layout the views\n",
+ "vc.layout(spatial | layer_controller);"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "RGSE",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### Render the widget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Kclp",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
}
- },
- "source": [
- "# Visualization of a SpatialData object, blobs example"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Import dependencies"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "vblA",
- "metadata": {},
- "outputs": [],
- "source": [
- "import spatialdata\n",
- "from os.path import join"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "bkHC",
- "metadata": {},
- "outputs": [],
- "source": [
- "sdata = spatialdata.datasets.blobs()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "lEQa",
- "metadata": {},
- "outputs": [],
- "source": [
- "spatialdata_filepath = join(\"data\", \"blobs.spatialdata.zarr\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "PKri",
- "metadata": {},
- "outputs": [],
- "source": [
- "sdata.write(spatialdata_filepath, overwrite=True)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " ViewType as vt,\n",
- " CoordinationType as ct,\n",
- " CoordinationLevel as CL,\n",
- " SpatialDataWrapper,\n",
- " get_initial_coordination_scope_prefix\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "SFPL",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Configure Vitessce\n",
- "\n",
- "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "BYtC",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(\n",
- " schema_version=\"1.0.18\",\n",
- " name='Visium SpatialData Demo (blobs)',\n",
- ")\n",
- "# Add data to the configuration:\n",
- "wrapper = SpatialDataWrapper(\n",
- " sdata_store=spatialdata_filepath,\n",
- " # The following paths are relative to the root of the SpatialData zarr store on-disk.\n",
- " image_path=\"images/blobs_image\",\n",
- " obs_segmentations_path=\"labels/blobs_labels\",\n",
- " coordinate_system=\"global\",\n",
- " coordination_values={\n",
- " \"obsType\": \"blob\",\n",
- " \"fileUid\": \"my_unique_id\"\n",
- " }\n",
- ")\n",
- "dataset = vc.add_dataset(name='Blobs').add_object(wrapper)\n",
- "\n",
- "# Add views (visualizations) to the configuration:\n",
- "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
- "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
- "\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " 'imageLayer': CL([{\n",
- " \"fileUid\": \"my_unique_id\",\n",
- " 'photometricInterpretation': 'BlackIsZero',\n",
- " 'spatialLayerOpacity': 0.9,\n",
- " 'imageChannel': CL([\n",
- " {\n",
- " \"spatialTargetC\": 0,\n",
- " \"spatialChannelColor\": [255, 0, 0],\n",
- " \"spatialChannelOpacity\": 1.0\n",
- " },\n",
- " {\n",
- " \"spatialTargetC\": 1,\n",
- " \"spatialChannelColor\": [0, 255, 0],\n",
- " \"spatialChannelOpacity\": 1.0\n",
- " },\n",
- " {\n",
- " \"spatialTargetC\": 2,\n",
- " \"spatialChannelColor\": [0, 0, 255],\n",
- " \"spatialChannelOpacity\": 1.0\n",
- " }\n",
- " ])\n",
- " }]),\n",
- "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
- "\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " 'segmentationLayer': CL([{\n",
- " \"fileUid\": \"my_unique_id\",\n",
- " 'segmentationChannel': CL([{\n",
- " 'spatialChannelVisible': True,\n",
- " 'obsType': 'blob',\n",
- " }]),\n",
- " }]),\n",
- "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"obsSegmentations\"))\n",
- "\n",
- "# Layout the views\n",
- "vc.layout(spatial | layer_controller);"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "RGSE",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "### Render the widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Kclp",
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "emfo",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/spatial_data_kpmp_vis.ipynb b/docs/notebooks/__ipynb__/spatial_data_kpmp_vis.ipynb
index bef7be79..a4f871b4 100644
--- a/docs/notebooks/__ipynb__/spatial_data_kpmp_vis.ipynb
+++ b/docs/notebooks/__ipynb__/spatial_data_kpmp_vis.ipynb
@@ -1,473 +1,481 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of a SpatialData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Import dependencies"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Reference: https://github.com/vitessce/vitessce/blob/main/examples/configs/src/view-configs/spatial-beta/kpmp.js"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " ViewType as vt,\n",
+ " CoordinationType as ct,\n",
+ " CoordinationLevel as CL,\n",
+ " SpatialDataWrapper,\n",
+ " AnnDataWrapper,\n",
+ " ImageOmeTiffWrapper,\n",
+ " ImageOmeZarrWrapper,\n",
+ " ObsSegmentationsOmeZarrWrapper,\n",
+ " get_initial_coordination_scope_prefix,\n",
+ " hconcat,\n",
+ " vconcat,\n",
+ ")\n",
+ "from os.path import join"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Configure Vitessce"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "sdata_url = \"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/sdata.zarr\""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Create a VitessceConfig instance.\n",
+ "vc = VitessceConfig(schema_version=\"1.0.18\", name=\"SpatialData\")\n",
+ "\n",
+ "t_obstype = \"Tubule\"\n",
+ "a_obstype = \"Artery\"\n",
+ "ci_obstype = \"Cortical Interstitium\"\n",
+ "gsg_obstype = \"G. S. Glomerulus\"\n",
+ "ngsg_obstype = \"Non-G. S. Glomerulus\"\n",
+ "ifta_obstype = \"Interstitial Fibrosis and Tubular Atrophy\"\n",
+ "ptc_obstype = \"Peritubular Capillaries\"\n",
+ "\n",
+ "# Add a new dataset to the Vitessce configuration,\n",
+ "# then add the wrapper class instance to this dataset.\n",
+ "dataset = vc.add_dataset(name='KPMP').add_object(\n",
+ " SpatialDataWrapper(\n",
+ " sdata_url=sdata_url,\n",
+ " image_path=\"images/image\",\n",
+ " coordinate_system=\"global\",\n",
+ " )\n",
+ ").add_object(\n",
+ " SpatialDataWrapper(\n",
+ " sdata_url=sdata_url,\n",
+ " table_path=\"tables/table_tubules\",\n",
+ " obs_segmentations_path=\"labels/labels_tubules\",\n",
+ " obs_feature_matrix_path=\"tables/table_tubules/X\",\n",
+ " coordinate_system=\"global\",\n",
+ " coordination_values={\n",
+ " \"fileUid\": \"labels_tubules\",\n",
+ " \"obsType\": t_obstype,\n",
+ " \"featureType\": 'feature',\n",
+ " \"featureValueType\": 'value',\n",
+ " }\n",
+ " )\n",
+ ").add_object(\n",
+ " SpatialDataWrapper(\n",
+ " sdata_url=sdata_url,\n",
+ " obs_segmentations_path=\"labels/labels_arteries_arterioles\",\n",
+ " coordinate_system=\"global\",\n",
+ " coordination_values={\n",
+ " \"fileUid\": \"labels_arteries_arterioles\",\n",
+ " \"obsType\": a_obstype,\n",
+ " \"featureType\": 'feature',\n",
+ " \"featureValueType\": 'value',\n",
+ " }\n",
+ " )\n",
+ ").add_object(\n",
+ " SpatialDataWrapper(\n",
+ " sdata_url=sdata_url,\n",
+ " table_path=\"tables/table_cortical_interstitia\",\n",
+ " obs_segmentations_path=\"labels/labels_cortical_interstitia\",\n",
+ " obs_feature_matrix_path=\"tables/table_cortical_interstitia/X\",\n",
+ " coordinate_system=\"global\",\n",
+ " coordination_values={\n",
+ " \"fileUid\": \"labels_cortical_interstitia\",\n",
+ " \"obsType\": ci_obstype,\n",
+ " \"featureType\": 'feature',\n",
+ " \"featureValueType\": 'value',\n",
+ " }\n",
+ " )\n",
+ ").add_object(\n",
+ " SpatialDataWrapper(\n",
+ " sdata_url=sdata_url,\n",
+ " table_path=\"tables/table_globally_sclerotic_glomeruli\",\n",
+ " obs_segmentations_path=\"labels/labels_globally_sclerotic_glomeruli\",\n",
+ " obs_feature_matrix_path=\"tables/table_globally_sclerotic_glomeruli/X\",\n",
+ " coordinate_system=\"global\",\n",
+ " coordination_values={\n",
+ " \"fileUid\": \"labels_globally_sclerotic_glomeruli\",\n",
+ " \"obsType\": gsg_obstype,\n",
+ " \"featureType\": 'feature',\n",
+ " \"featureValueType\": 'value',\n",
+ " }\n",
+ " )\n",
+ ").add_object(\n",
+ " SpatialDataWrapper(\n",
+ " sdata_url=sdata_url,\n",
+ " table_path=\"tables/table_non_globally_sclerotic_glomeruli\",\n",
+ " obs_segmentations_path=\"labels/labels_non_globally_sclerotic_glomeruli\",\n",
+ " obs_feature_matrix_path=\"tables/table_non_globally_sclerotic_glomeruli/X\",\n",
+ " coordinate_system=\"global\",\n",
+ " coordination_values={\n",
+ " \"fileUid\": \"labels_non_globally_sclerotic_glomeruli\",\n",
+ " \"obsType\": ngsg_obstype,\n",
+ " \"featureType\": 'feature',\n",
+ " \"featureValueType\": 'value',\n",
+ " }\n",
+ " )\n",
+ ").add_object(\n",
+ " SpatialDataWrapper(\n",
+ " sdata_url=sdata_url,\n",
+ " table_path=\"tables/table_interstitialfibrosis_and_tubular_atrophy\",\n",
+ " obs_segmentations_path=\"labels/labels_interstitialfibrosis_and_tubular_atrophy\",\n",
+ " coordinate_system=\"global\",\n",
+ " coordination_values={\n",
+ " \"fileUid\": \"labels_interstitialfibrosis_and_tubular_atrophy\",\n",
+ " \"obsType\": ifta_obstype,\n",
+ " \"featureType\": 'feature',\n",
+ " \"featureValueType\": 'value',\n",
+ " }\n",
+ " )\n",
+ ").add_object(\n",
+ " SpatialDataWrapper(\n",
+ " sdata_url=sdata_url,\n",
+ " table_path=\"tables/table_peritubular_capillaries\",\n",
+ " obs_segmentations_path=\"labels/labels_peritubular_capillaries\",\n",
+ " obs_feature_matrix_path=\"tables/table_peritubular_capillaries/X\",\n",
+ " obs_set_paths=[\n",
+ " \"tables/table_peritubular_capillaries/obs/cortex_ifta_set\",\n",
+ " \"tables/table_peritubular_capillaries/obs/cortex_set\",\n",
+ " \"tables/table_peritubular_capillaries/obs/ifta_set\",\n",
+ " [\"tables/table_peritubular_capillaries/obs/cortex_set\", \"tables/table_peritubular_capillaries/obs/ifta_set\"],\n",
+ " ],\n",
+ " obs_set_names=[\n",
+ " \"Cortex and IFTA membership\",\n",
+ " \"Cortex membership\",\n",
+ " \"IFTA membership\",\n",
+ " \"Cortex and IFTA hierarchy\",\n",
+ " ],\n",
+ " coordinate_system=\"global\",\n",
+ " coordination_values={\n",
+ " \"fileUid\": \"labels_peritubular_capillaries\",\n",
+ " \"obsType\": ptc_obstype,\n",
+ " \"featureType\": 'feature',\n",
+ " \"featureValueType\": 'value',\n",
+ " }\n",
+ " )\n",
+ ")\n",
+ "\n",
+ "# Add views (visualizations) to the configuration.\n",
+ "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
+ "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
+ "# Tubules\n",
+ "tubules_feature_list = vc.add_view(\"featureList\", dataset=dataset).set_props(title=\"Tubules\")\n",
+ "tubules_histogram = vc.add_view(\"featureValueHistogram\", dataset=dataset)\n",
+ "# Peritubular capillaries\n",
+ "pt_feature_list = vc.add_view(\"featureList\", dataset=dataset).set_props(title=\"Peritubular Capillaries\")\n",
+ "pt_histogram = vc.add_view(\"featureValueHistogram\", dataset=dataset)\n",
+ "# GSG\n",
+ "gsg_feature_list = vc.add_view(\"featureList\", dataset=dataset).set_props(title=\"Globally Sclerotic Glomeruli\")\n",
+ "gsg_histogram = vc.add_view(\"featureValueHistogram\", dataset=dataset)\n",
+ "# NGSG\n",
+ "ngsg_feature_list = vc.add_view(\"featureList\", dataset=dataset).set_props(title=\"Non-Globally Sclerotic Glomeruli\")\n",
+ "ngsg_histogram = vc.add_view(\"featureValueHistogram\", dataset=dataset)\n",
+ "\n",
+ "# Add obsSets, obsSetSizes, and violin plot views for PTC sets+areas/aspectRatio\n",
+ "pt_sets = vc.add_view(\"obsSets\", dataset=dataset)\n",
+ "pt_bar_plot = vc.add_view(\"obsSetSizes\", dataset=dataset)\n",
+ "pt_violin_plot = vc.add_view(\"obsSetFeatureValueDistribution\", dataset=dataset).set_props(jitter=True)\n",
+ "\n",
+ "\n",
+ "# Coordination of views.\n",
+ "[ft_scope, fvt_scope] = vc.add_coordination(\"featureType\", \"featureValueType\")\n",
+ "ft_scope.set_value(\"feature\")\n",
+ "fvt_scope.set_value(\"value\")\n",
+ "\n",
+ "[t_ot_scope, t_fs_scope, t_oce_scope] = vc.add_coordination(\"obsType\", \"featureSelection\", \"obsColorEncoding\")\n",
+ "t_ot_scope.set_value(t_obstype)\n",
+ "t_oce_scope.set_value(\"spatialChannelColor\")\n",
+ "\n",
+ "[pt_ot_scope, pt_fs_scope, pt_oce_scope] = vc.add_coordination(\"obsType\", \"featureSelection\", \"obsColorEncoding\")\n",
+ "pt_ot_scope.set_value(ptc_obstype)\n",
+ "pt_fs_scope.set_value([\"Area\"])\n",
+ "pt_oce_scope.set_value(\"cellSetSelection\")\n",
+ "\n",
+ "\n",
+ "[gsg_ot_scope, gsg_fs_scope, gsg_oce_scope, gsg_fvcr_scope] = vc.add_coordination(\"obsType\", \"featureSelection\", \"obsColorEncoding\", \"featureValueColormapRange\")\n",
+ "gsg_ot_scope.set_value(gsg_obstype)\n",
+ "gsg_oce_scope.set_value(\"spatialChannelColor\")\n",
+ "gsg_fvcr_scope.set_value([(3077 - 2333) / (29911 - 2333), 1.0])\n",
+ "\n",
+ "[ngsg_ot_scope, ngsg_fs_scope, ngsg_oce_scope, ngsg_fvcr_scope] = vc.add_coordination(\"obsType\", \"featureSelection\", \"obsColorEncoding\", \"featureValueColormapRange\")\n",
+ "ngsg_ot_scope.set_value(ngsg_obstype)\n",
+ "ngsg_oce_scope.set_value(\"spatialChannelColor\")\n",
+ "ngsg_fvcr_scope.set_value([0.0, 1 - (59451 - 29911) / (59451 - 3077)])\n",
+ "\n",
+ "vc.link_views_by_dict([spatial, layer_controller], {\n",
+ " \"imageLayer\": CL([{\n",
+ " \"spatialLayerOpacity\": 0.1,\n",
+ " \"photometricInterpretation\": \"RGB\",\n",
+ " }]),\n",
+ "}, meta=True, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
+ "\n",
+ "vc.link_views_by_dict([spatial, layer_controller], {\n",
+ " \"segmentationLayer\": CL([\n",
+ " {\n",
+ " \"fileUid\": \"labels_tubules\",\n",
+ " \"segmentationChannel\": CL([{\n",
+ " \"spatialTargetC\": 0,\n",
+ " \"obsType\": t_ot_scope,\n",
+ " \"featureType\": ft_scope,\n",
+ " \"featureValueType\": fvt_scope,\n",
+ " \"featureSelection\": t_fs_scope,\n",
+ " \"spatialChannelVisible\": False,\n",
+ " \"spatialChannelColor\": [73, 155, 119],\n",
+ " \"spatialChannelOpacity\": 0.5,\n",
+ " \"obsColorEncoding\": t_oce_scope,\n",
+ " \"featureValueColormapRange\": [0, 1],\n",
+ " \"featureAggregationStrategy\": \"first\",\n",
+ " \"spatialSegmentationFilled\": True,\n",
+ " \"obsHighlight\": None,\n",
+ " }]),\n",
+ " },\n",
+ " {\n",
+ " \"fileUid\": \"labels_arteries_arterioles\",\n",
+ " \"segmentationChannel\": CL([{\n",
+ " \"spatialTargetC\": 0,\n",
+ " \"obsType\": \"Artery\",\n",
+ " \"featureType\": ft_scope,\n",
+ " \"featureValueType\": fvt_scope,\n",
+ " \"spatialChannelVisible\": False,\n",
+ " \"spatialChannelColor\": [237, 226, 107],\n",
+ " \"spatialChannelOpacity\": 0.5,\n",
+ " \"obsColorEncoding\": \"spatialChannelColor\",\n",
+ " \"featureValueColormapRange\": [0, 1],\n",
+ " \"featureAggregationStrategy\": \"first\",\n",
+ " \"spatialSegmentationFilled\": True,\n",
+ " \"obsHighlight\": None,\n",
+ " }]),\n",
+ " },\n",
+ " {\n",
+ " \"fileUid\": \"labels_cortical_interstitia\",\n",
+ " \"segmentationChannel\": CL([{\n",
+ " \"spatialTargetC\": 0,\n",
+ " \"obsType\": \"Cortical Interstitium\",\n",
+ " \"featureType\": ft_scope,\n",
+ " \"featureValueType\": fvt_scope,\n",
+ " \"spatialChannelVisible\": False,\n",
+ " \"spatialChannelColor\": [255, 255, 255],\n",
+ " \"spatialChannelOpacity\": 0.5,\n",
+ " \"obsColorEncoding\": \"spatialChannelColor\",\n",
+ " \"featureValueColormapRange\": [0, 1],\n",
+ " \"featureAggregationStrategy\": \"first\",\n",
+ " \"spatialSegmentationFilled\": True,\n",
+ " \"obsHighlight\": None,\n",
+ " }]),\n",
+ " },\n",
+ " {\n",
+ " \"fileUid\": \"labels_globally_sclerotic_glomeruli\",\n",
+ " \"segmentationChannel\": CL([{\n",
+ " \"spatialTargetC\": 0,\n",
+ " \"obsType\": gsg_ot_scope,\n",
+ " \"featureType\": ft_scope,\n",
+ " \"featureValueType\": fvt_scope,\n",
+ " \"featureSelection\": gsg_fs_scope,\n",
+ " \"spatialChannelVisible\": False,\n",
+ " \"spatialChannelColor\": [52, 113, 171],\n",
+ " \"spatialChannelOpacity\": 0.5,\n",
+ " \"obsColorEncoding\": gsg_oce_scope,\n",
+ " \"featureValueColormapRange\": gsg_fvcr_scope,\n",
+ " \"featureAggregationStrategy\": \"first\",\n",
+ " \"spatialSegmentationFilled\": True,\n",
+ " \"obsHighlight\": None,\n",
+ " }]),\n",
+ " },\n",
+ " {\n",
+ " \"fileUid\": \"labels_non_globally_sclerotic_glomeruli\",\n",
+ " \"segmentationChannel\": CL([{\n",
+ " \"spatialTargetC\": 0,\n",
+ " \"obsType\": ngsg_ot_scope,\n",
+ " \"featureType\": ft_scope,\n",
+ " \"featureValueType\": fvt_scope,\n",
+ " \"featureSelection\": ngsg_fs_scope,\n",
+ " \"spatialChannelVisible\": False,\n",
+ " \"spatialChannelColor\": [114, 179, 226],\n",
+ " \"spatialChannelOpacity\": 0.5,\n",
+ " \"obsColorEncoding\": ngsg_oce_scope,\n",
+ " \"featureValueColormapRange\": ngsg_fvcr_scope,\n",
+ " \"featureAggregationStrategy\": \"first\",\n",
+ " \"spatialSegmentationFilled\": True,\n",
+ " \"obsHighlight\": None,\n",
+ " }]),\n",
+ " },\n",
+ " {\n",
+ " \"fileUid\": \"labels_interstitialfibrosis_and_tubular_atrophy\",\n",
+ " \"segmentationChannel\": CL([{\n",
+ " \"spatialTargetC\": 0,\n",
+ " \"obsType\": \"Interstitial Fibrosis and Tubular Atrophy\",\n",
+ " \"featureType\": ft_scope,\n",
+ " \"featureValueType\": fvt_scope,\n",
+ " \"spatialChannelVisible\": True,\n",
+ " \"spatialChannelColor\": [218, 161, 66],\n",
+ " \"spatialChannelOpacity\": 1.0,\n",
+ " \"obsColorEncoding\": \"spatialChannelColor\",\n",
+ " \"featureValueColormapRange\": [0, 1],\n",
+ " \"featureAggregationStrategy\": \"first\",\n",
+ " \"spatialSegmentationFilled\": False,\n",
+ " \"obsHighlight\": None,\n",
+ " }]),\n",
+ " },\n",
+ " {\n",
+ " \"fileUid\": \"labels_peritubular_capillaries\",\n",
+ " \"segmentationChannel\": CL([{\n",
+ " \"spatialTargetC\": 0,\n",
+ " \"obsType\": pt_ot_scope,\n",
+ " \"featureType\": ft_scope,\n",
+ " \"featureValueType\": fvt_scope,\n",
+ " \"featureSelection\": pt_fs_scope,\n",
+ " \"spatialChannelVisible\": True,\n",
+ " \"spatialChannelColor\": [197, 101, 47],\n",
+ " \"spatialChannelOpacity\": 1.0,\n",
+ " \"obsColorEncoding\": pt_oce_scope,\n",
+ " \"featureValueColormapRange\": [0, 0.5],\n",
+ " \"featureAggregationStrategy\": \"first\",\n",
+ " \"spatialSegmentationFilled\": True,\n",
+ " \"obsHighlight\": None,\n",
+ " }]),\n",
+ " }\n",
+ " ]),\n",
+ "}, meta=True, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"obsSegmentations\"))\n",
+ "\n",
+ "tubules_feature_list.use_coordination(t_ot_scope, ft_scope, fvt_scope, t_fs_scope, t_oce_scope)\n",
+ "tubules_histogram.use_coordination(t_ot_scope, ft_scope, fvt_scope, t_fs_scope, t_oce_scope)\n",
+ "\n",
+ "pt_feature_list.use_coordination(pt_ot_scope, ft_scope, fvt_scope, pt_fs_scope, pt_oce_scope)\n",
+ "pt_histogram.use_coordination(pt_ot_scope, ft_scope, fvt_scope, pt_fs_scope, pt_oce_scope)\n",
+ "\n",
+ "pt_sets.use_coordination(pt_ot_scope, ft_scope, fvt_scope, pt_fs_scope, pt_oce_scope)\n",
+ "pt_bar_plot.use_coordination(pt_ot_scope, ft_scope, fvt_scope, pt_fs_scope, pt_oce_scope)\n",
+ "pt_violin_plot.use_coordination(pt_ot_scope, ft_scope, fvt_scope, pt_fs_scope, pt_oce_scope)\n",
+ "\n",
+ "\n",
+ "gsg_feature_list.use_coordination(gsg_ot_scope, ft_scope, fvt_scope, gsg_fs_scope, gsg_oce_scope, gsg_fvcr_scope)\n",
+ "gsg_histogram.use_coordination(gsg_ot_scope, ft_scope, fvt_scope, gsg_fs_scope, gsg_oce_scope, gsg_fvcr_scope)\n",
+ "\n",
+ "ngsg_feature_list.use_coordination(ngsg_ot_scope, ft_scope, fvt_scope, ngsg_fs_scope, ngsg_oce_scope, ngsg_fvcr_scope)\n",
+ "ngsg_histogram.use_coordination(ngsg_ot_scope, ft_scope, fvt_scope, ngsg_fs_scope, ngsg_oce_scope, ngsg_fvcr_scope)\n",
+ "\n",
+ "\n",
+ "# Layout the views in a grid arrangement.\n",
+ "vc.layout(vconcat(\n",
+ " hconcat(spatial, layer_controller, split=[3, 1]),\n",
+ " hconcat(\n",
+ " (tubules_feature_list / tubules_histogram),\n",
+ " (pt_feature_list / pt_histogram),\n",
+ " (gsg_feature_list / gsg_histogram),\n",
+ " (ngsg_feature_list / ngsg_histogram)\n",
+ " ),\n",
+ " hconcat(pt_sets, pt_bar_plot, pt_violin_plot)\n",
+ "));"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget(height=1000)\n",
+ "vw"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "#import json\n",
+ "#print(json.dumps(vc.to_dict(), indent=2))"
+ ]
}
- },
- "source": [
- "# Visualization of a SpatialData object"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Import dependencies"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "vblA",
- "metadata": {},
- "outputs": [],
- "source": [
- "# Reference: https://github.com/vitessce/vitessce/blob/main/examples/configs/src/view-configs/spatial-beta/kpmp.js"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "bkHC",
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " ViewType as vt,\n",
- " CoordinationType as ct,\n",
- " CoordinationLevel as CL,\n",
- " SpatialDataWrapper,\n",
- " AnnDataWrapper,\n",
- " ImageOmeTiffWrapper,\n",
- " ImageOmeZarrWrapper,\n",
- " ObsSegmentationsOmeZarrWrapper,\n",
- " get_initial_coordination_scope_prefix,\n",
- " hconcat,\n",
- " vconcat,\n",
- ")\n",
- "from os.path import join"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "lEQa",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "## Configure Vitessce"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "PKri",
- "metadata": {},
- "outputs": [],
- "source": [
- "sdata_url = \"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/sdata.zarr\""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "# Create a VitessceConfig instance.\n",
- "vc = VitessceConfig(schema_version=\"1.0.18\", name=\"SpatialData\")\n",
- "\n",
- "t_obstype = \"Tubule\"\n",
- "a_obstype = \"Artery\"\n",
- "ci_obstype = \"Cortical Interstitium\"\n",
- "gsg_obstype = \"G. S. Glomerulus\"\n",
- "ngsg_obstype = \"Non-G. S. Glomerulus\"\n",
- "ifta_obstype = \"Interstitial Fibrosis and Tubular Atrophy\"\n",
- "ptc_obstype = \"Peritubular Capillaries\"\n",
- "\n",
- "# Add a new dataset to the Vitessce configuration,\n",
- "# then add the wrapper class instance to this dataset.\n",
- "dataset = vc.add_dataset(name='KPMP').add_object(\n",
- " SpatialDataWrapper(\n",
- " sdata_url=sdata_url,\n",
- " image_path=\"images/image\",\n",
- " coordinate_system=\"global\",\n",
- " )\n",
- ").add_object(\n",
- " SpatialDataWrapper(\n",
- " sdata_url=sdata_url,\n",
- " table_path=\"tables/table_tubules\",\n",
- " obs_segmentations_path=\"labels/labels_tubules\",\n",
- " obs_feature_matrix_path=\"tables/table_tubules/X\",\n",
- " coordinate_system=\"global\",\n",
- " coordination_values={\n",
- " \"fileUid\": \"labels_tubules\",\n",
- " \"obsType\": t_obstype,\n",
- " \"featureType\": 'feature',\n",
- " \"featureValueType\": 'value',\n",
- " }\n",
- " )\n",
- ").add_object(\n",
- " SpatialDataWrapper(\n",
- " sdata_url=sdata_url,\n",
- " obs_segmentations_path=\"labels/labels_arteries_arterioles\",\n",
- " coordinate_system=\"global\",\n",
- " coordination_values={\n",
- " \"fileUid\": \"labels_arteries_arterioles\",\n",
- " \"obsType\": a_obstype,\n",
- " \"featureType\": 'feature',\n",
- " \"featureValueType\": 'value',\n",
- " }\n",
- " )\n",
- ").add_object(\n",
- " SpatialDataWrapper(\n",
- " sdata_url=sdata_url,\n",
- " table_path=\"tables/table_cortical_interstitia\",\n",
- " obs_segmentations_path=\"labels/labels_cortical_interstitia\",\n",
- " obs_feature_matrix_path=\"tables/table_cortical_interstitia/X\",\n",
- " coordinate_system=\"global\",\n",
- " coordination_values={\n",
- " \"fileUid\": \"labels_cortical_interstitia\",\n",
- " \"obsType\": ci_obstype,\n",
- " \"featureType\": 'feature',\n",
- " \"featureValueType\": 'value',\n",
- " }\n",
- " )\n",
- ").add_object(\n",
- " SpatialDataWrapper(\n",
- " sdata_url=sdata_url,\n",
- " table_path=\"tables/table_globally_sclerotic_glomeruli\",\n",
- " obs_segmentations_path=\"labels/labels_globally_sclerotic_glomeruli\",\n",
- " obs_feature_matrix_path=\"tables/table_globally_sclerotic_glomeruli/X\",\n",
- " coordinate_system=\"global\",\n",
- " coordination_values={\n",
- " \"fileUid\": \"labels_globally_sclerotic_glomeruli\",\n",
- " \"obsType\": gsg_obstype,\n",
- " \"featureType\": 'feature',\n",
- " \"featureValueType\": 'value',\n",
- " }\n",
- " )\n",
- ").add_object(\n",
- " SpatialDataWrapper(\n",
- " sdata_url=sdata_url,\n",
- " table_path=\"tables/table_non_globally_sclerotic_glomeruli\",\n",
- " obs_segmentations_path=\"labels/labels_non_globally_sclerotic_glomeruli\",\n",
- " obs_feature_matrix_path=\"tables/table_non_globally_sclerotic_glomeruli/X\",\n",
- " coordinate_system=\"global\",\n",
- " coordination_values={\n",
- " \"fileUid\": \"labels_non_globally_sclerotic_glomeruli\",\n",
- " \"obsType\": ngsg_obstype,\n",
- " \"featureType\": 'feature',\n",
- " \"featureValueType\": 'value',\n",
- " }\n",
- " )\n",
- ").add_object(\n",
- " SpatialDataWrapper(\n",
- " sdata_url=sdata_url,\n",
- " table_path=\"tables/table_interstitialfibrosis_and_tubular_atrophy\",\n",
- " obs_segmentations_path=\"labels/labels_interstitialfibrosis_and_tubular_atrophy\",\n",
- " coordinate_system=\"global\",\n",
- " coordination_values={\n",
- " \"fileUid\": \"labels_interstitialfibrosis_and_tubular_atrophy\",\n",
- " \"obsType\": ifta_obstype,\n",
- " \"featureType\": 'feature',\n",
- " \"featureValueType\": 'value',\n",
- " }\n",
- " )\n",
- ").add_object(\n",
- " SpatialDataWrapper(\n",
- " sdata_url=sdata_url,\n",
- " table_path=\"tables/table_peritubular_capillaries\",\n",
- " obs_segmentations_path=\"labels/labels_peritubular_capillaries\",\n",
- " obs_feature_matrix_path=\"tables/table_peritubular_capillaries/X\",\n",
- " obs_set_paths=[\n",
- " \"tables/table_peritubular_capillaries/obs/cortex_ifta_set\",\n",
- " \"tables/table_peritubular_capillaries/obs/cortex_set\",\n",
- " \"tables/table_peritubular_capillaries/obs/ifta_set\",\n",
- " [\"tables/table_peritubular_capillaries/obs/cortex_set\", \"tables/table_peritubular_capillaries/obs/ifta_set\"],\n",
- " ],\n",
- " obs_set_names=[\n",
- " \"Cortex and IFTA membership\",\n",
- " \"Cortex membership\",\n",
- " \"IFTA membership\",\n",
- " \"Cortex and IFTA hierarchy\",\n",
- " ],\n",
- " coordinate_system=\"global\",\n",
- " coordination_values={\n",
- " \"fileUid\": \"labels_peritubular_capillaries\",\n",
- " \"obsType\": ptc_obstype,\n",
- " \"featureType\": 'feature',\n",
- " \"featureValueType\": 'value',\n",
- " }\n",
- " )\n",
- ")\n",
- "\n",
- "# Add views (visualizations) to the configuration.\n",
- "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
- "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
- "# Tubules\n",
- "tubules_feature_list = vc.add_view(\"featureList\", dataset=dataset).set_props(title=\"Tubules\")\n",
- "tubules_histogram = vc.add_view(\"featureValueHistogram\", dataset=dataset)\n",
- "# Peritubular capillaries\n",
- "pt_feature_list = vc.add_view(\"featureList\", dataset=dataset).set_props(title=\"Peritubular Capillaries\")\n",
- "pt_histogram = vc.add_view(\"featureValueHistogram\", dataset=dataset)\n",
- "# GSG\n",
- "gsg_feature_list = vc.add_view(\"featureList\", dataset=dataset).set_props(title=\"Globally Sclerotic Glomeruli\")\n",
- "gsg_histogram = vc.add_view(\"featureValueHistogram\", dataset=dataset)\n",
- "# NGSG\n",
- "ngsg_feature_list = vc.add_view(\"featureList\", dataset=dataset).set_props(title=\"Non-Globally Sclerotic Glomeruli\")\n",
- "ngsg_histogram = vc.add_view(\"featureValueHistogram\", dataset=dataset)\n",
- "\n",
- "# Add obsSets, obsSetSizes, and violin plot views for PTC sets+areas/aspectRatio\n",
- "pt_sets = vc.add_view(\"obsSets\", dataset=dataset)\n",
- "pt_bar_plot = vc.add_view(\"obsSetSizes\", dataset=dataset)\n",
- "pt_violin_plot = vc.add_view(\"obsSetFeatureValueDistribution\", dataset=dataset).set_props(jitter=True)\n",
- "\n",
- "\n",
- "# Coordination of views.\n",
- "[ft_scope, fvt_scope] = vc.add_coordination(\"featureType\", \"featureValueType\")\n",
- "ft_scope.set_value(\"feature\")\n",
- "fvt_scope.set_value(\"value\")\n",
- "\n",
- "[t_ot_scope, t_fs_scope, t_oce_scope] = vc.add_coordination(\"obsType\", \"featureSelection\", \"obsColorEncoding\")\n",
- "t_ot_scope.set_value(t_obstype)\n",
- "t_oce_scope.set_value(\"spatialChannelColor\")\n",
- "\n",
- "[pt_ot_scope, pt_fs_scope, pt_oce_scope] = vc.add_coordination(\"obsType\", \"featureSelection\", \"obsColorEncoding\")\n",
- "pt_ot_scope.set_value(ptc_obstype)\n",
- "pt_fs_scope.set_value([\"Area\"])\n",
- "pt_oce_scope.set_value(\"cellSetSelection\")\n",
- "\n",
- "\n",
- "[gsg_ot_scope, gsg_fs_scope, gsg_oce_scope, gsg_fvcr_scope] = vc.add_coordination(\"obsType\", \"featureSelection\", \"obsColorEncoding\", \"featureValueColormapRange\")\n",
- "gsg_ot_scope.set_value(gsg_obstype)\n",
- "gsg_oce_scope.set_value(\"spatialChannelColor\")\n",
- "gsg_fvcr_scope.set_value([(3077 - 2333) / (29911 - 2333), 1.0])\n",
- "\n",
- "[ngsg_ot_scope, ngsg_fs_scope, ngsg_oce_scope, ngsg_fvcr_scope] = vc.add_coordination(\"obsType\", \"featureSelection\", \"obsColorEncoding\", \"featureValueColormapRange\")\n",
- "ngsg_ot_scope.set_value(ngsg_obstype)\n",
- "ngsg_oce_scope.set_value(\"spatialChannelColor\")\n",
- "ngsg_fvcr_scope.set_value([0.0, 1 - (59451 - 29911) / (59451 - 3077)])\n",
- "\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " \"imageLayer\": CL([{\n",
- " \"spatialLayerOpacity\": 0.1,\n",
- " \"photometricInterpretation\": \"RGB\",\n",
- " }]),\n",
- "}, meta=True, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
- "\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " \"segmentationLayer\": CL([\n",
- " {\n",
- " \"fileUid\": \"labels_tubules\",\n",
- " \"segmentationChannel\": CL([{\n",
- " \"spatialTargetC\": 0,\n",
- " \"obsType\": t_ot_scope,\n",
- " \"featureType\": ft_scope,\n",
- " \"featureValueType\": fvt_scope,\n",
- " \"featureSelection\": t_fs_scope,\n",
- " \"spatialChannelVisible\": False,\n",
- " \"spatialChannelColor\": [73, 155, 119],\n",
- " \"spatialChannelOpacity\": 0.5,\n",
- " \"obsColorEncoding\": t_oce_scope,\n",
- " \"featureValueColormapRange\": [0, 1],\n",
- " \"featureAggregationStrategy\": \"first\",\n",
- " \"spatialSegmentationFilled\": True,\n",
- " \"obsHighlight\": None,\n",
- " }]),\n",
- " },\n",
- " {\n",
- " \"fileUid\": \"labels_arteries_arterioles\",\n",
- " \"segmentationChannel\": CL([{\n",
- " \"spatialTargetC\": 0,\n",
- " \"obsType\": \"Artery\",\n",
- " \"featureType\": ft_scope,\n",
- " \"featureValueType\": fvt_scope,\n",
- " \"spatialChannelVisible\": False,\n",
- " \"spatialChannelColor\": [237, 226, 107],\n",
- " \"spatialChannelOpacity\": 0.5,\n",
- " \"obsColorEncoding\": \"spatialChannelColor\",\n",
- " \"featureValueColormapRange\": [0, 1],\n",
- " \"featureAggregationStrategy\": \"first\",\n",
- " \"spatialSegmentationFilled\": True,\n",
- " \"obsHighlight\": None,\n",
- " }]),\n",
- " },\n",
- " {\n",
- " \"fileUid\": \"labels_cortical_interstitia\",\n",
- " \"segmentationChannel\": CL([{\n",
- " \"spatialTargetC\": 0,\n",
- " \"obsType\": \"Cortical Interstitium\",\n",
- " \"featureType\": ft_scope,\n",
- " \"featureValueType\": fvt_scope,\n",
- " \"spatialChannelVisible\": False,\n",
- " \"spatialChannelColor\": [255, 255, 255],\n",
- " \"spatialChannelOpacity\": 0.5,\n",
- " \"obsColorEncoding\": \"spatialChannelColor\",\n",
- " \"featureValueColormapRange\": [0, 1],\n",
- " \"featureAggregationStrategy\": \"first\",\n",
- " \"spatialSegmentationFilled\": True,\n",
- " \"obsHighlight\": None,\n",
- " }]),\n",
- " },\n",
- " {\n",
- " \"fileUid\": \"labels_globally_sclerotic_glomeruli\",\n",
- " \"segmentationChannel\": CL([{\n",
- " \"spatialTargetC\": 0,\n",
- " \"obsType\": gsg_ot_scope,\n",
- " \"featureType\": ft_scope,\n",
- " \"featureValueType\": fvt_scope,\n",
- " \"featureSelection\": gsg_fs_scope,\n",
- " \"spatialChannelVisible\": False,\n",
- " \"spatialChannelColor\": [52, 113, 171],\n",
- " \"spatialChannelOpacity\": 0.5,\n",
- " \"obsColorEncoding\": gsg_oce_scope,\n",
- " \"featureValueColormapRange\": gsg_fvcr_scope,\n",
- " \"featureAggregationStrategy\": \"first\",\n",
- " \"spatialSegmentationFilled\": True,\n",
- " \"obsHighlight\": None,\n",
- " }]),\n",
- " },\n",
- " {\n",
- " \"fileUid\": \"labels_non_globally_sclerotic_glomeruli\",\n",
- " \"segmentationChannel\": CL([{\n",
- " \"spatialTargetC\": 0,\n",
- " \"obsType\": ngsg_ot_scope,\n",
- " \"featureType\": ft_scope,\n",
- " \"featureValueType\": fvt_scope,\n",
- " \"featureSelection\": ngsg_fs_scope,\n",
- " \"spatialChannelVisible\": False,\n",
- " \"spatialChannelColor\": [114, 179, 226],\n",
- " \"spatialChannelOpacity\": 0.5,\n",
- " \"obsColorEncoding\": ngsg_oce_scope,\n",
- " \"featureValueColormapRange\": ngsg_fvcr_scope,\n",
- " \"featureAggregationStrategy\": \"first\",\n",
- " \"spatialSegmentationFilled\": True,\n",
- " \"obsHighlight\": None,\n",
- " }]),\n",
- " },\n",
- " {\n",
- " \"fileUid\": \"labels_interstitialfibrosis_and_tubular_atrophy\",\n",
- " \"segmentationChannel\": CL([{\n",
- " \"spatialTargetC\": 0,\n",
- " \"obsType\": \"Interstitial Fibrosis and Tubular Atrophy\",\n",
- " \"featureType\": ft_scope,\n",
- " \"featureValueType\": fvt_scope,\n",
- " \"spatialChannelVisible\": True,\n",
- " \"spatialChannelColor\": [218, 161, 66],\n",
- " \"spatialChannelOpacity\": 1.0,\n",
- " \"obsColorEncoding\": \"spatialChannelColor\",\n",
- " \"featureValueColormapRange\": [0, 1],\n",
- " \"featureAggregationStrategy\": \"first\",\n",
- " \"spatialSegmentationFilled\": False,\n",
- " \"obsHighlight\": None,\n",
- " }]),\n",
- " },\n",
- " {\n",
- " \"fileUid\": \"labels_peritubular_capillaries\",\n",
- " \"segmentationChannel\": CL([{\n",
- " \"spatialTargetC\": 0,\n",
- " \"obsType\": pt_ot_scope,\n",
- " \"featureType\": ft_scope,\n",
- " \"featureValueType\": fvt_scope,\n",
- " \"featureSelection\": pt_fs_scope,\n",
- " \"spatialChannelVisible\": True,\n",
- " \"spatialChannelColor\": [197, 101, 47],\n",
- " \"spatialChannelOpacity\": 1.0,\n",
- " \"obsColorEncoding\": pt_oce_scope,\n",
- " \"featureValueColormapRange\": [0, 0.5],\n",
- " \"featureAggregationStrategy\": \"first\",\n",
- " \"spatialSegmentationFilled\": True,\n",
- " \"obsHighlight\": None,\n",
- " }]),\n",
- " }\n",
- " ]),\n",
- "}, meta=True, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"obsSegmentations\"))\n",
- "\n",
- "tubules_feature_list.use_coordination(t_ot_scope, ft_scope, fvt_scope, t_fs_scope, t_oce_scope)\n",
- "tubules_histogram.use_coordination(t_ot_scope, ft_scope, fvt_scope, t_fs_scope, t_oce_scope)\n",
- "\n",
- "pt_feature_list.use_coordination(pt_ot_scope, ft_scope, fvt_scope, pt_fs_scope, pt_oce_scope)\n",
- "pt_histogram.use_coordination(pt_ot_scope, ft_scope, fvt_scope, pt_fs_scope, pt_oce_scope)\n",
- "\n",
- "pt_sets.use_coordination(pt_ot_scope, ft_scope, fvt_scope, pt_fs_scope, pt_oce_scope)\n",
- "pt_bar_plot.use_coordination(pt_ot_scope, ft_scope, fvt_scope, pt_fs_scope, pt_oce_scope)\n",
- "pt_violin_plot.use_coordination(pt_ot_scope, ft_scope, fvt_scope, pt_fs_scope, pt_oce_scope)\n",
- "\n",
- "\n",
- "gsg_feature_list.use_coordination(gsg_ot_scope, ft_scope, fvt_scope, gsg_fs_scope, gsg_oce_scope, gsg_fvcr_scope)\n",
- "gsg_histogram.use_coordination(gsg_ot_scope, ft_scope, fvt_scope, gsg_fs_scope, gsg_oce_scope, gsg_fvcr_scope)\n",
- "\n",
- "ngsg_feature_list.use_coordination(ngsg_ot_scope, ft_scope, fvt_scope, ngsg_fs_scope, ngsg_oce_scope, ngsg_fvcr_scope)\n",
- "ngsg_histogram.use_coordination(ngsg_ot_scope, ft_scope, fvt_scope, ngsg_fs_scope, ngsg_oce_scope, ngsg_fvcr_scope)\n",
- "\n",
- "\n",
- "# Layout the views in a grid arrangement.\n",
- "vc.layout(vconcat(\n",
- " hconcat(spatial, layer_controller, split=[3, 1]),\n",
- " hconcat(\n",
- " (tubules_feature_list / tubules_histogram),\n",
- " (pt_feature_list / pt_histogram),\n",
- " (gsg_feature_list / gsg_histogram),\n",
- " (ngsg_feature_list / ngsg_histogram)\n",
- " ),\n",
- " hconcat(pt_sets, pt_bar_plot, pt_violin_plot)\n",
- "));"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "SFPL",
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget(height=1000)\n",
- "vw"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "BYtC",
- "metadata": {},
- "outputs": [],
- "source": [
- "#import json\n",
- "#print(json.dumps(vc.to_dict(), indent=2))"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "RGSE",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/spatial_data_merfish.ipynb b/docs/notebooks/__ipynb__/spatial_data_merfish.ipynb
index 13823404..822f44c8 100644
--- a/docs/notebooks/__ipynb__/spatial_data_merfish.ipynb
+++ b/docs/notebooks/__ipynb__/spatial_data_merfish.ipynb
@@ -1,209 +1,217 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of a SpatialData object, blobs example"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Import dependencies"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "sdata_url = \"https://data-2.vitessce.io/data/moffitt/merfish_mouse_ileum.sdata.zarr\""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " ViewType as vt,\n",
+ " CoordinationType as ct,\n",
+ " CoordinationLevel as CL,\n",
+ " SpatialDataWrapper,\n",
+ " get_initial_coordination_scope_prefix\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Configure Vitessce\n",
+ "\n",
+ "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(\n",
+ " schema_version=\"1.0.18\",\n",
+ " name='SpatialData with MERFISH data',\n",
+ ")\n",
+ "# Add data to the configuration:\n",
+ "\n",
+ "dataset = vc.add_dataset(name='MERFISH').add_object(SpatialDataWrapper(\n",
+ " sdata_url=sdata_url,\n",
+ " # The following paths are relative to the root of the SpatialData zarr store on-disk.\n",
+ " image_path=\"images/stains\",\n",
+ " coordinate_system=\"global\",\n",
+ " coordination_values={\n",
+ " \"fileUid\": \"stains\"\n",
+ " }\n",
+ ")).add_object(SpatialDataWrapper(\n",
+ " sdata_url=sdata_url,\n",
+ " # The following paths are relative to the root of the SpatialData zarr store on-disk.\n",
+ " obs_segmentations_path=\"labels/dapi_labels\",\n",
+ " coordinate_system=\"global\",\n",
+ " coordination_values={\n",
+ " \"obsType\": \"nucleus\",\n",
+ " \"fileUid\": \"dapi\"\n",
+ " }\n",
+ ")).add_object(SpatialDataWrapper(\n",
+ " sdata_url=sdata_url,\n",
+ " # The following paths are relative to the root of the SpatialData zarr store on-disk.\n",
+ " obs_segmentations_path=\"labels/membrane_labels\",\n",
+ " coordinate_system=\"global\",\n",
+ " coordination_values={\n",
+ " \"obsType\": \"cell\",\n",
+ " \"fileUid\": \"membrane\"\n",
+ " }\n",
+ "))\n",
+ "\n",
+ "# Add views (visualizations) to the configuration:\n",
+ "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
+ "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
+ "\n",
+ "vc.link_views_by_dict([spatial, layer_controller], {\n",
+ " 'imageLayer': CL([{\n",
+ " \"fileUid\": \"stains\",\n",
+ " 'photometricInterpretation': 'BlackIsZero',\n",
+ " 'spatialLayerOpacity': 1.0,\n",
+ " 'spatialLayerVisible': True,\n",
+ " 'imageChannel': CL([\n",
+ " {\n",
+ " 'spatialChannelVisible': True,\n",
+ " \"spatialTargetC\": 0, # DAPI, Nucleus\n",
+ " \"spatialChannelColor\": [0, 0, 255],\n",
+ " \"spatialChannelOpacity\": 1.0\n",
+ " },\n",
+ " {\n",
+ " 'spatialChannelVisible': True,\n",
+ " \"spatialTargetC\": 1, # Membrane, Cell\n",
+ " \"spatialChannelColor\": [255, 255, 255],\n",
+ " \"spatialChannelOpacity\": 1.0\n",
+ " }\n",
+ " ])\n",
+ " }]),\n",
+ "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
+ "\n",
+ "vc.link_views_by_dict([spatial, layer_controller], {\n",
+ " 'segmentationLayer': CL([{\n",
+ " \"fileUid\": \"membrane\",\n",
+ " 'spatialLayerOpacity': 1.0,\n",
+ " 'spatialLayerVisible': True,\n",
+ " 'segmentationChannel': CL([{\n",
+ " 'spatialChannelVisible': True,\n",
+ " 'obsType': 'cell',\n",
+ " \"spatialChannelColor\": [200, 200, 200],\n",
+ " \"obsColorEncoding\": \"spatialChannelColor\",\n",
+ " }]),\n",
+ " }, {\n",
+ " \"fileUid\": \"dapi\",\n",
+ " 'spatialLayerOpacity': 1.0,\n",
+ " 'spatialLayerVisible': True,\n",
+ " 'segmentationChannel': CL([{\n",
+ " 'spatialChannelVisible': True,\n",
+ " 'obsType': 'nucleus',\n",
+ " \"spatialChannelColor\": [255, 255, 255],\n",
+ " \"obsColorEncoding\": \"spatialChannelColor\",\n",
+ " }]),\n",
+ " }]),\n",
+ "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"obsSegmentations\"))\n",
+ "\n",
+ "# Layout the views\n",
+ "vc.layout(spatial | layer_controller);"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Xref",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### Render the widget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
}
- },
- "source": [
- "# Visualization of a SpatialData object, blobs example"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Import dependencies"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "vblA",
- "metadata": {},
- "outputs": [],
- "source": [
- "sdata_url = \"https://data-2.vitessce.io/data/moffitt/merfish_mouse_ileum.sdata.zarr\""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "bkHC",
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " ViewType as vt,\n",
- " CoordinationType as ct,\n",
- " CoordinationLevel as CL,\n",
- " SpatialDataWrapper,\n",
- " get_initial_coordination_scope_prefix\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "lEQa",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "## Configure Vitessce\n",
- "\n",
- "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "PKri",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(\n",
- " schema_version=\"1.0.18\",\n",
- " name='SpatialData with MERFISH data',\n",
- ")\n",
- "# Add data to the configuration:\n",
- "\n",
- "dataset = vc.add_dataset(name='MERFISH').add_object(SpatialDataWrapper(\n",
- " sdata_url=sdata_url,\n",
- " # The following paths are relative to the root of the SpatialData zarr store on-disk.\n",
- " image_path=\"images/stains\",\n",
- " coordinate_system=\"global\",\n",
- " coordination_values={\n",
- " \"fileUid\": \"stains\"\n",
- " }\n",
- ")).add_object(SpatialDataWrapper(\n",
- " sdata_url=sdata_url,\n",
- " # The following paths are relative to the root of the SpatialData zarr store on-disk.\n",
- " obs_segmentations_path=\"labels/dapi_labels\",\n",
- " coordinate_system=\"global\",\n",
- " coordination_values={\n",
- " \"obsType\": \"nucleus\",\n",
- " \"fileUid\": \"dapi\"\n",
- " }\n",
- ")).add_object(SpatialDataWrapper(\n",
- " sdata_url=sdata_url,\n",
- " # The following paths are relative to the root of the SpatialData zarr store on-disk.\n",
- " obs_segmentations_path=\"labels/membrane_labels\",\n",
- " coordinate_system=\"global\",\n",
- " coordination_values={\n",
- " \"obsType\": \"cell\",\n",
- " \"fileUid\": \"membrane\"\n",
- " }\n",
- "))\n",
- "\n",
- "# Add views (visualizations) to the configuration:\n",
- "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
- "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
- "\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " 'imageLayer': CL([{\n",
- " \"fileUid\": \"stains\",\n",
- " 'photometricInterpretation': 'BlackIsZero',\n",
- " 'spatialLayerOpacity': 1.0,\n",
- " 'spatialLayerVisible': True,\n",
- " 'imageChannel': CL([\n",
- " {\n",
- " 'spatialChannelVisible': True,\n",
- " \"spatialTargetC\": 0, # DAPI, Nucleus\n",
- " \"spatialChannelColor\": [0, 0, 255],\n",
- " \"spatialChannelOpacity\": 1.0\n",
- " },\n",
- " {\n",
- " 'spatialChannelVisible': True,\n",
- " \"spatialTargetC\": 1, # Membrane, Cell\n",
- " \"spatialChannelColor\": [255, 255, 255],\n",
- " \"spatialChannelOpacity\": 1.0\n",
- " }\n",
- " ])\n",
- " }]),\n",
- "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
- "\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " 'segmentationLayer': CL([{\n",
- " \"fileUid\": \"membrane\",\n",
- " 'spatialLayerOpacity': 1.0,\n",
- " 'spatialLayerVisible': True,\n",
- " 'segmentationChannel': CL([{\n",
- " 'spatialChannelVisible': True,\n",
- " 'obsType': 'cell',\n",
- " \"spatialChannelColor\": [200, 200, 200],\n",
- " \"obsColorEncoding\": \"spatialChannelColor\",\n",
- " }]),\n",
- " }, {\n",
- " \"fileUid\": \"dapi\",\n",
- " 'spatialLayerOpacity': 1.0,\n",
- " 'spatialLayerVisible': True,\n",
- " 'segmentationChannel': CL([{\n",
- " 'spatialChannelVisible': True,\n",
- " 'obsType': 'nucleus',\n",
- " \"spatialChannelColor\": [255, 255, 255],\n",
- " \"obsColorEncoding\": \"spatialChannelColor\",\n",
- " }]),\n",
- " }]),\n",
- "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"obsSegmentations\"))\n",
- "\n",
- "# Layout the views\n",
- "vc.layout(spatial | layer_controller);"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Xref",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "### Render the widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "SFPL",
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "BYtC",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/spatial_data_merfish_2.ipynb b/docs/notebooks/__ipynb__/spatial_data_merfish_2.ipynb
index bb6eaf83..861bcdf4 100644
--- a/docs/notebooks/__ipynb__/spatial_data_merfish_2.ipynb
+++ b/docs/notebooks/__ipynb__/spatial_data_merfish_2.ipynb
@@ -1,181 +1,189 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of a SpatialData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Import dependencies"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from os.path import join, isfile, isdir\n",
+ "from urllib.request import urlretrieve\n",
+ "import zipfile\n",
+ "\n",
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " ViewType as vt,\n",
+ " CoordinationType as ct,\n",
+ " CoordinationLevel as CL,\n",
+ " SpatialDataWrapper,\n",
+ " get_initial_coordination_scope_prefix\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "data_dir = \"data\"\n",
+ "zip_filepath = join(data_dir, \"merfish_2.spatialdata.zarr.zip\")\n",
+ "spatialdata_filepath = join(data_dir, \"merfish_2.spatialdata.zarr\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "if not isdir(spatialdata_filepath):\n",
+ " if not isfile(zip_filepath):\n",
+ " os.makedirs(data_dir, exist_ok=True)\n",
+ " urlretrieve('https://s3.embl.de/spatialdata/spatialdata-sandbox/merfish.zip', zip_filepath)\n",
+ " with zipfile.ZipFile(zip_filepath,\"r\") as zip_ref:\n",
+ " zip_ref.extractall(data_dir)\n",
+ " os.rename(join(data_dir, \"data.zarr\"), spatialdata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "PKri",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Configure Vitessce\n",
+ "\n",
+ "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(\n",
+ " schema_version=\"1.0.18\",\n",
+ " name='MERFISH SpatialData Demo',\n",
+ ")\n",
+ "# Add data to the configuration:\n",
+ "wrapper = SpatialDataWrapper(\n",
+ " sdata_path=spatialdata_filepath,\n",
+ " # The following paths are relative to the root of the SpatialData zarr store on-disk.\n",
+ " image_path=\"images/rasterized\",\n",
+ " table_path=\"tables/table\",\n",
+ " obs_feature_matrix_path=\"tables/table/X\",\n",
+ " obs_spots_path=\"shapes/cells\",\n",
+ " coordinate_system=\"global\",\n",
+ " coordination_values={\n",
+ " # The following tells Vitessce to consider each observation as a \"spot\"\n",
+ " \"obsType\": \"cell\",\n",
+ " }\n",
+ ")\n",
+ "dataset = vc.add_dataset(name='MERFISH').add_object(wrapper)\n",
+ "\n",
+ "# Add views (visualizations) to the configuration:\n",
+ "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
+ "feature_list = vc.add_view(\"featureList\", dataset=dataset)\n",
+ "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
+ "obs_sets = vc.add_view(\"obsSets\", dataset=dataset)\n",
+ "\n",
+ "vc.link_views_by_dict([spatial, layer_controller], {\n",
+ " 'spotLayer': CL([{\n",
+ " 'obsType': 'cell',\n",
+ " }]),\n",
+ "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"obsSpots\"))\n",
+ "\n",
+ "vc.link_views([spatial, layer_controller, feature_list, obs_sets], ['obsType'], [wrapper.obs_type_label])\n",
+ "\n",
+ "# Layout the views\n",
+ "vc.layout(spatial | (feature_list / layer_controller / obs_sets));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### Render the widget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
}
- },
- "source": [
- "# Visualization of a SpatialData object"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Import dependencies"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "vblA",
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join, isfile, isdir\n",
- "from urllib.request import urlretrieve\n",
- "import zipfile\n",
- "\n",
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " ViewType as vt,\n",
- " CoordinationType as ct,\n",
- " CoordinationLevel as CL,\n",
- " SpatialDataWrapper,\n",
- " get_initial_coordination_scope_prefix\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "bkHC",
- "metadata": {},
- "outputs": [],
- "source": [
- "data_dir = \"data\"\n",
- "zip_filepath = join(data_dir, \"merfish_2.spatialdata.zarr.zip\")\n",
- "spatialdata_filepath = join(data_dir, \"merfish_2.spatialdata.zarr\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "lEQa",
- "metadata": {},
- "outputs": [],
- "source": [
- "if not isdir(spatialdata_filepath):\n",
- " if not isfile(zip_filepath):\n",
- " os.makedirs(data_dir, exist_ok=True)\n",
- " urlretrieve('https://s3.embl.de/spatialdata/spatialdata-sandbox/merfish.zip', zip_filepath)\n",
- " with zipfile.ZipFile(zip_filepath,\"r\") as zip_ref:\n",
- " zip_ref.extractall(data_dir)\n",
- " os.rename(join(data_dir, \"data.zarr\"), spatialdata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "PKri",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "## Configure Vitessce\n",
- "\n",
- "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(\n",
- " schema_version=\"1.0.18\",\n",
- " name='MERFISH SpatialData Demo',\n",
- ")\n",
- "# Add data to the configuration:\n",
- "wrapper = SpatialDataWrapper(\n",
- " sdata_path=spatialdata_filepath,\n",
- " # The following paths are relative to the root of the SpatialData zarr store on-disk.\n",
- " image_path=\"images/rasterized\",\n",
- " table_path=\"tables/table\",\n",
- " obs_feature_matrix_path=\"tables/table/X\",\n",
- " obs_spots_path=\"shapes/cells\",\n",
- " coordinate_system=\"global\",\n",
- " coordination_values={\n",
- " # The following tells Vitessce to consider each observation as a \"spot\"\n",
- " \"obsType\": \"cell\",\n",
- " }\n",
- ")\n",
- "dataset = vc.add_dataset(name='MERFISH').add_object(wrapper)\n",
- "\n",
- "# Add views (visualizations) to the configuration:\n",
- "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
- "feature_list = vc.add_view(\"featureList\", dataset=dataset)\n",
- "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
- "obs_sets = vc.add_view(\"obsSets\", dataset=dataset)\n",
- "\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " 'spotLayer': CL([{\n",
- " 'obsType': 'cell',\n",
- " }]),\n",
- "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"obsSpots\"))\n",
- "\n",
- "vc.link_views([spatial, layer_controller, feature_list, obs_sets], ['obsType'], [wrapper.obs_type_label])\n",
- "\n",
- "# Layout the views\n",
- "vc.layout(spatial | (feature_list / layer_controller / obs_sets));"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "SFPL",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "### Render the widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "BYtC",
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "RGSE",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/spatial_data_mouseliver.ipynb b/docs/notebooks/__ipynb__/spatial_data_mouseliver.ipynb
index f83f56bb..c8ca14a2 100644
--- a/docs/notebooks/__ipynb__/spatial_data_mouseliver.ipynb
+++ b/docs/notebooks/__ipynb__/spatial_data_mouseliver.ipynb
@@ -1,890 +1,898 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "# Visualization of a SpatialData object and individual Spatial Elements, local data"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "This notebook explains how to create interactive visualizations of data that is accessible locally.\n",
- "\n",
- "\n",
- "We progress through different visualization tasks, first demonstrating how Vitessce facilitates integrated imaging and spatial single-cell visualizations, then demonstrating visualization of non-spatial and image-only datasets."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "vblA",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- ""
- ]
- },
- {
- "cell_type": "markdown",
- "id": "bkHC",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Utility dependencies"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "lEQa",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "First, we import utility dependencies which will be used to download the example dataset and manipulate file paths, zip files, and JSON files."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "PKri",
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join, isfile, isdir\n",
- "from urllib.request import urlretrieve\n",
- "import zipfile\n",
- "import json"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Xref",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Dependencies for Vitessce"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "SFPL",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "Here, we import classes and functions from the `vitessce` Python package.\n",
- "This package includes not only APIs for [visualization configuration](https://python-docs.vitessce.io/api_config.html) but also [helper functions](https://python-docs.vitessce.io/api_data.html#vitessce-data-utils) for basic data transformation tasks.\n",
- "To specify mappings between data fields and visualization properties, the package contains [classes](https://python-docs.vitessce.io/api_data.html#module-vitessce.wrappers) which wrap standard single-cell data structures stored in formats including [AnnData](https://doi.org/10.1101/2021.12.16.473007), [SpatialData](https://doi.org/10.1038/s41592-024-02212-x), [OME-TIFF](https://doi.org/10.1007/978-3-030-23937-4_1), and [OME-Zarr](https://doi.org/10.1038/s41592-021-01326-w):\n",
- "\n",
- "- [AnnDataWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.AnnDataWrapper)\n",
- "- [ImageOmeTiffWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ImageOmeTiffWrapper)\n",
- "- [ImageOmeZarrWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ImageOmeZarrWrapper)\n",
- "- [ObsSegmentationsOmeTiffWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ObsSegmentationsOmeTiffWrapper)\n",
- "- [ObsSegmentationsOmeZarrWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ObsSegmentationsOmeZarrWrapper)\n",
- "- [SpatialDataWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.SpatialDataWrapper)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "BYtC",
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " ViewType as vt,\n",
- " CoordinationType as ct,\n",
- " CoordinationLevel as CL,\n",
- " SpatialDataWrapper,\n",
- " AnnDataWrapper,\n",
- " ImageOmeTiffWrapper,\n",
- " ImageOmeZarrWrapper,\n",
- " ObsSegmentationsOmeZarrWrapper,\n",
- " get_initial_coordination_scope_prefix,\n",
- " hconcat,\n",
- " vconcat,\n",
- ")\n",
- "from vitessce.data_utils import (\n",
- " VAR_CHUNK_SIZE,\n",
- " generate_h5ad_ref_spec,\n",
- " multiplex_img_to_ome_tiff,\n",
- " multiplex_img_to_ome_zarr,\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "RGSE",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Dependencies for data structures"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Kclp",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "In this blog post, we perform basic data transformation tasks to save individual elements of an integrated SpatialData object to separate files in AnnData, OME-TIFF, and OME-Zarr formats.\n",
- "To perform these data transformations, we import the following dependencies.\n",
- "In general, you will typically not need to import all of these dependencies, either because you are only working with data in one of these formats, or because the data you intend to visualize is already saved to a file or directory.\n",
- "\n",
- "Note: Dependencies such as `spatialdata` may need to be installed before they can be imported in the next code cell."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "emfo",
- "metadata": {},
- "outputs": [],
- "source": [
- "import numpy as np\n",
- "from spatialdata import read_zarr\n",
- "from anndata import AnnData\n",
- "from ome_zarr.writer import write_image\n",
- "import tifffile\n",
- "from generate_tiff_offsets import get_offsets"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Hstk",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Download example dataset"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "nWHF",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "We download a mouse liver dataset which serves as a SpatialData [example dataset](https://github.com/scverse/spatialdata-notebooks/blob/main/notebooks/examples/transformations.ipynb).\n",
- "\n",
- "This dataset was generated by [Guilliams et al.](https://doi.org/10.1016/j.cell.2021.12.018) and processed using [SPArrOW](https://doi.org/10.1101/2024.07.04.601829) during the SpatialData [developer workshop](https://doi.org/10.37044/osf.io/8ck3e) in 2024."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "iLit",
- "metadata": {},
- "outputs": [],
- "source": [
- "data_dir = \"data\"\n",
- "zip_filepath = join(data_dir, \"mouse_liver.spatialdata.zarr.zip\")\n",
- "spatialdata_filepath = join(data_dir, \"mouse_liver.spatialdata.zarr\")\n",
- "adata_zarr_filepath = join(data_dir, \"mouse_liver.anndata.zarr\")\n",
- "adata_h5ad_filepath = join(data_dir, \"mouse_liver.h5ad\")\n",
- "ref_spec_json_filepath = join(data_dir, \"mouse_liver.h5ad.ref.json\")\n",
- "ome_tiff_filepath = join(data_dir, \"mouse_liver.ome.tif\")\n",
- "offsets_json_filepath = join(data_dir, \"mouse_liver.ome.tif.offsets.json\")\n",
- "ome_zarr_filepath = join(data_dir, \"mouse_liver.ome.zarr\")\n",
- "labels_ome_zarr_filepath = join(data_dir, \"mouse_liver.labels.ome.zarr\")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "ZHCJ",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "The following code uses Python's `urlretrieve` to download the SpatialData object as a zip file, then unzips the file using the `zipfile` module."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "ROlb",
- "metadata": {},
- "outputs": [],
- "source": [
- "if not isdir(spatialdata_filepath):\n",
- " if not isfile(zip_filepath):\n",
- " os.makedirs(data_dir, exist_ok=True)\n",
- " urlretrieve('https://s3.embl.de/spatialdata/spatialdata-sandbox/mouse_liver.zip', zip_filepath)\n",
- " with zipfile.ZipFile(zip_filepath,\"r\") as zip_ref:\n",
- " zip_ref.extractall(data_dir)\n",
- " os.rename(join(data_dir, \"data.zarr\"), spatialdata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "qnkX",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Visualization of a SpatialData object"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "TqIu",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "SpatialData objects are the most complex type of data structure we will work with in this blog post.\n",
- "SpatialData objects function as contains for multiple types of Spatial Elements:\n",
- "\n",
- "- Tables (each table is represented as an AnnData object)\n",
- "- Points (e.g., coordinates of transcripts from FISH-based experiments)\n",
- "- Shapes (vector-based shapes such as polygons and circles)\n",
- "- Labels (label images, i.e., segmentation bitmasks; each label image is stored using OME-Zarr)\n",
- "- Images (microscopy images; each image is stored using OME-Zarr)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Vxnm",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Configure Vitessce\n",
- "\n",
- "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views.\n",
- "To visualize data stored in a SpatialData object, we use the `SpatialDataWrapper` class and specify the paths (relative to the root of the Zarr [directory store](https://zarr.readthedocs.io/en/v2.18.5/api/storage.html#zarr.storage.DirectoryStore)) to different spatial elements of interest."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "DnEU",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version='1.0.18', name='SpatialData Demo')\n",
- "_wrapper = SpatialDataWrapper(sdata_path=spatialdata_filepath, table_path='tables/table', image_path='images/raw_image', obs_segmentations_path='labels/segmentation_mask', obs_feature_matrix_path='tables/table/X', obs_set_paths=['tables/table/obs/annotation'], obs_set_names=['Annotation'], region='nucleus_boundaries', coordinate_system='global', coordination_values={'obsType': 'cell'})\n",
- "_dataset = vc.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
- "_spatial = vc.add_view('spatialBeta', dataset=_dataset)\n",
- "feature_list = vc.add_view('featureList', dataset=_dataset)\n",
- "_layer_controller = vc.add_view('layerControllerBeta', dataset=_dataset)\n",
- "obs_sets = vc.add_view('obsSets', dataset=_dataset)\n",
- "_heatmap = vc.add_view('heatmap', dataset=_dataset)\n",
- "[obs_color_encoding_scope] = vc.add_coordination('obsColorEncoding')\n",
- "obs_color_encoding_scope.set_value('cellSetSelection')\n",
- "vc.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))\n",
- "vc.link_views_by_dict([_spatial, _layer_controller], {'segmentationLayer': CL([{'segmentationChannel': CL([{'obsColorEncoding': obs_color_encoding_scope}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'obsSegmentations'))\n",
- "vc.link_views([_spatial, _layer_controller, feature_list, obs_sets, _heatmap], ['obsType'], [_wrapper.obs_type_label])\n",
- "vc.link_views_by_dict([feature_list, obs_sets, _heatmap], {'obsColorEncoding': obs_color_encoding_scope}, meta=False)\n",
- "vc.layout(_spatial / _heatmap | _layer_controller / (feature_list | obs_sets))"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "ulZA",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "### Render the widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "ecfG",
- "metadata": {},
- "outputs": [],
- "source": [
- "_vw = vc.widget()\n",
- "_vw"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Pvdt",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Extract AnnData object from SpatialData object"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "ZBYS",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "The above example demonstrates how to visualize a spatial 'omics dataset containing not only single-cell information (e.g., a cell-by-gene expression matrix, cell type annotations) but also an image and cell segmentations.\n",
- "To demonstrate how to use Vitessce to visualize data from a (non-spatial) single-cell experiment, we will extract this information from the SpatialData object and save it to a simpler [AnnData](https://anndata.readthedocs.io/) object (ignoring the imaging and spatially-resolved elements)."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "aLJB",
- "metadata": {},
- "outputs": [],
- "source": [
- "sdata = read_zarr(spatialdata_filepath)\n",
- "sdata"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "nHfw",
- "metadata": {},
- "outputs": [],
- "source": [
- "adata = sdata.tables['table']\n",
- "adata"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "xXTn",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "As Zarr-formatted data can be easily visualized by Vitessce, we recommend saving the AnnData object to a Zarr store using the [write_zarr](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_zarr.html) method.\n",
- "Optionally, the shape of array chunks (for the AnnData `X` array) can be specified as a parameter, to optimize performance based on data access patterns.\n",
- "For example, a common pattern is to visualize data across all cells for one gene.\n",
- "To support such a pattern, the chunk shape can be specified as follows, `(total number of cells, small number of genes)`, resulting in tall-and-skinny array chunks."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "AjVT",
- "metadata": {},
- "outputs": [],
- "source": [
- "adata.write_zarr(adata_zarr_filepath, chunks=(adata.shape[0], VAR_CHUNK_SIZE))"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "pHFh",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "Alternatively, your AnnData object may already be stored using the H5AD (HDF5-based) format.\n",
- "To demonstrate this scenario, we save the object using the [write_h5ad](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_h5ad.html) method."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "NCOB",
- "metadata": {},
- "outputs": [],
- "source": [
- "adata.write_h5ad(adata_h5ad_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "aqbW",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "To read H5AD-formatted data, Vitessce requires an accompanying JSON [references specification](https://fsspec.github.io/kerchunk/spec.html) file, which can be constructed using the `generate_h5ad_ref_spec` utility function."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "TRpd",
- "metadata": {},
- "outputs": [],
- "source": [
- "ref_dict = generate_h5ad_ref_spec(adata_h5ad_filepath)\n",
- "with open(ref_spec_json_filepath, 'w') as _f:\n",
- " json.dump(ref_dict, _f)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "TXez",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Visualization of an AnnData object"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "dNNg",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "### Zarr-based AnnData"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "yCnT",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc_1 = VitessceConfig(schema_version='1.0.18', name='AnnData (zarr)')\n",
- "_wrapper = AnnDataWrapper(adata_path=adata_zarr_filepath, obs_feature_matrix_path='X', obs_set_paths=['obs/annotation'], obs_set_names=['Annotation'], coordination_values={'obsType': 'cell'})\n",
- "_dataset = vc_1.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
- "_heatmap = vc_1.add_view(vt.HEATMAP, dataset=_dataset)\n",
- "feature_list_1 = vc_1.add_view(vt.FEATURE_LIST, dataset=_dataset)\n",
- "obs_sets_1 = vc_1.add_view(vt.OBS_SETS, dataset=_dataset)\n",
- "_violin_plots = vc_1.add_view('obsSetFeatureValueDistribution', dataset=_dataset)\n",
- "vc_1.link_views([_heatmap, feature_list_1, obs_sets_1], ['obsType', 'featureValueColormapRange'], ['cell', [0, 0.01]])\n",
- "vc_1.layout(_heatmap / _violin_plots | feature_list_1 / obs_sets_1)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "wlCL",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc_1.widget()"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "kqZH",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "### H5AD-based AnnData"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "wAgl",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc_2 = VitessceConfig(schema_version='1.0.18', name='AnnData (h5ad)')\n",
- "_wrapper = AnnDataWrapper(adata_path=adata_h5ad_filepath, ref_path=ref_spec_json_filepath, obs_feature_matrix_path='X', obs_set_paths=['obs/annotation'], obs_set_names=['Annotation'], coordination_values={'obsType': 'cell'})\n",
- "_dataset = vc_2.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
- "_heatmap = vc_2.add_view(vt.HEATMAP, dataset=_dataset)\n",
- "feature_list_2 = vc_2.add_view(vt.FEATURE_LIST, dataset=_dataset)\n",
- "obs_sets_2 = vc_2.add_view(vt.OBS_SETS, dataset=_dataset)\n",
- "_violin_plots = vc_2.add_view('obsSetFeatureValueDistribution', dataset=_dataset)\n",
- "vc_2.link_views([_heatmap, feature_list_2, obs_sets_2], ['obsType', 'featureValueColormapRange'], ['cell', [0, 0.01]])\n",
- "vc_2.layout(_heatmap / _violin_plots | feature_list_2 / obs_sets_2)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "rEll",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc_2.widget()"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "dGlV",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Extract image from SpatialData object"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "SdmI",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "In contrast to extraction of the non-spatial data from the SpatialData object, we can extract the imaging (and segmentation/label image) data and save it to a dedicated bioimaging file format."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "lgWD",
- "metadata": {},
- "outputs": [],
- "source": [
- "img_arr = sdata.images['raw_image'].to_numpy()\n",
- "labels_arr = sdata.labels['segmentation_mask'].to_numpy()\n",
- "labels_arr = labels_arr[np.newaxis, :]"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "yOPj",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "### Save image to OME-Zarr"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "fwwy",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "For small images, the data can be saved to OME-Zarr or OME-TIFF format using [utility functions](https://python-docs.vitessce.io/api_data.html#vitessce-data-utils) from the Vitessce package.\n",
- "Larger images require generation of an [image pyramid](https://en.wikipedia.org/wiki/Pyramid_(image_processing)), which can be performed using tools from the OME ecosystem such as [bioformats2raw](https://github.com/glencoesoftware/bioformats2raw) and [raw2ometiff](https://github.com/glencoesoftware/raw2ometiff)."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "LJZf",
- "metadata": {},
- "outputs": [],
- "source": [
- "multiplex_img_to_ome_zarr(img_arr, [\"Channel 0\"], ome_zarr_filepath)\n",
- "multiplex_img_to_ome_zarr(labels_arr, [\"cell\"], labels_ome_zarr_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "urSm",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "### Save image and segmentations to OME-TIFF"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "jxvo",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "To efficiently visualize OME-TIFF data using Vitessce, a JSON-based offsets file can be constructed using [generate-tiff-offsets](https://github.com/hms-dbmi/generate-tiff-offsets).\n",
- "This JSON file contains byte offsets into different partitions of the TIFF file, effectively resulting in an \"indexed TIFF\" which is described by [Manz et al. 2022](https://doi.org/10.1038/s41592-022-01482-7)."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "mWxS",
- "metadata": {},
- "outputs": [],
- "source": [
- "multiplex_img_to_ome_tiff(img_arr, ['Channel 0'], ome_tiff_filepath)\n",
- "offsets = get_offsets(ome_tiff_filepath)\n",
- "with open(offsets_json_filepath, 'w') as _f:\n",
- " json.dump(offsets, _f)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "CcZR",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Visualization of an image file"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "YWSi",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "### OME-Zarr image"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "zlud",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc_3 = VitessceConfig(schema_version='1.0.18', name='Image (ome-zarr)')\n",
- "img_wrapper = ImageOmeZarrWrapper(img_path=ome_zarr_filepath, coordination_values={'fileUid': 'image'})\n",
- "segmentations_wrapper = ObsSegmentationsOmeZarrWrapper(img_path=labels_ome_zarr_filepath, coordination_values={'fileUid': 'segmentations'})\n",
- "_dataset = vc_3.add_dataset(name='Mouse Liver').add_object(img_wrapper).add_object(segmentations_wrapper)\n",
- "_spatial = vc_3.add_view('spatialBeta', dataset=_dataset)\n",
- "_layer_controller = vc_3.add_view('layerControllerBeta', dataset=_dataset)\n",
- "vc_3.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'fileUid': 'image', 'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))\n",
- "vc_3.link_views_by_dict([_spatial, _layer_controller], {'segmentationLayer': CL([{'fileUid': 'segmentations', 'segmentationChannel': CL([{'obsColorEncoding': 'spatialChannelColor', 'spatialChannelColor': [0, 255, 0], 'spatialChannelOpacity': 0.75, 'spatialSegmentationFilled': False, 'spatialSegmentationStrokeWidth': 0.25}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'obsSegmentations'))\n",
- "vc_3.link_views([_spatial, _layer_controller, feature_list_2, obs_sets_2], ['obsType'], ['cell'])\n",
- "vc_3.layout(hconcat(_spatial, _layer_controller, split=(2, 1)))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "tZnO",
- "metadata": {},
- "outputs": [],
- "source": [
- "_vw = vc_3.widget()\n",
- "_vw"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "xvXZ",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "### OME-TIFF image"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "CLip",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc_4 = VitessceConfig(schema_version='1.0.18', name='Image and segmentations (ome-tiff)')\n",
- "_wrapper = ImageOmeTiffWrapper(img_path=ome_tiff_filepath, offsets_path=offsets_json_filepath)\n",
- "_dataset = vc_4.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
- "_spatial = vc_4.add_view('spatialBeta', dataset=_dataset)\n",
- "_layer_controller = vc_4.add_view('layerControllerBeta', dataset=_dataset)\n",
- "vc_4.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))\n",
- "vc_4.layout(hconcat(_spatial, _layer_controller, split=(2, 1)))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "YECM",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc_4.widget()"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "cEAS",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Data location options\n",
- "\n",
- "Vitessce can visualize data [not only stored](https://python-docs.vitessce.io/data_options.html) locally (referenced using local file or directory paths) but also stored remotely (referenced using absolute URL paths).\n",
- "Depending on whether the Python kernel running the Jupyter process is running locally versus remotely (e.g., on a cluster or cloud platform such as Google Colab), certain data locations may be challenging to access from the machine running the Jupyter notebook frontend (i.e., the machine on which the web browser used to view the notebook is installed).\n",
- "\n",
- "To provide data via one of these alternative mechanisms, use parameters with the following suffices when instantiating the data wrapper classes.\n",
- "\n",
- "- `_path`: Local file or directory\n",
- "- `_url`: Remote file or directory\n",
- "- `_store`: Zarr-store-accessible (for zarr-based formats)\n",
- "- `_artifact`: Lamin artifact\n",
- "\n",
- "For example, `adata_path` can be exchanged for one of the following options.\n",
- "\n",
- "```diff\n",
- "AnnDataWrapper(\n",
- "- adata_path=\"./mouse_liver.spatialdata.zarr\",\n",
- "+ adata_url=\"https://example.com/mouse_liver.spatialdata.zarr\", # Absolute URL\n",
- "+ adata_store=\"./mouse_liver.spatialdata.zarr\", # String interpreted as root of DirectoryStore\n",
- "+ adata_store=zarr.DirectoryStore(\"./mouse_liver.spatialdata.zarr\"), # Instance of zarr.storage\n",
- "+ adata_artifact=adata_zarr_artifact, # Instance of ln.Artifact\n",
- " ...\n",
- "```\n",
- "\n",
- "Note that the `_store` options are only available for Zarr-based formats, such as AnnDataWrapper, SpatialDataWrapper, and ImageOmeZarrWrapper.\n",
- "Further, when multiple files are required, such as both `adata_path` and `ref_path` (for the JSON reference specification file accompanying an H5AD file) or `img_path` and `offsets_path`, multiple parameter suffices may need to be changed."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "iXej",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of a SpatialData object and individual Spatial Elements, local data"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "This notebook explains how to create interactive visualizations of data that is accessible locally.\n",
+ "\n",
+ "\n",
+ "We progress through different visualization tasks, first demonstrating how Vitessce facilitates integrated imaging and spatial single-cell visualizations, then demonstrating visualization of non-spatial and image-only datasets."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Utility dependencies"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "First, we import utility dependencies which will be used to download the example dataset and manipulate file paths, zip files, and JSON files."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from os.path import join, isfile, isdir\n",
+ "from urllib.request import urlretrieve\n",
+ "import zipfile\n",
+ "import json"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Xref",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Dependencies for Vitessce"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "Here, we import classes and functions from the `vitessce` Python package.\n",
+ "This package includes not only APIs for [visualization configuration](https://python-docs.vitessce.io/api_config.html) but also [helper functions](https://python-docs.vitessce.io/api_data.html#vitessce-data-utils) for basic data transformation tasks.\n",
+ "To specify mappings between data fields and visualization properties, the package contains [classes](https://python-docs.vitessce.io/api_data.html#module-vitessce.wrappers) which wrap standard single-cell data structures stored in formats including [AnnData](https://doi.org/10.1101/2021.12.16.473007), [SpatialData](https://doi.org/10.1038/s41592-024-02212-x), [OME-TIFF](https://doi.org/10.1007/978-3-030-23937-4_1), and [OME-Zarr](https://doi.org/10.1038/s41592-021-01326-w):\n",
+ "\n",
+ "- [AnnDataWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.AnnDataWrapper)\n",
+ "- [ImageOmeTiffWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ImageOmeTiffWrapper)\n",
+ "- [ImageOmeZarrWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ImageOmeZarrWrapper)\n",
+ "- [ObsSegmentationsOmeTiffWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ObsSegmentationsOmeTiffWrapper)\n",
+ "- [ObsSegmentationsOmeZarrWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ObsSegmentationsOmeZarrWrapper)\n",
+ "- [SpatialDataWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.SpatialDataWrapper)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " ViewType as vt,\n",
+ " CoordinationType as ct,\n",
+ " CoordinationLevel as CL,\n",
+ " SpatialDataWrapper,\n",
+ " AnnDataWrapper,\n",
+ " ImageOmeTiffWrapper,\n",
+ " ImageOmeZarrWrapper,\n",
+ " ObsSegmentationsOmeZarrWrapper,\n",
+ " get_initial_coordination_scope_prefix,\n",
+ " hconcat,\n",
+ " vconcat,\n",
+ ")\n",
+ "from vitessce.data_utils import (\n",
+ " VAR_CHUNK_SIZE,\n",
+ " generate_h5ad_ref_spec,\n",
+ " multiplex_img_to_ome_tiff,\n",
+ " multiplex_img_to_ome_zarr,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "RGSE",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Dependencies for data structures"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Kclp",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "In this blog post, we perform basic data transformation tasks to save individual elements of an integrated SpatialData object to separate files in AnnData, OME-TIFF, and OME-Zarr formats.\n",
+ "To perform these data transformations, we import the following dependencies.\n",
+ "In general, you will typically not need to import all of these dependencies, either because you are only working with data in one of these formats, or because the data you intend to visualize is already saved to a file or directory.\n",
+ "\n",
+ "Note: Dependencies such as `spatialdata` may need to be installed before they can be imported in the next code cell."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "emfo",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import numpy as np\n",
+ "from spatialdata import read_zarr\n",
+ "from anndata import AnnData\n",
+ "from ome_zarr.writer import write_image\n",
+ "import tifffile\n",
+ "from generate_tiff_offsets import get_offsets"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hstk",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Download example dataset"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "nWHF",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "We download a mouse liver dataset which serves as a SpatialData [example dataset](https://github.com/scverse/spatialdata-notebooks/blob/main/notebooks/examples/transformations.ipynb).\n",
+ "\n",
+ "This dataset was generated by [Guilliams et al.](https://doi.org/10.1016/j.cell.2021.12.018) and processed using [SPArrOW](https://doi.org/10.1101/2024.07.04.601829) during the SpatialData [developer workshop](https://doi.org/10.37044/osf.io/8ck3e) in 2024."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "iLit",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "data_dir = \"data\"\n",
+ "zip_filepath = join(data_dir, \"mouse_liver.spatialdata.zarr.zip\")\n",
+ "spatialdata_filepath = join(data_dir, \"mouse_liver.spatialdata.zarr\")\n",
+ "adata_zarr_filepath = join(data_dir, \"mouse_liver.anndata.zarr\")\n",
+ "adata_h5ad_filepath = join(data_dir, \"mouse_liver.h5ad\")\n",
+ "ref_spec_json_filepath = join(data_dir, \"mouse_liver.h5ad.ref.json\")\n",
+ "ome_tiff_filepath = join(data_dir, \"mouse_liver.ome.tif\")\n",
+ "offsets_json_filepath = join(data_dir, \"mouse_liver.ome.tif.offsets.json\")\n",
+ "ome_zarr_filepath = join(data_dir, \"mouse_liver.ome.zarr\")\n",
+ "labels_ome_zarr_filepath = join(data_dir, \"mouse_liver.labels.ome.zarr\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ZHCJ",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "The following code uses Python's `urlretrieve` to download the SpatialData object as a zip file, then unzips the file using the `zipfile` module."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ROlb",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "if not isdir(spatialdata_filepath):\n",
+ " if not isfile(zip_filepath):\n",
+ " os.makedirs(data_dir, exist_ok=True)\n",
+ " urlretrieve('https://s3.embl.de/spatialdata/spatialdata-sandbox/mouse_liver.zip', zip_filepath)\n",
+ " with zipfile.ZipFile(zip_filepath,\"r\") as zip_ref:\n",
+ " zip_ref.extractall(data_dir)\n",
+ " os.rename(join(data_dir, \"data.zarr\"), spatialdata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "qnkX",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Visualization of a SpatialData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "TqIu",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "SpatialData objects are the most complex type of data structure we will work with in this blog post.\n",
+ "SpatialData objects function as contains for multiple types of Spatial Elements:\n",
+ "\n",
+ "- Tables (each table is represented as an AnnData object)\n",
+ "- Points (e.g., coordinates of transcripts from FISH-based experiments)\n",
+ "- Shapes (vector-based shapes such as polygons and circles)\n",
+ "- Labels (label images, i.e., segmentation bitmasks; each label image is stored using OME-Zarr)\n",
+ "- Images (microscopy images; each image is stored using OME-Zarr)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Vxnm",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Configure Vitessce\n",
+ "\n",
+ "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views.\n",
+ "To visualize data stored in a SpatialData object, we use the `SpatialDataWrapper` class and specify the paths (relative to the root of the Zarr [directory store](https://zarr.readthedocs.io/en/v2.18.5/api/storage.html#zarr.storage.DirectoryStore)) to different spatial elements of interest."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "DnEU",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version='1.0.18', name='SpatialData Demo')\n",
+ "_wrapper = SpatialDataWrapper(sdata_path=spatialdata_filepath, table_path='tables/table', image_path='images/raw_image', obs_segmentations_path='labels/segmentation_mask', obs_feature_matrix_path='tables/table/X', obs_set_paths=['tables/table/obs/annotation'], obs_set_names=['Annotation'], region='nucleus_boundaries', coordinate_system='global', coordination_values={'obsType': 'cell'})\n",
+ "_dataset = vc.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
+ "_spatial = vc.add_view('spatialBeta', dataset=_dataset)\n",
+ "feature_list = vc.add_view('featureList', dataset=_dataset)\n",
+ "_layer_controller = vc.add_view('layerControllerBeta', dataset=_dataset)\n",
+ "obs_sets = vc.add_view('obsSets', dataset=_dataset)\n",
+ "_heatmap = vc.add_view('heatmap', dataset=_dataset)\n",
+ "[obs_color_encoding_scope] = vc.add_coordination('obsColorEncoding')\n",
+ "obs_color_encoding_scope.set_value('cellSetSelection')\n",
+ "vc.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))\n",
+ "vc.link_views_by_dict([_spatial, _layer_controller], {'segmentationLayer': CL([{'segmentationChannel': CL([{'obsColorEncoding': obs_color_encoding_scope}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'obsSegmentations'))\n",
+ "vc.link_views([_spatial, _layer_controller, feature_list, obs_sets, _heatmap], ['obsType'], [_wrapper.obs_type_label])\n",
+ "vc.link_views_by_dict([feature_list, obs_sets, _heatmap], {'obsColorEncoding': obs_color_encoding_scope}, meta=False)\n",
+ "vc.layout(_spatial / _heatmap | _layer_controller / (feature_list | obs_sets))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ulZA",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### Render the widget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ecfG",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "_vw = vc.widget()\n",
+ "_vw"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Pvdt",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Extract AnnData object from SpatialData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ZBYS",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "The above example demonstrates how to visualize a spatial 'omics dataset containing not only single-cell information (e.g., a cell-by-gene expression matrix, cell type annotations) but also an image and cell segmentations.\n",
+ "To demonstrate how to use Vitessce to visualize data from a (non-spatial) single-cell experiment, we will extract this information from the SpatialData object and save it to a simpler [AnnData](https://anndata.readthedocs.io/) object (ignoring the imaging and spatially-resolved elements)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "aLJB",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "sdata = read_zarr(spatialdata_filepath)\n",
+ "sdata"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "nHfw",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata = sdata.tables['table']\n",
+ "adata"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "xXTn",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "As Zarr-formatted data can be easily visualized by Vitessce, we recommend saving the AnnData object to a Zarr store using the [write_zarr](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_zarr.html) method.\n",
+ "Optionally, the shape of array chunks (for the AnnData `X` array) can be specified as a parameter, to optimize performance based on data access patterns.\n",
+ "For example, a common pattern is to visualize data across all cells for one gene.\n",
+ "To support such a pattern, the chunk shape can be specified as follows, `(total number of cells, small number of genes)`, resulting in tall-and-skinny array chunks."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "AjVT",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata.write_zarr(adata_zarr_filepath, chunks=(adata.shape[0], VAR_CHUNK_SIZE))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "pHFh",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "Alternatively, your AnnData object may already be stored using the H5AD (HDF5-based) format.\n",
+ "To demonstrate this scenario, we save the object using the [write_h5ad](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_h5ad.html) method."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "NCOB",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata.write_h5ad(adata_h5ad_filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "aqbW",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "To read H5AD-formatted data, Vitessce requires an accompanying JSON [references specification](https://fsspec.github.io/kerchunk/spec.html) file, which can be constructed using the `generate_h5ad_ref_spec` utility function."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "TRpd",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "ref_dict = generate_h5ad_ref_spec(adata_h5ad_filepath)\n",
+ "with open(ref_spec_json_filepath, 'w') as _f:\n",
+ " json.dump(ref_dict, _f)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "TXez",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Visualization of an AnnData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "dNNg",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### Zarr-based AnnData"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "yCnT",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc_1 = VitessceConfig(schema_version='1.0.18', name='AnnData (zarr)')\n",
+ "_wrapper = AnnDataWrapper(adata_path=adata_zarr_filepath, obs_feature_matrix_path='X', obs_set_paths=['obs/annotation'], obs_set_names=['Annotation'], coordination_values={'obsType': 'cell'})\n",
+ "_dataset = vc_1.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
+ "_heatmap = vc_1.add_view(vt.HEATMAP, dataset=_dataset)\n",
+ "feature_list_1 = vc_1.add_view(vt.FEATURE_LIST, dataset=_dataset)\n",
+ "obs_sets_1 = vc_1.add_view(vt.OBS_SETS, dataset=_dataset)\n",
+ "_violin_plots = vc_1.add_view('obsSetFeatureValueDistribution', dataset=_dataset)\n",
+ "vc_1.link_views([_heatmap, feature_list_1, obs_sets_1], ['obsType', 'featureValueColormapRange'], ['cell', [0, 0.01]])\n",
+ "vc_1.layout(_heatmap / _violin_plots | feature_list_1 / obs_sets_1)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "wlCL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc_1.widget()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "kqZH",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### H5AD-based AnnData"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "wAgl",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc_2 = VitessceConfig(schema_version='1.0.18', name='AnnData (h5ad)')\n",
+ "_wrapper = AnnDataWrapper(adata_path=adata_h5ad_filepath, ref_path=ref_spec_json_filepath, obs_feature_matrix_path='X', obs_set_paths=['obs/annotation'], obs_set_names=['Annotation'], coordination_values={'obsType': 'cell'})\n",
+ "_dataset = vc_2.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
+ "_heatmap = vc_2.add_view(vt.HEATMAP, dataset=_dataset)\n",
+ "feature_list_2 = vc_2.add_view(vt.FEATURE_LIST, dataset=_dataset)\n",
+ "obs_sets_2 = vc_2.add_view(vt.OBS_SETS, dataset=_dataset)\n",
+ "_violin_plots = vc_2.add_view('obsSetFeatureValueDistribution', dataset=_dataset)\n",
+ "vc_2.link_views([_heatmap, feature_list_2, obs_sets_2], ['obsType', 'featureValueColormapRange'], ['cell', [0, 0.01]])\n",
+ "vc_2.layout(_heatmap / _violin_plots | feature_list_2 / obs_sets_2)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "rEll",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc_2.widget()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "dGlV",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Extract image from SpatialData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "SdmI",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "In contrast to extraction of the non-spatial data from the SpatialData object, we can extract the imaging (and segmentation/label image) data and save it to a dedicated bioimaging file format."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lgWD",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "img_arr = sdata.images['raw_image'].to_numpy()\n",
+ "labels_arr = sdata.labels['segmentation_mask'].to_numpy()\n",
+ "labels_arr = labels_arr[np.newaxis, :]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "yOPj",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### Save image to OME-Zarr"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "fwwy",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "For small images, the data can be saved to OME-Zarr or OME-TIFF format using [utility functions](https://python-docs.vitessce.io/api_data.html#vitessce-data-utils) from the Vitessce package.\n",
+ "Larger images require generation of an [image pyramid](https://en.wikipedia.org/wiki/Pyramid_(image_processing)), which can be performed using tools from the OME ecosystem such as [bioformats2raw](https://github.com/glencoesoftware/bioformats2raw) and [raw2ometiff](https://github.com/glencoesoftware/raw2ometiff)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "LJZf",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "multiplex_img_to_ome_zarr(img_arr, [\"Channel 0\"], ome_zarr_filepath)\n",
+ "multiplex_img_to_ome_zarr(labels_arr, [\"cell\"], labels_ome_zarr_filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "urSm",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### Save image and segmentations to OME-TIFF"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "jxvo",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "To efficiently visualize OME-TIFF data using Vitessce, a JSON-based offsets file can be constructed using [generate-tiff-offsets](https://github.com/hms-dbmi/generate-tiff-offsets).\n",
+ "This JSON file contains byte offsets into different partitions of the TIFF file, effectively resulting in an \"indexed TIFF\" which is described by [Manz et al. 2022](https://doi.org/10.1038/s41592-022-01482-7)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "mWxS",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "multiplex_img_to_ome_tiff(img_arr, ['Channel 0'], ome_tiff_filepath)\n",
+ "offsets = get_offsets(ome_tiff_filepath)\n",
+ "with open(offsets_json_filepath, 'w') as _f:\n",
+ " json.dump(offsets, _f)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "CcZR",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Visualization of an image file"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "YWSi",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### OME-Zarr image"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "zlud",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc_3 = VitessceConfig(schema_version='1.0.18', name='Image (ome-zarr)')\n",
+ "img_wrapper = ImageOmeZarrWrapper(img_path=ome_zarr_filepath, coordination_values={'fileUid': 'image'})\n",
+ "segmentations_wrapper = ObsSegmentationsOmeZarrWrapper(img_path=labels_ome_zarr_filepath, coordination_values={'fileUid': 'segmentations'})\n",
+ "_dataset = vc_3.add_dataset(name='Mouse Liver').add_object(img_wrapper).add_object(segmentations_wrapper)\n",
+ "_spatial = vc_3.add_view('spatialBeta', dataset=_dataset)\n",
+ "_layer_controller = vc_3.add_view('layerControllerBeta', dataset=_dataset)\n",
+ "vc_3.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'fileUid': 'image', 'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))\n",
+ "vc_3.link_views_by_dict([_spatial, _layer_controller], {'segmentationLayer': CL([{'fileUid': 'segmentations', 'segmentationChannel': CL([{'obsColorEncoding': 'spatialChannelColor', 'spatialChannelColor': [0, 255, 0], 'spatialChannelOpacity': 0.75, 'spatialSegmentationFilled': False, 'spatialSegmentationStrokeWidth': 0.25}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'obsSegmentations'))\n",
+ "vc_3.link_views([_spatial, _layer_controller, feature_list_2, obs_sets_2], ['obsType'], ['cell'])\n",
+ "vc_3.layout(hconcat(_spatial, _layer_controller, split=(2, 1)))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "tZnO",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "_vw = vc_3.widget()\n",
+ "_vw"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "xvXZ",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### OME-TIFF image"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "CLip",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc_4 = VitessceConfig(schema_version='1.0.18', name='Image and segmentations (ome-tiff)')\n",
+ "_wrapper = ImageOmeTiffWrapper(img_path=ome_tiff_filepath, offsets_path=offsets_json_filepath)\n",
+ "_dataset = vc_4.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
+ "_spatial = vc_4.add_view('spatialBeta', dataset=_dataset)\n",
+ "_layer_controller = vc_4.add_view('layerControllerBeta', dataset=_dataset)\n",
+ "vc_4.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))\n",
+ "vc_4.layout(hconcat(_spatial, _layer_controller, split=(2, 1)))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "YECM",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc_4.widget()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "cEAS",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Data location options\n",
+ "\n",
+ "Vitessce can visualize data [not only stored](https://python-docs.vitessce.io/data_options.html) locally (referenced using local file or directory paths) but also stored remotely (referenced using absolute URL paths).\n",
+ "Depending on whether the Python kernel running the Jupyter process is running locally versus remotely (e.g., on a cluster or cloud platform such as Google Colab), certain data locations may be challenging to access from the machine running the Jupyter notebook frontend (i.e., the machine on which the web browser used to view the notebook is installed).\n",
+ "\n",
+ "To provide data via one of these alternative mechanisms, use parameters with the following suffices when instantiating the data wrapper classes.\n",
+ "\n",
+ "- `_path`: Local file or directory\n",
+ "- `_url`: Remote file or directory\n",
+ "- `_store`: Zarr-store-accessible (for zarr-based formats)\n",
+ "- `_artifact`: Lamin artifact\n",
+ "\n",
+ "For example, `adata_path` can be exchanged for one of the following options.\n",
+ "\n",
+ "```diff\n",
+ "AnnDataWrapper(\n",
+ "- adata_path=\"./mouse_liver.spatialdata.zarr\",\n",
+ "+ adata_url=\"https://example.com/mouse_liver.spatialdata.zarr\", # Absolute URL\n",
+ "+ adata_store=\"./mouse_liver.spatialdata.zarr\", # String interpreted as root of DirectoryStore\n",
+ "+ adata_store=zarr.DirectoryStore(\"./mouse_liver.spatialdata.zarr\"), # Instance of zarr.storage\n",
+ "+ adata_artifact=adata_zarr_artifact, # Instance of ln.Artifact\n",
+ " ...\n",
+ "```\n",
+ "\n",
+ "Note that the `_store` options are only available for Zarr-based formats, such as AnnDataWrapper, SpatialDataWrapper, and ImageOmeZarrWrapper.\n",
+ "Further, when multiple files are required, such as both `adata_path` and `ref_path` (for the JSON reference specification file accompanying an H5AD file) or `img_path` and `offsets_path`, multiple parameter suffices may need to be changed."
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/spatial_data_mouseliver_remote.ipynb b/docs/notebooks/__ipynb__/spatial_data_mouseliver_remote.ipynb
index d6d25b92..184e962b 100644
--- a/docs/notebooks/__ipynb__/spatial_data_mouseliver_remote.ipynb
+++ b/docs/notebooks/__ipynb__/spatial_data_mouseliver_remote.ipynb
@@ -1,676 +1,684 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of a SpatialData object and individual Spatial Elements, remote data"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "This notebook explains how to create interactive visualizations of data that are accessible remotely.\n",
+ "\n",
+ "\n",
+ "We progress through different visualization tasks, first demonstrating how Vitessce facilitates integrated imaging and spatial single-cell visualizations, then demonstrating visualization of non-spatial and image-only datasets."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Utility dependencies"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "PKri",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "First, we import utility dependencies which will be used to download the example dataset and manipulate file paths, zip files, and JSON files."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from os.path import join, isfile, isdir\n",
+ "from urllib.request import urlretrieve\n",
+ "import zipfile\n",
+ "import json"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Dependencies for Vitessce"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "BYtC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "Here, we import classes and functions from the `vitessce` Python package.\n",
+ "This package includes not only APIs for [visualization configuration](https://python-docs.vitessce.io/api_config.html) but also [helper functions](https://python-docs.vitessce.io/api_data.html#vitessce-data-utils) for basic data transformation tasks.\n",
+ "To specify mappings between data fields and visualization properties, the package contains [classes](https://python-docs.vitessce.io/api_data.html#module-vitessce.wrappers) which wrap standard single-cell data structures stored in formats including [AnnData](https://doi.org/10.1101/2021.12.16.473007), [SpatialData](https://doi.org/10.1038/s41592-024-02212-x), [OME-TIFF](https://doi.org/10.1007/978-3-030-23937-4_1), and [OME-Zarr](https://doi.org/10.1038/s41592-021-01326-w):\n",
+ "\n",
+ "- [AnnDataWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.AnnDataWrapper)\n",
+ "- [ImageOmeTiffWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ImageOmeTiffWrapper)\n",
+ "- [ImageOmeZarrWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ImageOmeZarrWrapper)\n",
+ "- [ObsSegmentationsOmeTiffWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ObsSegmentationsOmeTiffWrapper)\n",
+ "- [ObsSegmentationsOmeZarrWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ObsSegmentationsOmeZarrWrapper)\n",
+ "- [SpatialDataWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.SpatialDataWrapper)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " ViewType as vt,\n",
+ " CoordinationType as ct,\n",
+ " CoordinationLevel as CL,\n",
+ " SpatialDataWrapper,\n",
+ " AnnDataWrapper,\n",
+ " ImageOmeTiffWrapper,\n",
+ " ImageOmeZarrWrapper,\n",
+ " ObsSegmentationsOmeZarrWrapper,\n",
+ " get_initial_coordination_scope_prefix,\n",
+ " hconcat,\n",
+ " vconcat,\n",
+ ")\n",
+ "from vitessce.data_utils import (\n",
+ " VAR_CHUNK_SIZE,\n",
+ " generate_h5ad_ref_spec,\n",
+ " multiplex_img_to_ome_tiff,\n",
+ " multiplex_img_to_ome_zarr,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Kclp",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "In this blog post, we perform basic data transformation tasks to save individual elements of an integrated SpatialData object to separate files in AnnData, OME-TIFF, and OME-Zarr formats.\n",
+ "To perform these data transformations, we import the following dependencies.\n",
+ "In general, you will typically not need to import all of these dependencies, either because you are only working with data in one of these formats, or because the data you intend to visualize is already saved to a file or directory."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "emfo",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Download example dataset"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hstk",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "We download a mouse liver dataset which serves as a SpatialData [example dataset](https://github.com/scverse/spatialdata-notebooks/blob/main/notebooks/examples/transformations.ipynb).\n",
+ "\n",
+ "This dataset was generated by [Guilliams et al.](https://doi.org/10.1016/j.cell.2021.12.018) and processed using [SPArrOW](https://doi.org/10.1101/2024.07.04.601829) during the SpatialData [developer workshop](https://doi.org/10.37044/osf.io/8ck3e) in 2024."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "nWHF",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "base_url = \"https://storage.googleapis.com/vitessce-demo-data/spatialdata-may-2025\""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "iLit",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "zip_filepath = f\"{base_url}/mouse_liver.spatialdata.zarr.zip\"\n",
+ "spatialdata_filepath = f\"{base_url}/mouse_liver.spatialdata.zarr\"\n",
+ "adata_zarr_filepath = f\"{base_url}/mouse_liver.anndata.zarr\"\n",
+ "adata_h5ad_filepath = f\"{base_url}/mouse_liver.h5ad\"\n",
+ "ref_spec_json_filepath = f\"{base_url}/mouse_liver.h5ad.ref.json\"\n",
+ "ome_tiff_filepath = f\"{base_url}/mouse_liver.ome.tif\"\n",
+ "offsets_json_filepath = f\"{base_url}/mouse_liver.ome.tif.offsets.json\"\n",
+ "ome_zarr_filepath = f\"{base_url}/mouse_liver.ome.zarr\"\n",
+ "labels_ome_zarr_filepath = f\"{base_url}/mouse_liver.labels.ome.zarr\""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ZHCJ",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Visualization of a SpatialData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ROlb",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "SpatialData objects are the most complex type of data structure we will work with in this blog post.\n",
+ "SpatialData objects function as contains for multiple types of Spatial Elements:\n",
+ "\n",
+ "- Tables (each table is represented as an AnnData object)\n",
+ "- Points (e.g., coordinates of transcripts from FISH-based experiments)\n",
+ "- Shapes (vector-based shapes such as polygons and circles)\n",
+ "- Labels (label images, i.e., segmentation bitmasks; each label image is stored using OME-Zarr)\n",
+ "- Images (microscopy images; each image is stored using OME-Zarr)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "qnkX",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Configure Vitessce\n",
+ "\n",
+ "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views.\n",
+ "To visualize data stored in a SpatialData object, we use the `SpatialDataWrapper` class and specify the paths (relative to the root of the Zarr [directory store](https://zarr.readthedocs.io/en/v2.18.5/api/storage.html#zarr.storage.DirectoryStore)) to different spatial elements of interest."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "TqIu",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version='1.0.18', name='SpatialData Demo')\n",
+ "_wrapper = SpatialDataWrapper(sdata_url=spatialdata_filepath, table_path='tables/table', image_path='images/raw_image', obs_segmentations_path='labels/segmentation_mask', obs_feature_matrix_path='tables/table/X', obs_set_paths=['tables/table/obs/annotation'], obs_set_names=['Annotation'], region='nucleus_boundaries', coordinate_system='global', coordination_values={'obsType': 'cell'})\n",
+ "_dataset = vc.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
+ "_spatial = vc.add_view('spatialBeta', dataset=_dataset)\n",
+ "feature_list = vc.add_view('featureList', dataset=_dataset)\n",
+ "_layer_controller = vc.add_view('layerControllerBeta', dataset=_dataset)\n",
+ "obs_sets = vc.add_view('obsSets', dataset=_dataset)\n",
+ "_heatmap = vc.add_view('heatmap', dataset=_dataset)\n",
+ "[obs_color_encoding_scope] = vc.add_coordination('obsColorEncoding')\n",
+ "obs_color_encoding_scope.set_value('cellSetSelection')\n",
+ "vc.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))\n",
+ "vc.link_views_by_dict([_spatial, _layer_controller], {'segmentationLayer': CL([{'segmentationChannel': CL([{'obsColorEncoding': obs_color_encoding_scope}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'obsSegmentations'))\n",
+ "vc.link_views([_spatial, _layer_controller, feature_list, obs_sets, _heatmap], ['obsType'], [_wrapper.obs_type_label])\n",
+ "vc.link_views_by_dict([feature_list, obs_sets, _heatmap], {'obsColorEncoding': obs_color_encoding_scope}, meta=False)\n",
+ "vc.layout(_spatial / _heatmap | _layer_controller / (feature_list | obs_sets))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Vxnm",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### Render the widget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "DnEU",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "_vw = vc.widget(height=900)\n",
+ "_vw"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ulZA",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Extract AnnData object from SpatialData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ecfG",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "The above example demonstrates how to visualize a spatial 'omics dataset containing not only single-cell information (e.g., a cell-by-gene expression matrix, cell type annotations) but also an image and cell segmentations.\n",
+ "To demonstrate how to use Vitessce to visualize data from a (non-spatial) single-cell experiment, we will extract this information from the SpatialData object and save it to a simpler [AnnData](https://anndata.readthedocs.io/) object (ignoring the imaging and spatially-resolved elements)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Pvdt",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "As Zarr-formatted data can be easily visualized by Vitessce, we recommend saving the AnnData object to a Zarr store using the [write_zarr](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_zarr.html) method.\n",
+ "Optionally, the shape of array chunks (for the AnnData `X` array) can be specified as a parameter, to optimize performance based on data access patterns.\n",
+ "For example, a common pattern is to visualize data across all cells for one gene.\n",
+ "To support such a pattern, the chunk shape can be specified as follows, `(total number of cells, small number of genes)`, resulting in tall-and-skinny array chunks."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ZBYS",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "Alternatively, your AnnData object may already be stored using the H5AD (HDF5-based) format.\n",
+ "To demonstrate this scenario, we save the object using the [write_h5ad](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_h5ad.html) method."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "aLJB",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "To read H5AD-formatted data, Vitessce requires an accompanying JSON [references specification](https://fsspec.github.io/kerchunk/spec.html) file, which can be constructed using the `generate_h5ad_ref_spec` utility function."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "nHfw",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Visualization of an AnnData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "xXTn",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### Zarr-based AnnData"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "AjVT",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc_1 = VitessceConfig(schema_version='1.0.18', name='AnnData (zarr)')\n",
+ "_wrapper = AnnDataWrapper(adata_url=adata_zarr_filepath, obs_feature_matrix_path='X', obs_set_paths=['obs/annotation'], obs_set_names=['Annotation'], coordination_values={'obsType': 'cell'})\n",
+ "_dataset = vc_1.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
+ "_heatmap = vc_1.add_view(vt.HEATMAP, dataset=_dataset)\n",
+ "feature_list_1 = vc_1.add_view(vt.FEATURE_LIST, dataset=_dataset)\n",
+ "obs_sets_1 = vc_1.add_view(vt.OBS_SETS, dataset=_dataset)\n",
+ "_violin_plots = vc_1.add_view('obsSetFeatureValueDistribution', dataset=_dataset)\n",
+ "vc_1.link_views([_heatmap, feature_list_1, obs_sets_1], ['obsType', 'featureValueColormapRange'], ['cell', [0, 0.01]])\n",
+ "vc_1.layout(_heatmap / _violin_plots | feature_list_1 / obs_sets_1)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "pHFh",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc_1.widget()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "NCOB",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### H5AD-based AnnData"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "aqbW",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc_2 = VitessceConfig(schema_version='1.0.18', name='AnnData (h5ad)')\n",
+ "_wrapper = AnnDataWrapper(adata_url=adata_h5ad_filepath, ref_url=ref_spec_json_filepath, obs_feature_matrix_path='X', obs_set_paths=['obs/annotation'], obs_set_names=['Annotation'], coordination_values={'obsType': 'cell'})\n",
+ "_dataset = vc_2.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
+ "_heatmap = vc_2.add_view(vt.HEATMAP, dataset=_dataset)\n",
+ "feature_list_2 = vc_2.add_view(vt.FEATURE_LIST, dataset=_dataset)\n",
+ "obs_sets_2 = vc_2.add_view(vt.OBS_SETS, dataset=_dataset)\n",
+ "_violin_plots = vc_2.add_view('obsSetFeatureValueDistribution', dataset=_dataset)\n",
+ "vc_2.link_views([_heatmap, feature_list_2, obs_sets_2], ['obsType', 'featureValueColormapRange'], ['cell', [0, 0.01]])\n",
+ "vc_2.layout(_heatmap / _violin_plots | feature_list_2 / obs_sets_2)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "TRpd",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc_2.widget()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "TXez",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Visualization of an image file"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "dNNg",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### OME-Zarr image"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "yCnT",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc_3 = VitessceConfig(schema_version='1.0.18', name='Image (ome-zarr)')\n",
+ "img_wrapper = ImageOmeZarrWrapper(img_url=ome_zarr_filepath, coordination_values={'fileUid': 'image'})\n",
+ "segmentations_wrapper = ObsSegmentationsOmeZarrWrapper(img_url=labels_ome_zarr_filepath, coordination_values={'fileUid': 'segmentations'})\n",
+ "_dataset = vc_3.add_dataset(name='Mouse Liver').add_object(img_wrapper).add_object(segmentations_wrapper)\n",
+ "_spatial = vc_3.add_view('spatialBeta', dataset=_dataset)\n",
+ "_layer_controller = vc_3.add_view('layerControllerBeta', dataset=_dataset)\n",
+ "vc_3.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'fileUid': 'image', 'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))\n",
+ "vc_3.link_views_by_dict([_spatial, _layer_controller], {'segmentationLayer': CL([{'fileUid': 'segmentations', 'segmentationChannel': CL([{'obsColorEncoding': 'spatialChannelColor', 'spatialChannelColor': [0, 255, 0], 'spatialChannelOpacity': 0.75, 'spatialSegmentationFilled': False, 'spatialSegmentationStrokeWidth': 0.25}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'obsSegmentations'))\n",
+ "vc_3.link_views([_spatial, _layer_controller, feature_list_2, obs_sets_2], ['obsType'], ['cell'])\n",
+ "vc_3.layout(hconcat(_spatial, _layer_controller, split=(2, 1)))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "wlCL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "_vw = vc_3.widget()\n",
+ "_vw"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "kqZH",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### OME-TIFF image"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "wAgl",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc_4 = VitessceConfig(schema_version='1.0.18', name='Image and segmentations (ome-tiff)')\n",
+ "_wrapper = ImageOmeTiffWrapper(img_url=ome_tiff_filepath, offsets_url=offsets_json_filepath)\n",
+ "_dataset = vc_4.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
+ "_spatial = vc_4.add_view('spatialBeta', dataset=_dataset)\n",
+ "_layer_controller = vc_4.add_view('layerControllerBeta', dataset=_dataset)\n",
+ "vc_4.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))\n",
+ "vc_4.layout(hconcat(_spatial, _layer_controller, split=(2, 1)))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "rEll",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc_4.widget()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "dGlV",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Data location options\n",
+ "\n",
+ "Vitessce can visualize data [not only stored](https://python-docs.vitessce.io/data_options.html) locally (referenced using local file or directory paths) but also stored remotely (referenced using absolute URL paths).\n",
+ "Depending on whether the Python kernel running the Jupyter process is running locally versus remotely (e.g., on a cluster or cloud platform such as Google Colab), certain data locations may be challenging to access from the machine running the Jupyter notebook frontend (i.e., the machine on which the web browser used to view the notebook is installed).\n",
+ "\n",
+ "To provide data via one of these alternative mechanisms, use parameters with the following suffices when instantiating the data wrapper classes.\n",
+ "\n",
+ "- `_path`: Local file or directory\n",
+ "- `_url`: Remote file or directory\n",
+ "- `_store`: Zarr-store-accessible (for zarr-based formats)\n",
+ "- `_artifact`: Lamin artifact\n",
+ "\n",
+ "For example, `adata_path` can be exchanged for one of the following options.\n",
+ "\n",
+ "```diff\n",
+ "AnnDataWrapper(\n",
+ "- adata_path=\"./mouse_liver.spatialdata.zarr\",\n",
+ "+ adata_url=\"https://example.com/mouse_liver.spatialdata.zarr\", # Absolute URL\n",
+ "+ adata_store=\"./mouse_liver.spatialdata.zarr\", # String interpreted as root of DirectoryStore\n",
+ "+ adata_store=zarr.DirectoryStore(\"./mouse_liver.spatialdata.zarr\"), # Instance of zarr.storage\n",
+ "+ adata_artifact=adata_zarr_artifact, # Instance of ln.Artifact\n",
+ " ...\n",
+ "```\n",
+ "\n",
+ "Note that the `_store` options are only available for Zarr-based formats, such as AnnDataWrapper, SpatialDataWrapper, and ImageOmeZarrWrapper.\n",
+ "Further, when multiple files are required, such as both `adata_path` and `ref_path` (for the JSON reference specification file accompanying an H5AD file) or `img_path` and `offsets_path`, multiple parameter suffices may need to be changed."
+ ]
}
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "# Visualization of a SpatialData object and individual Spatial Elements, remote data"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "vblA",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "This notebook explains how to create interactive visualizations of data that are accessible remotely.\n",
- "\n",
- "\n",
- "We progress through different visualization tasks, first demonstrating how Vitessce facilitates integrated imaging and spatial single-cell visualizations, then demonstrating visualization of non-spatial and image-only datasets."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "bkHC",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- ""
- ]
- },
- {
- "cell_type": "markdown",
- "id": "lEQa",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Utility dependencies"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "PKri",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "First, we import utility dependencies which will be used to download the example dataset and manipulate file paths, zip files, and JSON files."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join, isfile, isdir\n",
- "from urllib.request import urlretrieve\n",
- "import zipfile\n",
- "import json"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "SFPL",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Dependencies for Vitessce"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "BYtC",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "Here, we import classes and functions from the `vitessce` Python package.\n",
- "This package includes not only APIs for [visualization configuration](https://python-docs.vitessce.io/api_config.html) but also [helper functions](https://python-docs.vitessce.io/api_data.html#vitessce-data-utils) for basic data transformation tasks.\n",
- "To specify mappings between data fields and visualization properties, the package contains [classes](https://python-docs.vitessce.io/api_data.html#module-vitessce.wrappers) which wrap standard single-cell data structures stored in formats including [AnnData](https://doi.org/10.1101/2021.12.16.473007), [SpatialData](https://doi.org/10.1038/s41592-024-02212-x), [OME-TIFF](https://doi.org/10.1007/978-3-030-23937-4_1), and [OME-Zarr](https://doi.org/10.1038/s41592-021-01326-w):\n",
- "\n",
- "- [AnnDataWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.AnnDataWrapper)\n",
- "- [ImageOmeTiffWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ImageOmeTiffWrapper)\n",
- "- [ImageOmeZarrWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ImageOmeZarrWrapper)\n",
- "- [ObsSegmentationsOmeTiffWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ObsSegmentationsOmeTiffWrapper)\n",
- "- [ObsSegmentationsOmeZarrWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ObsSegmentationsOmeZarrWrapper)\n",
- "- [SpatialDataWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.SpatialDataWrapper)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "RGSE",
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " ViewType as vt,\n",
- " CoordinationType as ct,\n",
- " CoordinationLevel as CL,\n",
- " SpatialDataWrapper,\n",
- " AnnDataWrapper,\n",
- " ImageOmeTiffWrapper,\n",
- " ImageOmeZarrWrapper,\n",
- " ObsSegmentationsOmeZarrWrapper,\n",
- " get_initial_coordination_scope_prefix,\n",
- " hconcat,\n",
- " vconcat,\n",
- ")\n",
- "from vitessce.data_utils import (\n",
- " VAR_CHUNK_SIZE,\n",
- " generate_h5ad_ref_spec,\n",
- " multiplex_img_to_ome_tiff,\n",
- " multiplex_img_to_ome_zarr,\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Kclp",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "In this blog post, we perform basic data transformation tasks to save individual elements of an integrated SpatialData object to separate files in AnnData, OME-TIFF, and OME-Zarr formats.\n",
- "To perform these data transformations, we import the following dependencies.\n",
- "In general, you will typically not need to import all of these dependencies, either because you are only working with data in one of these formats, or because the data you intend to visualize is already saved to a file or directory."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "emfo",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Download example dataset"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Hstk",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "We download a mouse liver dataset which serves as a SpatialData [example dataset](https://github.com/scverse/spatialdata-notebooks/blob/main/notebooks/examples/transformations.ipynb).\n",
- "\n",
- "This dataset was generated by [Guilliams et al.](https://doi.org/10.1016/j.cell.2021.12.018) and processed using [SPArrOW](https://doi.org/10.1101/2024.07.04.601829) during the SpatialData [developer workshop](https://doi.org/10.37044/osf.io/8ck3e) in 2024."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "nWHF",
- "metadata": {},
- "outputs": [],
- "source": [
- "base_url = \"https://storage.googleapis.com/vitessce-demo-data/spatialdata-may-2025\""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "iLit",
- "metadata": {},
- "outputs": [],
- "source": [
- "zip_filepath = f\"{base_url}/mouse_liver.spatialdata.zarr.zip\"\n",
- "spatialdata_filepath = f\"{base_url}/mouse_liver.spatialdata.zarr\"\n",
- "adata_zarr_filepath = f\"{base_url}/mouse_liver.anndata.zarr\"\n",
- "adata_h5ad_filepath = f\"{base_url}/mouse_liver.h5ad\"\n",
- "ref_spec_json_filepath = f\"{base_url}/mouse_liver.h5ad.ref.json\"\n",
- "ome_tiff_filepath = f\"{base_url}/mouse_liver.ome.tif\"\n",
- "offsets_json_filepath = f\"{base_url}/mouse_liver.ome.tif.offsets.json\"\n",
- "ome_zarr_filepath = f\"{base_url}/mouse_liver.ome.zarr\"\n",
- "labels_ome_zarr_filepath = f\"{base_url}/mouse_liver.labels.ome.zarr\""
- ]
- },
- {
- "cell_type": "markdown",
- "id": "ZHCJ",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Visualization of a SpatialData object"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "ROlb",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "SpatialData objects are the most complex type of data structure we will work with in this blog post.\n",
- "SpatialData objects function as contains for multiple types of Spatial Elements:\n",
- "\n",
- "- Tables (each table is represented as an AnnData object)\n",
- "- Points (e.g., coordinates of transcripts from FISH-based experiments)\n",
- "- Shapes (vector-based shapes such as polygons and circles)\n",
- "- Labels (label images, i.e., segmentation bitmasks; each label image is stored using OME-Zarr)\n",
- "- Images (microscopy images; each image is stored using OME-Zarr)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "qnkX",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Configure Vitessce\n",
- "\n",
- "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views.\n",
- "To visualize data stored in a SpatialData object, we use the `SpatialDataWrapper` class and specify the paths (relative to the root of the Zarr [directory store](https://zarr.readthedocs.io/en/v2.18.5/api/storage.html#zarr.storage.DirectoryStore)) to different spatial elements of interest."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "TqIu",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version='1.0.18', name='SpatialData Demo')\n",
- "_wrapper = SpatialDataWrapper(sdata_url=spatialdata_filepath, table_path='tables/table', image_path='images/raw_image', obs_segmentations_path='labels/segmentation_mask', obs_feature_matrix_path='tables/table/X', obs_set_paths=['tables/table/obs/annotation'], obs_set_names=['Annotation'], region='nucleus_boundaries', coordinate_system='global', coordination_values={'obsType': 'cell'})\n",
- "_dataset = vc.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
- "_spatial = vc.add_view('spatialBeta', dataset=_dataset)\n",
- "feature_list = vc.add_view('featureList', dataset=_dataset)\n",
- "_layer_controller = vc.add_view('layerControllerBeta', dataset=_dataset)\n",
- "obs_sets = vc.add_view('obsSets', dataset=_dataset)\n",
- "_heatmap = vc.add_view('heatmap', dataset=_dataset)\n",
- "[obs_color_encoding_scope] = vc.add_coordination('obsColorEncoding')\n",
- "obs_color_encoding_scope.set_value('cellSetSelection')\n",
- "vc.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))\n",
- "vc.link_views_by_dict([_spatial, _layer_controller], {'segmentationLayer': CL([{'segmentationChannel': CL([{'obsColorEncoding': obs_color_encoding_scope}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'obsSegmentations'))\n",
- "vc.link_views([_spatial, _layer_controller, feature_list, obs_sets, _heatmap], ['obsType'], [_wrapper.obs_type_label])\n",
- "vc.link_views_by_dict([feature_list, obs_sets, _heatmap], {'obsColorEncoding': obs_color_encoding_scope}, meta=False)\n",
- "vc.layout(_spatial / _heatmap | _layer_controller / (feature_list | obs_sets))"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Vxnm",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "### Render the widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "DnEU",
- "metadata": {},
- "outputs": [],
- "source": [
- "_vw = vc.widget(height=900)\n",
- "_vw"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "ulZA",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Extract AnnData object from SpatialData object"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "ecfG",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "The above example demonstrates how to visualize a spatial 'omics dataset containing not only single-cell information (e.g., a cell-by-gene expression matrix, cell type annotations) but also an image and cell segmentations.\n",
- "To demonstrate how to use Vitessce to visualize data from a (non-spatial) single-cell experiment, we will extract this information from the SpatialData object and save it to a simpler [AnnData](https://anndata.readthedocs.io/) object (ignoring the imaging and spatially-resolved elements)."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Pvdt",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "As Zarr-formatted data can be easily visualized by Vitessce, we recommend saving the AnnData object to a Zarr store using the [write_zarr](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_zarr.html) method.\n",
- "Optionally, the shape of array chunks (for the AnnData `X` array) can be specified as a parameter, to optimize performance based on data access patterns.\n",
- "For example, a common pattern is to visualize data across all cells for one gene.\n",
- "To support such a pattern, the chunk shape can be specified as follows, `(total number of cells, small number of genes)`, resulting in tall-and-skinny array chunks."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "ZBYS",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "Alternatively, your AnnData object may already be stored using the H5AD (HDF5-based) format.\n",
- "To demonstrate this scenario, we save the object using the [write_h5ad](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_h5ad.html) method."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "aLJB",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "To read H5AD-formatted data, Vitessce requires an accompanying JSON [references specification](https://fsspec.github.io/kerchunk/spec.html) file, which can be constructed using the `generate_h5ad_ref_spec` utility function."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "nHfw",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Visualization of an AnnData object"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "xXTn",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "### Zarr-based AnnData"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "AjVT",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc_1 = VitessceConfig(schema_version='1.0.18', name='AnnData (zarr)')\n",
- "_wrapper = AnnDataWrapper(adata_url=adata_zarr_filepath, obs_feature_matrix_path='X', obs_set_paths=['obs/annotation'], obs_set_names=['Annotation'], coordination_values={'obsType': 'cell'})\n",
- "_dataset = vc_1.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
- "_heatmap = vc_1.add_view(vt.HEATMAP, dataset=_dataset)\n",
- "feature_list_1 = vc_1.add_view(vt.FEATURE_LIST, dataset=_dataset)\n",
- "obs_sets_1 = vc_1.add_view(vt.OBS_SETS, dataset=_dataset)\n",
- "_violin_plots = vc_1.add_view('obsSetFeatureValueDistribution', dataset=_dataset)\n",
- "vc_1.link_views([_heatmap, feature_list_1, obs_sets_1], ['obsType', 'featureValueColormapRange'], ['cell', [0, 0.01]])\n",
- "vc_1.layout(_heatmap / _violin_plots | feature_list_1 / obs_sets_1)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "pHFh",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc_1.widget()"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "NCOB",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "### H5AD-based AnnData"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "aqbW",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc_2 = VitessceConfig(schema_version='1.0.18', name='AnnData (h5ad)')\n",
- "_wrapper = AnnDataWrapper(adata_url=adata_h5ad_filepath, ref_url=ref_spec_json_filepath, obs_feature_matrix_path='X', obs_set_paths=['obs/annotation'], obs_set_names=['Annotation'], coordination_values={'obsType': 'cell'})\n",
- "_dataset = vc_2.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
- "_heatmap = vc_2.add_view(vt.HEATMAP, dataset=_dataset)\n",
- "feature_list_2 = vc_2.add_view(vt.FEATURE_LIST, dataset=_dataset)\n",
- "obs_sets_2 = vc_2.add_view(vt.OBS_SETS, dataset=_dataset)\n",
- "_violin_plots = vc_2.add_view('obsSetFeatureValueDistribution', dataset=_dataset)\n",
- "vc_2.link_views([_heatmap, feature_list_2, obs_sets_2], ['obsType', 'featureValueColormapRange'], ['cell', [0, 0.01]])\n",
- "vc_2.layout(_heatmap / _violin_plots | feature_list_2 / obs_sets_2)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "TRpd",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc_2.widget()"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "TXez",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Visualization of an image file"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "dNNg",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "### OME-Zarr image"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "yCnT",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc_3 = VitessceConfig(schema_version='1.0.18', name='Image (ome-zarr)')\n",
- "img_wrapper = ImageOmeZarrWrapper(img_url=ome_zarr_filepath, coordination_values={'fileUid': 'image'})\n",
- "segmentations_wrapper = ObsSegmentationsOmeZarrWrapper(img_url=labels_ome_zarr_filepath, coordination_values={'fileUid': 'segmentations'})\n",
- "_dataset = vc_3.add_dataset(name='Mouse Liver').add_object(img_wrapper).add_object(segmentations_wrapper)\n",
- "_spatial = vc_3.add_view('spatialBeta', dataset=_dataset)\n",
- "_layer_controller = vc_3.add_view('layerControllerBeta', dataset=_dataset)\n",
- "vc_3.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'fileUid': 'image', 'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))\n",
- "vc_3.link_views_by_dict([_spatial, _layer_controller], {'segmentationLayer': CL([{'fileUid': 'segmentations', 'segmentationChannel': CL([{'obsColorEncoding': 'spatialChannelColor', 'spatialChannelColor': [0, 255, 0], 'spatialChannelOpacity': 0.75, 'spatialSegmentationFilled': False, 'spatialSegmentationStrokeWidth': 0.25}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'obsSegmentations'))\n",
- "vc_3.link_views([_spatial, _layer_controller, feature_list_2, obs_sets_2], ['obsType'], ['cell'])\n",
- "vc_3.layout(hconcat(_spatial, _layer_controller, split=(2, 1)))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "wlCL",
- "metadata": {},
- "outputs": [],
- "source": [
- "_vw = vc_3.widget()\n",
- "_vw"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "kqZH",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "### OME-TIFF image"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "wAgl",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc_4 = VitessceConfig(schema_version='1.0.18', name='Image and segmentations (ome-tiff)')\n",
- "_wrapper = ImageOmeTiffWrapper(img_url=ome_tiff_filepath, offsets_url=offsets_json_filepath)\n",
- "_dataset = vc_4.add_dataset(name='Mouse Liver').add_object(_wrapper)\n",
- "_spatial = vc_4.add_view('spatialBeta', dataset=_dataset)\n",
- "_layer_controller = vc_4.add_view('layerControllerBeta', dataset=_dataset)\n",
- "vc_4.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))\n",
- "vc_4.layout(hconcat(_spatial, _layer_controller, split=(2, 1)))"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "rEll",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc_4.widget()"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "dGlV",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "## Data location options\n",
- "\n",
- "Vitessce can visualize data [not only stored](https://python-docs.vitessce.io/data_options.html) locally (referenced using local file or directory paths) but also stored remotely (referenced using absolute URL paths).\n",
- "Depending on whether the Python kernel running the Jupyter process is running locally versus remotely (e.g., on a cluster or cloud platform such as Google Colab), certain data locations may be challenging to access from the machine running the Jupyter notebook frontend (i.e., the machine on which the web browser used to view the notebook is installed).\n",
- "\n",
- "To provide data via one of these alternative mechanisms, use parameters with the following suffices when instantiating the data wrapper classes.\n",
- "\n",
- "- `_path`: Local file or directory\n",
- "- `_url`: Remote file or directory\n",
- "- `_store`: Zarr-store-accessible (for zarr-based formats)\n",
- "- `_artifact`: Lamin artifact\n",
- "\n",
- "For example, `adata_path` can be exchanged for one of the following options.\n",
- "\n",
- "```diff\n",
- "AnnDataWrapper(\n",
- "- adata_path=\"./mouse_liver.spatialdata.zarr\",\n",
- "+ adata_url=\"https://example.com/mouse_liver.spatialdata.zarr\", # Absolute URL\n",
- "+ adata_store=\"./mouse_liver.spatialdata.zarr\", # String interpreted as root of DirectoryStore\n",
- "+ adata_store=zarr.DirectoryStore(\"./mouse_liver.spatialdata.zarr\"), # Instance of zarr.storage\n",
- "+ adata_artifact=adata_zarr_artifact, # Instance of ln.Artifact\n",
- " ...\n",
- "```\n",
- "\n",
- "Note that the `_store` options are only available for Zarr-based formats, such as AnnDataWrapper, SpatialDataWrapper, and ImageOmeZarrWrapper.\n",
- "Further, when multiple files are required, such as both `adata_path` and `ref_path` (for the JSON reference specification file accompanying an H5AD file) or `img_path` and `offsets_path`, multiple parameter suffices may need to be changed."
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "SdmI",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/spatial_data_visium_hd.ipynb b/docs/notebooks/__ipynb__/spatial_data_visium_hd.ipynb
index 70d6aebf..dd1dd599 100644
--- a/docs/notebooks/__ipynb__/spatial_data_visium_hd.ipynb
+++ b/docs/notebooks/__ipynb__/spatial_data_visium_hd.ipynb
@@ -1,271 +1,279 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Vitessce Widget Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of a SpatialData object"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Import dependencies"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from os.path import join, isfile, isdir\n",
+ "from urllib.request import urlretrieve\n",
+ "import zipfile\n",
+ "\n",
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " ViewType as vt,\n",
+ " CoordinationType as ct,\n",
+ " CoordinationLevel as CL,\n",
+ " SpatialDataWrapper,\n",
+ " get_initial_coordination_scope_prefix\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "data_dir = \"data\"\n",
+ "zip_filepath = join(data_dir, \"visium_hd_3.0.0_io.zip\")\n",
+ "spatialdata_filepath = join(data_dir, \"visium_hd_3.0.0.spatialdata.zarr\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "if not isdir(spatialdata_filepath):\n",
+ " if not isfile(zip_filepath):\n",
+ " os.makedirs(data_dir, exist_ok=True)\n",
+ " urlretrieve('https://s3.embl.de/spatialdata/spatialdata-sandbox/visium_hd_3.0.0_io.zip', zip_filepath)\n",
+ " with zipfile.ZipFile(zip_filepath,\"r\") as zip_ref:\n",
+ " zip_ref.extractall(data_dir)\n",
+ " os.rename(join(data_dir, \"data.zarr\"), spatialdata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Xref",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Rasterize bins\n",
+ "Reference: https://spatialdata.scverse.org/en/stable/tutorials/notebooks/notebooks/examples/technology_visium_hd.html#performant-on-the-fly-data-rasterization"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from spatialdata import (\n",
+ " read_zarr,\n",
+ " rasterize_bins,\n",
+ " rasterize_bins_link_table_to_labels\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "sdata = read_zarr(spatialdata_filepath)\n",
+ "\n",
+ "for bin_size in [\"016\", \"008\", \"002\"]:\n",
+ " # rasterize_bins() requires a compresed sparse column (csc) matrix\n",
+ " sdata.tables[f\"square_{bin_size}um\"].X = sdata.tables[f\"square_{bin_size}um\"].X.tocsc()\n",
+ " rasterized = rasterize_bins(\n",
+ " sdata,\n",
+ " f\"Visium_HD_Mouse_Small_Intestine_square_{bin_size}um\",\n",
+ " f\"square_{bin_size}um\",\n",
+ " \"array_col\",\n",
+ " \"array_row\",\n",
+ " # We want to rasterize to a Labels element, rather than an Image element.\n",
+ " return_region_as_labels=True\n",
+ " )\n",
+ " sdata[f\"rasterized_{bin_size}um\"] = rasterized\n",
+ " rasterize_bins_link_table_to_labels(\n",
+ " sdata,\n",
+ " table_name=f\"square_{bin_size}um\",\n",
+ " rasterized_labels_name=f\"rasterized_{bin_size}um\",\n",
+ " )\n",
+ " try:\n",
+ " sdata.write_element(f\"rasterized_{bin_size}um\")\n",
+ " except:\n",
+ " pass\n",
+ "\n",
+ "sdata"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "sdata"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Kclp",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## Configure Vitessce\n",
+ "\n",
+ "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "emfo",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(\n",
+ " schema_version=\"1.0.18\",\n",
+ " name='Visium HD SpatialData Demo',\n",
+ ")\n",
+ "# Add data to the configuration:\n",
+ "wrapper = SpatialDataWrapper(\n",
+ " sdata_path=spatialdata_filepath,\n",
+ " # The following paths are relative to the root of the SpatialData zarr store on-disk.\n",
+ " image_path=\"images/Visium_HD_Mouse_Small_Intestine_full_image\",\n",
+ " table_path=\"tables/square_016um\",\n",
+ " obs_feature_matrix_path=\"tables/square_016um/X\",\n",
+ " obs_segmentations_path=\"labels/rasterized_016um\",\n",
+ " #region=\"CytAssist_FFPE_Human_Breast_Cancer\",\n",
+ " coordinate_system=\"Visium_HD_Mouse_Small_Intestine\",\n",
+ " coordination_values={\n",
+ " # The following tells Vitessce to consider each observation as a \"bin\"\n",
+ " \"obsType\": \"bin\",\n",
+ " }\n",
+ ")\n",
+ "dataset = vc.add_dataset(name='Visium HD').add_object(wrapper)\n",
+ "\n",
+ "# Add views (visualizations) to the configuration:\n",
+ "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
+ "feature_list = vc.add_view(\"featureList\", dataset=dataset)\n",
+ "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
+ "vc.link_views_by_dict([spatial, layer_controller], {\n",
+ " 'imageLayer': CL([{\n",
+ " 'photometricInterpretation': 'RGB',\n",
+ " }]),\n",
+ "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
+ "vc.link_views_by_dict([spatial, layer_controller], {\n",
+ " 'segmentationLayer': CL([{\n",
+ " 'segmentationChannel': CL([{\n",
+ " 'spatialChannelOpacity': 0.5,\n",
+ " 'obsColorEncoding': 'geneSelection',\n",
+ " 'featureValueColormapRange': [0, 0.5],\n",
+ " }])\n",
+ " }]),\n",
+ "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"obsSegmentations\"))\n",
+ "obs_sets = vc.add_view(vt.OBS_SETS, dataset=dataset)\n",
+ "vc.link_views([spatial, layer_controller, feature_list, obs_sets], ['obsType', 'featureSelection'], [wrapper.obs_type_label, ['AA986860']])\n",
+ "\n",
+ "# Layout the views\n",
+ "vc.layout(spatial | (feature_list / layer_controller / obs_sets));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hstk",
+ "metadata": {},
+ "source": [
+ "### Render the widget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "nWHF",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
}
- },
- "source": [
- "# Vitessce Widget Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "# Visualization of a SpatialData object"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "vblA",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Import dependencies"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "bkHC",
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join, isfile, isdir\n",
- "from urllib.request import urlretrieve\n",
- "import zipfile\n",
- "\n",
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " ViewType as vt,\n",
- " CoordinationType as ct,\n",
- " CoordinationLevel as CL,\n",
- " SpatialDataWrapper,\n",
- " get_initial_coordination_scope_prefix\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "lEQa",
- "metadata": {},
- "outputs": [],
- "source": [
- "data_dir = \"data\"\n",
- "zip_filepath = join(data_dir, \"visium_hd_3.0.0_io.zip\")\n",
- "spatialdata_filepath = join(data_dir, \"visium_hd_3.0.0.spatialdata.zarr\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "PKri",
- "metadata": {},
- "outputs": [],
- "source": [
- "if not isdir(spatialdata_filepath):\n",
- " if not isfile(zip_filepath):\n",
- " os.makedirs(data_dir, exist_ok=True)\n",
- " urlretrieve('https://s3.embl.de/spatialdata/spatialdata-sandbox/visium_hd_3.0.0_io.zip', zip_filepath)\n",
- " with zipfile.ZipFile(zip_filepath,\"r\") as zip_ref:\n",
- " zip_ref.extractall(data_dir)\n",
- " os.rename(join(data_dir, \"data.zarr\"), spatialdata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Xref",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "## Rasterize bins\n",
- "Reference: https://spatialdata.scverse.org/en/stable/tutorials/notebooks/notebooks/examples/technology_visium_hd.html#performant-on-the-fly-data-rasterization"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "SFPL",
- "metadata": {},
- "outputs": [],
- "source": [
- "from spatialdata import (\n",
- " read_zarr,\n",
- " rasterize_bins,\n",
- " rasterize_bins_link_table_to_labels\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "BYtC",
- "metadata": {},
- "outputs": [],
- "source": [
- "sdata = read_zarr(spatialdata_filepath)\n",
- "\n",
- "for bin_size in [\"016\", \"008\", \"002\"]:\n",
- " # rasterize_bins() requires a compresed sparse column (csc) matrix\n",
- " sdata.tables[f\"square_{bin_size}um\"].X = sdata.tables[f\"square_{bin_size}um\"].X.tocsc()\n",
- " rasterized = rasterize_bins(\n",
- " sdata,\n",
- " f\"Visium_HD_Mouse_Small_Intestine_square_{bin_size}um\",\n",
- " f\"square_{bin_size}um\",\n",
- " \"array_col\",\n",
- " \"array_row\",\n",
- " # We want to rasterize to a Labels element, rather than an Image element.\n",
- " return_region_as_labels=True\n",
- " )\n",
- " sdata[f\"rasterized_{bin_size}um\"] = rasterized\n",
- " rasterize_bins_link_table_to_labels(\n",
- " sdata,\n",
- " table_name=f\"square_{bin_size}um\",\n",
- " rasterized_labels_name=f\"rasterized_{bin_size}um\",\n",
- " )\n",
- " try:\n",
- " sdata.write_element(f\"rasterized_{bin_size}um\")\n",
- " except:\n",
- " pass\n",
- "\n",
- "sdata"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "RGSE",
- "metadata": {},
- "outputs": [],
- "source": [
- "sdata"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Kclp",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## Configure Vitessce\n",
- "\n",
- "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "emfo",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(\n",
- " schema_version=\"1.0.18\",\n",
- " name='Visium HD SpatialData Demo',\n",
- ")\n",
- "# Add data to the configuration:\n",
- "wrapper = SpatialDataWrapper(\n",
- " sdata_path=spatialdata_filepath,\n",
- " # The following paths are relative to the root of the SpatialData zarr store on-disk.\n",
- " image_path=\"images/Visium_HD_Mouse_Small_Intestine_full_image\",\n",
- " table_path=\"tables/square_016um\",\n",
- " obs_feature_matrix_path=\"tables/square_016um/X\",\n",
- " obs_segmentations_path=\"labels/rasterized_016um\",\n",
- " #region=\"CytAssist_FFPE_Human_Breast_Cancer\",\n",
- " coordinate_system=\"Visium_HD_Mouse_Small_Intestine\",\n",
- " coordination_values={\n",
- " # The following tells Vitessce to consider each observation as a \"bin\"\n",
- " \"obsType\": \"bin\",\n",
- " }\n",
- ")\n",
- "dataset = vc.add_dataset(name='Visium HD').add_object(wrapper)\n",
- "\n",
- "# Add views (visualizations) to the configuration:\n",
- "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
- "feature_list = vc.add_view(\"featureList\", dataset=dataset)\n",
- "layer_controller = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " 'imageLayer': CL([{\n",
- " 'photometricInterpretation': 'RGB',\n",
- " }]),\n",
- "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
- "vc.link_views_by_dict([spatial, layer_controller], {\n",
- " 'segmentationLayer': CL([{\n",
- " 'segmentationChannel': CL([{\n",
- " 'spatialChannelOpacity': 0.5,\n",
- " 'obsColorEncoding': 'geneSelection',\n",
- " 'featureValueColormapRange': [0, 0.5],\n",
- " }])\n",
- " }]),\n",
- "}, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"obsSegmentations\"))\n",
- "obs_sets = vc.add_view(vt.OBS_SETS, dataset=dataset)\n",
- "vc.link_views([spatial, layer_controller, feature_list, obs_sets], ['obsType', 'featureSelection'], [wrapper.obs_type_label, ['AA986860']])\n",
- "\n",
- "# Layout the views\n",
- "vc.layout(spatial | (feature_list / layer_controller / obs_sets));"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Hstk",
- "metadata": {},
- "source": [
- "### Render the widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "nWHF",
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "iLit",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/web_app_brain.ipynb b/docs/notebooks/__ipynb__/web_app_brain.ipynb
index 5ef1205f..ba5aeb17 100644
--- a/docs/notebooks/__ipynb__/web_app_brain.ipynb
+++ b/docs/notebooks/__ipynb__/web_app_brain.ipynb
@@ -1,336 +1,344 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Vitessce Web App Tutorial"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of single-cell RNA seq data using vitessce.io"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the classes and functions that we will be using from the corresponding packages."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from os.path import join\n",
+ "from urllib.request import urlretrieve\n",
+ "from anndata import read_h5ad\n",
+ "import scanpy as sc\n",
+ "\n",
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " AnnDataWrapper,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 2. Download the data\n",
+ "\n",
+ "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "os.makedirs(\"data\", exist_ok=True)\n",
+ "adata_filepath = join(\"data\", \"habib17.processed.h5ad\")\n",
+ "urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Xref",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 3. Load the data\n",
+ "\n",
+ "Note: this function may print a `FutureWarning`"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata = read_h5ad(adata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "BYtC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 3.1. Preprocess the Data For Visualization\n",
+ "\n",
+ "This dataset contains 25,587 genes. In order to visualize it efficiently, we convert it to CSC sparse format so that we can make fast requests for gene data. We also prepare to visualize the top 50 highly variable genes for the heatmap as ranked by dispersion norm, although one may use any boolean array filter for the heatmap."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "top_dispersion = adata.var[\"dispersions_norm\"][\n",
+ " sorted(\n",
+ " range(len(adata.var[\"dispersions_norm\"])),\n",
+ " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
+ " )[-51:][0]\n",
+ "]\n",
+ "adata.var[\"top_highly_variable\"] = (\n",
+ " adata.var[\"dispersions_norm\"] > top_dispersion\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Kclp",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 4. Create the Vitessce widget configuration\n",
+ "\n",
+ "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "emfo",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### 4.1. Instantiate a `VitessceConfig` object\n",
+ "\n",
+ "Use the `VitessceConfig(name, description)` constructor to create an instance."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Hstk",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', description='COVID-19 Healthy Donor Brain')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "nWHF",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### 4.2. Add a dataset to the `VitessceConfig` instance\n",
+ "\n",
+ "In Vitessce, a dataset is a container for one file per data type. The `.add_dataset(name)` method on the `vc` instance sets up and returns a new dataset instance.\n",
+ "\n",
+ "Then, we can call the dataset's `.add_object(wrapper_object)` method to attach a \"data wrapper\" instance to our new dataset. For example, the `AnnDataWrapper` class knows how to convert AnnData objects to the corresponding Vitessce data types.\n",
+ "\n",
+ "Dataset wrapper classes may require additional parameters to resolve ambiguities. For instance, `AnnData` objects may store multiple clusterings or cell type annotation columns in the `adata.obs` dataframe. We can use the parameter `cell_set_obs_cols` to tell Vitessce which columns of the `obs` dataframe correspond to cell sets."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "iLit",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
+ " adata,\n",
+ " obs_embedding_paths=[\"obsm/X_umap\"],\n",
+ " obs_embedding_names=[\"UMAP\"],\n",
+ " obs_set_paths=[\"obs/CellType\"],\n",
+ " obs_set_names=[\"Cell Type\"],\n",
+ " obs_feature_matrix_path=\"X\",\n",
+ " feature_filter_path=\"var/top_highly_variable\"\n",
+ " )\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ZHCJ",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### 4.3. Add visualizations to the `VitessceConfig` instance\n",
+ "\n",
+ "Now that we have added a dataset, we can configure visualizations. The `.add_view(dataset, component_type)` method adds a view (i.e. visualization or controller component) to the configuration.\n",
+ "\n",
+ "The `Component` enum class (which we have imported as `cm` here) can be used to fill in the `component_type` parameter.\n",
+ "\n",
+ "For convenience, the `SCATTERPLOT` component type takes the extra `mapping` keyword argument, which specifies which embedding should be used for mapping cells to (x,y) points on the plot."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ROlb",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
+ "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
+ "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
+ "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "qnkX",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### 4.4. Define the visualization layout\n",
+ "\n",
+ "The `vc.layout(view_concat)` method allows us to specify how our views will be arranged in the layout grid in the widget. The `|` and `/` characters are magic syntax for `hconcat(v1, v2)` and `vconcat(v1, v2)`, respectively."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "TqIu",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc.layout((scatterplot | cell_sets) / (heatmap | genes));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Vxnm",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 5. Launch the web application\n",
+ "\n",
+ "The `vc.web_app()` method serves the processed data locally and opens a web browser to `http://vitessce.io/?url={config_as_json}`"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "DnEU",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc.web_app()"
+ ]
}
- },
- "source": [
- "# Vitessce Web App Tutorial"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "# Visualization of single-cell RNA seq data using vitessce.io"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "vblA",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 1. Import dependencies\n",
- "\n",
- "We need to import the classes and functions that we will be using from the corresponding packages."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "bkHC",
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join\n",
- "from urllib.request import urlretrieve\n",
- "from anndata import read_h5ad\n",
- "import scanpy as sc\n",
- "\n",
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " AnnDataWrapper,\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "lEQa",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 2. Download the data\n",
- "\n",
- "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "PKri",
- "metadata": {},
- "outputs": [],
- "source": [
- "os.makedirs(\"data\", exist_ok=True)\n",
- "adata_filepath = join(\"data\", \"habib17.processed.h5ad\")\n",
- "urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Xref",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 3. Load the data\n",
- "\n",
- "Note: this function may print a `FutureWarning`"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "SFPL",
- "metadata": {},
- "outputs": [],
- "source": [
- "adata = read_h5ad(adata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "BYtC",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 3.1. Preprocess the Data For Visualization\n",
- "\n",
- "This dataset contains 25,587 genes. In order to visualize it efficiently, we convert it to CSC sparse format so that we can make fast requests for gene data. We also prepare to visualize the top 50 highly variable genes for the heatmap as ranked by dispersion norm, although one may use any boolean array filter for the heatmap."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "RGSE",
- "metadata": {},
- "outputs": [],
- "source": [
- "top_dispersion = adata.var[\"dispersions_norm\"][\n",
- " sorted(\n",
- " range(len(adata.var[\"dispersions_norm\"])),\n",
- " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
- " )[-51:][0]\n",
- "]\n",
- "adata.var[\"top_highly_variable\"] = (\n",
- " adata.var[\"dispersions_norm\"] > top_dispersion\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Kclp",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "## 4. Create the Vitessce widget configuration\n",
- "\n",
- "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "emfo",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "### 4.1. Instantiate a `VitessceConfig` object\n",
- "\n",
- "Use the `VitessceConfig(name, description)` constructor to create an instance."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Hstk",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', description='COVID-19 Healthy Donor Brain')"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "nWHF",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "### 4.2. Add a dataset to the `VitessceConfig` instance\n",
- "\n",
- "In Vitessce, a dataset is a container for one file per data type. The `.add_dataset(name)` method on the `vc` instance sets up and returns a new dataset instance.\n",
- "\n",
- "Then, we can call the dataset's `.add_object(wrapper_object)` method to attach a \"data wrapper\" instance to our new dataset. For example, the `AnnDataWrapper` class knows how to convert AnnData objects to the corresponding Vitessce data types.\n",
- "\n",
- "Dataset wrapper classes may require additional parameters to resolve ambiguities. For instance, `AnnData` objects may store multiple clusterings or cell type annotation columns in the `adata.obs` dataframe. We can use the parameter `cell_set_obs_cols` to tell Vitessce which columns of the `obs` dataframe correspond to cell sets."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "iLit",
- "metadata": {},
- "outputs": [],
- "source": [
- "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
- " adata,\n",
- " obs_embedding_paths=[\"obsm/X_umap\"],\n",
- " obs_embedding_names=[\"UMAP\"],\n",
- " obs_set_paths=[\"obs/CellType\"],\n",
- " obs_set_names=[\"Cell Type\"],\n",
- " obs_feature_matrix_path=\"X\",\n",
- " feature_filter_path=\"var/top_highly_variable\"\n",
- " )\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "ZHCJ",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "### 4.3. Add visualizations to the `VitessceConfig` instance\n",
- "\n",
- "Now that we have added a dataset, we can configure visualizations. The `.add_view(dataset, component_type)` method adds a view (i.e. visualization or controller component) to the configuration.\n",
- "\n",
- "The `Component` enum class (which we have imported as `cm` here) can be used to fill in the `component_type` parameter.\n",
- "\n",
- "For convenience, the `SCATTERPLOT` component type takes the extra `mapping` keyword argument, which specifies which embedding should be used for mapping cells to (x,y) points on the plot."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "ROlb",
- "metadata": {},
- "outputs": [],
- "source": [
- "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
- "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
- "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
- "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "qnkX",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "### 4.4. Define the visualization layout\n",
- "\n",
- "The `vc.layout(view_concat)` method allows us to specify how our views will be arranged in the layout grid in the widget. The `|` and `/` characters are magic syntax for `hconcat(v1, v2)` and `vconcat(v1, v2)`, respectively."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "TqIu",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc.layout((scatterplot | cell_sets) / (heatmap | genes));"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Vxnm",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 5. Launch the web application\n",
- "\n",
- "The `vc.web_app()` method serves the processed data locally and opens a web browser to `http://vitessce.io/?url={config_as_json}`"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "DnEU",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc.web_app()"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "ulZA",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/widget_anndata_with_image.ipynb b/docs/notebooks/__ipynb__/widget_anndata_with_image.ipynb
index 64747b59..3d1e38ca 100644
--- a/docs/notebooks/__ipynb__/widget_anndata_with_image.ipynb
+++ b/docs/notebooks/__ipynb__/widget_anndata_with_image.ipynb
@@ -1,132 +1,140 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of AnnData object containing an image in `uns`"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "Note: This approach to storing images within AnnData objects is no longer recommended now that [SpatialData](https://spatialdata.scverse.org/en/stable/) has been introduced."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import scanpy as sc\n",
+ "import numpy as np\n",
+ "from vitessce.data_utils import rgb_img_to_ome_zarr, VAR_CHUNK_SIZE\n",
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " AnnDataWrapper,\n",
+ " ImageOmeZarrWrapper,\n",
+ ")\n",
+ "from os.path import join"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "output_img = join(\"data\", \"V1_Human_Lymph_Node.ome.zarr\")\n",
+ "output_adata = join(\"data\", \"V1_Human_Lymph_Node.anndata.zarr\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata = sc.datasets.visium_sge(sample_id=\"V1_Human_Lymph_Node\", include_hires_tiff=True)\n",
+ "\n",
+ "# Write img_arr to OME-Zarr.\n",
+ "# Need to convert images from interleaved to non-interleaved (color axis should be first).\n",
+ "img_hires = adata.uns['spatial']['V1_Human_Lymph_Node']['images']['hires']\n",
+ "img_arr = np.transpose(img_hires, (2, 0, 1))\n",
+ "# Convert values from [0, 1] to [0, 255].\n",
+ "img_arr *= 255.0\n",
+ "\n",
+ "# First, save the image to an OME-Zarr image format\n",
+ "rgb_img_to_ome_zarr(img_arr, output_img, axes=\"cyx\", chunks=(1, 256, 256), img_name=\"Image\")\n",
+ "# Second, save the AnnData object to Zarr format\n",
+ "adata.write_zarr(output_adata, chunks=[adata.shape[0], VAR_CHUNK_SIZE])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.17\", name=\"AnnData with image\")\n",
+ "dataset = vc.add_dataset(\"My dataset\").add_object(\n",
+ " AnnDataWrapper(\n",
+ " adata_path=output_adata,\n",
+ "\n",
+ " )\n",
+ ").add_object(\n",
+ " ImageOmeZarrWrapper(\n",
+ " img_path=output_img,\n",
+ " )\n",
+ ")\n",
+ "\n",
+ "spatial_view = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
+ "lc_view = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
+ "\n",
+ "vc.layout(spatial_view | lc_view);"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
}
- },
- "source": [
- "# Visualization of AnnData object containing an image in `uns`"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "Note: This approach to storing images within AnnData objects is no longer recommended now that [SpatialData](https://spatialdata.scverse.org/en/stable/) has been introduced."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "vblA",
- "metadata": {},
- "outputs": [],
- "source": [
- "import scanpy as sc\n",
- "import numpy as np\n",
- "from vitessce.data_utils import rgb_img_to_ome_zarr, VAR_CHUNK_SIZE\n",
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " AnnDataWrapper,\n",
- " ImageOmeZarrWrapper,\n",
- ")\n",
- "from os.path import join"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "bkHC",
- "metadata": {},
- "outputs": [],
- "source": [
- "output_img = join(\"data\", \"V1_Human_Lymph_Node.ome.zarr\")\n",
- "output_adata = join(\"data\", \"V1_Human_Lymph_Node.anndata.zarr\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "lEQa",
- "metadata": {},
- "outputs": [],
- "source": [
- "adata = sc.datasets.visium_sge(sample_id=\"V1_Human_Lymph_Node\", include_hires_tiff=True)\n",
- "\n",
- "# Write img_arr to OME-Zarr.\n",
- "# Need to convert images from interleaved to non-interleaved (color axis should be first).\n",
- "img_hires = adata.uns['spatial']['V1_Human_Lymph_Node']['images']['hires']\n",
- "img_arr = np.transpose(img_hires, (2, 0, 1))\n",
- "# Convert values from [0, 1] to [0, 255].\n",
- "img_arr *= 255.0\n",
- "\n",
- "# First, save the image to an OME-Zarr image format\n",
- "rgb_img_to_ome_zarr(img_arr, output_img, axes=\"cyx\", chunks=(1, 256, 256), img_name=\"Image\")\n",
- "# Second, save the AnnData object to Zarr format\n",
- "adata.write_zarr(output_adata, chunks=[adata.shape[0], VAR_CHUNK_SIZE])"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "PKri",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.17\", name=\"AnnData with image\")\n",
- "dataset = vc.add_dataset(\"My dataset\").add_object(\n",
- " AnnDataWrapper(\n",
- " adata_path=output_adata,\n",
- "\n",
- " )\n",
- ").add_object(\n",
- " ImageOmeZarrWrapper(\n",
- " img_path=output_img,\n",
- " )\n",
- ")\n",
- "\n",
- "spatial_view = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
- "lc_view = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
- "\n",
- "vc.layout(spatial_view | lc_view);"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "SFPL",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/widget_brain.ipynb b/docs/notebooks/__ipynb__/widget_brain.ipynb
index a0ac732f..9e7cedb4 100644
--- a/docs/notebooks/__ipynb__/widget_brain.ipynb
+++ b/docs/notebooks/__ipynb__/widget_brain.ipynb
@@ -1,357 +1,365 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of single-cell RNA seq data"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the classes and functions that we will be using from the corresponding packages."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from os.path import join, isfile, isdir\n",
+ "from urllib.request import urlretrieve\n",
+ "from anndata import read_h5ad\n",
+ "import scanpy as sc\n",
+ "\n",
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " AnnDataWrapper,\n",
+ ")\n",
+ "from vitessce.data_utils import (\n",
+ " optimize_adata,\n",
+ " VAR_CHUNK_SIZE,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 2. Download the data\n",
+ "\n",
+ "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata_filepath = join(\"data\", \"habib17.processed.h5ad\")\n",
+ "if not isfile(adata_filepath):\n",
+ " os.makedirs(\"data\", exist_ok=True)\n",
+ " urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "PKri",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 3. Load the data\n",
+ "\n",
+ "Note: this function may print a `FutureWarning`"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata = read_h5ad(adata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 3.1. Preprocess the Data For Visualization\n",
+ "\n",
+ "This dataset contains 25,587 genes. We prepare to visualize the top 50 highly variable genes for the heatmap as ranked by dispersion norm, although one may use any boolean array filter for the heatmap."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "top_dispersion = adata.var[\"dispersions_norm\"][\n",
+ " sorted(\n",
+ " range(len(adata.var[\"dispersions_norm\"])),\n",
+ " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
+ " )[-51:][0]\n",
+ "]\n",
+ "adata.var[\"top_highly_variable\"] = (\n",
+ " adata.var[\"dispersions_norm\"] > top_dispersion\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "RGSE",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 3.2 Save the Data to Zarr store\n",
+ "\n",
+ "We want to convert the original `h5ad` file to a [Zarr](https://zarr.readthedocs.io/en/stable/) store, which Vitessce is able to load. We can use the `optimize_adata` function to ensure that all arrays and dataframe columns that we intend to use in our visualization are in the optimal format to be loaded by Vitessce. This function will cast arrays to numerical data types that take up less space (as long as the values allow). Note: unused arrays and columns (i.e., not specified in any of the parameters to `optimize_adata`) will not be copied into the new AnnData object."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Kclp",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "zarr_filepath = join('data', 'habib17.processed.zarr')\n",
+ "if not isdir(zarr_filepath):\n",
+ " adata_1 = optimize_adata(adata, obs_cols=['CellType'], obsm_keys=['X_umap'], optimize_X=True, var_cols=['top_highly_variable'])\n",
+ " adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "emfo",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 4. Create the Vitessce widget configuration\n",
+ "\n",
+ "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hstk",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### 4.1. Instantiate a `VitessceConfig` object\n",
+ "\n",
+ "Use the `VitessceConfig` constructor to create an instance."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "nWHF",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', description='COVID-19 Healthy Donor Brain')"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "iLit",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### 4.2. Add a dataset to the `VitessceConfig` instance\n",
+ "\n",
+ "In Vitessce, a dataset is a container for one file per data type. The `.add_dataset(name)` method on the `vc` instance sets up and returns a new dataset instance.\n",
+ "\n",
+ "Then, we can call the dataset's `.add_object(wrapper_object)` method to attach a \"data wrapper\" instance to our new dataset. For example, the `AnnDataWrapper` helps to configure AnnData Zarr stores for use in the Vitessce configuration.\n",
+ "\n",
+ "Dataset wrapper classes may require additional parameters to resolve ambiguities. For instance, `AnnData` objects may store multiple clusterings or cell type annotation columns in the `adata.obs` dataframe. We can use the parameter `obs_set_paths` to tell Vitessce that certain columns of the `obs` dataframe correspond to cell type annotations or cell clusterings."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ZHCJ",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
+ " adata_path=zarr_filepath,\n",
+ " obs_embedding_paths=[\"obsm/X_umap\"],\n",
+ " obs_embedding_names=[\"UMAP\"],\n",
+ " obs_set_paths=[\"obs/CellType\"],\n",
+ " obs_set_names=[\"Cell Type\"],\n",
+ " obs_feature_matrix_path=\"X\",\n",
+ " initial_feature_filter_path=\"var/top_highly_variable\"\n",
+ " )\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ROlb",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### 4.3. Add visualizations to the `VitessceConfig` instance\n",
+ "\n",
+ "Now that we have added a dataset, we can configure visualizations. The `.add_view` method adds a view (i.e. visualization or controller component) to the configuration.\n",
+ "\n",
+ "The `Component` enum class (which we have imported as `cm` here) can be used to fill in the `component_type` parameter.\n",
+ "\n",
+ "For convenience, the `SCATTERPLOT` component type takes the extra `mapping` keyword argument, which specifies which embedding should be used for mapping cells to (x,y) points on the plot."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "qnkX",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
+ "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
+ "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
+ "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "TqIu",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### 4.4. Define the visualization layout\n",
+ "\n",
+ "The `vc.layout(view_concat)` method allows us to specify how our views will be arranged in the layout grid in the widget. The `|` and `/` characters are magic syntax for `hconcat(v1, v2)` and `vconcat(v1, v2)`, respectively."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Vxnm",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc.layout((scatterplot | cell_sets) / (heatmap | genes));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "DnEU",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 5. Create the widget\n",
+ "\n",
+ "The `vc.widget()` method returns the configured widget instance."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ulZA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
}
- },
- "source": [
- "# Visualization of single-cell RNA seq data"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 1. Import dependencies\n",
- "\n",
- "We need to import the classes and functions that we will be using from the corresponding packages."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "vblA",
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join, isfile, isdir\n",
- "from urllib.request import urlretrieve\n",
- "from anndata import read_h5ad\n",
- "import scanpy as sc\n",
- "\n",
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " AnnDataWrapper,\n",
- ")\n",
- "from vitessce.data_utils import (\n",
- " optimize_adata,\n",
- " VAR_CHUNK_SIZE,\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "bkHC",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 2. Download the data\n",
- "\n",
- "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "lEQa",
- "metadata": {},
- "outputs": [],
- "source": [
- "adata_filepath = join(\"data\", \"habib17.processed.h5ad\")\n",
- "if not isfile(adata_filepath):\n",
- " os.makedirs(\"data\", exist_ok=True)\n",
- " urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "PKri",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 3. Load the data\n",
- "\n",
- "Note: this function may print a `FutureWarning`"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "adata = read_h5ad(adata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "SFPL",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 3.1. Preprocess the Data For Visualization\n",
- "\n",
- "This dataset contains 25,587 genes. We prepare to visualize the top 50 highly variable genes for the heatmap as ranked by dispersion norm, although one may use any boolean array filter for the heatmap."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "BYtC",
- "metadata": {},
- "outputs": [],
- "source": [
- "top_dispersion = adata.var[\"dispersions_norm\"][\n",
- " sorted(\n",
- " range(len(adata.var[\"dispersions_norm\"])),\n",
- " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
- " )[-51:][0]\n",
- "]\n",
- "adata.var[\"top_highly_variable\"] = (\n",
- " adata.var[\"dispersions_norm\"] > top_dispersion\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "RGSE",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 3.2 Save the Data to Zarr store\n",
- "\n",
- "We want to convert the original `h5ad` file to a [Zarr](https://zarr.readthedocs.io/en/stable/) store, which Vitessce is able to load. We can use the `optimize_adata` function to ensure that all arrays and dataframe columns that we intend to use in our visualization are in the optimal format to be loaded by Vitessce. This function will cast arrays to numerical data types that take up less space (as long as the values allow). Note: unused arrays and columns (i.e., not specified in any of the parameters to `optimize_adata`) will not be copied into the new AnnData object."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Kclp",
- "metadata": {},
- "outputs": [],
- "source": [
- "zarr_filepath = join('data', 'habib17.processed.zarr')\n",
- "if not isdir(zarr_filepath):\n",
- " adata_1 = optimize_adata(adata, obs_cols=['CellType'], obsm_keys=['X_umap'], optimize_X=True, var_cols=['top_highly_variable'])\n",
- " adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "emfo",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "## 4. Create the Vitessce widget configuration\n",
- "\n",
- "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Hstk",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "### 4.1. Instantiate a `VitessceConfig` object\n",
- "\n",
- "Use the `VitessceConfig` constructor to create an instance."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "nWHF",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', description='COVID-19 Healthy Donor Brain')"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "iLit",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "### 4.2. Add a dataset to the `VitessceConfig` instance\n",
- "\n",
- "In Vitessce, a dataset is a container for one file per data type. The `.add_dataset(name)` method on the `vc` instance sets up and returns a new dataset instance.\n",
- "\n",
- "Then, we can call the dataset's `.add_object(wrapper_object)` method to attach a \"data wrapper\" instance to our new dataset. For example, the `AnnDataWrapper` helps to configure AnnData Zarr stores for use in the Vitessce configuration.\n",
- "\n",
- "Dataset wrapper classes may require additional parameters to resolve ambiguities. For instance, `AnnData` objects may store multiple clusterings or cell type annotation columns in the `adata.obs` dataframe. We can use the parameter `obs_set_paths` to tell Vitessce that certain columns of the `obs` dataframe correspond to cell type annotations or cell clusterings."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "ZHCJ",
- "metadata": {},
- "outputs": [],
- "source": [
- "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
- " adata_path=zarr_filepath,\n",
- " obs_embedding_paths=[\"obsm/X_umap\"],\n",
- " obs_embedding_names=[\"UMAP\"],\n",
- " obs_set_paths=[\"obs/CellType\"],\n",
- " obs_set_names=[\"Cell Type\"],\n",
- " obs_feature_matrix_path=\"X\",\n",
- " initial_feature_filter_path=\"var/top_highly_variable\"\n",
- " )\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "ROlb",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "### 4.3. Add visualizations to the `VitessceConfig` instance\n",
- "\n",
- "Now that we have added a dataset, we can configure visualizations. The `.add_view` method adds a view (i.e. visualization or controller component) to the configuration.\n",
- "\n",
- "The `Component` enum class (which we have imported as `cm` here) can be used to fill in the `component_type` parameter.\n",
- "\n",
- "For convenience, the `SCATTERPLOT` component type takes the extra `mapping` keyword argument, which specifies which embedding should be used for mapping cells to (x,y) points on the plot."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "qnkX",
- "metadata": {},
- "outputs": [],
- "source": [
- "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
- "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
- "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
- "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "TqIu",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "### 4.4. Define the visualization layout\n",
- "\n",
- "The `vc.layout(view_concat)` method allows us to specify how our views will be arranged in the layout grid in the widget. The `|` and `/` characters are magic syntax for `hconcat(v1, v2)` and `vconcat(v1, v2)`, respectively."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Vxnm",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc.layout((scatterplot | cell_sets) / (heatmap | genes));"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "DnEU",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 5. Create the widget\n",
- "\n",
- "The `vc.widget()` method returns the configured widget instance."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "ulZA",
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "ecfG",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/widget_brain_h5ad.ipynb b/docs/notebooks/__ipynb__/widget_brain_h5ad.ipynb
index b4f56631..67dc0d6a 100644
--- a/docs/notebooks/__ipynb__/widget_brain_h5ad.ipynb
+++ b/docs/notebooks/__ipynb__/widget_brain_h5ad.ipynb
@@ -1,190 +1,198 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of single-cell RNA seq data from H5AD file"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "MJUe",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from os.path import join, isfile, isdir\n",
+ "from urllib.request import urlretrieve\n",
+ "from anndata import read_h5ad\n",
+ "import scanpy as sc\n",
+ "import json\n",
+ "\n",
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " AnnDataWrapper,\n",
+ ")\n",
+ "from vitessce.data_utils import (\n",
+ " generate_h5ad_ref_spec\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 0. Download data"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "h5_url = \"https://datasets.cellxgene.cziscience.com/84df8fa1-ab53-43c9-a439-95dcb9148265.h5ad\""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata_filepath = join(\"data\", \"84df8fa1-ab53-43c9-a439-95dcb9148265.h5ad\")\n",
+ "if not isfile(adata_filepath):\n",
+ " os.makedirs(\"data\", exist_ok=True)\n",
+ " urlretrieve(h5_url, adata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "PKri",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Create a Reference Spec JSON file for the H5AD file\n",
+ "\n",
+ "In order for Vitessce to load H5AD files, we also need to provide a corresponding [Reference Spec](https://fsspec.github.io/kerchunk/spec.html) JSON file which contains mappings between AnnData object keys and the byte offsets at which those AnnData object values begin within the H5AD file binary contents."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "json_filepath = join(\"data\", \"84df8fa1-ab53-43c9-a439-95dcb9148265.h5ad.reference.json\")\n",
+ "if not isfile(json_filepath):\n",
+ " ref_dict = generate_h5ad_ref_spec(h5_url)\n",
+ " with open(json_filepath, \"w\") as f:\n",
+ " json.dump(ref_dict, f)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 2. Create the Vitessce widget configuration"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.17\", name='Nakshatri et al', description='snRNA-seq analyses of breast tissues of healthy women of diverse genetic ancestry')\n",
+ "\n",
+ "dataset = vc.add_dataset(name='84df8fa1').add_object(AnnDataWrapper(\n",
+ " adata_path=adata_filepath,\n",
+ " ref_path=json_filepath, # We specify paths to both the H5AD and JSON files\n",
+ " obs_embedding_paths=[\"obsm/X_wnn.umap\"],\n",
+ " obs_embedding_names=[\"UMAP\"],\n",
+ " obs_set_paths=[\"obs/cell_type\"],\n",
+ " obs_set_names=[\"Cell Type\"],\n",
+ " obs_feature_matrix_path=\"X\",\n",
+ " )\n",
+ ")\n",
+ "\n",
+ "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
+ "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
+ "cell_set_sizes = vc.add_view(cm.OBS_SET_SIZES, dataset=dataset)\n",
+ "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
+ "\n",
+ "vc.layout((scatterplot | cell_sets) / (cell_set_sizes | genes));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "RGSE",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 3. Create the widget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Kclp",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
}
- },
- "source": [
- "# Visualization of single-cell RNA seq data from H5AD file"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "MJUe",
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join, isfile, isdir\n",
- "from urllib.request import urlretrieve\n",
- "from anndata import read_h5ad\n",
- "import scanpy as sc\n",
- "import json\n",
- "\n",
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " AnnDataWrapper,\n",
- ")\n",
- "from vitessce.data_utils import (\n",
- " generate_h5ad_ref_spec\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "vblA",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "## 0. Download data"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "bkHC",
- "metadata": {},
- "outputs": [],
- "source": [
- "h5_url = \"https://datasets.cellxgene.cziscience.com/84df8fa1-ab53-43c9-a439-95dcb9148265.h5ad\""
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "lEQa",
- "metadata": {},
- "outputs": [],
- "source": [
- "adata_filepath = join(\"data\", \"84df8fa1-ab53-43c9-a439-95dcb9148265.h5ad\")\n",
- "if not isfile(adata_filepath):\n",
- " os.makedirs(\"data\", exist_ok=True)\n",
- " urlretrieve(h5_url, adata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "PKri",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 1. Create a Reference Spec JSON file for the H5AD file\n",
- "\n",
- "In order for Vitessce to load H5AD files, we also need to provide a corresponding [Reference Spec](https://fsspec.github.io/kerchunk/spec.html) JSON file which contains mappings between AnnData object keys and the byte offsets at which those AnnData object values begin within the H5AD file binary contents."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "json_filepath = join(\"data\", \"84df8fa1-ab53-43c9-a439-95dcb9148265.h5ad.reference.json\")\n",
- "if not isfile(json_filepath):\n",
- " ref_dict = generate_h5ad_ref_spec(h5_url)\n",
- " with open(json_filepath, \"w\") as f:\n",
- " json.dump(ref_dict, f)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "SFPL",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 2. Create the Vitessce widget configuration"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "BYtC",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.17\", name='Nakshatri et al', description='snRNA-seq analyses of breast tissues of healthy women of diverse genetic ancestry')\n",
- "\n",
- "dataset = vc.add_dataset(name='84df8fa1').add_object(AnnDataWrapper(\n",
- " adata_path=adata_filepath,\n",
- " ref_path=json_filepath, # We specify paths to both the H5AD and JSON files\n",
- " obs_embedding_paths=[\"obsm/X_wnn.umap\"],\n",
- " obs_embedding_names=[\"UMAP\"],\n",
- " obs_set_paths=[\"obs/cell_type\"],\n",
- " obs_set_names=[\"Cell Type\"],\n",
- " obs_feature_matrix_path=\"X\",\n",
- " )\n",
- ")\n",
- "\n",
- "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
- "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
- "cell_set_sizes = vc.add_view(cm.OBS_SET_SIZES, dataset=dataset)\n",
- "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
- "\n",
- "vc.layout((scatterplot | cell_sets) / (cell_set_sizes | genes));"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "RGSE",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 3. Create the widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Kclp",
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "emfo",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/widget_brain_with_base_dir.ipynb b/docs/notebooks/__ipynb__/widget_brain_with_base_dir.ipynb
index 0f03d764..2eb26bb6 100644
--- a/docs/notebooks/__ipynb__/widget_brain_with_base_dir.ipynb
+++ b/docs/notebooks/__ipynb__/widget_brain_with_base_dir.ipynb
@@ -1,414 +1,422 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Configure relative to a base_dir"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the classes and functions that we will be using from the corresponding packages."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from os.path import join, isfile, isdir\n",
+ "from urllib.request import urlretrieve\n",
+ "from anndata import read_h5ad\n",
+ "\n",
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " AnnDataWrapper,\n",
+ " BASE_URL_PLACEHOLDER,\n",
+ ")\n",
+ "from vitessce.data_utils import (\n",
+ " optimize_adata,\n",
+ " VAR_CHUNK_SIZE,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 2. Define a `base_dir`\n",
+ "\n",
+ "We will define a `base_dir` inside which our data will live. We will provide this to `VitessceConfig` in order to construct a configuration that contains URL paths relative to this directory."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "BASE_DIR = \"data\""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "PKri",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 3. Download the data\n",
+ "\n",
+ "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata_relative_filepath = \"habib17.processed.h5ad\" # Relative to BASE_DIR\n",
+ "adata_filepath = join(BASE_DIR, adata_relative_filepath)\n",
+ "if not isfile(adata_filepath):\n",
+ " os.makedirs(BASE_DIR, exist_ok=True)\n",
+ " urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 4. Load the data\n",
+ "\n",
+ "Note: this function may print a `FutureWarning`"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata = read_h5ad(adata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "RGSE",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 4.1. Preprocess the Data For Visualization\n",
+ "\n",
+ "This dataset contains 25,587 genes. We prepare to visualize the top 50 highly variable genes for the heatmap as ranked by dispersion norm, although one may use any boolean array filter for the heatmap."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Kclp",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "top_dispersion = adata.var[\"dispersions_norm\"][\n",
+ " sorted(\n",
+ " range(len(adata.var[\"dispersions_norm\"])),\n",
+ " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
+ " )[-51:][0]\n",
+ "]\n",
+ "adata.var[\"top_highly_variable\"] = (\n",
+ " adata.var[\"dispersions_norm\"] > top_dispersion\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "emfo",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 4.2 Save the Data to Zarr store\n",
+ "\n",
+ "We want to convert the original `h5ad` file to a [Zarr](https://zarr.readthedocs.io/en/stable/) store, which Vitessce is able to load. We can use the `optimize_adata` function to ensure that all arrays and dataframe columns that we intend to use in our visualization are in the optimal format to be loaded by Vitessce. This function will cast arrays to numerical data types that take up less space (as long as the values allow). Note: unused arrays and columns (i.e., not specified in any of the parameters to `optimize_adata`) will not be copied into the new AnnData object."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Hstk",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "zarr_relative_filepath = 'habib17.processed.zarr'\n",
+ "zarr_filepath = join(BASE_DIR, zarr_relative_filepath)\n",
+ "if not isdir(zarr_filepath):\n",
+ " adata_1 = optimize_adata(adata, obs_cols=['CellType'], obsm_keys=['X_umap'], optimize_X=True, var_cols=['top_highly_variable'])\n",
+ " adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "nWHF",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 5. Create the Vitessce widget configuration\n",
+ "\n",
+ "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "iLit",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### 5.1. Instantiate a `VitessceConfig` object\n",
+ "\n",
+ "Use the `VitessceConfig` constructor to create an instance. In this case, we want to construct our configuration using local data that is relative to a particular directory, so we provide the `base_dir` parameter.\n",
+ "\n",
+ "Note: This `base_dir` parameter is optional. When it is omitted, local data paths are assumed to be relative to the current working directory."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ZHCJ",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', base_dir=BASE_DIR)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ROlb",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### 5.2. Add a dataset to the `VitessceConfig` instance\n",
+ "\n",
+ "In Vitessce, a dataset is a container for one file per data type. The `.add_dataset(name)` method on the `vc` instance sets up and returns a new dataset instance.\n",
+ "\n",
+ "Then, we can call the dataset's `.add_object(wrapper_object)` method to attach a \"data wrapper\" instance to our new dataset. For example, the `AnnDataWrapper` helps to configure AnnData Zarr stores for use in the Vitessce configuration.\n",
+ "\n",
+ "Dataset wrapper classes may require additional parameters to resolve ambiguities. For instance, `AnnData` objects may store multiple clusterings or cell type annotation columns in the `adata.obs` dataframe. We can use the parameter `obs_set_paths` to tell Vitessce that certain columns of the `obs` dataframe correspond to cell type annotations or cell clusterings."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "qnkX",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
+ " adata_path=zarr_relative_filepath, # Relative to BASE_DIR (because we specified base_dir in the VitessceConfig constructor)\n",
+ " obs_embedding_paths=[\"obsm/X_umap\"],\n",
+ " obs_embedding_names=[\"UMAP\"],\n",
+ " obs_set_paths=[\"obs/CellType\"],\n",
+ " obs_set_names=[\"Cell Type\"],\n",
+ " obs_feature_matrix_path=\"X\",\n",
+ " initial_feature_filter_path=\"var/top_highly_variable\"\n",
+ " )\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "TqIu",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### 5.3. Add visualizations to the `VitessceConfig` instance\n",
+ "\n",
+ "Now that we have added a dataset, we can configure visualizations. The `.add_view` method adds a view (i.e. visualization or controller component) to the configuration.\n",
+ "\n",
+ "The `Component` enum class (which we have imported as `cm` here) can be used to fill in the `component_type` parameter.\n",
+ "\n",
+ "For convenience, the `SCATTERPLOT` component type takes the extra `mapping` keyword argument, which specifies which embedding should be used for mapping cells to (x,y) points on the plot."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Vxnm",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
+ "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
+ "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
+ "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "DnEU",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "### 5.4. Define the visualization layout\n",
+ "\n",
+ "The `vc.layout(view_concat)` method allows us to specify how our views will be arranged in the layout grid in the widget. The `|` and `/` characters are magic syntax for `hconcat(v1, v2)` and `vconcat(v1, v2)`, respectively."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ulZA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc.layout((scatterplot | cell_sets) / (heatmap | genes));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ecfG",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 6. Create the widget\n",
+ "\n",
+ "The `vc.widget()` method returns the configured widget instance."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Pvdt",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "ZBYS",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 7. Check the URLs in the configuration\n",
+ "\n",
+ "We can check that the data URLs in the configuration respected the specified `base_dir`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "aLJB",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "config_dict = vc.to_dict(base_url=BASE_URL_PLACEHOLDER)\n",
+ "config_dict"
+ ]
}
- },
- "source": [
- "# Configure relative to a base_dir"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 1. Import dependencies\n",
- "\n",
- "We need to import the classes and functions that we will be using from the corresponding packages."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "vblA",
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join, isfile, isdir\n",
- "from urllib.request import urlretrieve\n",
- "from anndata import read_h5ad\n",
- "\n",
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " AnnDataWrapper,\n",
- " BASE_URL_PLACEHOLDER,\n",
- ")\n",
- "from vitessce.data_utils import (\n",
- " optimize_adata,\n",
- " VAR_CHUNK_SIZE,\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "bkHC",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 2. Define a `base_dir`\n",
- "\n",
- "We will define a `base_dir` inside which our data will live. We will provide this to `VitessceConfig` in order to construct a configuration that contains URL paths relative to this directory."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "lEQa",
- "metadata": {},
- "outputs": [],
- "source": [
- "BASE_DIR = \"data\""
- ]
- },
- {
- "cell_type": "markdown",
- "id": "PKri",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 3. Download the data\n",
- "\n",
- "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "adata_relative_filepath = \"habib17.processed.h5ad\" # Relative to BASE_DIR\n",
- "adata_filepath = join(BASE_DIR, adata_relative_filepath)\n",
- "if not isfile(adata_filepath):\n",
- " os.makedirs(BASE_DIR, exist_ok=True)\n",
- " urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "SFPL",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 4. Load the data\n",
- "\n",
- "Note: this function may print a `FutureWarning`"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "BYtC",
- "metadata": {},
- "outputs": [],
- "source": [
- "adata = read_h5ad(adata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "RGSE",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 4.1. Preprocess the Data For Visualization\n",
- "\n",
- "This dataset contains 25,587 genes. We prepare to visualize the top 50 highly variable genes for the heatmap as ranked by dispersion norm, although one may use any boolean array filter for the heatmap."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Kclp",
- "metadata": {},
- "outputs": [],
- "source": [
- "top_dispersion = adata.var[\"dispersions_norm\"][\n",
- " sorted(\n",
- " range(len(adata.var[\"dispersions_norm\"])),\n",
- " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
- " )[-51:][0]\n",
- "]\n",
- "adata.var[\"top_highly_variable\"] = (\n",
- " adata.var[\"dispersions_norm\"] > top_dispersion\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "emfo",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 4.2 Save the Data to Zarr store\n",
- "\n",
- "We want to convert the original `h5ad` file to a [Zarr](https://zarr.readthedocs.io/en/stable/) store, which Vitessce is able to load. We can use the `optimize_adata` function to ensure that all arrays and dataframe columns that we intend to use in our visualization are in the optimal format to be loaded by Vitessce. This function will cast arrays to numerical data types that take up less space (as long as the values allow). Note: unused arrays and columns (i.e., not specified in any of the parameters to `optimize_adata`) will not be copied into the new AnnData object."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Hstk",
- "metadata": {},
- "outputs": [],
- "source": [
- "zarr_relative_filepath = 'habib17.processed.zarr'\n",
- "zarr_filepath = join(BASE_DIR, zarr_relative_filepath)\n",
- "if not isdir(zarr_filepath):\n",
- " adata_1 = optimize_adata(adata, obs_cols=['CellType'], obsm_keys=['X_umap'], optimize_X=True, var_cols=['top_highly_variable'])\n",
- " adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "nWHF",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "## 5. Create the Vitessce widget configuration\n",
- "\n",
- "Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views."
- ]
- },
- {
- "cell_type": "markdown",
- "id": "iLit",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "### 5.1. Instantiate a `VitessceConfig` object\n",
- "\n",
- "Use the `VitessceConfig` constructor to create an instance. In this case, we want to construct our configuration using local data that is relative to a particular directory, so we provide the `base_dir` parameter.\n",
- "\n",
- "Note: This `base_dir` parameter is optional. When it is omitted, local data paths are assumed to be relative to the current working directory."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "ZHCJ",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='Habib et al', base_dir=BASE_DIR)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "ROlb",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "### 5.2. Add a dataset to the `VitessceConfig` instance\n",
- "\n",
- "In Vitessce, a dataset is a container for one file per data type. The `.add_dataset(name)` method on the `vc` instance sets up and returns a new dataset instance.\n",
- "\n",
- "Then, we can call the dataset's `.add_object(wrapper_object)` method to attach a \"data wrapper\" instance to our new dataset. For example, the `AnnDataWrapper` helps to configure AnnData Zarr stores for use in the Vitessce configuration.\n",
- "\n",
- "Dataset wrapper classes may require additional parameters to resolve ambiguities. For instance, `AnnData` objects may store multiple clusterings or cell type annotation columns in the `adata.obs` dataframe. We can use the parameter `obs_set_paths` to tell Vitessce that certain columns of the `obs` dataframe correspond to cell type annotations or cell clusterings."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "qnkX",
- "metadata": {},
- "outputs": [],
- "source": [
- "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
- " adata_path=zarr_relative_filepath, # Relative to BASE_DIR (because we specified base_dir in the VitessceConfig constructor)\n",
- " obs_embedding_paths=[\"obsm/X_umap\"],\n",
- " obs_embedding_names=[\"UMAP\"],\n",
- " obs_set_paths=[\"obs/CellType\"],\n",
- " obs_set_names=[\"Cell Type\"],\n",
- " obs_feature_matrix_path=\"X\",\n",
- " initial_feature_filter_path=\"var/top_highly_variable\"\n",
- " )\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "TqIu",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "### 5.3. Add visualizations to the `VitessceConfig` instance\n",
- "\n",
- "Now that we have added a dataset, we can configure visualizations. The `.add_view` method adds a view (i.e. visualization or controller component) to the configuration.\n",
- "\n",
- "The `Component` enum class (which we have imported as `cm` here) can be used to fill in the `component_type` parameter.\n",
- "\n",
- "For convenience, the `SCATTERPLOT` component type takes the extra `mapping` keyword argument, which specifies which embedding should be used for mapping cells to (x,y) points on the plot."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Vxnm",
- "metadata": {},
- "outputs": [],
- "source": [
- "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
- "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
- "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
- "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "DnEU",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "### 5.4. Define the visualization layout\n",
- "\n",
- "The `vc.layout(view_concat)` method allows us to specify how our views will be arranged in the layout grid in the widget. The `|` and `/` characters are magic syntax for `hconcat(v1, v2)` and `vconcat(v1, v2)`, respectively."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "ulZA",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc.layout((scatterplot | cell_sets) / (heatmap | genes));"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "ecfG",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 6. Create the widget\n",
- "\n",
- "The `vc.widget()` method returns the configured widget instance."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Pvdt",
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "ZBYS",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 7. Check the URLs in the configuration\n",
- "\n",
- "We can check that the data URLs in the configuration respected the specified `base_dir`."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "aLJB",
- "metadata": {},
- "outputs": [],
- "source": [
- "config_dict = vc.to_dict(base_url=BASE_URL_PLACEHOLDER)\n",
- "config_dict"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "nHfw",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/widget_brain_with_quality_metric.ipynb b/docs/notebooks/__ipynb__/widget_brain_with_quality_metric.ipynb
index 2f4f3cbe..4bd0b706 100644
--- a/docs/notebooks/__ipynb__/widget_brain_with_quality_metric.ipynb
+++ b/docs/notebooks/__ipynb__/widget_brain_with_quality_metric.ipynb
@@ -1,281 +1,289 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of single-cell RNA seq data"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the classes and functions that we will be using from the corresponding packages."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from os.path import join, isfile, isdir\n",
+ "from urllib.request import urlretrieve\n",
+ "from anndata import read_h5ad\n",
+ "import scanpy as sc\n",
+ "\n",
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " AnnDataWrapper,\n",
+ ")\n",
+ "from vitessce.data_utils import (\n",
+ " optimize_adata,\n",
+ " VAR_CHUNK_SIZE,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 2. Download the data\n",
+ "\n",
+ "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata_filepath = join(\"data\", \"habib17.processed.h5ad\")\n",
+ "if not isfile(adata_filepath):\n",
+ " os.makedirs(\"data\", exist_ok=True)\n",
+ " urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "PKri",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 3. Load the data\n",
+ "\n",
+ "Note: this function may print a `FutureWarning`"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata = read_h5ad(adata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 3.1. Preprocess the Data For Visualization\n",
+ "\n",
+ "This dataset contains 25,587 genes. We prepare to visualize the top 50 highly variable genes for the heatmap as ranked by dispersion norm, although one may use any boolean array filter for the heatmap."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "top_dispersion = adata.var[\"dispersions_norm\"][\n",
+ " sorted(\n",
+ " range(len(adata.var[\"dispersions_norm\"])),\n",
+ " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
+ " )[-51:][0]\n",
+ "]\n",
+ "adata.var[\"top_highly_variable\"] = (\n",
+ " adata.var[\"dispersions_norm\"] > top_dispersion\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "RGSE",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 3.2 Save the Data to Zarr store\n",
+ "\n",
+ "We want to convert the original `h5ad` file to a [Zarr](https://zarr.readthedocs.io/en/stable/) store, which Vitessce is able to load. We can use the `optimize_adata` function to ensure that all arrays and dataframe columns that we intend to use in our visualization are in the optimal format to be loaded by Vitessce. This function will cast arrays to numerical data types that take up less space (as long as the values allow). Note: unused arrays and columns (i.e., not specified in any of the parameters to `optimize_adata`) will not be copied into the new AnnData object."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Kclp",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "zarr_filepath = join(\"data\", \"habib17.h5ad.zarr\")\n",
+ "if not isdir(zarr_filepath):\n",
+ " adata.write_zarr(zarr_filepath, chunks=[adata.shape[0], VAR_CHUNK_SIZE])"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "emfo",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(\n",
+ " schema_version=\"1.0.17\",\n",
+ " name='Habib et al',\n",
+ " description='COVID-19 Healthy Donor Brain'\n",
+ ")\n",
+ "\n",
+ "# Add data.\n",
+ "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
+ " adata_path=zarr_filepath,\n",
+ " obs_embedding_paths=[\"obsm/X_umap\"],\n",
+ " obs_embedding_names=[\"UMAP\"],\n",
+ " obs_set_paths=[\"obs/CellType\"],\n",
+ " obs_set_names=[\"Cell Type\"],\n",
+ " obs_feature_matrix_path=\"X\",\n",
+ " initial_feature_filter_path=\"var/top_highly_variable\",\n",
+ " coordination_values={\n",
+ " \"obsType\": 'cell',\n",
+ " \"featureType\": 'gene',\n",
+ " \"featureValueType\": 'expression',\n",
+ " },\n",
+ ")).add_object(AnnDataWrapper(\n",
+ " adata_path=zarr_filepath,\n",
+ " obs_feature_column_paths=[\"obs/percent_mito\"],\n",
+ " coordination_values={\n",
+ " \"obsType\": 'cell',\n",
+ " \"featureType\": 'qualityMetric',\n",
+ " \"featureValueType\": 'value',\n",
+ " }\n",
+ "))\n",
+ "\n",
+ "# Add views.\n",
+ "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
+ "scatterplot_2 = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
+ "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
+ "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
+ "histogram = vc.add_view(cm.FEATURE_VALUE_HISTOGRAM, dataset=dataset)\n",
+ "\n",
+ "# Link views.\n",
+ "\n",
+ "# Color one of the two scatterplots by the percent_mito quality metric.\n",
+ "# Also use this quality metric for the histogram values.\n",
+ "vc.link_views_by_dict([histogram, scatterplot_2], {\n",
+ " \"obsType\": 'cell',\n",
+ " \"featureType\": 'qualityMetric',\n",
+ " \"featureValueType\": 'value',\n",
+ " \"featureSelection\": [\"percent_mito\"],\n",
+ " \"obsColorEncoding\": \"geneSelection\",\n",
+ "}, meta=False)\n",
+ "\n",
+ "# Synchronize the zooming and panning of the two scatterplots\n",
+ "vc.link_views_by_dict([scatterplot, scatterplot_2], {\n",
+ " \"embeddingZoom\": None,\n",
+ " \"embeddingTargetX\": None,\n",
+ " \"embeddingTargetY\": None,\n",
+ "}, meta=False)\n",
+ "\n",
+ "# Define the layout.\n",
+ "vc.layout((scatterplot | (cell_sets / genes)) / (scatterplot_2 | histogram));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Hstk",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 5. Create the widget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "nWHF",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
}
- },
- "source": [
- "# Visualization of single-cell RNA seq data"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 1. Import dependencies\n",
- "\n",
- "We need to import the classes and functions that we will be using from the corresponding packages."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "vblA",
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join, isfile, isdir\n",
- "from urllib.request import urlretrieve\n",
- "from anndata import read_h5ad\n",
- "import scanpy as sc\n",
- "\n",
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " AnnDataWrapper,\n",
- ")\n",
- "from vitessce.data_utils import (\n",
- " optimize_adata,\n",
- " VAR_CHUNK_SIZE,\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "bkHC",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 2. Download the data\n",
- "\n",
- "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "lEQa",
- "metadata": {},
- "outputs": [],
- "source": [
- "adata_filepath = join(\"data\", \"habib17.processed.h5ad\")\n",
- "if not isfile(adata_filepath):\n",
- " os.makedirs(\"data\", exist_ok=True)\n",
- " urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "PKri",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 3. Load the data\n",
- "\n",
- "Note: this function may print a `FutureWarning`"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "adata = read_h5ad(adata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "SFPL",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "## 3.1. Preprocess the Data For Visualization\n",
- "\n",
- "This dataset contains 25,587 genes. We prepare to visualize the top 50 highly variable genes for the heatmap as ranked by dispersion norm, although one may use any boolean array filter for the heatmap."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "BYtC",
- "metadata": {},
- "outputs": [],
- "source": [
- "top_dispersion = adata.var[\"dispersions_norm\"][\n",
- " sorted(\n",
- " range(len(adata.var[\"dispersions_norm\"])),\n",
- " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
- " )[-51:][0]\n",
- "]\n",
- "adata.var[\"top_highly_variable\"] = (\n",
- " adata.var[\"dispersions_norm\"] > top_dispersion\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "RGSE",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 3.2 Save the Data to Zarr store\n",
- "\n",
- "We want to convert the original `h5ad` file to a [Zarr](https://zarr.readthedocs.io/en/stable/) store, which Vitessce is able to load. We can use the `optimize_adata` function to ensure that all arrays and dataframe columns that we intend to use in our visualization are in the optimal format to be loaded by Vitessce. This function will cast arrays to numerical data types that take up less space (as long as the values allow). Note: unused arrays and columns (i.e., not specified in any of the parameters to `optimize_adata`) will not be copied into the new AnnData object."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Kclp",
- "metadata": {},
- "outputs": [],
- "source": [
- "zarr_filepath = join(\"data\", \"habib17.h5ad.zarr\")\n",
- "if not isdir(zarr_filepath):\n",
- " adata.write_zarr(zarr_filepath, chunks=[adata.shape[0], VAR_CHUNK_SIZE])"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "emfo",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(\n",
- " schema_version=\"1.0.17\",\n",
- " name='Habib et al',\n",
- " description='COVID-19 Healthy Donor Brain'\n",
- ")\n",
- "\n",
- "# Add data.\n",
- "dataset = vc.add_dataset(name='Brain').add_object(AnnDataWrapper(\n",
- " adata_path=zarr_filepath,\n",
- " obs_embedding_paths=[\"obsm/X_umap\"],\n",
- " obs_embedding_names=[\"UMAP\"],\n",
- " obs_set_paths=[\"obs/CellType\"],\n",
- " obs_set_names=[\"Cell Type\"],\n",
- " obs_feature_matrix_path=\"X\",\n",
- " initial_feature_filter_path=\"var/top_highly_variable\",\n",
- " coordination_values={\n",
- " \"obsType\": 'cell',\n",
- " \"featureType\": 'gene',\n",
- " \"featureValueType\": 'expression',\n",
- " },\n",
- ")).add_object(AnnDataWrapper(\n",
- " adata_path=zarr_filepath,\n",
- " obs_feature_column_paths=[\"obs/percent_mito\"],\n",
- " coordination_values={\n",
- " \"obsType\": 'cell',\n",
- " \"featureType\": 'qualityMetric',\n",
- " \"featureValueType\": 'value',\n",
- " }\n",
- "))\n",
- "\n",
- "# Add views.\n",
- "scatterplot = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
- "scatterplot_2 = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
- "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
- "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
- "histogram = vc.add_view(cm.FEATURE_VALUE_HISTOGRAM, dataset=dataset)\n",
- "\n",
- "# Link views.\n",
- "\n",
- "# Color one of the two scatterplots by the percent_mito quality metric.\n",
- "# Also use this quality metric for the histogram values.\n",
- "vc.link_views_by_dict([histogram, scatterplot_2], {\n",
- " \"obsType\": 'cell',\n",
- " \"featureType\": 'qualityMetric',\n",
- " \"featureValueType\": 'value',\n",
- " \"featureSelection\": [\"percent_mito\"],\n",
- " \"obsColorEncoding\": \"geneSelection\",\n",
- "}, meta=False)\n",
- "\n",
- "# Synchronize the zooming and panning of the two scatterplots\n",
- "vc.link_views_by_dict([scatterplot, scatterplot_2], {\n",
- " \"embeddingZoom\": None,\n",
- " \"embeddingTargetX\": None,\n",
- " \"embeddingTargetY\": None,\n",
- "}, meta=False)\n",
- "\n",
- "# Define the layout.\n",
- "vc.layout((scatterplot | (cell_sets / genes)) / (scatterplot_2 | histogram));"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Hstk",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 5. Create the widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "nWHF",
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "iLit",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/widget_from_dict.ipynb b/docs/notebooks/__ipynb__/widget_from_dict.ipynb
index 8ebcc7e5..35065dfe 100644
--- a/docs/notebooks/__ipynb__/widget_from_dict.ipynb
+++ b/docs/notebooks/__ipynb__/widget_from_dict.ipynb
@@ -1,115 +1,123 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Using an existing view config dict"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the `VitessceConfig` class."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import VitessceConfig"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 2. Import config of interest as a dict\n",
+ "\n",
+ "The Vitessce config at its lowest level is a JSON object or a Python `dict` that specifies a layout for the Vitessce components will be rendered in the widget. These components may be scatterplots, spatial plots, heatmaps, or control components. The config also describes the datasets and files that will be visualized.\n",
+ "\n",
+ "The `vitessce` package provides helper functions and classes to simplify the process of defining Vitessce configs. Those functions are demonstrated in the other notebooks. The helper functions are intended to make visualization of local datasets easy. However, in this case, we are importing a config that has been pre-defined in the file `example_configs.py`, in which the dataset being visualized is stored remotely in AWS S3 (rather than locally)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from example_configs import dries as dries_config"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "PKri",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 3. Create the Vitessce widget\n",
+ "\n",
+ "Create the widget by creating a new config instance using the `VitessceConfig.from_dict` static method, then calling the config's `.widget()` method.\n",
+ "\n",
+ "Render the widget by placing the widget variable on its own line at the end of the notebook cell."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig.from_dict(dries_config)\n",
+ "vw = vc.widget()\n",
+ "vw"
+ ]
}
- },
- "source": [
- "# Using an existing view config dict"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 1. Import dependencies\n",
- "\n",
- "We need to import the `VitessceConfig` class."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "vblA",
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import VitessceConfig"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "bkHC",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "## 2. Import config of interest as a dict\n",
- "\n",
- "The Vitessce config at its lowest level is a JSON object or a Python `dict` that specifies a layout for the Vitessce components will be rendered in the widget. These components may be scatterplots, spatial plots, heatmaps, or control components. The config also describes the datasets and files that will be visualized.\n",
- "\n",
- "The `vitessce` package provides helper functions and classes to simplify the process of defining Vitessce configs. Those functions are demonstrated in the other notebooks. The helper functions are intended to make visualization of local datasets easy. However, in this case, we are importing a config that has been pre-defined in the file `example_configs.py`, in which the dataset being visualized is stored remotely in AWS S3 (rather than locally)."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "lEQa",
- "metadata": {},
- "outputs": [],
- "source": [
- "from example_configs import dries as dries_config"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "PKri",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 3. Create the Vitessce widget\n",
- "\n",
- "Create the widget by creating a new config instance using the `VitessceConfig.from_dict` static method, then calling the config's `.widget()` method.\n",
- "\n",
- "Render the widget by placing the widget variable on its own line at the end of the notebook cell."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig.from_dict(dries_config)\n",
- "vw = vc.widget()\n",
- "vw"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "SFPL",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/widget_genomic_profiles.ipynb b/docs/notebooks/__ipynb__/widget_genomic_profiles.ipynb
index 8d4d91fc..5544627b 100644
--- a/docs/notebooks/__ipynb__/widget_genomic_profiles.ipynb
+++ b/docs/notebooks/__ipynb__/widget_genomic_profiles.ipynb
@@ -1,245 +1,253 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of genomic profiles"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the classes and functions that we will be using from the corresponding packages."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " ViewType as vt,\n",
+ " CoordinationType as ct,\n",
+ " AnnDataWrapper,\n",
+ " MultivecZarrWrapper,\n",
+ ")\n",
+ "from vitessce.data_utils import (\n",
+ " adata_to_multivec_zarr,\n",
+ ")\n",
+ "from os.path import join\n",
+ "from scipy.io import mmread\n",
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "from anndata import AnnData"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 2. Load the data\n",
+ "\n",
+ "In this step, we load the raw data that has been downloaded from the HuBMAP portal https://portal.hubmapconsortium.org/browse/dataset/210d118a14c8624b6bb9610a9062656e"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "mtx = mmread(join('data', 'snapatac', 'filtered_cell_by_bin.mtx')).toarray()\n",
+ "barcodes_df = pd.read_csv(join('data', 'snapatac', 'barcodes.txt'), header=None)\n",
+ "bins_df = pd.read_csv(join('data', 'snapatac', 'bins.txt'), header=None, names=[\"interval\"])\n",
+ "clusters_df = pd.read_csv(join('data', 'snapatac', 'umap_coords_clusters.csv'), index_col=0)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "PKri",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 3. Convert the data to Vitessce-compatible formats\n",
+ "\n",
+ "Vitessce can load AnnData objects saved to Zarr formats efficiently."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# The genome assembly is GRCh38 but the chromosome names in the bin names do not start with the \"chr\" prefix.\n",
+ "# This is incompatible with the chromosome names from `negspy`, so we need to append the prefix.\n",
+ "bins_df[\"interval\"] = bins_df[\"interval\"].apply(lambda x: \"chr\" + x)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "obs = clusters_df[[\"cluster\"]]\n",
+ "obs[\"cluster\"] = obs[\"cluster\"].astype(str)\n",
+ "obsm = { \"X_umap\": clusters_df[[\"umap.1\", \"umap.2\"]].values }\n",
+ "adata = AnnData(X=mtx, obs=obs, var=bins_df, obsm=obsm)\n",
+ "adata"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "multivec_zarr_path = join(\"data\", \"HBM485.TBWH.322.multivec.zarr\")\n",
+ "adata_zarr_path = join(\"data\", \"HBM485.TBWH.322.adata.zarr\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Sort cluster IDs\n",
+ "cluster_ids = obs[\"cluster\"].unique().tolist()\n",
+ "cluster_ids.sort(key=int)\n",
+ "# Save genomic profiles to multivec-zarr format.\n",
+ "adata_to_multivec_zarr(adata, multivec_zarr_path, obs_set_col=\"cluster\", obs_set_name=\"Cluster\", obs_set_vals=cluster_ids)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Kclp",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Save anndata object to AnnData-Zarr format.\n",
+ "adata.write_zarr(adata_zarr_path)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "emfo",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 4. Make a Vitessce configuration\n",
+ "\n",
+ "We need to tell Vitessce about the data that we want to load and the visualization components that we want to include in the widget.\n",
+ "For this dataset, we want to add the `GENOMIC_PROFILES` component, which renders genome browser tracks with [HiGlass](http://higlass.io)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Hstk",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='HuBMAP snATAC-seq')\n",
+ "dataset = vc.add_dataset(name='HBM485.TBWH.322').add_object(MultivecZarrWrapper(\n",
+ " zarr_path=multivec_zarr_path\n",
+ ")).add_object(AnnDataWrapper(\n",
+ " adata_path=adata_zarr_path,\n",
+ " obs_embedding_paths=[\"obsm/X_umap\"],\n",
+ " obs_embedding_names=[\"UMAP\"],\n",
+ " obs_set_paths=[\"obs/cluster\"],\n",
+ " obs_set_names=[\"Cluster\"],\n",
+ "))\n",
+ "\n",
+ "genomic_profiles = vc.add_view(vt.GENOMIC_PROFILES, dataset=dataset)\n",
+ "scatter = vc.add_view(vt.SCATTERPLOT, dataset=dataset, mapping = \"UMAP\")\n",
+ "cell_sets = vc.add_view(vt.OBS_SETS, dataset=dataset)\n",
+ "\n",
+ "vc.layout(genomic_profiles / (scatter | cell_sets));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "nWHF",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 5. Create the widget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "iLit",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget(height=800)\n",
+ "vw"
+ ]
}
- },
- "source": [
- "# Visualization of genomic profiles"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 1. Import dependencies\n",
- "\n",
- "We need to import the classes and functions that we will be using from the corresponding packages."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "vblA",
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " ViewType as vt,\n",
- " CoordinationType as ct,\n",
- " AnnDataWrapper,\n",
- " MultivecZarrWrapper,\n",
- ")\n",
- "from vitessce.data_utils import (\n",
- " adata_to_multivec_zarr,\n",
- ")\n",
- "from os.path import join\n",
- "from scipy.io import mmread\n",
- "import pandas as pd\n",
- "import numpy as np\n",
- "from anndata import AnnData"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "bkHC",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 2. Load the data\n",
- "\n",
- "In this step, we load the raw data that has been downloaded from the HuBMAP portal https://portal.hubmapconsortium.org/browse/dataset/210d118a14c8624b6bb9610a9062656e"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "lEQa",
- "metadata": {},
- "outputs": [],
- "source": [
- "mtx = mmread(join('data', 'snapatac', 'filtered_cell_by_bin.mtx')).toarray()\n",
- "barcodes_df = pd.read_csv(join('data', 'snapatac', 'barcodes.txt'), header=None)\n",
- "bins_df = pd.read_csv(join('data', 'snapatac', 'bins.txt'), header=None, names=[\"interval\"])\n",
- "clusters_df = pd.read_csv(join('data', 'snapatac', 'umap_coords_clusters.csv'), index_col=0)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "PKri",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 3. Convert the data to Vitessce-compatible formats\n",
- "\n",
- "Vitessce can load AnnData objects saved to Zarr formats efficiently."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "# The genome assembly is GRCh38 but the chromosome names in the bin names do not start with the \"chr\" prefix.\n",
- "# This is incompatible with the chromosome names from `negspy`, so we need to append the prefix.\n",
- "bins_df[\"interval\"] = bins_df[\"interval\"].apply(lambda x: \"chr\" + x)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "SFPL",
- "metadata": {},
- "outputs": [],
- "source": [
- "obs = clusters_df[[\"cluster\"]]\n",
- "obs[\"cluster\"] = obs[\"cluster\"].astype(str)\n",
- "obsm = { \"X_umap\": clusters_df[[\"umap.1\", \"umap.2\"]].values }\n",
- "adata = AnnData(X=mtx, obs=obs, var=bins_df, obsm=obsm)\n",
- "adata"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "BYtC",
- "metadata": {},
- "outputs": [],
- "source": [
- "multivec_zarr_path = join(\"data\", \"HBM485.TBWH.322.multivec.zarr\")\n",
- "adata_zarr_path = join(\"data\", \"HBM485.TBWH.322.adata.zarr\")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "RGSE",
- "metadata": {},
- "outputs": [],
- "source": [
- "# Sort cluster IDs\n",
- "cluster_ids = obs[\"cluster\"].unique().tolist()\n",
- "cluster_ids.sort(key=int)\n",
- "# Save genomic profiles to multivec-zarr format.\n",
- "adata_to_multivec_zarr(adata, multivec_zarr_path, obs_set_col=\"cluster\", obs_set_name=\"Cluster\", obs_set_vals=cluster_ids)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Kclp",
- "metadata": {},
- "outputs": [],
- "source": [
- "# Save anndata object to AnnData-Zarr format.\n",
- "adata.write_zarr(adata_zarr_path)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "emfo",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "## 4. Make a Vitessce configuration\n",
- "\n",
- "We need to tell Vitessce about the data that we want to load and the visualization components that we want to include in the widget.\n",
- "For this dataset, we want to add the `GENOMIC_PROFILES` component, which renders genome browser tracks with [HiGlass](http://higlass.io)."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Hstk",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='HuBMAP snATAC-seq')\n",
- "dataset = vc.add_dataset(name='HBM485.TBWH.322').add_object(MultivecZarrWrapper(\n",
- " zarr_path=multivec_zarr_path\n",
- ")).add_object(AnnDataWrapper(\n",
- " adata_path=adata_zarr_path,\n",
- " obs_embedding_paths=[\"obsm/X_umap\"],\n",
- " obs_embedding_names=[\"UMAP\"],\n",
- " obs_set_paths=[\"obs/cluster\"],\n",
- " obs_set_names=[\"Cluster\"],\n",
- "))\n",
- "\n",
- "genomic_profiles = vc.add_view(vt.GENOMIC_PROFILES, dataset=dataset)\n",
- "scatter = vc.add_view(vt.SCATTERPLOT, dataset=dataset, mapping = \"UMAP\")\n",
- "cell_sets = vc.add_view(vt.OBS_SETS, dataset=dataset)\n",
- "\n",
- "vc.layout(genomic_profiles / (scatter | cell_sets));"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "nWHF",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 5. Create the widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "iLit",
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget(height=800)\n",
- "vw"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "ZHCJ",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/widget_imaging.ipynb b/docs/notebooks/__ipynb__/widget_imaging.ipynb
index fbbe59d9..cde3f76a 100644
--- a/docs/notebooks/__ipynb__/widget_imaging.ipynb
+++ b/docs/notebooks/__ipynb__/widget_imaging.ipynb
@@ -1,114 +1,122 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of Multi-Modal Imaging Data\n",
+ "We visualize IMS, PAS, and AF imaging data overlaid from the Spraggins Lab of the Biomolecular Multimodal Imaging Center (BIOMC) at Vanderbilt University, uploaded to the HuBMAP data portal."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "MJUe",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " OmeTiffWrapper,\n",
+ " MultiImageWrapper,\n",
+ ")\n",
+ "from os.path import join"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Configure Vitessce\n",
+ "Set up the images from the three different assays, with the `use_physical_size_scaling` set to `True` so that the IMS image scales to the other images based on their physical sizes."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='Spraggins Multi-Modal', description='PAS + IMS + AF From https://portal.hubmapconsortium.org/browse/collection/6a6efd0c1a2681dc7d2faab8e4ab0bca')\n",
+ "dataset = vc.add_dataset(name='Spraggins').add_object(\n",
+ " MultiImageWrapper(\n",
+ " image_wrappers=[\n",
+ " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/f4188a148e4c759092d19369d310883b/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-PAS_images/VAN0006-LK-2-85-PAS_registered.ome.tif?token=', name='PAS'),\n",
+ " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/2130d5f91ce61d7157a42c0497b06de8/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-AF_preIMS_images/VAN0006-LK-2-85-AF_preIMS_registered.ome.tif?token=', name='AF'),\n",
+ " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/be503a021ed910c0918842e318e6efa2/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_PosMode_multilayer.ome.tif?token=', name='IMS Pos Mode'),\n",
+ " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/ca886a630b2038997a4cfbbf4abfd283/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_NegMode_multilayer.ome.tif?token=', name='IMS Neg Mode')\n",
+ " ],\n",
+ " use_physical_size_scaling=True,\n",
+ " )\n",
+ ")\n",
+ "spatial = vc.add_view(cm.SPATIAL, dataset=dataset)\n",
+ "status = vc.add_view(cm.STATUS, dataset=dataset)\n",
+ "lc = vc.add_view(cm.LAYER_CONTROLLER, dataset=dataset).set_props(disableChannelsIfRgbDetected=True)\n",
+ "vc.layout(spatial | (lc / status));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 2. Create the Vitessce widget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
}
- },
- "source": [
- "# Visualization of Multi-Modal Imaging Data\n",
- "We visualize IMS, PAS, and AF imaging data overlaid from the Spraggins Lab of the Biomolecular Multimodal Imaging Center (BIOMC) at Vanderbilt University, uploaded to the HuBMAP data portal."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "MJUe",
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " OmeTiffWrapper,\n",
- " MultiImageWrapper,\n",
- ")\n",
- "from os.path import join"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "vblA",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 1. Configure Vitessce\n",
- "Set up the images from the three different assays, with the `use_physical_size_scaling` set to `True` so that the IMS image scales to the other images based on their physical sizes."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "bkHC",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='Spraggins Multi-Modal', description='PAS + IMS + AF From https://portal.hubmapconsortium.org/browse/collection/6a6efd0c1a2681dc7d2faab8e4ab0bca')\n",
- "dataset = vc.add_dataset(name='Spraggins').add_object(\n",
- " MultiImageWrapper(\n",
- " image_wrappers=[\n",
- " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/f4188a148e4c759092d19369d310883b/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-PAS_images/VAN0006-LK-2-85-PAS_registered.ome.tif?token=', name='PAS'),\n",
- " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/2130d5f91ce61d7157a42c0497b06de8/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-AF_preIMS_images/VAN0006-LK-2-85-AF_preIMS_registered.ome.tif?token=', name='AF'),\n",
- " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/be503a021ed910c0918842e318e6efa2/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_PosMode_multilayer.ome.tif?token=', name='IMS Pos Mode'),\n",
- " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/ca886a630b2038997a4cfbbf4abfd283/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_NegMode_multilayer.ome.tif?token=', name='IMS Neg Mode')\n",
- " ],\n",
- " use_physical_size_scaling=True,\n",
- " )\n",
- ")\n",
- "spatial = vc.add_view(cm.SPATIAL, dataset=dataset)\n",
- "status = vc.add_view(cm.STATUS, dataset=dataset)\n",
- "lc = vc.add_view(cm.LAYER_CONTROLLER, dataset=dataset).set_props(disableChannelsIfRgbDetected=True)\n",
- "vc.layout(spatial | (lc / status));"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "lEQa",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "## 2. Create the Vitessce widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "PKri",
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/widget_imaging_beta.ipynb b/docs/notebooks/__ipynb__/widget_imaging_beta.ipynb
index 9b116c80..da1a6413 100644
--- a/docs/notebooks/__ipynb__/widget_imaging_beta.ipynb
+++ b/docs/notebooks/__ipynb__/widget_imaging_beta.ipynb
@@ -1,152 +1,160 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of Multi-Modal Imaging Data\n",
+ "We visualize IMS, PAS, and AF imaging data overlaid from the Spraggins Lab of the Biomolecular Multimodal Imaging Center (BIOMC) at Vanderbilt University, uploaded to the HuBMAP data portal."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "MJUe",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " OmeTiffWrapper,\n",
+ " MultiImageWrapper,\n",
+ " CoordinationLevel as CL,\n",
+ ")\n",
+ "from os.path import join"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Configure Vitessce\n",
+ "Set up the images from the three different assays, with the `use_physical_size_scaling` set to `True` so that the IMS image scales to the other images based on their physical sizes."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.16\", name='Spraggins Multi-Modal', description='PAS + IMS + AF From https://portal.hubmapconsortium.org/browse/collection/6a6efd0c1a2681dc7d2faab8e4ab0bca')\n",
+ "dataset = vc.add_dataset(name='Spraggins').add_file(\n",
+ " url='https://assets.hubmapconsortium.org/f4188a148e4c759092d19369d310883b/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-PAS_images/VAN0006-LK-2-85-PAS_registered.ome.tif?token=',\n",
+ " file_type=\"image.ome-tiff\",\n",
+ " coordination_values={\n",
+ " \"fileUid\": \"PAS\",\n",
+ " },\n",
+ ")\n",
+ "\n",
+ "imageScopes = vc.add_coordination_by_dict({\n",
+ " \"imageLayer\": CL([\n",
+ " {\n",
+ " \"fileUid\": 'PAS',\n",
+ " \"spatialLayerOpacity\": 1,\n",
+ " \"spatialLayerVisible\": True,\n",
+ " \"photometricInterpretation\": 'RGB',\n",
+ " \"imageChannel\": CL([\n",
+ " {\n",
+ " \"spatialTargetC\": 0,\n",
+ " \"spatialChannelColor\": [255, 0, 0],\n",
+ " \"spatialChannelVisible\": True,\n",
+ " \"spatialChannelOpacity\": 1.0,\n",
+ " \"spatialChannelWindow\": [0, 255],\n",
+ " },\n",
+ " {\n",
+ " \"spatialTargetC\": 1,\n",
+ " \"spatialChannelColor\": [0, 255, 0],\n",
+ " \"spatialChannelVisible\": True,\n",
+ " \"spatialChannelOpacity\": 1.0,\n",
+ " \"spatialChannelWindow\": [0, 255],\n",
+ " },\n",
+ " {\n",
+ " \"spatialTargetC\": 2,\n",
+ " \"spatialChannelColor\": [0, 0, 255],\n",
+ " \"spatialChannelVisible\": True,\n",
+ " \"spatialChannelOpacity\": 1.0,\n",
+ " \"spatialChannelWindow\": [0, 255],\n",
+ " },\n",
+ " ]),\n",
+ " }\n",
+ " ])\n",
+ "})\n",
+ "\n",
+ "metaCoordinationScope = vc.add_meta_coordination()\n",
+ "metaCoordinationScope.use_coordination_by_dict(imageScopes)\n",
+ "\n",
+ "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
+ "lc = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
+ "\n",
+ "spatial.use_meta_coordination(metaCoordinationScope)\n",
+ "lc.use_meta_coordination(metaCoordinationScope)\n",
+ "\n",
+ "vc.layout(spatial | lc);"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 2. Create the Vitessce widget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget(custom_js_url='http://localhost:8000/packages/main/prod/dist/index.min.js')\n",
+ "vw"
+ ]
}
- },
- "source": [
- "# Visualization of Multi-Modal Imaging Data\n",
- "We visualize IMS, PAS, and AF imaging data overlaid from the Spraggins Lab of the Biomolecular Multimodal Imaging Center (BIOMC) at Vanderbilt University, uploaded to the HuBMAP data portal."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "MJUe",
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " OmeTiffWrapper,\n",
- " MultiImageWrapper,\n",
- " CoordinationLevel as CL,\n",
- ")\n",
- "from os.path import join"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "vblA",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 1. Configure Vitessce\n",
- "Set up the images from the three different assays, with the `use_physical_size_scaling` set to `True` so that the IMS image scales to the other images based on their physical sizes."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "bkHC",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.16\", name='Spraggins Multi-Modal', description='PAS + IMS + AF From https://portal.hubmapconsortium.org/browse/collection/6a6efd0c1a2681dc7d2faab8e4ab0bca')\n",
- "dataset = vc.add_dataset(name='Spraggins').add_file(\n",
- " url='https://assets.hubmapconsortium.org/f4188a148e4c759092d19369d310883b/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-PAS_images/VAN0006-LK-2-85-PAS_registered.ome.tif?token=',\n",
- " file_type=\"image.ome-tiff\",\n",
- " coordination_values={\n",
- " \"fileUid\": \"PAS\",\n",
- " },\n",
- ")\n",
- "\n",
- "imageScopes = vc.add_coordination_by_dict({\n",
- " \"imageLayer\": CL([\n",
- " {\n",
- " \"fileUid\": 'PAS',\n",
- " \"spatialLayerOpacity\": 1,\n",
- " \"spatialLayerVisible\": True,\n",
- " \"photometricInterpretation\": 'RGB',\n",
- " \"imageChannel\": CL([\n",
- " {\n",
- " \"spatialTargetC\": 0,\n",
- " \"spatialChannelColor\": [255, 0, 0],\n",
- " \"spatialChannelVisible\": True,\n",
- " \"spatialChannelOpacity\": 1.0,\n",
- " \"spatialChannelWindow\": [0, 255],\n",
- " },\n",
- " {\n",
- " \"spatialTargetC\": 1,\n",
- " \"spatialChannelColor\": [0, 255, 0],\n",
- " \"spatialChannelVisible\": True,\n",
- " \"spatialChannelOpacity\": 1.0,\n",
- " \"spatialChannelWindow\": [0, 255],\n",
- " },\n",
- " {\n",
- " \"spatialTargetC\": 2,\n",
- " \"spatialChannelColor\": [0, 0, 255],\n",
- " \"spatialChannelVisible\": True,\n",
- " \"spatialChannelOpacity\": 1.0,\n",
- " \"spatialChannelWindow\": [0, 255],\n",
- " },\n",
- " ]),\n",
- " }\n",
- " ])\n",
- "})\n",
- "\n",
- "metaCoordinationScope = vc.add_meta_coordination()\n",
- "metaCoordinationScope.use_coordination_by_dict(imageScopes)\n",
- "\n",
- "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
- "lc = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
- "\n",
- "spatial.use_meta_coordination(metaCoordinationScope)\n",
- "lc.use_meta_coordination(metaCoordinationScope)\n",
- "\n",
- "vc.layout(spatial | lc);"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "lEQa",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "## 2. Create the Vitessce widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "PKri",
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget(custom_js_url='http://localhost:8000/packages/main/prod/dist/index.min.js')\n",
- "vw"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/widget_imaging_segmentation.ipynb b/docs/notebooks/__ipynb__/widget_imaging_segmentation.ipynb
index 69eed98b..c46df0e8 100644
--- a/docs/notebooks/__ipynb__/widget_imaging_segmentation.ipynb
+++ b/docs/notebooks/__ipynb__/widget_imaging_segmentation.ipynb
@@ -1,111 +1,119 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of Segmentation Bitmask\n",
+ "We visualize raw imaging data + a segmentation bitmask the [MCMicro piplene](https://mcmicro.org/) - see https://www.biorxiv.org/content/10.1101/2021.03.15.435473v1.full and specifically [Figure S1](https://www.google.com/url?q=https://www.biorxiv.org/content/10.1101/2021.03.15.435473v1.full%23F3&sa=D&source=editors&ust=1623173627976000&usg=AOvVaw3JkzCxYyE86q8jxfNCgShh)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "MJUe",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " OmeTiffWrapper,\n",
+ " MultiImageWrapper,\n",
+ ")\n",
+ "from os.path import join"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Configure Vitessce\n",
+ "Set up the two images, already pyramidal from the [bioformats2raw + raw2ometiff pipeline](https://github.com/hms-dbmi/viv/tree/master/tutorial), labeling the segmentation \"on top\" as the bitmask and the other as simply the image data."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='MCMicro Bitmask Visualization', description='Segmentation + Data of Exemplar 001')\n",
+ "dataset = vc.add_dataset(name='MCMicro').add_object(\n",
+ " MultiImageWrapper(\n",
+ " image_wrappers=[\n",
+ " OmeTiffWrapper(img_url='https://vitessce-demo-data.storage.googleapis.com/exemplar-001/exemplar-001.pyramid.ome.tif', name='Image'),\n",
+ " OmeTiffWrapper(img_url='https://vitessce-demo-data.storage.googleapis.com/exemplar-001/cellMask.pyramid.ome.tif', name='Mask', is_bitmask=True),\n",
+ " ]\n",
+ " )\n",
+ ")\n",
+ "spatial = vc.add_view(cm.SPATIAL, dataset=dataset)\n",
+ "status = vc.add_view(cm.STATUS, dataset=dataset)\n",
+ "lc = vc.add_view(cm.LAYER_CONTROLLER, dataset=dataset)\n",
+ "vc.layout(spatial | (lc / status));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 2. Create the Vitessce widget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
}
- },
- "source": [
- "# Visualization of Segmentation Bitmask\n",
- "We visualize raw imaging data + a segmentation bitmask the [MCMicro piplene](https://mcmicro.org/) - see https://www.biorxiv.org/content/10.1101/2021.03.15.435473v1.full and specifically [Figure S1](https://www.google.com/url?q=https://www.biorxiv.org/content/10.1101/2021.03.15.435473v1.full%23F3&sa=D&source=editors&ust=1623173627976000&usg=AOvVaw3JkzCxYyE86q8jxfNCgShh)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "MJUe",
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " OmeTiffWrapper,\n",
- " MultiImageWrapper,\n",
- ")\n",
- "from os.path import join"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "vblA",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 1. Configure Vitessce\n",
- "Set up the two images, already pyramidal from the [bioformats2raw + raw2ometiff pipeline](https://github.com/hms-dbmi/viv/tree/master/tutorial), labeling the segmentation \"on top\" as the bitmask and the other as simply the image data."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "bkHC",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='MCMicro Bitmask Visualization', description='Segmentation + Data of Exemplar 001')\n",
- "dataset = vc.add_dataset(name='MCMicro').add_object(\n",
- " MultiImageWrapper(\n",
- " image_wrappers=[\n",
- " OmeTiffWrapper(img_url='https://vitessce-demo-data.storage.googleapis.com/exemplar-001/exemplar-001.pyramid.ome.tif', name='Image'),\n",
- " OmeTiffWrapper(img_url='https://vitessce-demo-data.storage.googleapis.com/exemplar-001/cellMask.pyramid.ome.tif', name='Mask', is_bitmask=True),\n",
- " ]\n",
- " )\n",
- ")\n",
- "spatial = vc.add_view(cm.SPATIAL, dataset=dataset)\n",
- "status = vc.add_view(cm.STATUS, dataset=dataset)\n",
- "lc = vc.add_view(cm.LAYER_CONTROLLER, dataset=dataset)\n",
- "vc.layout(spatial | (lc / status));"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "lEQa",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "## 2. Create the Vitessce widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "PKri",
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/widget_loom.ipynb b/docs/notebooks/__ipynb__/widget_loom.ipynb
index b6a86875..19344fdf 100644
--- a/docs/notebooks/__ipynb__/widget_loom.ipynb
+++ b/docs/notebooks/__ipynb__/widget_loom.ipynb
@@ -1,260 +1,268 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of a Loom file"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Import dependencies"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from os.path import join, isfile, isdir\n",
+ "from urllib.request import urlretrieve\n",
+ "from anndata import read_loom\n",
+ "import numpy as np\n",
+ "\n",
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " AnnDataWrapper,\n",
+ ")\n",
+ "from vitessce.data_utils import (\n",
+ " optimize_adata,\n",
+ " to_diamond,\n",
+ " VAR_CHUNK_SIZE,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 2. Download data\n",
+ "\n",
+ "Download `osmFISH_SScortex_mouse_all_cells.loom` from http://loom.linnarssonlab.org/."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "loom_filepath = join(\"data\", \"osmFISH_SScortex_mouse_all_cells.loom\")\n",
+ "if not isfile(loom_filepath):\n",
+ " os.makedirs(\"data\", exist_ok=True)\n",
+ " urlretrieve('http://loom.linnarssonlab.org/clone/osmFISH/osmFISH_SScortex_mouse_all_cells.loom', loom_filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "PKri",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 3. Open Loom file with AnnData's read_loom"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata = read_loom(loom_filepath, obsm_names={\"tSNE\": [\"_tSNE_1\", \"_tSNE_2\"], \"spatial\": [\"X\", \"Y\"]})"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "Generate pseudo-segmentations as diamond-shaped polygons centered on the spatial coordinate of each cell, and store in `adata.obsm[\"segmentations\"]`"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "num_cells = adata.obs.shape[0]\n",
+ "adata.obsm[\"segmentations\"] = np.zeros((num_cells, 4, 2))\n",
+ "radius = 100\n",
+ "for i in range(num_cells):\n",
+ " adata.obsm[\"segmentations\"][i, :, :] = to_diamond(adata.obsm['spatial'][i, 0], adata.obsm['spatial'][i, 1], radius)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "RGSE",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "Save the AnnData object to a Zarr store:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Kclp",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "zarr_filepath = join('data', 'osmFISH_SScortex_mouse_all_cells.zarr')\n",
+ "if not isdir(zarr_filepath) or True:\n",
+ " adata_1 = optimize_adata(adata, obs_cols=['ClusterName'], obsm_keys=['tSNE', 'spatial', 'segmentations'], optimize_X=True)\n",
+ " adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "emfo",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 4. Configure Vitessce\n",
+ "\n",
+ "Create a Vitessce view config."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Hstk",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='Loom Example', description='osmFISH dataset of the mouse cortex including all cells')\n",
+ "w = AnnDataWrapper(adata_path=zarr_filepath, obs_set_paths=[\"obs/ClusterName\"], obs_set_names=[\"Clusters\"], obs_locations_path=\"obsm/spatial\", obs_segmentations_path=\"obsm/segmentations\", obs_embedding_paths=[\"obsm/tSNE\"])\n",
+ "dataset = vc.add_dataset(name='SScortex').add_object(w)\n",
+ "\n",
+ "tsne = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"tSNE\")\n",
+ "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
+ "spatial = vc.add_view(cm.SPATIAL, dataset=dataset)\n",
+ "\n",
+ "spatial_segmentation_layer_value = {\n",
+ " \"opacity\": 1,\n",
+ " \"radius\": 0,\n",
+ " \"visible\": True,\n",
+ " \"stroked\": False\n",
+ "}\n",
+ "\n",
+ "vc.link_views([spatial], [ct.SPATIAL_ZOOM, ct.SPATIAL_TARGET_X, ct.SPATIAL_TARGET_Y, ct.SPATIAL_SEGMENTATION_LAYER], [-6.43, 10417.69, 24885.55, spatial_segmentation_layer_value])\n",
+ "vc.layout(spatial | (tsne / cell_sets));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "nWHF",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 5. Render the widget"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "iLit",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "A widget can be created with the `.widget()` method on the config instance."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "ZHCJ",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
}
- },
- "source": [
- "# Visualization of a Loom file"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 1. Import dependencies"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "vblA",
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join, isfile, isdir\n",
- "from urllib.request import urlretrieve\n",
- "from anndata import read_loom\n",
- "import numpy as np\n",
- "\n",
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " AnnDataWrapper,\n",
- ")\n",
- "from vitessce.data_utils import (\n",
- " optimize_adata,\n",
- " to_diamond,\n",
- " VAR_CHUNK_SIZE,\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "bkHC",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 2. Download data\n",
- "\n",
- "Download `osmFISH_SScortex_mouse_all_cells.loom` from http://loom.linnarssonlab.org/."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "lEQa",
- "metadata": {},
- "outputs": [],
- "source": [
- "loom_filepath = join(\"data\", \"osmFISH_SScortex_mouse_all_cells.loom\")\n",
- "if not isfile(loom_filepath):\n",
- " os.makedirs(\"data\", exist_ok=True)\n",
- " urlretrieve('http://loom.linnarssonlab.org/clone/osmFISH/osmFISH_SScortex_mouse_all_cells.loom', loom_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "PKri",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 3. Open Loom file with AnnData's read_loom"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "adata = read_loom(loom_filepath, obsm_names={\"tSNE\": [\"_tSNE_1\", \"_tSNE_2\"], \"spatial\": [\"X\", \"Y\"]})"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "SFPL",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "Generate pseudo-segmentations as diamond-shaped polygons centered on the spatial coordinate of each cell, and store in `adata.obsm[\"segmentations\"]`"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "BYtC",
- "metadata": {},
- "outputs": [],
- "source": [
- "num_cells = adata.obs.shape[0]\n",
- "adata.obsm[\"segmentations\"] = np.zeros((num_cells, 4, 2))\n",
- "radius = 100\n",
- "for i in range(num_cells):\n",
- " adata.obsm[\"segmentations\"][i, :, :] = to_diamond(adata.obsm['spatial'][i, 0], adata.obsm['spatial'][i, 1], radius)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "RGSE",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "Save the AnnData object to a Zarr store:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Kclp",
- "metadata": {},
- "outputs": [],
- "source": [
- "zarr_filepath = join('data', 'osmFISH_SScortex_mouse_all_cells.zarr')\n",
- "if not isdir(zarr_filepath) or True:\n",
- " adata_1 = optimize_adata(adata, obs_cols=['ClusterName'], obsm_keys=['tSNE', 'spatial', 'segmentations'], optimize_X=True)\n",
- " adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "emfo",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "## 4. Configure Vitessce\n",
- "\n",
- "Create a Vitessce view config."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Hstk",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='Loom Example', description='osmFISH dataset of the mouse cortex including all cells')\n",
- "w = AnnDataWrapper(adata_path=zarr_filepath, obs_set_paths=[\"obs/ClusterName\"], obs_set_names=[\"Clusters\"], obs_locations_path=\"obsm/spatial\", obs_segmentations_path=\"obsm/segmentations\", obs_embedding_paths=[\"obsm/tSNE\"])\n",
- "dataset = vc.add_dataset(name='SScortex').add_object(w)\n",
- "\n",
- "tsne = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"tSNE\")\n",
- "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
- "spatial = vc.add_view(cm.SPATIAL, dataset=dataset)\n",
- "\n",
- "spatial_segmentation_layer_value = {\n",
- " \"opacity\": 1,\n",
- " \"radius\": 0,\n",
- " \"visible\": True,\n",
- " \"stroked\": False\n",
- "}\n",
- "\n",
- "vc.link_views([spatial], [ct.SPATIAL_ZOOM, ct.SPATIAL_TARGET_X, ct.SPATIAL_TARGET_Y, ct.SPATIAL_SEGMENTATION_LAYER], [-6.43, 10417.69, 24885.55, spatial_segmentation_layer_value])\n",
- "vc.layout(spatial | (tsne / cell_sets));"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "nWHF",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 5. Render the widget"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "iLit",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "A widget can be created with the `.widget()` method on the config instance."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "ZHCJ",
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "ROlb",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/widget_modify_config.ipynb b/docs/notebooks/__ipynb__/widget_modify_config.ipynb
index a2a5363a..b3b6af1e 100644
--- a/docs/notebooks/__ipynb__/widget_modify_config.ipynb
+++ b/docs/notebooks/__ipynb__/widget_modify_config.ipynb
@@ -1,145 +1,153 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Programmatic modification of widget configuration"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "MJUe",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " OmeTiffWrapper,\n",
+ " MultiImageWrapper,\n",
+ " CoordinationLevel as CL,\n",
+ " ObsSegmentationsOmeTiffWrapper,\n",
+ " ImageOmeTiffWrapper,\n",
+ " get_initial_coordination_scope_prefix,\n",
+ ")\n",
+ "import random"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.16\")\n",
+ "dataset = vc.add_dataset(name='Spraggins').add_object(\n",
+ " ImageOmeTiffWrapper(\n",
+ " img_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2_bf.ome.tif\",\n",
+ " offsets_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2_bf.offsets.json\"\n",
+ " )\n",
+ ").add_object(\n",
+ " ObsSegmentationsOmeTiffWrapper(\n",
+ " img_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2.ome.tif\",\n",
+ " offsets_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2.offsets.json\",\n",
+ " obs_types_from_channel_names=True\n",
+ " )\n",
+ ")\n",
+ "\n",
+ "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
+ "lc = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
+ "\n",
+ "vc.link_views_by_dict([spatial, lc], {\n",
+ " \"imageLayer\": CL([\n",
+ " {\n",
+ " \"photometricInterpretation\": \"RGB\"\n",
+ " }\n",
+ " ]),\n",
+ "}, meta=True, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
+ "\n",
+ "vc.layout(spatial | lc);"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget(remount_on_uid_change=False)\n",
+ "vw"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Inspect the current configuration value.\n",
+ "# This is a dict in the JSON-based format https://vitessce.io/docs/view-config-json/\n",
+ "vw.config"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Programatically set a different zoom level and toggle the visibility/color of different segmentation layers:\n",
+ "vw.config = {\n",
+ " **vw.config,\n",
+ " # Need to provide a fresh \"uid\" value.\n",
+ " # This will tell Vitessce that the contents should be diff-ed against the previous config.\n",
+ " \"uid\": f\"new_config_{random.random()}\",\n",
+ " \"coordinationSpace\": {\n",
+ " # Information about the coordination space can be found at https://vitessce.io/docs/coordination-types/\n",
+ " **vw.config[\"coordinationSpace\"],\n",
+ " \"spatialZoom\": {\n",
+ " **vw.config[\"coordinationSpace\"][\"spatialZoom\"],\n",
+ " \"A\": -8\n",
+ " },\n",
+ " \"spatialChannelVisible\": {\n",
+ " **vw.config[\"coordinationSpace\"][\"spatialChannelVisible\"],\n",
+ " \"init_A_obsSegmentations_0\": True,\n",
+ " \"init_A_obsSegmentations_1\": False,\n",
+ " \"init_A_obsSegmentations_2\": False,\n",
+ " \"init_A_obsSegmentations_3\": False\n",
+ " },\n",
+ " \"spatialChannelColor\": {\n",
+ " **vw.config[\"coordinationSpace\"][\"spatialChannelColor\"],\n",
+ " \"init_A_obsSegmentations_0\": [255, 0, 0],\n",
+ " }\n",
+ " }\n",
+ "}"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "# Programmatic modification of widget configuration"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "MJUe",
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " OmeTiffWrapper,\n",
- " MultiImageWrapper,\n",
- " CoordinationLevel as CL,\n",
- " ObsSegmentationsOmeTiffWrapper,\n",
- " ImageOmeTiffWrapper,\n",
- " get_initial_coordination_scope_prefix,\n",
- ")\n",
- "import random"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "vblA",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.16\")\n",
- "dataset = vc.add_dataset(name='Spraggins').add_object(\n",
- " ImageOmeTiffWrapper(\n",
- " img_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2_bf.ome.tif\",\n",
- " offsets_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2_bf.offsets.json\"\n",
- " )\n",
- ").add_object(\n",
- " ObsSegmentationsOmeTiffWrapper(\n",
- " img_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2.ome.tif\",\n",
- " offsets_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2.offsets.json\",\n",
- " obs_types_from_channel_names=True\n",
- " )\n",
- ")\n",
- "\n",
- "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
- "lc = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
- "\n",
- "vc.link_views_by_dict([spatial, lc], {\n",
- " \"imageLayer\": CL([\n",
- " {\n",
- " \"photometricInterpretation\": \"RGB\"\n",
- " }\n",
- " ]),\n",
- "}, meta=True, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
- "\n",
- "vc.layout(spatial | lc);"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "bkHC",
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget(remount_on_uid_change=False)\n",
- "vw"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "lEQa",
- "metadata": {},
- "outputs": [],
- "source": [
- "# Inspect the current configuration value.\n",
- "# This is a dict in the JSON-based format https://vitessce.io/docs/view-config-json/\n",
- "vw.config"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "PKri",
- "metadata": {},
- "outputs": [],
- "source": [
- "# Programatically set a different zoom level and toggle the visibility/color of different segmentation layers:\n",
- "vw.config = {\n",
- " **vw.config,\n",
- " # Need to provide a fresh \"uid\" value.\n",
- " # This will tell Vitessce that the contents should be diff-ed against the previous config.\n",
- " \"uid\": f\"new_config_{random.random()}\",\n",
- " \"coordinationSpace\": {\n",
- " # Information about the coordination space can be found at https://vitessce.io/docs/coordination-types/\n",
- " **vw.config[\"coordinationSpace\"],\n",
- " \"spatialZoom\": {\n",
- " **vw.config[\"coordinationSpace\"][\"spatialZoom\"],\n",
- " \"A\": -8\n",
- " },\n",
- " \"spatialChannelVisible\": {\n",
- " **vw.config[\"coordinationSpace\"][\"spatialChannelVisible\"],\n",
- " \"init_A_obsSegmentations_0\": True,\n",
- " \"init_A_obsSegmentations_1\": False,\n",
- " \"init_A_obsSegmentations_2\": False,\n",
- " \"init_A_obsSegmentations_3\": False\n",
- " },\n",
- " \"spatialChannelColor\": {\n",
- " **vw.config[\"coordinationSpace\"][\"spatialChannelColor\"],\n",
- " \"init_A_obsSegmentations_0\": [255, 0, 0],\n",
- " }\n",
- " }\n",
- "}"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/widget_neuroglancer.ipynb b/docs/notebooks/__ipynb__/widget_neuroglancer.ipynb
index a7577622..6bdaef0b 100644
--- a/docs/notebooks/__ipynb__/widget_neuroglancer.ipynb
+++ b/docs/notebooks/__ipynb__/widget_neuroglancer.ipynb
@@ -1,225 +1,233 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Example usage of Neuroglancer view"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "MJUe",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " ImageOmeTiffWrapper,\n",
+ " CsvWrapper,\n",
+ " hconcat,\n",
+ " vconcat,\n",
+ " get_initial_coordination_scope_prefix,\n",
+ " CoordinationLevel as CL\n",
+ ")\n",
+ "from os.path import join"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "vblA",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Configure Vitessce"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.17\")\n",
+ "dataset = vc.add_dataset(name='Meshes').add_object(\n",
+ " ImageOmeTiffWrapper(\n",
+ " img_url='https://lsp-public-data.s3.amazonaws.com/yapp-2023-3d-melanoma/Dataset1-LSP13626-invasive-margin.ome.tiff',\n",
+ " offsets_url='https://lsp-public-data.s3.amazonaws.com/yapp-2023-3d-melanoma/Dataset1-LSP13626-invasive-margin.offsets.json',\n",
+ " coordination_values={\n",
+ " \"fileUid\": 'melanoma',\n",
+ " },\n",
+ " )\n",
+ ").add_object(\n",
+ " CsvWrapper(\n",
+ " data_type=\"obsEmbedding\",\n",
+ " csv_url='https://storage.googleapis.com/vitessce-demo-data/neuroglancer-march-2025/melanoma_with_embedding_filtered_ids.csv',\n",
+ " options= {\n",
+ " \"obsIndex\": 'id',\n",
+ " \"obsEmbedding\": ['tSNE1', 'tSNE2'],\n",
+ " },\n",
+ " coordination_values= {\n",
+ " \"obsType\": 'cell',\n",
+ " \"embeddingType\": 'TSNE',\n",
+ " },\n",
+ " )\n",
+ ").add_object(\n",
+ " CsvWrapper(\n",
+ " data_type=\"obsSets\",\n",
+ " csv_url='https://storage.googleapis.com/vitessce-demo-data/neuroglancer-march-2025/melanoma_with_embedding_filtered_ids.csv',\n",
+ " coordination_values={\n",
+ " \"obsType\": 'cell',\n",
+ " },\n",
+ " options= {\n",
+ " \"obsIndex\": 'id',\n",
+ " \"obsSets\": [\n",
+ " {\n",
+ " \"name\": 'Clusters',\n",
+ " \"column\": 'cluster',\n",
+ " },\n",
+ " ],\n",
+ " },\n",
+ " )\n",
+ ")\n",
+ "spatialThreeView = vc.add_view('spatialBeta', dataset=dataset);\n",
+ "lcView = vc.add_view('layerControllerBeta', dataset=dataset);\n",
+ "obsSets = vc.add_view('obsSets', dataset=dataset);\n",
+ "scatterView = vc.add_view('scatterplot', dataset=dataset, mapping=\"TSNE\");\n",
+ "# Configuration via props.viewerState is temporary and subject to change.\n",
+ "neuroglancerView = vc.add_view('neuroglancer', dataset=dataset).set_props(viewerState={\n",
+ " \"dimensions\": {\n",
+ " \"x\": [\n",
+ " 1e-9,\n",
+ " \"m\"\n",
+ " ],\n",
+ " \"y\": [\n",
+ " 1e-9,\n",
+ " \"m\"\n",
+ " ],\n",
+ " \"z\": [\n",
+ " 1e-9,\n",
+ " \"m\"\n",
+ " ]\n",
+ " },\n",
+ " \"position\": [\n",
+ " 49.5,\n",
+ " 1000.5,\n",
+ " 5209.5\n",
+ " ],\n",
+ " \"crossSectionScale\": 1,\n",
+ " \"projectionOrientation\": [\n",
+ " -0.636204183101654,\n",
+ " -0.5028395652770996,\n",
+ " 0.5443811416625977,\n",
+ " 0.2145828753709793\n",
+ " ],\n",
+ " \"projectionScale\": 1024,\n",
+ " \"layers\": [\n",
+ " {\n",
+ " \"type\": \"segmentation\",\n",
+ " \"source\": \"precomputed://https://vitessce-data-v2.s3.us-east-1.amazonaws.com/data/sorger/invasive_meshes\",\n",
+ " \"segments\": [\n",
+ " \"5\"\n",
+ " ],\n",
+ " \"segmentColors\": {\n",
+ " \"5\": \"red\"\n",
+ " },\n",
+ " \"name\": \"segmentation\"\n",
+ " }\n",
+ " ],\n",
+ " \"showSlices\": False,\n",
+ " \"layout\": \"3d\"\n",
+ "});\n",
+ "\n",
+ "vc.link_views([scatterView], ['embeddingObsRadiusMode', 'embeddingObsRadius'], ['manual', 4]);\n",
+ "\n",
+ "# Sync the zoom/rotation/pan states\n",
+ "vc.link_views_by_dict([spatialThreeView, lcView, neuroglancerView], {\n",
+ " \"spatialRenderingMode\": '3D',\n",
+ " \"spatialZoom\": 0,\n",
+ " \"spatialTargetT\": 0,\n",
+ " \"spatialTargetX\": 0,\n",
+ " \"spatialTargetY\": 0,\n",
+ " \"spatialTargetZ\": 0,\n",
+ " \"spatialRotationX\": 0,\n",
+ " \"spatialRotationY\": 0,\n",
+ "}, meta=False);\n",
+ "\n",
+ "# Initialize the image properties\n",
+ "vc.link_views_by_dict([spatialThreeView, lcView], {\n",
+ " \"imageLayer\": CL([\n",
+ " {\n",
+ " \"fileUid\": 'melanoma',\n",
+ " \"spatialLayerOpacity\": 1,\n",
+ " \"spatialTargetResolution\": None,\n",
+ " \"imageChannel\": CL([\n",
+ " {\n",
+ " \"spatialTargetC\": 0,\n",
+ " \"spatialChannelColor\": [255, 0, 0],\n",
+ " \"spatialChannelVisible\": True,\n",
+ " \"spatialChannelOpacity\": 1.0,\n",
+ " },\n",
+ " ]),\n",
+ " },\n",
+ " ]),\n",
+ "}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'));\n",
+ "\n",
+ "\n",
+ "vc.layout(hconcat(neuroglancerView, spatialThreeView, vconcat(lcView, obsSets, scatterView)));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 2. Create the Vitessce widget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
}
- },
- "source": [
- "# Example usage of Neuroglancer view"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "MJUe",
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " ImageOmeTiffWrapper,\n",
- " CsvWrapper,\n",
- " hconcat,\n",
- " vconcat,\n",
- " get_initial_coordination_scope_prefix,\n",
- " CoordinationLevel as CL\n",
- ")\n",
- "from os.path import join"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "vblA",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 1. Configure Vitessce"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "bkHC",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.17\")\n",
- "dataset = vc.add_dataset(name='Meshes').add_object(\n",
- " ImageOmeTiffWrapper(\n",
- " img_url='https://lsp-public-data.s3.amazonaws.com/yapp-2023-3d-melanoma/Dataset1-LSP13626-invasive-margin.ome.tiff',\n",
- " offsets_url='https://lsp-public-data.s3.amazonaws.com/yapp-2023-3d-melanoma/Dataset1-LSP13626-invasive-margin.offsets.json',\n",
- " coordination_values={\n",
- " \"fileUid\": 'melanoma',\n",
- " },\n",
- " )\n",
- ").add_object(\n",
- " CsvWrapper(\n",
- " data_type=\"obsEmbedding\",\n",
- " csv_url='https://storage.googleapis.com/vitessce-demo-data/neuroglancer-march-2025/melanoma_with_embedding_filtered_ids.csv',\n",
- " options= {\n",
- " \"obsIndex\": 'id',\n",
- " \"obsEmbedding\": ['tSNE1', 'tSNE2'],\n",
- " },\n",
- " coordination_values= {\n",
- " \"obsType\": 'cell',\n",
- " \"embeddingType\": 'TSNE',\n",
- " },\n",
- " )\n",
- ").add_object(\n",
- " CsvWrapper(\n",
- " data_type=\"obsSets\",\n",
- " csv_url='https://storage.googleapis.com/vitessce-demo-data/neuroglancer-march-2025/melanoma_with_embedding_filtered_ids.csv',\n",
- " coordination_values={\n",
- " \"obsType\": 'cell',\n",
- " },\n",
- " options= {\n",
- " \"obsIndex\": 'id',\n",
- " \"obsSets\": [\n",
- " {\n",
- " \"name\": 'Clusters',\n",
- " \"column\": 'cluster',\n",
- " },\n",
- " ],\n",
- " },\n",
- " )\n",
- ")\n",
- "spatialThreeView = vc.add_view('spatialBeta', dataset=dataset);\n",
- "lcView = vc.add_view('layerControllerBeta', dataset=dataset);\n",
- "obsSets = vc.add_view('obsSets', dataset=dataset);\n",
- "scatterView = vc.add_view('scatterplot', dataset=dataset, mapping=\"TSNE\");\n",
- "# Configuration via props.viewerState is temporary and subject to change.\n",
- "neuroglancerView = vc.add_view('neuroglancer', dataset=dataset).set_props(viewerState={\n",
- " \"dimensions\": {\n",
- " \"x\": [\n",
- " 1e-9,\n",
- " \"m\"\n",
- " ],\n",
- " \"y\": [\n",
- " 1e-9,\n",
- " \"m\"\n",
- " ],\n",
- " \"z\": [\n",
- " 1e-9,\n",
- " \"m\"\n",
- " ]\n",
- " },\n",
- " \"position\": [\n",
- " 49.5,\n",
- " 1000.5,\n",
- " 5209.5\n",
- " ],\n",
- " \"crossSectionScale\": 1,\n",
- " \"projectionOrientation\": [\n",
- " -0.636204183101654,\n",
- " -0.5028395652770996,\n",
- " 0.5443811416625977,\n",
- " 0.2145828753709793\n",
- " ],\n",
- " \"projectionScale\": 1024,\n",
- " \"layers\": [\n",
- " {\n",
- " \"type\": \"segmentation\",\n",
- " \"source\": \"precomputed://https://vitessce-data-v2.s3.us-east-1.amazonaws.com/data/sorger/invasive_meshes\",\n",
- " \"segments\": [\n",
- " \"5\"\n",
- " ],\n",
- " \"segmentColors\": {\n",
- " \"5\": \"red\"\n",
- " },\n",
- " \"name\": \"segmentation\"\n",
- " }\n",
- " ],\n",
- " \"showSlices\": False,\n",
- " \"layout\": \"3d\"\n",
- "});\n",
- "\n",
- "vc.link_views([scatterView], ['embeddingObsRadiusMode', 'embeddingObsRadius'], ['manual', 4]);\n",
- "\n",
- "# Sync the zoom/rotation/pan states\n",
- "vc.link_views_by_dict([spatialThreeView, lcView, neuroglancerView], {\n",
- " \"spatialRenderingMode\": '3D',\n",
- " \"spatialZoom\": 0,\n",
- " \"spatialTargetT\": 0,\n",
- " \"spatialTargetX\": 0,\n",
- " \"spatialTargetY\": 0,\n",
- " \"spatialTargetZ\": 0,\n",
- " \"spatialRotationX\": 0,\n",
- " \"spatialRotationY\": 0,\n",
- "}, meta=False);\n",
- "\n",
- "# Initialize the image properties\n",
- "vc.link_views_by_dict([spatialThreeView, lcView], {\n",
- " \"imageLayer\": CL([\n",
- " {\n",
- " \"fileUid\": 'melanoma',\n",
- " \"spatialLayerOpacity\": 1,\n",
- " \"spatialTargetResolution\": None,\n",
- " \"imageChannel\": CL([\n",
- " {\n",
- " \"spatialTargetC\": 0,\n",
- " \"spatialChannelColor\": [255, 0, 0],\n",
- " \"spatialChannelVisible\": True,\n",
- " \"spatialChannelOpacity\": 1.0,\n",
- " },\n",
- " ]),\n",
- " },\n",
- " ]),\n",
- "}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'));\n",
- "\n",
- "\n",
- "vc.layout(hconcat(neuroglancerView, spatialThreeView, vconcat(lcView, obsSets, scatterView)));"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "lEQa",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "## 2. Create the Vitessce widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "PKri",
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/widget_pbmc.ipynb b/docs/notebooks/__ipynb__/widget_pbmc.ipynb
index edef6265..0fb8a0f7 100644
--- a/docs/notebooks/__ipynb__/widget_pbmc.ipynb
+++ b/docs/notebooks/__ipynb__/widget_pbmc.ipynb
@@ -1,223 +1,231 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of 3k PBMC reference"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the classes and functions that we will be using from the corresponding packages."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from os.path import join, isfile, isdir\n",
+ "from urllib.request import urlretrieve\n",
+ "from anndata import read_h5ad\n",
+ "import scanpy as sc\n",
+ "\n",
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " AnnDataWrapper,\n",
+ ")\n",
+ "from vitessce.data_utils import (\n",
+ " optimize_adata,\n",
+ " VAR_CHUNK_SIZE,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 2. Download the dataset\n",
+ "\n",
+ "Download `pbmc3k_final.h5ad` from https://seurat.nygenome.org/pbmc3k_final.h5ad"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata_filepath = join(\"data\", \"pbmc3k_final.h5ad\")\n",
+ "if not isfile(adata_filepath):\n",
+ " os.makedirs(\"data\", exist_ok=True)\n",
+ " urlretrieve('https://seurat.nygenome.org/pbmc3k_final.h5ad', adata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "PKri",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 3. Load the dataset\n",
+ "\n",
+ "Load the dataset using AnnData's `read_h5ad` function."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata = read_h5ad(adata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 3.1 Save the AnnData object to Zarr"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "zarr_filepath = join('data', 'pbmc3k_final.zarr')\n",
+ "if not isdir(zarr_filepath):\n",
+ " adata_1 = optimize_adata(adata, obs_cols=['leiden'], obsm_keys=['X_umap', 'X_pca'], optimize_X=True)\n",
+ " adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "RGSE",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 4. Create a Vitessce view config\n",
+ "\n",
+ "Define the data and views you would like to include in the widget.\n",
+ "\n",
+ "For more details about how to configure data depending on where the files are located relative to the notebook execution, see https://python-docs.vitessce.io/data_options.html."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Kclp",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='PBMC Reference')\n",
+ "dataset = vc.add_dataset(name='PBMC 3k').add_object(AnnDataWrapper(\n",
+ " adata_store=zarr_filepath,\n",
+ " obs_set_paths=[\"obs/leiden\"],\n",
+ " obs_set_names=[\"Leiden\"],\n",
+ " obs_embedding_paths=[\"obsm/X_umap\", \"obsm/X_pca\"],\n",
+ " obs_embedding_names=[\"UMAP\", \"PCA\"],\n",
+ " obs_feature_matrix_path=\"X\"\n",
+ "))\n",
+ "\n",
+ "umap = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
+ "pca = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"PCA\")\n",
+ "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
+ "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
+ "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)\n",
+ "\n",
+ "vc.layout((umap / pca) | ((cell_sets | genes) / heatmap));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "emfo",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 5. Create the Vitessce widget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Hstk",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
}
- },
- "source": [
- "# Visualization of 3k PBMC reference"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "## 1. Import dependencies\n",
- "\n",
- "We need to import the classes and functions that we will be using from the corresponding packages."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "vblA",
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join, isfile, isdir\n",
- "from urllib.request import urlretrieve\n",
- "from anndata import read_h5ad\n",
- "import scanpy as sc\n",
- "\n",
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " AnnDataWrapper,\n",
- ")\n",
- "from vitessce.data_utils import (\n",
- " optimize_adata,\n",
- " VAR_CHUNK_SIZE,\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "bkHC",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 2. Download the dataset\n",
- "\n",
- "Download `pbmc3k_final.h5ad` from https://seurat.nygenome.org/pbmc3k_final.h5ad"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "lEQa",
- "metadata": {},
- "outputs": [],
- "source": [
- "adata_filepath = join(\"data\", \"pbmc3k_final.h5ad\")\n",
- "if not isfile(adata_filepath):\n",
- " os.makedirs(\"data\", exist_ok=True)\n",
- " urlretrieve('https://seurat.nygenome.org/pbmc3k_final.h5ad', adata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "PKri",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 3. Load the dataset\n",
- "\n",
- "Load the dataset using AnnData's `read_h5ad` function."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "adata = read_h5ad(adata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "SFPL",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 3.1 Save the AnnData object to Zarr"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "BYtC",
- "metadata": {},
- "outputs": [],
- "source": [
- "zarr_filepath = join('data', 'pbmc3k_final.zarr')\n",
- "if not isdir(zarr_filepath):\n",
- " adata_1 = optimize_adata(adata, obs_cols=['leiden'], obsm_keys=['X_umap', 'X_pca'], optimize_X=True)\n",
- " adata_1.write_zarr(zarr_filepath, chunks=[adata_1.shape[0], VAR_CHUNK_SIZE])"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "RGSE",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 4. Create a Vitessce view config\n",
- "\n",
- "Define the data and views you would like to include in the widget.\n",
- "\n",
- "For more details about how to configure data depending on where the files are located relative to the notebook execution, see https://python-docs.vitessce.io/data_options.html."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Kclp",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='PBMC Reference')\n",
- "dataset = vc.add_dataset(name='PBMC 3k').add_object(AnnDataWrapper(\n",
- " adata_store=zarr_filepath,\n",
- " obs_set_paths=[\"obs/leiden\"],\n",
- " obs_set_names=[\"Leiden\"],\n",
- " obs_embedding_paths=[\"obsm/X_umap\", \"obsm/X_pca\"],\n",
- " obs_embedding_names=[\"UMAP\", \"PCA\"],\n",
- " obs_feature_matrix_path=\"X\"\n",
- "))\n",
- "\n",
- "umap = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
- "pca = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"PCA\")\n",
- "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
- "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
- "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)\n",
- "\n",
- "vc.layout((umap / pca) | ((cell_sets | genes) / heatmap));"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "emfo",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 5. Create the Vitessce widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Hstk",
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "nWHF",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/widget_pbmc_remote.ipynb b/docs/notebooks/__ipynb__/widget_pbmc_remote.ipynb
index c21d07ec..7b9ff492 100644
--- a/docs/notebooks/__ipynb__/widget_pbmc_remote.ipynb
+++ b/docs/notebooks/__ipynb__/widget_pbmc_remote.ipynb
@@ -1,168 +1,176 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of 3k PBMC reference from Remote Zarr Store"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "We need to import the classes and functions that we will be using from the corresponding packages."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from os.path import join\n",
+ "from urllib.request import urlretrieve\n",
+ "from anndata import read_h5ad\n",
+ "import scanpy as sc\n",
+ "\n",
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " AnnDataWrapper,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 2. Set the URL for the Remote Dataset\n",
+ "\n",
+ "For this example, we already have uploaded the `pbmc3k` dataset as a zarr store from the [scanpy docs](https://scanpy.readthedocs.io/en/stable/api/scanpy.datasets.pbmc3k.html) to the cloud."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "url = 'https://storage.googleapis.com/vitessce-demo-data/anndata-test/pbmc3k_processed.zarr/'"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "PKri",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 3. Create a Vitessce view config\n",
+ "\n",
+ "Define the data and views you would like to include in the widget."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='PBMC Reference')\n",
+ "dataset = vc.add_dataset(name='PBMC 3k').add_object(AnnDataWrapper(adata_url=url, obs_set_paths=[\"obs/louvain\"], obs_set_names=[\"Louvain\"], obs_embedding_paths=[\"obsm/X_umap\", \"obsm/X_pca\"], obs_embedding_names=[\"UMAP\", \"PCA\"], obs_feature_matrix_path=\"X\"))\n",
+ "\n",
+ "umap = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
+ "pca = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"PCA\")\n",
+ "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
+ "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
+ "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)\n",
+ "\n",
+ "vc.layout((umap / pca) | ((cell_sets | genes) / heatmap));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 4. Create the Vitessce widget"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "BYtC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "A widget can be created with the `.widget()` method on the config instance. Here, the `proxy=True` parameter allows this widget to be used in a cloud notebook environment, such as Binder."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "RGSE",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
}
- },
- "source": [
- "# Visualization of 3k PBMC reference from Remote Zarr Store"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 1. Import dependencies\n",
- "\n",
- "We need to import the classes and functions that we will be using from the corresponding packages."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "vblA",
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join\n",
- "from urllib.request import urlretrieve\n",
- "from anndata import read_h5ad\n",
- "import scanpy as sc\n",
- "\n",
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " AnnDataWrapper,\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "bkHC",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 2. Set the URL for the Remote Dataset\n",
- "\n",
- "For this example, we already have uploaded the `pbmc3k` dataset as a zarr store from the [scanpy docs](https://scanpy.readthedocs.io/en/stable/api/scanpy.datasets.pbmc3k.html) to the cloud."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "lEQa",
- "metadata": {},
- "outputs": [],
- "source": [
- "url = 'https://storage.googleapis.com/vitessce-demo-data/anndata-test/pbmc3k_processed.zarr/'"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "PKri",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "## 3. Create a Vitessce view config\n",
- "\n",
- "Define the data and views you would like to include in the widget."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='PBMC Reference')\n",
- "dataset = vc.add_dataset(name='PBMC 3k').add_object(AnnDataWrapper(adata_url=url, obs_set_paths=[\"obs/louvain\"], obs_set_names=[\"Louvain\"], obs_embedding_paths=[\"obsm/X_umap\", \"obsm/X_pca\"], obs_embedding_names=[\"UMAP\", \"PCA\"], obs_feature_matrix_path=\"X\"))\n",
- "\n",
- "umap = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"UMAP\")\n",
- "pca = vc.add_view(cm.SCATTERPLOT, dataset=dataset, mapping=\"PCA\")\n",
- "cell_sets = vc.add_view(cm.OBS_SETS, dataset=dataset)\n",
- "genes = vc.add_view(cm.FEATURE_LIST, dataset=dataset)\n",
- "heatmap = vc.add_view(cm.HEATMAP, dataset=dataset)\n",
- "\n",
- "vc.layout((umap / pca) | ((cell_sets | genes) / heatmap));"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "SFPL",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 4. Create the Vitessce widget"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "BYtC",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "A widget can be created with the `.widget()` method on the config instance. Here, the `proxy=True` parameter allows this widget to be used in a cloud notebook environment, such as Binder."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "RGSE",
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Kclp",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/widget_plugin_custom.ipynb b/docs/notebooks/__ipynb__/widget_plugin_custom.ipynb
index e2b99f84..ea9cad9a 100644
--- a/docs/notebooks/__ipynb__/widget_plugin_custom.ipynb
+++ b/docs/notebooks/__ipynb__/widget_plugin_custom.ipynb
@@ -1,185 +1,193 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Vitessce custom plugin definition"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "MJUe",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " OmeTiffWrapper,\n",
+ " MultiImageWrapper,\n",
+ " VitesscePlugin\n",
+ ")\n",
+ "from oxc_py import transform"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "PLUGIN_ESM = transform(\"\"\"\n",
+ "function createPlugins(utilsForPlugins) {\n",
+ " const {\n",
+ " React,\n",
+ " PluginFileType,\n",
+ " PluginViewType,\n",
+ " PluginCoordinationType,\n",
+ " PluginJointFileType,\n",
+ " z,\n",
+ " useCoordination,\n",
+ " invokeCommand,\n",
+ " } = utilsForPlugins;\n",
+ "\n",
+ " const CSS = `\n",
+ " .chat {\n",
+ " overflow-y: scroll;\n",
+ " }\n",
+ " `;\n",
+ "\n",
+ " function ChatView(props) {\n",
+ "\n",
+ " const [nextMessage, setNextMessage] = React.useState('');\n",
+ " const [isLoading, setIsLoading] = React.useState(false);\n",
+ " const [chatHistory, setChatHistory] = React.useState([]); // chatHistory is an array of message objects like [{ user, text }, ...]\n",
+ "\n",
+ " async function handleClick() { \n",
+ " setChatHistory(prev => ([\n",
+ " ...prev,\n",
+ " { user: 'You', text: nextMessage },\n",
+ " ]));\n",
+ " setIsLoading(true);\n",
+ " const [chatReceiveValue, chatReceiveBuffers] = await invokeCommand(\"chat_send\", nextMessage, []);\n",
+ " setChatHistory(prev => ([\n",
+ " ...prev,\n",
+ " { user: 'AI', text: chatReceiveValue.text },\n",
+ " ]));\n",
+ " setIsLoading(false);\n",
+ " }\n",
+ "\n",
+ " return (\n",
+ " <>\n",
+ " \n",
+ " \n",
+ "
Chat view
\n",
+ "
\n",
+ " {chatHistory.map(message => (\n",
+ "
\n",
+ " {message.user} :\n",
+ " {message.text} \n",
+ "
\n",
+ " ))}\n",
+ "
\n",
+ "
setNextMessage(e.target.value)} disabled={isLoading} />\n",
+ "
Send message \n",
+ "
\n",
+ " >\n",
+ " );\n",
+ " }\n",
+ "\n",
+ " const pluginViewTypes = [\n",
+ " new PluginViewType('chat', ChatView, []),\n",
+ " ];\n",
+ " return { pluginViewTypes };\n",
+ "}\n",
+ "export default { createPlugins };\n",
+ "\"\"\")\n",
+ "\n",
+ "\n",
+ "def handle_chat_message(message, buffers):\n",
+ " return { \"text\": message.upper() }, []\n",
+ "\n",
+ "\n",
+ "class ChatPlugin(VitesscePlugin):\n",
+ " plugin_esm = PLUGIN_ESM\n",
+ " commands = {\n",
+ " \"chat_send\": handle_chat_message,\n",
+ " }"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='Spraggins Multi-Modal', description='PAS + IMS + AF From https://portal.hubmapconsortium.org/browse/collection/6a6efd0c1a2681dc7d2faab8e4ab0bca')\n",
+ "dataset = vc.add_dataset(name='Spraggins').add_object(\n",
+ " MultiImageWrapper(\n",
+ " image_wrappers=[\n",
+ " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/f4188a148e4c759092d19369d310883b/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-PAS_images/VAN0006-LK-2-85-PAS_registered.ome.tif?token=', name='PAS'),\n",
+ " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/2130d5f91ce61d7157a42c0497b06de8/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-AF_preIMS_images/VAN0006-LK-2-85-AF_preIMS_registered.ome.tif?token=', name='AF'),\n",
+ " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/be503a021ed910c0918842e318e6efa2/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_PosMode_multilayer.ome.tif?token=', name='IMS Pos Mode'),\n",
+ " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/ca886a630b2038997a4cfbbf4abfd283/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_NegMode_multilayer.ome.tif?token=', name='IMS Neg Mode')\n",
+ " ],\n",
+ " use_physical_size_scaling=True,\n",
+ " )\n",
+ ")\n",
+ "spatial = vc.add_view(cm.SPATIAL, dataset=dataset)\n",
+ "status = vc.add_view(\"chat\", dataset=dataset)\n",
+ "lc = vc.add_view(cm.LAYER_CONTROLLER, dataset=dataset).set_props(disableChannelsIfRgbDetected=True)\n",
+ "vc.layout(spatial | (lc / status));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 2. Create the Vitessce widget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget(plugins=[ChatPlugin()])\n",
+ "vw"
+ ]
}
- },
- "source": [
- "# Vitessce custom plugin definition"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "MJUe",
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " OmeTiffWrapper,\n",
- " MultiImageWrapper,\n",
- " VitesscePlugin\n",
- ")\n",
- "from oxc_py import transform"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "vblA",
- "metadata": {},
- "outputs": [],
- "source": [
- "PLUGIN_ESM = transform(\"\"\"\n",
- "function createPlugins(utilsForPlugins) {\n",
- " const {\n",
- " React,\n",
- " PluginFileType,\n",
- " PluginViewType,\n",
- " PluginCoordinationType,\n",
- " PluginJointFileType,\n",
- " z,\n",
- " useCoordination,\n",
- " invokeCommand,\n",
- " } = utilsForPlugins;\n",
- "\n",
- " const CSS = `\n",
- " .chat {\n",
- " overflow-y: scroll;\n",
- " }\n",
- " `;\n",
- "\n",
- " function ChatView(props) {\n",
- "\n",
- " const [nextMessage, setNextMessage] = React.useState('');\n",
- " const [isLoading, setIsLoading] = React.useState(false);\n",
- " const [chatHistory, setChatHistory] = React.useState([]); // chatHistory is an array of message objects like [{ user, text }, ...]\n",
- "\n",
- " async function handleClick() { \n",
- " setChatHistory(prev => ([\n",
- " ...prev,\n",
- " { user: 'You', text: nextMessage },\n",
- " ]));\n",
- " setIsLoading(true);\n",
- " const [chatReceiveValue, chatReceiveBuffers] = await invokeCommand(\"chat_send\", nextMessage, []);\n",
- " setChatHistory(prev => ([\n",
- " ...prev,\n",
- " { user: 'AI', text: chatReceiveValue.text },\n",
- " ]));\n",
- " setIsLoading(false);\n",
- " }\n",
- "\n",
- " return (\n",
- " <>\n",
- " \n",
- " \n",
- "
Chat view
\n",
- "
\n",
- " {chatHistory.map(message => (\n",
- "
\n",
- " {message.user} :\n",
- " {message.text} \n",
- "
\n",
- " ))}\n",
- "
\n",
- "
setNextMessage(e.target.value)} disabled={isLoading} />\n",
- "
Send message \n",
- "
\n",
- " >\n",
- " );\n",
- " }\n",
- "\n",
- " const pluginViewTypes = [\n",
- " new PluginViewType('chat', ChatView, []),\n",
- " ];\n",
- " return { pluginViewTypes };\n",
- "}\n",
- "export default { createPlugins };\n",
- "\"\"\")\n",
- "\n",
- "\n",
- "def handle_chat_message(message, buffers):\n",
- " return { \"text\": message.upper() }, []\n",
- "\n",
- "\n",
- "class ChatPlugin(VitesscePlugin):\n",
- " plugin_esm = PLUGIN_ESM\n",
- " commands = {\n",
- " \"chat_send\": handle_chat_message,\n",
- " }"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "bkHC",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='Spraggins Multi-Modal', description='PAS + IMS + AF From https://portal.hubmapconsortium.org/browse/collection/6a6efd0c1a2681dc7d2faab8e4ab0bca')\n",
- "dataset = vc.add_dataset(name='Spraggins').add_object(\n",
- " MultiImageWrapper(\n",
- " image_wrappers=[\n",
- " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/f4188a148e4c759092d19369d310883b/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-PAS_images/VAN0006-LK-2-85-PAS_registered.ome.tif?token=', name='PAS'),\n",
- " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/2130d5f91ce61d7157a42c0497b06de8/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-AF_preIMS_images/VAN0006-LK-2-85-AF_preIMS_registered.ome.tif?token=', name='AF'),\n",
- " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/be503a021ed910c0918842e318e6efa2/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_PosMode_multilayer.ome.tif?token=', name='IMS Pos Mode'),\n",
- " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/ca886a630b2038997a4cfbbf4abfd283/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_NegMode_multilayer.ome.tif?token=', name='IMS Neg Mode')\n",
- " ],\n",
- " use_physical_size_scaling=True,\n",
- " )\n",
- ")\n",
- "spatial = vc.add_view(cm.SPATIAL, dataset=dataset)\n",
- "status = vc.add_view(\"chat\", dataset=dataset)\n",
- "lc = vc.add_view(cm.LAYER_CONTROLLER, dataset=dataset).set_props(disableChannelsIfRgbDetected=True)\n",
- "vc.layout(spatial | (lc / status));"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "lEQa",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "## 2. Create the Vitessce widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "PKri",
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget(plugins=[ChatPlugin()])\n",
- "vw"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/widget_plugin_demo.ipynb b/docs/notebooks/__ipynb__/widget_plugin_demo.ipynb
index 4ab1b120..13d3c4b4 100644
--- a/docs/notebooks/__ipynb__/widget_plugin_demo.ipynb
+++ b/docs/notebooks/__ipynb__/widget_plugin_demo.ipynb
@@ -1,137 +1,145 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Vitessce plugin usage demo"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "We visualize IMS, PAS, and AF imaging data overlaid from the Spraggins Lab of the Biomolecular Multimodal Imaging Center (BIOMC) at Vanderbilt University, uploaded to the HuBMAP data portal."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " OmeTiffWrapper,\n",
+ " MultiImageWrapper,\n",
+ ")\n",
+ "from os.path import join"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce.widget_plugins import DemoPlugin"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "lEQa",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Configure Vitessce\n",
+ "Set up the images from the three different assays, with the `use_physical_size_scaling` set to `True` so that the IMS image scales to the other images based on their physical sizes."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "PKri",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.15\", name='Spraggins Multi-Modal', description='PAS + IMS + AF From https://portal.hubmapconsortium.org/browse/collection/6a6efd0c1a2681dc7d2faab8e4ab0bca')\n",
+ "dataset = vc.add_dataset(name='Spraggins').add_object(\n",
+ " MultiImageWrapper(\n",
+ " image_wrappers=[\n",
+ " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/f4188a148e4c759092d19369d310883b/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-PAS_images/VAN0006-LK-2-85-PAS_registered.ome.tif?token=', name='PAS'),\n",
+ " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/2130d5f91ce61d7157a42c0497b06de8/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-AF_preIMS_images/VAN0006-LK-2-85-AF_preIMS_registered.ome.tif?token=', name='AF'),\n",
+ " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/be503a021ed910c0918842e318e6efa2/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_PosMode_multilayer.ome.tif?token=', name='IMS Pos Mode'),\n",
+ " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/ca886a630b2038997a4cfbbf4abfd283/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_NegMode_multilayer.ome.tif?token=', name='IMS Neg Mode')\n",
+ " ],\n",
+ " use_physical_size_scaling=True,\n",
+ " )\n",
+ ")\n",
+ "spatial = vc.add_view(cm.SPATIAL, dataset=dataset)\n",
+ "status = vc.add_view(\"demo\", dataset=dataset)\n",
+ "lc = vc.add_view(cm.LAYER_CONTROLLER, dataset=dataset).set_props(disableChannelsIfRgbDetected=True)\n",
+ "vc.layout(spatial | (lc / status));"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "Xref",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 2. Create the Vitessce widget"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "SFPL",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget(plugins=[DemoPlugin()])\n",
+ "vw"
+ ]
}
- },
- "source": [
- "# Vitessce plugin usage demo"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "We visualize IMS, PAS, and AF imaging data overlaid from the Spraggins Lab of the Biomolecular Multimodal Imaging Center (BIOMC) at Vanderbilt University, uploaded to the HuBMAP data portal."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "vblA",
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " OmeTiffWrapper,\n",
- " MultiImageWrapper,\n",
- ")\n",
- "from os.path import join"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "bkHC",
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce.widget_plugins import DemoPlugin"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "lEQa",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "## 1. Configure Vitessce\n",
- "Set up the images from the three different assays, with the `use_physical_size_scaling` set to `True` so that the IMS image scales to the other images based on their physical sizes."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "PKri",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.15\", name='Spraggins Multi-Modal', description='PAS + IMS + AF From https://portal.hubmapconsortium.org/browse/collection/6a6efd0c1a2681dc7d2faab8e4ab0bca')\n",
- "dataset = vc.add_dataset(name='Spraggins').add_object(\n",
- " MultiImageWrapper(\n",
- " image_wrappers=[\n",
- " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/f4188a148e4c759092d19369d310883b/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-PAS_images/VAN0006-LK-2-85-PAS_registered.ome.tif?token=', name='PAS'),\n",
- " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/2130d5f91ce61d7157a42c0497b06de8/ometiff-pyramids/processedMicroscopy/VAN0006-LK-2-85-AF_preIMS_images/VAN0006-LK-2-85-AF_preIMS_registered.ome.tif?token=', name='AF'),\n",
- " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/be503a021ed910c0918842e318e6efa2/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_PosMode_multilayer.ome.tif?token=', name='IMS Pos Mode'),\n",
- " OmeTiffWrapper(img_url='https://assets.hubmapconsortium.org/ca886a630b2038997a4cfbbf4abfd283/ometiff-pyramids/ometiffs/VAN0006-LK-2-85-IMS_NegMode_multilayer.ome.tif?token=', name='IMS Neg Mode')\n",
- " ],\n",
- " use_physical_size_scaling=True,\n",
- " )\n",
- ")\n",
- "spatial = vc.add_view(cm.SPATIAL, dataset=dataset)\n",
- "status = vc.add_view(\"demo\", dataset=dataset)\n",
- "lc = vc.add_view(cm.LAYER_CONTROLLER, dataset=dataset).set_props(disableChannelsIfRgbDetected=True)\n",
- "vc.layout(spatial | (lc / status));"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "Xref",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 2. Create the Vitessce widget"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "SFPL",
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget(plugins=[DemoPlugin()])\n",
- "vw"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "BYtC",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/widget_segmentations_beta.ipynb b/docs/notebooks/__ipynb__/widget_segmentations_beta.ipynb
index 4354b1b2..aef575d7 100644
--- a/docs/notebooks/__ipynb__/widget_segmentations_beta.ipynb
+++ b/docs/notebooks/__ipynb__/widget_segmentations_beta.ipynb
@@ -1,97 +1,105 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# Visualization of OME-TIFF images and segmentation masks"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "MJUe",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " OmeTiffWrapper,\n",
+ " MultiImageWrapper,\n",
+ " CoordinationLevel as CL,\n",
+ " ObsSegmentationsOmeTiffWrapper,\n",
+ " ImageOmeTiffWrapper,\n",
+ " get_initial_coordination_scope_prefix,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vc = VitessceConfig(schema_version=\"1.0.16\")\n",
+ "dataset = vc.add_dataset(name='Spraggins').add_object(\n",
+ " ImageOmeTiffWrapper(\n",
+ " img_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2_bf.ome.tif\",\n",
+ " offsets_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2_bf.offsets.json\"\n",
+ " )\n",
+ ").add_object(\n",
+ " ObsSegmentationsOmeTiffWrapper(\n",
+ " img_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2.ome.tif\",\n",
+ " offsets_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2.offsets.json\",\n",
+ " obs_types_from_channel_names=True\n",
+ " )\n",
+ ")\n",
+ "\n",
+ "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
+ "lc = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
+ "\n",
+ "vc.link_views_by_dict([spatial, lc], {\n",
+ " \"imageLayer\": CL([\n",
+ " {\n",
+ " \"photometricInterpretation\": \"RGB\" \n",
+ " }\n",
+ " ]),\n",
+ "}, meta=True, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
+ "\n",
+ "vc.layout(spatial | lc);"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "bkHC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = vc.widget()\n",
+ "vw"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "# Visualization of OME-TIFF images and segmentation masks"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "MJUe",
- "metadata": {},
- "outputs": [],
- "source": [
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " OmeTiffWrapper,\n",
- " MultiImageWrapper,\n",
- " CoordinationLevel as CL,\n",
- " ObsSegmentationsOmeTiffWrapper,\n",
- " ImageOmeTiffWrapper,\n",
- " get_initial_coordination_scope_prefix,\n",
- ")"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "vblA",
- "metadata": {},
- "outputs": [],
- "source": [
- "vc = VitessceConfig(schema_version=\"1.0.16\")\n",
- "dataset = vc.add_dataset(name='Spraggins').add_object(\n",
- " ImageOmeTiffWrapper(\n",
- " img_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2_bf.ome.tif\",\n",
- " offsets_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2_bf.offsets.json\"\n",
- " )\n",
- ").add_object(\n",
- " ObsSegmentationsOmeTiffWrapper(\n",
- " img_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2.ome.tif\",\n",
- " offsets_url=\"https://storage.googleapis.com/vitessce-demo-data/kpmp-f2f-march-2023/S-1905-017737/S-1905-017737_PAS_2of2.offsets.json\",\n",
- " obs_types_from_channel_names=True\n",
- " )\n",
- ")\n",
- "\n",
- "spatial = vc.add_view(\"spatialBeta\", dataset=dataset)\n",
- "lc = vc.add_view(\"layerControllerBeta\", dataset=dataset)\n",
- "\n",
- "vc.link_views_by_dict([spatial, lc], {\n",
- " \"imageLayer\": CL([\n",
- " {\n",
- " \"photometricInterpretation\": \"RGB\" \n",
- " }\n",
- " ]),\n",
- "}, meta=True, scope_prefix=get_initial_coordination_scope_prefix(\"A\", \"image\"))\n",
- "\n",
- "vc.layout(spatial | lc);"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "bkHC",
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = vc.widget()\n",
- "vw"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "lEQa",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/docs/notebooks/__ipynb__/widget_shortcut.ipynb b/docs/notebooks/__ipynb__/widget_shortcut.ipynb
index 68e38c52..7e4a2f48 100644
--- a/docs/notebooks/__ipynb__/widget_shortcut.ipynb
+++ b/docs/notebooks/__ipynb__/widget_shortcut.ipynb
@@ -1,185 +1,193 @@
{
- "cells": [
- {
- "cell_type": "markdown",
- "id": "Hbol",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "Hbol",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "# The from_object shortcut"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "MJUe",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 1. Import dependencies\n",
+ "\n",
+ "Import the functions and classes that we will be using."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "vblA",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "from os.path import join\n",
+ "from urllib.request import urlretrieve\n",
+ "from anndata import read_h5ad\n",
+ "import scanpy as sc\n",
+ "\n",
+ "from vitessce import (\n",
+ " VitessceConfig,\n",
+ " Component as cm,\n",
+ " CoordinationType as ct,\n",
+ " AnnDataWrapper,\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "bkHC",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 2. Download the data\n",
+ "\n",
+ "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "lEQa",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "os.makedirs(\"data\", exist_ok=True)\n",
+ "adata_filepath = join(\"data\", \"habib17.processed.h5ad\")\n",
+ "urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "PKri",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 3. Load the data"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Xref",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "adata = read_h5ad(join(\"data\", \"habib17.processed.h5ad\"))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "SFPL",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "## 3.1. Preprocess the Data For Visualization"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "BYtC",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "top_dispersion = adata.var[\"dispersions_norm\"][\n",
+ " sorted(\n",
+ " range(len(adata.var[\"dispersions_norm\"])),\n",
+ " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
+ " )[-51:][0]\n",
+ "]\n",
+ "adata.var[\"top_highly_variable\"] = (\n",
+ " adata.var[\"dispersions_norm\"] > top_dispersion\n",
+ ")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "RGSE",
+ "metadata": {
+ "marimo": {
+ "config": {
+ "hide_code": true
+ }
+ }
+ },
+ "source": [
+ "With one line of code, you may create a Vitessce widget based on an automatically inferred configuration."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "Kclp",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "vw = VitessceConfig.from_object(AnnDataWrapper(\n",
+ " adata,\n",
+ " obs_embedding_paths=[\"obsm/X_umap\"],\n",
+ " obs_embedding_names=[\"UMAP\"],\n",
+ " obs_set_paths=[\"obs/CellType\"],\n",
+ " obs_set_names=[\"Cell Type\"],\n",
+ " obs_feature_matrix_path=\"X\",\n",
+ " feature_filter_path=\"var/top_highly_variable\"\n",
+ "), schema_version=\"1.0.15\").widget(height=800)\n",
+ "vw"
+ ]
}
- },
- "source": [
- "# The from_object shortcut"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "MJUe",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 1. Import dependencies\n",
- "\n",
- "Import the functions and classes that we will be using."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "vblA",
- "metadata": {},
- "outputs": [],
- "source": [
- "import os\n",
- "from os.path import join\n",
- "from urllib.request import urlretrieve\n",
- "from anndata import read_h5ad\n",
- "import scanpy as sc\n",
- "\n",
- "from vitessce import (\n",
- " VitessceConfig,\n",
- " Component as cm,\n",
- " CoordinationType as ct,\n",
- " AnnDataWrapper,\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "bkHC",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 2. Download the data\n",
- "\n",
- "For this example, we need to download a dataset from the COVID-19 Cell Atlas https://www.covid19cellatlas.org/index.healthy.html#habib17."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "lEQa",
- "metadata": {},
- "outputs": [],
- "source": [
- "os.makedirs(\"data\", exist_ok=True)\n",
- "adata_filepath = join(\"data\", \"habib17.processed.h5ad\")\n",
- "urlretrieve('https://covid19.cog.sanger.ac.uk/habib17.processed.h5ad', adata_filepath)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "PKri",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.10.14"
}
- },
- "source": [
- "## 3. Load the data"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Xref",
- "metadata": {},
- "outputs": [],
- "source": [
- "adata = read_h5ad(join(\"data\", \"habib17.processed.h5ad\"))"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "SFPL",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "## 3.1. Preprocess the Data For Visualization"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "BYtC",
- "metadata": {},
- "outputs": [],
- "source": [
- "top_dispersion = adata.var[\"dispersions_norm\"][\n",
- " sorted(\n",
- " range(len(adata.var[\"dispersions_norm\"])),\n",
- " key=lambda k: adata.var[\"dispersions_norm\"][k],\n",
- " )[-51:][0]\n",
- "]\n",
- "adata.var[\"top_highly_variable\"] = (\n",
- " adata.var[\"dispersions_norm\"] > top_dispersion\n",
- ")"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "RGSE",
- "metadata": {
- "marimo": {
- "config": {
- "hide_code": true
- }
- }
- },
- "source": [
- "With one line of code, you may create a Vitessce widget based on an automatically inferred configuration."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "Kclp",
- "metadata": {},
- "outputs": [],
- "source": [
- "vw = VitessceConfig.from_object(AnnDataWrapper(\n",
- " adata,\n",
- " obs_embedding_paths=[\"obsm/X_umap\"],\n",
- " obs_embedding_names=[\"UMAP\"],\n",
- " obs_set_paths=[\"obs/CellType\"],\n",
- " obs_set_names=[\"Cell Type\"],\n",
- " obs_feature_matrix_path=\"X\",\n",
- " feature_filter_path=\"var/top_highly_variable\"\n",
- "), schema_version=\"1.0.15\").widget(height=800)\n",
- "vw"
- ]
},
- {
- "cell_type": "code",
- "execution_count": null,
- "id": "emfo",
- "metadata": {},
- "outputs": [],
- "source": [
- "import marimo as mo"
- ]
- }
- ],
- "metadata": {},
- "nbformat": 4,
- "nbformat_minor": 5
-}
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
From 15a04e2fe4ce726383e33c952a6748291556c03e Mon Sep 17 00:00:00 2001
From: Mark Keller <7525285+keller-mark@users.noreply.github.com>
Date: Fri, 8 Aug 2025 12:45:27 -0400
Subject: [PATCH 09/10] Update
---
tests-widget/example.spec.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tests-widget/example.spec.js b/tests-widget/example.spec.js
index 6d3d4c84..2cc26faa 100644
--- a/tests-widget/example.spec.js
+++ b/tests-widget/example.spec.js
@@ -17,7 +17,7 @@ test('Renders Vitessce widget containing a scatterplot view (Marimo)', async ({
await page.goto('http://localhost:3000/marimo.mo.html');
// Expect a title "to contain" a substring.
- await expect(page).toHaveTitle('marimo');
+ await expect(page).toHaveTitle('marimo.mo');
await expect(page.getByText('Scatterplot (UMAP)')).toBeVisible();
await expect(page.getByText('523 cells')).toHaveCount(3);
From f5dbff2c07c890feaf053c1adb8c7f8348525e8c Mon Sep 17 00:00:00 2001
From: Mark Keller <7525285+keller-mark@users.noreply.github.com>
Date: Wed, 13 Aug 2025 09:42:38 -0400
Subject: [PATCH 10/10] Update spatialdata notebooks. Rescale mouseliver
multiresolution image pyramid
---
docs/notebooks/spatial_data_mouseliver.mo.py | 383 +++++++++----------
docs/notebooks/spatial_data_visium_hd.mo.py | 58 ++-
2 files changed, 240 insertions(+), 201 deletions(-)
diff --git a/docs/notebooks/spatial_data_mouseliver.mo.py b/docs/notebooks/spatial_data_mouseliver.mo.py
index cf8d2e29..7cef96d3 100644
--- a/docs/notebooks/spatial_data_mouseliver.mo.py
+++ b/docs/notebooks/spatial_data_mouseliver.mo.py
@@ -1,16 +1,12 @@
import marimo
-__generated_with = "0.13.15"
+__generated_with = "0.14.16"
app = marimo.App()
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- # Visualization of a SpatialData object and individual Spatial Elements, local data
- """
- )
+ mo.md(r"""# Visualization of a SpatialData object and individual Spatial Elements, local data""")
return
@@ -18,11 +14,11 @@ def _(mo):
def _(mo):
mo.md(
r"""
- This notebook explains how to create interactive visualizations of data that is accessible locally.
+ This notebook explains how to create interactive visualizations of data that is accessible locally.
- We progress through different visualization tasks, first demonstrating how Vitessce facilitates integrated imaging and spatial single-cell visualizations, then demonstrating visualization of non-spatial and image-only datasets.
- """
+ We progress through different visualization tasks, first demonstrating how Vitessce facilitates integrated imaging and spatial single-cell visualizations, then demonstrating visualization of non-spatial and image-only datasets.
+ """
)
return
@@ -31,36 +27,28 @@ def _(mo):
def _(mo):
mo.md(
r"""
-
- """
+
+ """
)
return
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- ## Utility dependencies
- """
- )
+ mo.md(r"""## Utility dependencies""")
return
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- First, we import utility dependencies which will be used to download the example dataset and manipulate file paths, zip files, and JSON files.
- """
- )
+ mo.md(r"""First, we import utility dependencies which will be used to download the example dataset and manipulate file paths, zip files, and JSON files.""")
return
@@ -76,11 +64,7 @@ def _():
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- ## Dependencies for Vitessce
- """
- )
+ mo.md(r"""## Dependencies for Vitessce""")
return
@@ -88,17 +72,17 @@ def _(mo):
def _(mo):
mo.md(
r"""
- Here, we import classes and functions from the `vitessce` Python package.
- This package includes not only APIs for [visualization configuration](https://python-docs.vitessce.io/api_config.html) but also [helper functions](https://python-docs.vitessce.io/api_data.html#vitessce-data-utils) for basic data transformation tasks.
- To specify mappings between data fields and visualization properties, the package contains [classes](https://python-docs.vitessce.io/api_data.html#module-vitessce.wrappers) which wrap standard single-cell data structures stored in formats including [AnnData](https://doi.org/10.1101/2021.12.16.473007), [SpatialData](https://doi.org/10.1038/s41592-024-02212-x), [OME-TIFF](https://doi.org/10.1007/978-3-030-23937-4_1), and [OME-Zarr](https://doi.org/10.1038/s41592-021-01326-w):
-
- - [AnnDataWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.AnnDataWrapper)
- - [ImageOmeTiffWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ImageOmeTiffWrapper)
- - [ImageOmeZarrWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ImageOmeZarrWrapper)
- - [ObsSegmentationsOmeTiffWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ObsSegmentationsOmeTiffWrapper)
- - [ObsSegmentationsOmeZarrWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ObsSegmentationsOmeZarrWrapper)
- - [SpatialDataWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.SpatialDataWrapper)
- """
+ Here, we import classes and functions from the `vitessce` Python package.
+ This package includes not only APIs for [visualization configuration](https://python-docs.vitessce.io/api_config.html) but also [helper functions](https://python-docs.vitessce.io/api_data.html#vitessce-data-utils) for basic data transformation tasks.
+ To specify mappings between data fields and visualization properties, the package contains [classes](https://python-docs.vitessce.io/api_data.html#module-vitessce.wrappers) which wrap standard single-cell data structures stored in formats including [AnnData](https://doi.org/10.1101/2021.12.16.473007), [SpatialData](https://doi.org/10.1038/s41592-024-02212-x), [OME-TIFF](https://doi.org/10.1007/978-3-030-23937-4_1), and [OME-Zarr](https://doi.org/10.1038/s41592-021-01326-w):
+
+ - [AnnDataWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.AnnDataWrapper)
+ - [ImageOmeTiffWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ImageOmeTiffWrapper)
+ - [ImageOmeZarrWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ImageOmeZarrWrapper)
+ - [ObsSegmentationsOmeTiffWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ObsSegmentationsOmeTiffWrapper)
+ - [ObsSegmentationsOmeZarrWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.ObsSegmentationsOmeZarrWrapper)
+ - [SpatialDataWrapper](https://python-docs.vitessce.io/api_data.html#vitessce.wrappers.SpatialDataWrapper)
+ """
)
return
@@ -145,11 +129,7 @@ def _():
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- ## Dependencies for data structures
- """
- )
+ mo.md(r"""## Dependencies for data structures""")
return
@@ -157,12 +137,12 @@ def _(mo):
def _(mo):
mo.md(
r"""
- In this blog post, we perform basic data transformation tasks to save individual elements of an integrated SpatialData object to separate files in AnnData, OME-TIFF, and OME-Zarr formats.
- To perform these data transformations, we import the following dependencies.
- In general, you will typically not need to import all of these dependencies, either because you are only working with data in one of these formats, or because the data you intend to visualize is already saved to a file or directory.
+ In this blog post, we perform basic data transformation tasks to save individual elements of an integrated SpatialData object to separate files in AnnData, OME-TIFF, and OME-Zarr formats.
+ To perform these data transformations, we import the following dependencies.
+ In general, you will typically not need to import all of these dependencies, either because you are only working with data in one of these formats, or because the data you intend to visualize is already saved to a file or directory.
- Note: Dependencies such as `spatialdata` may need to be installed before they can be imported in the next code cell.
- """
+ Note: Dependencies such as `spatialdata` may need to be installed before they can be imported in the next code cell.
+ """
)
return
@@ -171,20 +151,17 @@ def _(mo):
def _():
import numpy as np
from spatialdata import read_zarr
+ from spatialdata.models import Image2DModel
from anndata import AnnData
from ome_zarr.writer import write_image
import tifffile
from generate_tiff_offsets import get_offsets
- return get_offsets, np, read_zarr
+ return Image2DModel, get_offsets, np, read_zarr
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- ## Download example dataset
- """
- )
+ mo.md(r"""## Download example dataset""")
return
@@ -192,10 +169,10 @@ def _(mo):
def _(mo):
mo.md(
r"""
- We download a mouse liver dataset which serves as a SpatialData [example dataset](https://github.com/scverse/spatialdata-notebooks/blob/main/notebooks/examples/transformations.ipynb).
+ We download a mouse liver dataset which serves as a SpatialData [example dataset](https://github.com/scverse/spatialdata-notebooks/blob/main/notebooks/examples/transformations.ipynb).
- This dataset was generated by [Guilliams et al.](https://doi.org/10.1016/j.cell.2021.12.018) and processed using [SPArrOW](https://doi.org/10.1101/2024.07.04.601829) during the SpatialData [developer workshop](https://doi.org/10.37044/osf.io/8ck3e) in 2024.
- """
+ This dataset was generated by [Guilliams et al.](https://doi.org/10.1016/j.cell.2021.12.018) and processed using [SPArrOW](https://doi.org/10.1101/2024.07.04.601829) during the SpatialData [developer workshop](https://doi.org/10.37044/osf.io/8ck3e) in 2024.
+ """
)
return
@@ -228,11 +205,7 @@ def _(join):
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- The following code uses Python's `urlretrieve` to download the SpatialData object as a zip file, then unzips the file using the `zipfile` module.
- """
- )
+ mo.md(r"""The following code uses Python's `urlretrieve` to download the SpatialData object as a zip file, then unzips the file using the `zipfile` module.""")
return
@@ -258,29 +231,67 @@ def _(
return
-@app.cell(hide_code=True)
+@app.cell
+def _(read_zarr, spatialdata_filepath):
+ sdata = read_zarr(spatialdata_filepath)
+ sdata
+ return (sdata,)
+
+
+@app.cell
def _(mo):
mo.md(
r"""
- ## Visualization of a SpatialData object
- """
+ ## Add image pyramid with `scale_factor`s of 2
+
+ Vitessce assumes pyramidal (multi-resolution) images have subsequent resolutions scaled by factors of 2.
+
+ In this case, `sdata.images['raw_image']` has 6432x6432 pixels in the highest resolution and 1608x1608 pixels in the next resolution, a scale factor of 4 (rather than 2).
+ """
)
return
+@app.cell
+def _(sdata):
+ img_arr2 = sdata.images['raw_image'].scale0.image.to_numpy()
+ img_arr2
+ return (img_arr2,)
+
+
+@app.cell
+def _(Image2DModel, img_arr2, sdata):
+ sdata['raw_image2'] = Image2DModel.parse(
+ data=img_arr2,
+ dims=['c', 'y', 'x'],
+ scale_factors=[2, 2],
+ )
+ try:
+ sdata.write_element("raw_image2")
+ except:
+ pass
+ return
+
+
+@app.cell(hide_code=True)
+def _(mo):
+ mo.md(r"""## Visualization of a SpatialData object""")
+ return
+
+
@app.cell(hide_code=True)
def _(mo):
mo.md(
r"""
- SpatialData objects are the most complex type of data structure we will work with in this blog post.
- SpatialData objects function as contains for multiple types of Spatial Elements:
-
- - Tables (each table is represented as an AnnData object)
- - Points (e.g., coordinates of transcripts from FISH-based experiments)
- - Shapes (vector-based shapes such as polygons and circles)
- - Labels (label images, i.e., segmentation bitmasks; each label image is stored using OME-Zarr)
- - Images (microscopy images; each image is stored using OME-Zarr)
- """
+ SpatialData objects are the most complex type of data structure we will work with in this blog post.
+ SpatialData objects function as contains for multiple types of Spatial Elements:
+
+ - Tables (each table is represented as an AnnData object)
+ - Points (e.g., coordinates of transcripts from FISH-based experiments)
+ - Shapes (vector-based shapes such as polygons and circles)
+ - Labels (label images, i.e., segmentation bitmasks; each label image is stored using OME-Zarr)
+ - Images (microscopy images; each image is stored using OME-Zarr)
+ """
)
return
@@ -289,11 +300,11 @@ def _(mo):
def _(mo):
mo.md(
r"""
- ## Configure Vitessce
+ ## Configure Vitessce
- Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views.
- To visualize data stored in a SpatialData object, we use the `SpatialDataWrapper` class and specify the paths (relative to the root of the Zarr [directory store](https://zarr.readthedocs.io/en/v2.18.5/api/storage.html#zarr.storage.DirectoryStore)) to different spatial elements of interest.
- """
+ Vitessce needs to know which pieces of data we are interested in visualizing, the visualization types we would like to use, and how we want to coordinate (or link) the views.
+ To visualize data stored in a SpatialData object, we use the `SpatialDataWrapper` class and specify the paths (relative to the root of the Zarr [directory store](https://zarr.readthedocs.io/en/v2.18.5/api/storage.html#zarr.storage.DirectoryStore)) to different spatial elements of interest.
+ """
)
return
@@ -307,30 +318,59 @@ def _(
spatialdata_filepath,
):
vc = VitessceConfig(schema_version='1.0.18', name='SpatialData Demo')
- _wrapper = SpatialDataWrapper(sdata_path=spatialdata_filepath, table_path='tables/table', image_path='images/raw_image', obs_segmentations_path='labels/segmentation_mask', obs_feature_matrix_path='tables/table/X', obs_set_paths=['tables/table/obs/annotation'], obs_set_names=['Annotation'], region='nucleus_boundaries', coordinate_system='global', coordination_values={'obsType': 'cell'})
+ _wrapper = SpatialDataWrapper(
+ sdata_path=spatialdata_filepath,
+ table_path='tables/table',
+ image_path='images/raw_image2',
+ obs_segmentations_path='labels/segmentation_mask',
+ obs_feature_matrix_path='tables/table/X',
+ obs_set_paths=['tables/table/obs/annotation'],
+ obs_set_names=['Annotation'],
+ region='nucleus_boundaries',
+ coordinate_system='global',
+ coordination_values={'obsType': 'cell'}
+ )
_dataset = vc.add_dataset(name='Mouse Liver').add_object(_wrapper)
+
_spatial = vc.add_view('spatialBeta', dataset=_dataset)
feature_list = vc.add_view('featureList', dataset=_dataset)
_layer_controller = vc.add_view('layerControllerBeta', dataset=_dataset)
obs_sets = vc.add_view('obsSets', dataset=_dataset)
_heatmap = vc.add_view('heatmap', dataset=_dataset)
+
[obs_color_encoding_scope] = vc.add_coordination('obsColorEncoding')
obs_color_encoding_scope.set_value('cellSetSelection')
- vc.link_views_by_dict([_spatial, _layer_controller], {'imageLayer': CL([{'photometricInterpretation': 'BlackIsZero', 'imageChannel': CL([{'spatialTargetC': 0, 'spatialChannelColor': [255, 255, 255], 'spatialChannelWindow': [0, 4000]}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))
- vc.link_views_by_dict([_spatial, _layer_controller], {'segmentationLayer': CL([{'segmentationChannel': CL([{'obsColorEncoding': obs_color_encoding_scope}])}])}, scope_prefix=get_initial_coordination_scope_prefix('A', 'obsSegmentations'))
+ vc.link_views_by_dict([_spatial, _layer_controller], {
+ 'imageLayer': CL([{
+ 'photometricInterpretation': 'BlackIsZero',
+ 'imageChannel': CL([{
+ 'spatialTargetC': 0,
+ 'spatialChannelColor': [255, 255, 255],
+ 'spatialChannelWindow': [0, 4000]
+ }])
+ }])
+ }, scope_prefix=get_initial_coordination_scope_prefix('A', 'image'))
+
+ vc.link_views_by_dict([_spatial, _layer_controller], {
+ 'segmentationLayer': CL([{
+ 'segmentationChannel': CL([{
+ 'obsColorEncoding': obs_color_encoding_scope
+ }])
+ }])
+ }, scope_prefix=get_initial_coordination_scope_prefix('A', 'obsSegmentations'))
+
vc.link_views([_spatial, _layer_controller, feature_list, obs_sets, _heatmap], ['obsType'], [_wrapper.obs_type_label])
- vc.link_views_by_dict([feature_list, obs_sets, _heatmap], {'obsColorEncoding': obs_color_encoding_scope}, meta=False)
+
+ vc.link_views_by_dict([feature_list, obs_sets, _heatmap], {
+ 'obsColorEncoding': obs_color_encoding_scope
+ }, meta=False)
vc.layout(_spatial / _heatmap | _layer_controller / (feature_list | obs_sets))
return (vc,)
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- ### Render the widget
- """
- )
+ mo.md(r"""### Render the widget""")
return
@@ -343,11 +383,7 @@ def _(vc):
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- ## Extract AnnData object from SpatialData object
- """
- )
+ mo.md(r"""## Extract AnnData object from SpatialData object""")
return
@@ -355,20 +391,13 @@ def _(mo):
def _(mo):
mo.md(
r"""
- The above example demonstrates how to visualize a spatial 'omics dataset containing not only single-cell information (e.g., a cell-by-gene expression matrix, cell type annotations) but also an image and cell segmentations.
- To demonstrate how to use Vitessce to visualize data from a (non-spatial) single-cell experiment, we will extract this information from the SpatialData object and save it to a simpler [AnnData](https://anndata.readthedocs.io/) object (ignoring the imaging and spatially-resolved elements).
- """
+ The above example demonstrates how to visualize a spatial 'omics dataset containing not only single-cell information (e.g., a cell-by-gene expression matrix, cell type annotations) but also an image and cell segmentations.
+ To demonstrate how to use Vitessce to visualize data from a (non-spatial) single-cell experiment, we will extract this information from the SpatialData object and save it to a simpler [AnnData](https://anndata.readthedocs.io/) object (ignoring the imaging and spatially-resolved elements).
+ """
)
return
-@app.cell
-def _(read_zarr, spatialdata_filepath):
- sdata = read_zarr(spatialdata_filepath)
- sdata
- return (sdata,)
-
-
@app.cell
def _(sdata):
adata = sdata.tables['table']
@@ -380,11 +409,11 @@ def _(sdata):
def _(mo):
mo.md(
r"""
- As Zarr-formatted data can be easily visualized by Vitessce, we recommend saving the AnnData object to a Zarr store using the [write_zarr](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_zarr.html) method.
- Optionally, the shape of array chunks (for the AnnData `X` array) can be specified as a parameter, to optimize performance based on data access patterns.
- For example, a common pattern is to visualize data across all cells for one gene.
- To support such a pattern, the chunk shape can be specified as follows, `(total number of cells, small number of genes)`, resulting in tall-and-skinny array chunks.
- """
+ As Zarr-formatted data can be easily visualized by Vitessce, we recommend saving the AnnData object to a Zarr store using the [write_zarr](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_zarr.html) method.
+ Optionally, the shape of array chunks (for the AnnData `X` array) can be specified as a parameter, to optimize performance based on data access patterns.
+ For example, a common pattern is to visualize data across all cells for one gene.
+ To support such a pattern, the chunk shape can be specified as follows, `(total number of cells, small number of genes)`, resulting in tall-and-skinny array chunks.
+ """
)
return
@@ -399,9 +428,9 @@ def _(VAR_CHUNK_SIZE, adata, adata_zarr_filepath):
def _(mo):
mo.md(
r"""
- Alternatively, your AnnData object may already be stored using the H5AD (HDF5-based) format.
- To demonstrate this scenario, we save the object using the [write_h5ad](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_h5ad.html) method.
- """
+ Alternatively, your AnnData object may already be stored using the H5AD (HDF5-based) format.
+ To demonstrate this scenario, we save the object using the [write_h5ad](https://anndata.readthedocs.io/en/stable/generated/anndata.AnnData.write_h5ad.html) method.
+ """
)
return
@@ -414,11 +443,7 @@ def _(adata, adata_h5ad_filepath):
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- To read H5AD-formatted data, Vitessce requires an accompanying JSON [references specification](https://fsspec.github.io/kerchunk/spec.html) file, which can be constructed using the `generate_h5ad_ref_spec` utility function.
- """
- )
+ mo.md(r"""To read H5AD-formatted data, Vitessce requires an accompanying JSON [references specification](https://fsspec.github.io/kerchunk/spec.html) file, which can be constructed using the `generate_h5ad_ref_spec` utility function.""")
return
@@ -437,21 +462,13 @@ def _(
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- ## Visualization of an AnnData object
- """
- )
+ mo.md(r"""## Visualization of an AnnData object""")
return
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- ### Zarr-based AnnData
- """
- )
+ mo.md(r"""### Zarr-based AnnData""")
return
@@ -477,11 +494,7 @@ def _(vc_1):
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- ### H5AD-based AnnData
- """
- )
+ mo.md(r"""### H5AD-based AnnData""")
return
@@ -513,27 +526,19 @@ def _(vc_2):
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- ## Extract image from SpatialData object
- """
- )
+ mo.md(r"""## Extract image from SpatialData object""")
return
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- In contrast to extraction of the non-spatial data from the SpatialData object, we can extract the imaging (and segmentation/label image) data and save it to a dedicated bioimaging file format.
- """
- )
+ mo.md(r"""In contrast to extraction of the non-spatial data from the SpatialData object, we can extract the imaging (and segmentation/label image) data and save it to a dedicated bioimaging file format.""")
return
@app.cell
def _(np, sdata):
- img_arr = sdata.images['raw_image'].to_numpy()
+ img_arr = sdata.images['raw_image'].scale0.image.to_numpy()
labels_arr = sdata.labels['segmentation_mask'].to_numpy()
labels_arr = labels_arr[np.newaxis, :]
return img_arr, labels_arr
@@ -541,11 +546,7 @@ def _(np, sdata):
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- ### Save image to OME-Zarr
- """
- )
+ mo.md(r"""### Save image to OME-Zarr""")
return
@@ -553,9 +554,9 @@ def _(mo):
def _(mo):
mo.md(
r"""
- For small images, the data can be saved to OME-Zarr or OME-TIFF format using [utility functions](https://python-docs.vitessce.io/api_data.html#vitessce-data-utils) from the Vitessce package.
- Larger images require generation of an [image pyramid](https://en.wikipedia.org/wiki/Pyramid_(image_processing)), which can be performed using tools from the OME ecosystem such as [bioformats2raw](https://github.com/glencoesoftware/bioformats2raw) and [raw2ometiff](https://github.com/glencoesoftware/raw2ometiff).
- """
+ For small images, the data can be saved to OME-Zarr or OME-TIFF format using [utility functions](https://python-docs.vitessce.io/api_data.html#vitessce-data-utils) from the Vitessce package.
+ Larger images require generation of an [image pyramid](https://en.wikipedia.org/wiki/Pyramid_(image_processing)), which can be performed using tools from the OME ecosystem such as [bioformats2raw](https://github.com/glencoesoftware/bioformats2raw) and [raw2ometiff](https://github.com/glencoesoftware/raw2ometiff).
+ """
)
return
@@ -575,11 +576,7 @@ def _(
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- ### Save image and segmentations to OME-TIFF
- """
- )
+ mo.md(r"""### Save image and segmentations to OME-TIFF""")
return
@@ -587,9 +584,9 @@ def _(mo):
def _(mo):
mo.md(
r"""
- To efficiently visualize OME-TIFF data using Vitessce, a JSON-based offsets file can be constructed using [generate-tiff-offsets](https://github.com/hms-dbmi/generate-tiff-offsets).
- This JSON file contains byte offsets into different partitions of the TIFF file, effectively resulting in an "indexed TIFF" which is described by [Manz et al. 2022](https://doi.org/10.1038/s41592-022-01482-7).
- """
+ To efficiently visualize OME-TIFF data using Vitessce, a JSON-based offsets file can be constructed using [generate-tiff-offsets](https://github.com/hms-dbmi/generate-tiff-offsets).
+ This JSON file contains byte offsets into different partitions of the TIFF file, effectively resulting in an "indexed TIFF" which is described by [Manz et al. 2022](https://doi.org/10.1038/s41592-022-01482-7).
+ """
)
return
@@ -612,21 +609,13 @@ def _(
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- ## Visualization of an image file
- """
- )
+ mo.md(r"""## Visualization of an image file""")
return
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- ### OME-Zarr image
- """
- )
+ mo.md(r"""### OME-Zarr image""")
return
@@ -665,11 +654,7 @@ def _(vc_3):
@app.cell(hide_code=True)
def _(mo):
- mo.md(
- r"""
- ### OME-TIFF image
- """
- )
+ mo.md(r"""### OME-TIFF image""")
return
@@ -703,33 +688,33 @@ def _(vc_4):
def _(mo):
mo.md(
r"""
- ## Data location options
+ ## Data location options
- Vitessce can visualize data [not only stored](https://python-docs.vitessce.io/data_options.html) locally (referenced using local file or directory paths) but also stored remotely (referenced using absolute URL paths).
- Depending on whether the Python kernel running the Jupyter process is running locally versus remotely (e.g., on a cluster or cloud platform such as Google Colab), certain data locations may be challenging to access from the machine running the Jupyter notebook frontend (i.e., the machine on which the web browser used to view the notebook is installed).
+ Vitessce can visualize data [not only stored](https://python-docs.vitessce.io/data_options.html) locally (referenced using local file or directory paths) but also stored remotely (referenced using absolute URL paths).
+ Depending on whether the Python kernel running the Jupyter process is running locally versus remotely (e.g., on a cluster or cloud platform such as Google Colab), certain data locations may be challenging to access from the machine running the Jupyter notebook frontend (i.e., the machine on which the web browser used to view the notebook is installed).
- To provide data via one of these alternative mechanisms, use parameters with the following suffices when instantiating the data wrapper classes.
+ To provide data via one of these alternative mechanisms, use parameters with the following suffices when instantiating the data wrapper classes.
- - `_path`: Local file or directory
- - `_url`: Remote file or directory
- - `_store`: Zarr-store-accessible (for zarr-based formats)
- - `_artifact`: Lamin artifact
+ - `_path`: Local file or directory
+ - `_url`: Remote file or directory
+ - `_store`: Zarr-store-accessible (for zarr-based formats)
+ - `_artifact`: Lamin artifact
- For example, `adata_path` can be exchanged for one of the following options.
+ For example, `adata_path` can be exchanged for one of the following options.
- ```diff
- AnnDataWrapper(
- - adata_path="./mouse_liver.spatialdata.zarr",
- + adata_url="https://example.com/mouse_liver.spatialdata.zarr", # Absolute URL
- + adata_store="./mouse_liver.spatialdata.zarr", # String interpreted as root of DirectoryStore
- + adata_store=zarr.DirectoryStore("./mouse_liver.spatialdata.zarr"), # Instance of zarr.storage
- + adata_artifact=adata_zarr_artifact, # Instance of ln.Artifact
- ...
- ```
+ ```diff
+ AnnDataWrapper(
+ - adata_path="./mouse_liver.spatialdata.zarr",
+ + adata_url="https://example.com/mouse_liver.spatialdata.zarr", # Absolute URL
+ + adata_store="./mouse_liver.spatialdata.zarr", # String interpreted as root of DirectoryStore
+ + adata_store=zarr.DirectoryStore("./mouse_liver.spatialdata.zarr"), # Instance of zarr.storage
+ + adata_artifact=adata_zarr_artifact, # Instance of ln.Artifact
+ ...
+ ```
- Note that the `_store` options are only available for Zarr-based formats, such as AnnDataWrapper, SpatialDataWrapper, and ImageOmeZarrWrapper.
- Further, when multiple files are required, such as both `adata_path` and `ref_path` (for the JSON reference specification file accompanying an H5AD file) or `img_path` and `offsets_path`, multiple parameter suffices may need to be changed.
- """
+ Note that the `_store` options are only available for Zarr-based formats, such as AnnDataWrapper, SpatialDataWrapper, and ImageOmeZarrWrapper.
+ Further, when multiple files are required, such as both `adata_path` and `ref_path` (for the JSON reference specification file accompanying an H5AD file) or `img_path` and `offsets_path`, multiple parameter suffices may need to be changed.
+ """
)
return
diff --git a/docs/notebooks/spatial_data_visium_hd.mo.py b/docs/notebooks/spatial_data_visium_hd.mo.py
index 10b11750..cff90aef 100644
--- a/docs/notebooks/spatial_data_visium_hd.mo.py
+++ b/docs/notebooks/spatial_data_visium_hd.mo.py
@@ -1,6 +1,6 @@
import marimo
-__generated_with = "0.13.15"
+__generated_with = "0.14.16"
app = marimo.App(width="full")
@@ -52,6 +52,12 @@ def _():
)
+@app.cell
+def _():
+ import scanpy as sc
+ return (sc,)
+
+
@app.cell
def _(join):
data_dir = "data"
@@ -134,7 +140,7 @@ def _(
sdata.write_element(f"rasterized_{bin_size}um")
except:
pass
-
+
sdata
return (sdata,)
@@ -145,6 +151,53 @@ def _(sdata):
return
+@app.cell
+def _(mo):
+ mo.md(r"""## Compute a UMAP embedding of the bins in `square_016um`""")
+ return
+
+
+@app.cell
+def _(sdata):
+ sdata.tables['square_016um']
+ return
+
+
+@app.cell
+def _(sc, sdata):
+ sc.pp.neighbors(sdata.tables['square_016um'])
+ sc.tl.umap(sdata.tables['square_016um'])
+ sc.pl.umap(sdata.tables['square_016um'])
+ return
+
+
+@app.cell
+def _(sdata):
+ sdata.tables['square_016um']
+ return
+
+
+@app.function
+def write_element(sdata, name):
+ # Reference: https://github.com/scverse/spatialdata/blob/7604a3d2325079293ff523c5dff4483dffc890cb/tests/io/test_readwrite.py#L216C21-L224C61
+ new_name = f"{name}_new_place"
+ # a. write a backup copy of the data
+ sdata[new_name] = sdata[name]
+ sdata.write_element(new_name)
+ # b. rewrite the original data
+ sdata.delete_element_from_disk(name)
+ sdata.write_element(name)
+ # c. remove the backup copy
+ del sdata[new_name]
+ sdata.delete_element_from_disk(new_name)
+
+
+@app.cell
+def _(sdata):
+ write_element(sdata, "square_016um")
+ return
+
+
@app.cell(hide_code=True)
def _(mo):
mo.md(
@@ -202,6 +255,7 @@ def _(
'spatialChannelOpacity': 0.5,
'obsColorEncoding': 'geneSelection',
'featureValueColormapRange': [0, 0.5],
+ 'obsHighlight': None
}])
}]),
}, scope_prefix=get_initial_coordination_scope_prefix("A", "obsSegmentations"))