Interactive WebGL visualization of single-cell RNA sequencing data. Points are rendered as glowing light sources on a black background, with continuous UMAP warping that smoothly interpolates between different embedding parameterizations.
- Continuous UMAP warping — Sweeps
n_neighbors(5-150) with Procrustes-aligned keyframes and cubic spline interpolation for smooth, mathematically meaningful transitions - 3D point cloud rendering — Custom Three.js shaders with additive blending, UnrealBloomPass, and optional trail persistence (persistence of vision effect)
- Color by metadata — Switch between cell type annotations (scType), Seurat clusters, sample, region, or subgroup
- Filter by metadata — Show/hide cells by any metadata column with checkbox toggles
- Gene expression overlay — Type any gene symbol to visualize expression with continuous colormaps (viridis, magma, plasma, inferno), brightness modulation, or point size mapping
- Gene autocomplete ranked by expression — Suggestions sorted by total expression level with rank annotations
- Legend with category toggle — Click any category in the legend to show/hide those cells
- 360 auto-rotation — Rotates around the camera's current up axis
- Video recording — Record animation loops as WebM with optional square crop
- Adjustable rendering — Point brightness, bloom strength, point size, trail length, FPS limiter
scAnimator/
index.html # Landing page — dataset picker + local folder upload
viewer.html # Three.js WebGL viewer (single file, no build step)
datasets/ # One subdirectory per dataset
index.json # Auto-generated dataset list
pbmc3k/ # Public demo dataset (tracked in git)
frames.bin, colors.bin, expression.bin, gene_index.json, metadata.json
scripts/
build_viewer.py # Python build script — generates all data files
update_dataset_index.py # Regenerates datasets/index.json
media/
logo.png
- R (code.Rmd) — Load Seurat object, run scType annotations, export PCA embeddings + sparse expression matrix + metadata to
export/ - Python (scripts/build_viewer.py) — Compute 3D UMAP keyframes at varying
n_neighbors, Procrustes-align them, cubic spline interpolate, quantize expression to uint8, write binary files - Browser (viewer.html) — Load binary data via fetch, render with Three.js, gene expression fetched on demand via HTTP Range requests
- Shader: Custom
ShaderMaterialwith per-point color (aColor) and size (aSize) attributes. Fragment shader applies radial intensity falloff:pow(1 - d*d, 1.5). - Bloom:
UnrealBloomPassfor glow effect on additive-blended points - Trails: Render target ping-pong — previous frame faded and composited via
max(old, new) - Animation: Accumulator-based frame stepping with configurable speed and FPS limiter
- Seurat, scType, tidyverse
numpy
pandas
scipy
umap-learn
Any modern browser with WebGL2 support. Serve locally:
python -m http.server 8000
# Open http://localhost:8000To regenerate the viewer data from the Seurat object:
-
Run the R notebook (
code.Rmd) to export PCA, metadata, and expression toexport/ -
Run the build script:
python scripts/build_viewer.py
This takes ~10 minutes (UMAP computation + expression quantization for 28K genes).
-
Optionally regenerate gene expression ranks:
# See inline script in build_viewer.py header comments
MIT

