Skip to content

Commit f1fe3db

Browse files
committed
Update notebooks - wip
1 parent 2abab8d commit f1fe3db

17 files changed

Lines changed: 5316 additions & 2468 deletions

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@ __pycache__/
22
_build/
33
.ipynb_checkpoints/
44
*.bed
5-
.DS_Store
5+
.DS_Store
6+
notebooks/data
7+
references/
8+
Untitled.ipynb

.python-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.12

notebooks/03-Available-View-Types.ipynb

Lines changed: 355 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,37 @@
77
},
88
"source": [
99
"# Session 3: Available View Types\n",
10-
"This notebook demonstrates additional view types that are available in Vitessce, including both visualization and control views.\n"
10+
"\n",
11+
"Vitessce ships with a large number of interactive visualization and control views. In this notebook, we look at some types of views that you may not be familiar with.\n",
12+
"\n",
13+
"\n",
14+
"The views available in Vitessce can generally be categorized into:\n",
15+
"- Spatial view (covered in notebook 01)\n",
16+
"- Scatterplot view for dimensionality reductions / embeddings\n",
17+
"- Heatmap for expression data\n",
18+
"- Genomic profiles for quantitative features aggregated by cell type\n",
19+
"- Control views\n",
20+
" - Cell set manager\n",
21+
" - Feature list\n",
22+
" - Spatial layer controller\n",
23+
"- Statistical plots\n",
24+
" - Cell set sizes bar plot\n",
25+
" - Expression distribution per cell set violin plots\n",
26+
" - Expression distribution histogram\n",
27+
" - Cell set and sample set sizes treemap\n",
28+
" - Volcano plot\n",
29+
" - Cell type composition bar plot\n",
30+
" - Gene set enrichment bar plot\n",
31+
" - Gating scatterplot\n",
32+
"\n",
33+
"We cover:\n",
34+
"\n",
35+
"1. **Embedding views** — UMAP, PCA, t-SNE scatterplots\n",
36+
"2. **Expression views** — heatmap, dot plot, violin/distribution plot\n",
37+
"3. **Spatial views** — tissue image, layer controller\n",
38+
"4. **Control views** — cell-set tree, gene list, status bar\n",
39+
"\n",
40+
"We use the EasyVitessce Scanpy API for most examples because it is the most concise, then show how to access additional view types through the lower-level `VitessceConfig` API."
1141
]
1242
},
1343
{
@@ -17,7 +47,9 @@
1747
"id": "8i7E1aKwtT8c"
1848
},
1949
"outputs": [],
20-
"source": []
50+
"source": [
51+
"!pip install \"vitessce[all]==3.9.2\" \"scanpy\" \"easy-vitessce==0.0.12\" \"spatialdata==0.7.3\" \"spatialdata-plot==0.4.0\""
52+
]
2153
},
2254
{
2355
"cell_type": "code",
@@ -26,7 +58,326 @@
2658
"id": "gli0oO6yszUm"
2759
},
2860
"outputs": [],
29-
"source": []
61+
"source": [
62+
"import easy_vitessce as ev\n",
63+
"import scanpy as sc\n",
64+
"\n",
65+
"# Load the reduced PBMC dataset (ships with Scanpy, no download required)\n",
66+
"adata = sc.datasets.pbmc68k_reduced()\n",
67+
"adata"
68+
]
69+
},
70+
{
71+
"cell_type": "code",
72+
"execution_count": null,
73+
"metadata": {},
74+
"outputs": [],
75+
"source": [
76+
"# Exercise 2 — interactive dot plot\n",
77+
"sc.pl.dotplot(\n",
78+
" adata,\n",
79+
" var_names=[\"C1QA\", \"PSAP\", \"CD79A\", \"CD79B\", \"CST3\", \"LYZ\", \"ANXA1\", \"S100A4\"],\n",
80+
" groupby=\"bulk_labels\",\n",
81+
")"
82+
]
83+
},
84+
{
85+
"cell_type": "code",
86+
"execution_count": null,
87+
"metadata": {},
88+
"outputs": [],
89+
"source": [
90+
"# Exercise 1 — your answer here\n",
91+
"vc_ex = VitessceConfig(schema_version=\"1.0.15\", name=\"Exercise 1\")\n",
92+
"ds_ex = vc_ex.add_dataset(name=\"PBMC\").add_object(AnnDataWrapper(\n",
93+
" adata_store=zarr_path,\n",
94+
" obs_set_paths=[\"obs/bulk_labels\"],\n",
95+
" obs_set_names=[\"Cell Type\"],\n",
96+
" obs_embedding_paths=[\"obsm/X_umap\"],\n",
97+
" obs_embedding_names=[\"UMAP\"],\n",
98+
" obs_feature_matrix_path=\"X\",\n",
99+
"))\n",
100+
"\n",
101+
"umap_ex = vc_ex.add_view(vt.SCATTERPLOT, dataset=ds_ex, mapping=\"UMAP\")\n",
102+
"violin_ex = vc_ex.add_view(vt.OBS_SET_FEATURE_VALUE_DISTRIBUTION, dataset=ds_ex)\n",
103+
"sets_ex = vc_ex.add_view(vt.OBS_SETS, dataset=ds_ex)\n",
104+
"\n",
105+
"vc_ex.layout(???) # TODO: arrange the three views\n",
106+
"vc_ex.widget()"
107+
]
108+
},
109+
{
110+
"cell_type": "markdown",
111+
"metadata": {},
112+
"source": [
113+
"## Exercise\n",
114+
"\n",
115+
"### Exercise 1 — Add a violin plot to the PBMC dashboard\n",
116+
"\n",
117+
"👉 **Starting from the `vc_hm` configuration** (the heatmap + UMAP example), add an `OBS_SET_FEATURE_VALUE_DISTRIBUTION` view showing violin plots.\n",
118+
"\n",
119+
"Steps:\n",
120+
"1. Add the violin view with `vc_hm.add_view(vt.OBS_SET_FEATURE_VALUE_DISTRIBUTION, dataset=ds_hm)`\n",
121+
"2. Include it in the layout, e.g., `(umap_hm | obs_sets3) / (heatmap | violin)`\n",
122+
"3. Re-run `vc_hm.widget()` to see the result\n",
123+
"\n",
124+
"```python\n",
125+
"# Template — fill in the blanks\n",
126+
"vc_ex = VitessceConfig(schema_version=\"1.0.15\", name=\"Exercise 1\")\n",
127+
"ds_ex = vc_ex.add_dataset(name=\"PBMC\").add_object(AnnDataWrapper(\n",
128+
" adata_store=zarr_path,\n",
129+
" obs_set_paths=[\"obs/bulk_labels\"],\n",
130+
" obs_set_names=[\"Cell Type\"],\n",
131+
" obs_embedding_paths=[\"obsm/X_umap\"],\n",
132+
" obs_embedding_names=[\"UMAP\"],\n",
133+
" obs_feature_matrix_path=\"X\",\n",
134+
"))\n",
135+
"\n",
136+
"umap_ex = vc_ex.add_view(vt.SCATTERPLOT, dataset=ds_ex, mapping=\"UMAP\")\n",
137+
"violin_ex = vc_ex.add_view(???, dataset=ds_ex) # Add the violin view\n",
138+
"sets_ex = vc_ex.add_view(vt.OBS_SETS, dataset=ds_ex)\n",
139+
"\n",
140+
"vc_ex.layout(???) # Arrange the views\n",
141+
"vc_ex.widget()\n",
142+
"```\n",
143+
"\n",
144+
"### Exercise 2 — Explore the dot plot interactively\n",
145+
"\n",
146+
"The dot plot view in Vitessce is interactive: you can click gene names to see them highlighted in other views. Run the cell below and try clicking a gene name in the dot plot row labels.\n",
147+
"\n",
148+
"```python\n",
149+
"sc.pl.dotplot(\n",
150+
" adata,\n",
151+
" var_names=[\"C1QA\", \"PSAP\", \"CD79A\", \"CD79B\", \"CST3\", \"LYZ\", \"ANXA1\", \"S100A4\"],\n",
152+
" groupby=\"bulk_labels\",\n",
153+
")\n",
154+
"```\n",
155+
"\n",
156+
"**What to notice:**\n",
157+
"- Hovering over a dot shows the exact mean expression and percentage\n",
158+
"- Clicking a gene selects it as the active feature (visible in other linked views if you have a multi-view layout)"
159+
]
160+
},
161+
{
162+
"cell_type": "code",
163+
"execution_count": null,
164+
"metadata": {},
165+
"outputs": [],
166+
"source": [
167+
"vc_ctrl = VitessceConfig(schema_version=\"1.0.15\", name=\"Control Views Demo\")\n",
168+
"ds_ctrl = vc_ctrl.add_dataset(name=\"PBMC\").add_object(AnnDataWrapper(\n",
169+
" adata_store=zarr_path,\n",
170+
" obs_set_paths=[\"obs/bulk_labels\"],\n",
171+
" obs_set_names=[\"Cell Type\"],\n",
172+
" obs_embedding_paths=[\"obsm/X_umap\"],\n",
173+
" obs_embedding_names=[\"UMAP\"],\n",
174+
" obs_feature_matrix_path=\"X\",\n",
175+
"))\n",
176+
"\n",
177+
"umap_c = vc_ctrl.add_view(vt.SCATTERPLOT, dataset=ds_ctrl, mapping=\"UMAP\")\n",
178+
"sets_c = vc_ctrl.add_view(vt.OBS_SETS, dataset=ds_ctrl)\n",
179+
"genes_c = vc_ctrl.add_view(vt.FEATURE_LIST, dataset=ds_ctrl)\n",
180+
"status = vc_ctrl.add_view(vt.STATUS, dataset=ds_ctrl)\n",
181+
"\n",
182+
"# Status bar is typically compact; place it below the main content\n",
183+
"vc_ctrl.layout((umap_c | (sets_c / genes_c)) / status)\n",
184+
"vc_ctrl.widget()"
185+
]
186+
},
187+
{
188+
"cell_type": "markdown",
189+
"metadata": {},
190+
"source": [
191+
"## 4. Control views\n",
192+
"\n",
193+
"Control views don't render data directly but provide UI panels that let users interact with the visualization.\n",
194+
"\n",
195+
"| View type | Purpose |\n",
196+
"|---|---|\n",
197+
"| `vt.OBS_SETS` | Navigate cell-type hierarchy; select/deselect groups |\n",
198+
"| `vt.FEATURE_LIST` | Search for genes; click to color embeddings by expression |\n",
199+
"| `vt.STATUS` | Shows hover information — gene name, cell ID, expression value |\n",
200+
"| `\"layerControllerBeta\"` | Toggle image channels on/off, adjust contrast windows and colors |\n",
201+
"\n",
202+
"The example below adds a `STATUS` view below the UMAP. Hover over points in the scatterplot to see live cell information in the status bar."
203+
]
204+
},
205+
{
206+
"cell_type": "code",
207+
"execution_count": null,
208+
"metadata": {},
209+
"outputs": [],
210+
"source": [
211+
"import os, zipfile\n",
212+
"from os.path import join, isfile, isdir\n",
213+
"from urllib.request import urlretrieve\n",
214+
"import spatialdata_plot # noqa: F401\n",
215+
"\n",
216+
"data_dir = \"data\"\n",
217+
"sdata_filepath = join(data_dir, \"visium.spatialdata.zarr\")\n",
218+
"\n",
219+
"if not isdir(sdata_filepath):\n",
220+
" zip_filepath = join(data_dir, \"visium.spatialdata.zarr.zip\")\n",
221+
" if not isfile(zip_filepath):\n",
222+
" os.makedirs(data_dir, exist_ok=True)\n",
223+
" urlretrieve(\"https://data-2.vitessce.io/sdata-datasets/visium.spatialdata.zarr.zip\", zip_filepath)\n",
224+
" with zipfile.ZipFile(zip_filepath, \"r\") as z:\n",
225+
" z.extractall(data_dir)\n",
226+
" os.rename(join(data_dir, \"data.zarr\"), sdata_filepath)\n",
227+
"\n",
228+
"from spatialdata import read_zarr\n",
229+
"sdata = read_zarr(sdata_filepath)\n",
230+
"\n",
231+
"# Interactive spatial view colored by Fth1 expression\n",
232+
"sdata.pl.render_images(\"ST8059050_hires_image\") \\\n",
233+
" .pl.render_shapes(\"ST8059050\", color=\"Fth1\", table_name=\"table\") \\\n",
234+
" .pl.show(\"ST8059050\")"
235+
]
236+
},
237+
{
238+
"cell_type": "markdown",
239+
"metadata": {},
240+
"source": [
241+
"## 3. Spatial views\n",
242+
"\n",
243+
"### 3a. The spatial viewer (`spatialBeta`)\n",
244+
"\n",
245+
"The spatial viewer renders the tissue image and overlays data layers such as Visium spots colored by gene expression. Use `.pl.render_images()` and `.pl.render_shapes()` with EasyVitessce to compose the spatial view from a SpatialData object."
246+
]
247+
},
248+
{
249+
"cell_type": "code",
250+
"execution_count": null,
251+
"metadata": {},
252+
"outputs": [],
253+
"source": [
254+
"import os\n",
255+
"from os.path import join, isdir\n",
256+
"from vitessce import VitessceConfig, ViewType as vt, AnnDataWrapper\n",
257+
"from vitessce.data_utils import optimize_adata, VAR_CHUNK_SIZE\n",
258+
"\n",
259+
"zarr_path = join(\"data\", \"pbmc68k.zarr\")\n",
260+
"if not isdir(zarr_path):\n",
261+
" os.makedirs(\"data\", exist_ok=True)\n",
262+
" adata_opt = optimize_adata(\n",
263+
" adata,\n",
264+
" obs_cols=[\"bulk_labels\", \"louvain\"],\n",
265+
" obsm_keys=[\"X_umap\", \"X_pca\"],\n",
266+
" optimize_X=True,\n",
267+
" )\n",
268+
" adata_opt.write_zarr(zarr_path, chunks=[adata_opt.shape[0], VAR_CHUNK_SIZE])\n",
269+
"\n",
270+
"vc_hm = VitessceConfig(schema_version=\"1.0.15\", name=\"Heatmap + UMAP\")\n",
271+
"ds_hm = vc_hm.add_dataset(name=\"PBMC\").add_object(AnnDataWrapper(\n",
272+
" adata_store=zarr_path,\n",
273+
" obs_set_paths=[\"obs/bulk_labels\"],\n",
274+
" obs_set_names=[\"Cell Type\"],\n",
275+
" obs_embedding_paths=[\"obsm/X_umap\"],\n",
276+
" obs_embedding_names=[\"UMAP\"],\n",
277+
" obs_feature_matrix_path=\"X\",\n",
278+
"))\n",
279+
"\n",
280+
"umap_hm = vc_hm.add_view(vt.SCATTERPLOT, dataset=ds_hm, mapping=\"UMAP\")\n",
281+
"heatmap = vc_hm.add_view(vt.HEATMAP, dataset=ds_hm)\n",
282+
"obs_sets3 = vc_hm.add_view(vt.OBS_SETS, dataset=ds_hm)\n",
283+
"\n",
284+
"vc_hm.layout((umap_hm | obs_sets3) / heatmap)\n",
285+
"vc_hm.widget()"
286+
]
287+
},
288+
{
289+
"cell_type": "markdown",
290+
"metadata": {},
291+
"source": [
292+
"### 2c. Heatmap (`heatmap`)\n",
293+
"\n",
294+
"A **heatmap** renders a cells × genes expression matrix where color intensity encodes the expression level. Use it to compare expression patterns across many genes simultaneously and to validate cluster markers.\n",
295+
"\n",
296+
"The EasyVitessce heatmap is accessible via the low-level `VitessceConfig` API. Let's build a compact example."
297+
]
298+
},
299+
{
300+
"cell_type": "code",
301+
"execution_count": null,
302+
"metadata": {},
303+
"outputs": [],
304+
"source": [
305+
"sc.pl.violin(adata, keys=\"LYZ\", groupby=\"bulk_labels\")"
306+
]
307+
},
308+
{
309+
"cell_type": "markdown",
310+
"metadata": {},
311+
"source": [
312+
"### 2b. Violin / distribution plot (`obsSetFeatureValueDistribution`)\n",
313+
"\n",
314+
"A **violin plot** shows the full distribution of expression values for one gene across cell-type groups. It combines a box plot (median, quartiles) with a density estimate (the width of the violin shape).\n",
315+
"\n",
316+
"Use violin plots to understand whether expression differences between groups are large or variable."
317+
]
318+
},
319+
{
320+
"cell_type": "code",
321+
"execution_count": null,
322+
"metadata": {},
323+
"outputs": [],
324+
"source": [
325+
"sc.pl.dotplot(\n",
326+
" adata,\n",
327+
" var_names=[\"C1QA\", \"PSAP\", \"CD79A\", \"CD79B\", \"CST3\", \"LYZ\"],\n",
328+
" groupby=\"bulk_labels\",\n",
329+
")"
330+
]
331+
},
332+
{
333+
"cell_type": "markdown",
334+
"metadata": {},
335+
"source": [
336+
"## 2. Expression views\n",
337+
"\n",
338+
"### 2a. Dot plot (`dotPlot`)\n",
339+
"\n",
340+
"A **dot plot** encodes two quantities simultaneously for each gene × cell-type combination:\n",
341+
"\n",
342+
"- **Dot size** — fraction of cells in the group that express the gene (above a threshold)\n",
343+
"- **Dot color** — mean expression level across all cells in the group\n",
344+
"\n",
345+
"Dot plots are useful for quickly comparing marker gene expression across many cell types."
346+
]
347+
},
348+
{
349+
"cell_type": "code",
350+
"execution_count": null,
351+
"metadata": {},
352+
"outputs": [],
353+
"source": [
354+
"# PCA colored by a gene — try changing CD79A to another gene name\n",
355+
"sc.pl.pca(adata, color=\"CD79A\")"
356+
]
357+
},
358+
{
359+
"cell_type": "code",
360+
"execution_count": null,
361+
"metadata": {},
362+
"outputs": [],
363+
"source": [
364+
"# UMAP colored by cell type label\n",
365+
"sc.pl.embedding(adata, basis=\"umap\", color=\"bulk_labels\")"
366+
]
367+
},
368+
{
369+
"cell_type": "markdown",
370+
"metadata": {},
371+
"source": [
372+
"## 1. Embedding views (`scatterplot`)\n",
373+
"\n",
374+
"A **scatterplot** view renders a 2D dimensionality reduction such as UMAP or PCA. Each point is one cell. Points can be colored by:\n",
375+
"\n",
376+
"- **Cell type / cluster label** — categorical coloring\n",
377+
"- **Gene expression** — continuous colormap from low (gray) to high (color)\n",
378+
"\n",
379+
"EasyVitessce hooks into `sc.pl.embedding()`. Pass `basis=` to choose the embedding and `color=` to choose what to encode with color."
380+
]
30381
}
31382
],
32383
"metadata": {
@@ -51,7 +402,7 @@
51402
"name": "python",
52403
"nbconvert_exporter": "python",
53404
"pygments_lexer": "ipython3",
54-
"version": "3.8.16"
405+
"version": "3.12.5"
55406
}
56407
},
57408
"nbformat": 4,

0 commit comments

Comments
 (0)