|
1 | | -<p> |
2 | | - <img src="https://raw.githubusercontent.com/theislab/cellucid-python/main/cellucid-logo.svg" alt="Cellucid logo" width="360"> |
3 | | -</p> |
| 1 | + |
4 | 2 |
|
5 | 3 | [](https://pypi.org/project/cellucid/) |
6 | 4 | [](https://pypi.org/project/cellucid/) |
7 | 5 | [](https://cellucid.readthedocs.io/en/latest/) |
| 6 | +[](https://pypi.org/project/cellucid/) |
8 | 7 |
|
9 | 8 | # Cellucid |
10 | 9 |
|
11 | | -Python package for visualizing single-cell data with the [Cellucid WebGL viewer](https://cellucid.com). Cellucid renders millions of cells in real-time 3D, enabling interactive exploration of UMAP/tSNE embeddings with gene expression overlays, filtering, and KNN connectivity visualization. |
| 10 | +**See every cell. Query any gene. Fly through millions. Interactive, GPU-accelerated single-cell visualization in the browser.** |
12 | 11 |
|
13 | | -## Features |
| 12 | +Cellucid is a browser-first viewer for exploring large single-cell datasets in real time: fly through 2D/3D embeddings (UMAP/t-SNE/PCA), color by genes or metadata, filter and compare populations, and share reproducible views with collaborators. |
14 | 13 |
|
15 | | -- **Interactive Single-Cell Data Visualization** of UMAP/tSNE embeddings |
16 | | -- **Gene expression overlays** with fast queries |
17 | | -- **Cell metadata filtering** and categorical coloring |
18 | | -- **KNN connectivity** edge visualization |
19 | | -- **Multi-dimensional** support (1D timelines, 2D, 3D) |
20 | | -- **Jupyter integration** with bidirectional communication |
21 | | -- **Scales to millions** of cells with adaptive LOD |
| 14 | +## Highlights |
22 | 15 |
|
23 | | -## Installation |
| 16 | +- **GPU-accelerated WebGL rendering** with adaptive detail for millions of cells |
| 17 | +- **AnnData-first workflow** for the Scanpy ecosystem (`.h5ad` and Zarr supported) |
| 18 | +- **Shareable exports** you can host locally, on GitHub, or behind a server |
| 19 | +- **Genes + metadata overlays** optimized for interactive querying |
| 20 | +- **Connectivity + dynamics**: KNN edges and animated vector fields (RNA velocity / drift) |
| 21 | +- **Collaboration**: community annotation voting with optional GitHub sync |
| 22 | +- **Publication export**: SVG (vector) and high-DPI PNG figures |
| 23 | +- **Works everywhere**: web app, local/remote server, and Jupyter notebooks |
24 | 24 |
|
25 | | -```bash |
26 | | -pip install cellucid |
27 | | -``` |
28 | | - |
29 | | -All features (Jupyter, AnnData, server) are included in the standard install. |
30 | | - |
31 | | -## Quick Start |
32 | | - |
33 | | -### Option 1: Direct AnnData Visualization (No Export) |
34 | | - |
35 | | -The fastest way to get started - visualize your AnnData directly: |
36 | | - |
37 | | -```python |
38 | | -from cellucid import show_anndata |
39 | | - |
40 | | -# In-memory AnnData |
41 | | -show_anndata(adata) |
42 | | - |
43 | | -# From h5ad file (lazy loading) |
44 | | -show_anndata("/path/to/data.h5ad") |
45 | | - |
46 | | -# From zarr store (lazy loading) |
47 | | -show_anndata("/path/to/data.zarr") |
48 | | -``` |
49 | | - |
50 | | -### Option 2: Pre-export for Best Performance |
51 | | - |
52 | | -For production use or sharing, export to optimized binary format: |
53 | | - |
54 | | -```python |
55 | | -from cellucid import prepare, show |
56 | | - |
57 | | -# Pick UMAP embeddings (explicit keys preferred, fall back to X_umap). |
58 | | -X_umap_1d = adata.obsm.get("X_umap_1d") |
59 | | -X_umap_2d = adata.obsm.get("X_umap_2d") |
60 | | -X_umap_3d = adata.obsm.get("X_umap_3d") |
61 | | -X_umap = adata.obsm.get("X_umap") # may be 1D/2D/3D depending on how it was computed |
62 | | -if X_umap is not None and X_umap_1d is None and X_umap.shape[1] == 1: |
63 | | - X_umap_1d = X_umap |
64 | | -if X_umap is not None and X_umap_2d is None and X_umap.shape[1] == 2: |
65 | | - X_umap_2d = X_umap |
66 | | -if X_umap is not None and X_umap_3d is None and X_umap.shape[1] == 3: |
67 | | - X_umap_3d = X_umap |
68 | | - |
69 | | -# Optional: include any per-cell displacement vector fields in embedding space |
70 | | -# (see "Vector Field Overlay" section below for naming conventions). |
71 | | -vector_fields = { |
72 | | - "velocity_umap_2d": adata.obsm.get("velocity_umap_2d"), |
73 | | - "velocity_umap_3d": adata.obsm.get("velocity_umap_3d"), |
74 | | -} |
75 | | - |
76 | | -prepare( |
77 | | - # Required inputs |
78 | | - latent_space=adata.obsm.get( |
79 | | - "X_pca", |
80 | | - X_umap_3d if X_umap_3d is not None else (X_umap_2d if X_umap_2d is not None else X_umap_1d), |
81 | | - ), |
82 | | - obs=adata.obs, |
83 | | - var=adata.var, |
84 | | - gene_expression=adata.X, |
85 | | - |
86 | | - # Optional inputs |
87 | | - connectivities=adata.obsp.get("connectivities"), |
88 | | - vector_fields=vector_fields, |
89 | | - |
90 | | - # Embeddings (provide any/all of 1D/2D/3D) |
91 | | - X_umap_1d=X_umap_1d, |
92 | | - X_umap_2d=X_umap_2d, |
93 | | - X_umap_3d=X_umap_3d, |
94 | | - |
95 | | - # Output + performance knobs |
96 | | - out_dir="./my_export", |
97 | | - compression=6, |
98 | | - var_quantization=8, |
99 | | - obs_continuous_quantization=8, |
100 | | -) |
101 | | - |
102 | | -# View anytime (fastest loading) |
103 | | -show("./my_export") |
104 | | -``` |
105 | | - |
106 | | -## AnnData Requirements |
107 | | - |
108 | | -Your AnnData needs UMAP coordinates in `obsm`: |
109 | | - |
110 | | -```python |
111 | | -# Required: one of these |
112 | | -adata.obsm['X_umap_3d'] # shape (n_cells, 3) - recommended |
113 | | -adata.obsm['X_umap_2d'] # shape (n_cells, 2) |
114 | | -adata.obsm['X_umap'] # shape (n_cells, 2 or 3) |
115 | | - |
116 | | -# Optional |
117 | | -adata.obsm['velocity_umap_2d'] # shape (n_cells, 2) - vector field overlay (velocity/drift) |
118 | | -adata.obs # Cell metadata (categorical/continuous) |
119 | | -adata.X # Gene expression (dense or sparse) |
120 | | -adata.obsp['connectivities'] # KNN graph edges |
121 | | -``` |
122 | | - |
123 | | -### Vector Field Overlay (Velocity / CellRank Drift) |
124 | | - |
125 | | -Cellucid’s web viewer can render an animated particle-flow overlay from **per-cell displacement vectors** in embedding space. |
126 | | - |
127 | | -Store vectors in `adata.obsm` with keys like: |
128 | | -- `velocity_umap_2d`, `velocity_umap_3d` |
129 | | -- `T_fwd_umap_2d`, `T_bwd_umap_2d` (CellRank-style drift) |
130 | | - |
131 | | -If you have a CellRank transition matrix `T` and an embedding `X_umap`, you can derive drift vectors: |
132 | | - |
133 | | -```python |
134 | | -from cellucid import add_transition_drift_to_obsm |
135 | | - |
136 | | -add_transition_drift_to_obsm( |
137 | | - adata, |
138 | | - T_fwd, # (n_cells, n_cells) sparse/dense transition matrix |
139 | | - basis="umap", |
140 | | - field_prefix="T_fwd", # -> writes adata.obsm['T_fwd_umap_<dim>d'] |
141 | | -) |
142 | | -``` |
143 | | - |
144 | | -Computing 3D UMAP with scanpy: |
145 | | - |
146 | | -```python |
147 | | -import scanpy as sc |
148 | | -sc.pp.neighbors(adata) |
149 | | -sc.tl.umap(adata, n_components=3) |
150 | | -adata.obsm['X_umap_3d'] = adata.obsm['X_umap'] |
151 | | -``` |
152 | | - |
153 | | -## All 14 Loading Options |
154 | | - |
155 | | -Cellucid supports 6 deployment modes, each with support for pre-exported binary data, h5ad files, and zarr stores: |
156 | | - |
157 | | -| # | Method | Exported | h5ad | zarr | Python | Lazy Load | Performance | |
158 | | -|---|--------|----------|------|------|--------|-----------|-------------| |
159 | | -| 1 | Local Demo (GitHub) | ✅ | - | - | No* | Yes | Best | |
160 | | -| 2 | Remote Demo (GitHub) | ✅ | - | - | No* | Yes | Best | |
161 | | -| 3 | Browser File Picker | ✅ | - | - | No | Yes | Best | |
162 | | -| 4 | Browser File Picker | - | ✅ | - | No | **No** | Slower | |
163 | | -| 5 | Browser File Picker | - | - | ✅ | No | **No** | Slower | |
164 | | -| 6 | Server CLI | ✅ | - | - | Yes | Yes | Best | |
165 | | -| 7 | Server CLI | - | ✅ | ✅ | Yes | Yes | Good | |
166 | | -| 8 | Python serve() | ✅ | - | - | Yes | Yes | Best | |
167 | | -| 9 | Python serve_anndata() | - | ✅ | ✅ | Yes | Yes | Good | |
168 | | -| 10 | Jupyter show() | ✅ | - | - | Yes | Yes | Best | |
169 | | -| 11 | Jupyter show_anndata() | - | ✅ | ✅ | Yes | Yes | Good | |
170 | | - |
171 | | -\* Python required for initial export, not for viewing |
172 | | - |
173 | | -**Summary by method:** |
174 | | -| Method | Exported | h5ad | zarr | Total | |
175 | | -|--------|----------|------|------|-------| |
176 | | -| Local/Remote Demo | ✅ | - | - | 2 | |
177 | | -| Browser File Picker | ✅ | ✅ | ✅ | 3 | |
178 | | -| Server CLI | ✅ | ✅ | ✅ | 3 | |
179 | | -| Python serve | ✅ | ✅ | ✅ | 3 | |
180 | | -| Jupyter | ✅ | ✅ | ✅ | 3 | |
181 | | -| **Total** | | | | **14** | |
182 | | - |
183 | | -### Key Notes: |
184 | | -- **Browser h5ad/zarr**: Entire file loaded into memory - no lazy loading due to JavaScript limitations |
185 | | -- **Python h5ad/zarr modes**: True lazy loading via AnnData backed mode (h5ad) or zarr's native chunked access |
186 | | -- **Pre-exported data**: Always fastest - use for production and sharing |
187 | | -- **zarr stores**: Can be a directory (.zarr) or a file - the Python server auto-detects the format |
188 | | - |
189 | | -## Deployment Modes |
190 | | - |
191 | | -| Mode | Best For | Command/Function | |
192 | | -|------|----------|------------------| |
193 | | -| **Jupyter** | Interactive analysis | `show_anndata(adata)` | |
194 | | -| **Local server** | Development | `cellucid serve ./data` | |
195 | | -| **Remote + SSH** | Team access | `cellucid serve data.h5ad` | |
196 | | -| **Browser** | Quick preview | [cellucid.com](https://cellucid.com) file picker | |
197 | | -| **Static hosting** | Public sharing | GitHub Pages | |
198 | | - |
199 | | -### CLI Commands |
| 25 | +## Install |
200 | 26 |
|
201 | 27 | ```bash |
202 | | -# Serve any data - format auto-detected |
203 | | -cellucid serve /path/to/data.h5ad # h5ad file |
204 | | -cellucid serve /path/to/data.zarr # zarr store |
205 | | -cellucid serve /path/to/export # pre-exported data |
206 | | - |
207 | | -# With options |
208 | | -cellucid serve data.h5ad --port 9000 --no-browser |
209 | | - |
210 | | -# Show version |
211 | | -cellucid --version |
| 28 | +pip install cellucid |
212 | 29 | ``` |
213 | 30 |
|
214 | | -### Remote Server Access |
| 31 | +## Quickstart |
215 | 32 |
|
216 | | -```bash |
217 | | -# On remote server |
218 | | -cellucid serve /data/cells.h5ad --no-browser |
| 33 | +Try the web app (no setup): |
219 | 34 |
|
220 | | -# On local machine (SSH tunnel) |
221 | | -ssh -L 8765:localhost:8765 user@server |
222 | | -# Then open: https://cellucid.com?remote=http://localhost:8765 |
223 | | -``` |
| 35 | +1. Open https://cellucid.com |
| 36 | +2. Load a pre-exported folder, `.h5ad`, or `.zarr` |
224 | 37 |
|
225 | | -## Jupyter Features |
| 38 | +Or visualize an AnnData from Python/Jupyter: |
226 | 39 |
|
227 | 40 | ```python |
228 | 41 | from cellucid import show_anndata |
229 | 42 |
|
230 | | -viewer = show_anndata(adata, height=600) |
231 | | - |
232 | | -# Programmatic control |
233 | | -viewer.highlight_cells([1, 2, 3], color="#ff0000") |
234 | | -viewer.set_color_by("cell_type") |
235 | | -viewer.set_visibility([0, 1, 2], visible=False) |
236 | | - |
237 | | -# Cleanup |
238 | | -viewer.stop() |
| 43 | +show_anndata(adata) # or: show_anndata("dataset.h5ad") |
239 | 44 | ``` |
240 | 45 |
|
241 | | -## Performance Guide |
242 | | - |
243 | | -| Method | Load Time | Gene Queries | Recommended For | |
244 | | -|--------|-----------|--------------|-----------------| |
245 | | -| Pre-exported (`show`) | Fast | Fast | Production, sharing | |
246 | | -| Direct AnnData (`show_anndata`) | Medium | Medium | Exploration | |
247 | | -| Browser file picker | Slower | Slower | Quick preview | |
248 | | - |
249 | | -For datasets > 500k cells, pre-export with `prepare()` is recommended. |
250 | | - |
251 | | -## Documentation |
| 46 | +## Links |
252 | 47 |
|
253 | | -- **[Full documentation](https://cellucid.readthedocs.io)** - API reference and tutorials |
254 | | -- **[Web viewer](https://github.com/theislab/cellucid)** - JavaScript repository |
| 48 | +- Web app: https://cellucid.com |
| 49 | +- Documentation: https://cellucid.readthedocs.io |
| 50 | +- Community annotation voting: https://cellucid.readthedocs.io/en/latest/user_guide/web_app/j_community_annotation/index.html |
| 51 | +- Source: https://github.com/theislab/cellucid-python |
| 52 | +- Web viewer: https://github.com/theislab/cellucid |
| 53 | +- Annotation template: https://github.com/theislab/cellucid-annotation |
| 54 | +- Issues: https://github.com/theislab/cellucid-python/issues |
255 | 55 |
|
256 | 56 | ## License |
257 | 57 |
|
|
0 commit comments