Note
Mental model.
Cells live in a ~20,000-D gene-expression space.
PCA collapses that to 20–50 signal dimensions; the neighbour graph translates those distances into “who is similar to whom”
Clustering carves the graph into groups
UMAP makes a 2D picture of all of it.
Every step compresses information — get any of them wrong and you can’t see what’s there.
Dimensionality reduction projects high-dimensional data into 2-3D
Warning
Don’t skip PCA and run UMAP on raw gene expression. UMAP/t-SNE on tens of thousands of genes is slow, noisy, and produces visibly worse embeddings. PCA is doing real statistical work, not just bookkeeping.
RunPCA(), sc.tl.pca(), and prcomp()
Tip
A PC dominated by mitochondrial or ribosomal genes is a red flag.
VizDimLoadings() for PC1 and PC2 before you trust the embedding.| Setting | Result | When to use |
|---|---|---|
center = TRUE, scale = FALSE |
PCA on the covariance matrix | All variables on the same scale |
center = TRUE, scale = TRUE |
PCA on the correlation matrix | Variables on different scales (default for HVGs) |
ScaleData() z-scores each gene across cells (mean 0, SD 1) before RunPCA(). In scanpy, sc.pp.scale() does the same.MALAT1, ribosomal proteins, some lncRNAs) dominate every PC simply because they have larger raw variance — not because they are biologically informative.Note
Using SCTransform? You can skip the separate center/scale step. Seurat’s SCTransform() replaces the NormalizeData → FindVariableFeatures → ScaleData trio with a single variance-stabilizing transformation (regularized NB regression). Its Pearson residuals are already variance-stabilized and effectively centered, so you go straight from SCTransform() to RunPCA() — no separate ScaleData() / explicit center-and-scale is needed (Hafemeister & Satija 2019).
ElbowPlot(seu, ndims = 50) is the visual; JackStraw() is a permutation-based statistical alternative when you want a defensible cutoffTip
When in doubt, lean high. Going from 20 PCs to 30 PCs rarely hurts clustering and often recovers a subtype that 20 PCs collapses. Going from 30 to 50 mostly costs runtime.
CD3D, CD3E, TRAC) from B-cell markers (CD79A, MS4A1);LYZ, S100A8, S100A9) from lymphoid.VizDimLoadings(seu, dims = 1:4) for bar plots,DimHeatmap(seu, dims = 1:9, balanced = TRUE) for a per-cell heatmap of the top loaders.Note
Louvain (default) vs. Leiden.
FindClusters() defaults to Louvain (algorithm = 1), and that is what the workshop tutorials run — for portability.algorithm = 4) is the modern preferred refinement (it guarantees well-connected communities) but needs the leidenalg Python package via reticulate.algorithm = 4 change once that dependency is installed.Note
This is the same reason single-cell pipelines have largely abandoned hierarchical clustering on raw expression: graph methods scale to millions of cells, run in minutes, and respect the local geometry that PCA preserved.
clustree to visualize cluster stability across a sweep of resolutionsTip
Workflow. Sweep resolutions, pick one where
clustree shows stable splits,Important
Tutorial 02 runs deliberately un-integrated. The ifnb dataset has two conditions (CTRL and STIM). Tutorial 02 runs PCA and clustering without integration — so your UMAP will show CTRL and STIM cells splitting into mirror-image islands rather than mixing by cell type. This is the expected, intentional outcome of Step 6 (“Diagnose the batch effect”). You will count those islands and interpret what drives the split before integration is introduced in Tutorial 05 / Lecture 05. On unintegrated data, resolution ≈ 0.5 typically yields ~15–20 clusters — more than the ~13 annotatable cell types — because each cell type appears as a CTRL island and a STIM island.
PCA gave us a denoised ~30-D space; clustering already happened on the SNN graph in that space. What’s left is a picture — a 2D embedding so we can show clusters, gradients, and trajectories on a slide.
Two non-linear methods dominate:
Both share the same philosophy:
Crucially, t-SNE/UMAP are visualizations, not analyses. They don’t replace PCA or clustering — they sit on top of them.
\[D_{KL}(P \| Q) = \sum_{i \neq j} p_{ij} \log \frac{p_{ij}}{q_{ij}}\]
KL divergence is asymmetric — and that’s the point
Heavily penalised: \(p_{ij}\) large but \(q_{ij}\) small → “you put true neighbours far apart” → strong attractive gradient pulls them together
Weakly penalised: \(p_{ij}\) small but \(q_{ij}\) large → “you put unrelated cells nearby” → near-zero contribution to the loss
Important
This asymmetry is the most important property of t-SNE. It is why t-SNE preserves local neighbourhoods beautifully — and why distances between clusters in a t-SNE plot are not meaningful. Two clusters drawn far apart could be biologically very similar, and vice versa.
\[CE = -\sum_{i,j} \left[ w_{ij} \log v_{ij} + (1 - w_{ij}) \log(1 - v_{ij}) \right]\]
Note
“More faithful” is not “fully faithful.” UMAP still warps global geometry; you should not measure trajectory length or biological similarity from UMAP coordinates alone.
| Parameter | Seurat default | Effect |
|---|---|---|
n.neighbors |
30 | Soft “k” — local vs. global balance, like t-SNE’s perplexity |
min.dist |
0.3 | Minimum distance between points in the embedding |
(Seurat’s RunUMAP defaults; the underlying Python umap-learn uses different defaults of 15 and 0.1, so don’t be surprised if other tutorials quote those.)
n_neighbors (5–10): very local detail; clusters fragment more. Large (30–50): broader topology; subtypes may merge.min_dist (≤ 0.1): tight clusters with clear gaps — good for discrete cell types. Large (0.4–0.8): spread-out — good for continuous gradients (development, pseudotime).n_neighbors than t-SNE is across perplexity — usually one well-chosen UMAP is enough; with t-SNE you really do want to sweep.FeaturePlot)Warning
Three things a UMAP plot does NOT tell you:
min_dist and is not biological cell densityTip
Build the intuition yourself. Google PAIR’s interactive Understanding UMAP lets you turn n_neighbors/min_dist and watch what the embedding does (and doesn’t) preserve; DataCamp’s Understanding UMAP guide is a written walkthrough. Highly recommended if these plots ever made your head spin.
Single Cell RNA-seq Workshop · Lecture 02