Before you start
- You know what bulk RNA-seq measures, for example from The RNA-seq Big Picture.
- Any term new? The Glossary has it.
Learning objectives
By the end of this lesson you will be able to: contrast bulk and single-cell RNA-seq, explain what cell barcodes and UMIs do, describe why the cells-by-genes matrix is sparse, and name the high-level steps of a standard single-cell pipeline and its main tools.
What this lesson is: an orientation that gives you the mental map and the vocabulary. It is not a full how-to, and you will not run a real dataset here. The goal is that the next tutorial you open feels familiar rather than overwhelming.
Bulk vs single-cell: averages vs individuals
Ordinary bulk RNA-seq grinds up a whole sample and measures the average expression across all the cells in it. That average hides which cell types were present and what each was doing. Single-cell RNA-seq (scRNA-seq) measures each cell separately, so instead of one averaged profile you get thousands of individual profiles. That resolution is what lets you discover cell types, see rare populations, and watch cells move through states that an average would blur together.
1How droplet platforms tag each cell
The most common technology is droplet-based, with 10x Genomics as the dominant example. Each cell is captured in a tiny droplet alongside a bead carrying two kinds of short DNA tags. A cell barcode is shared by everything from one droplet, so afterward you can tell which reads came from which cell. A UMI (unique molecular identifier) tags each individual RNA molecule before amplification, so when PCR makes many copies you can collapse them back to one and remove duplicates. Barcodes answer which cell; UMIs answer how many real molecules.
Barcode vs UMITwo different jobs
A cell barcode identifies which cell a read belongs to. A UMI identifies which original molecule a read came from, so PCR duplicates can be removed and each molecule is counted once. Together they turn raw reads into an honest count per gene per cell.
2The output: a sparse cells-by-genes matrix
The result of processing is a big cells-by-genes matrix of counts: thousands of cells, tens of thousands of genes. It is very sparse, meaning most entries are zero. This is partly biology (a given cell only expresses a fraction of all genes) and partly a sampling limit called dropout, where a gene is truly present but no molecule of it happened to be captured. Sparsity is the defining feature of single-cell data and shapes every method built for it.
3The standard pipeline at a high level
Almost every analysis follows the same arc. You do not need to memorize the details now, just recognize the shape.
| Step | What it does |
|---|---|
| Quality control | Filter low-quality cells and likely doublets; check the percentage of mitochondrial reads, which is high in dying cells |
| Normalization | Put cells on a comparable scale despite different total counts |
| Highly variable genes | Keep the genes that vary most across cells, since they carry the signal |
| PCA | Reduce to a handful of dimensions that capture the main variation |
| Graph-based clustering | Group similar cells with Leiden or Louvain clustering |
| UMAP | Project to 2D for visualization, so clusters can be seen |
| Label clusters | Name each cluster by its marker genes (known cell-type signatures) |
The two dominant toolkits are Seurat in R and Scanpy in Python. They cover this same pipeline with slightly different commands; learning one makes the other easy to read.
One-line summary
Single-cell RNA-seq measures each cell instead of an average. Droplet platforms use cell barcodes to mark which cell and UMIs to remove PCR duplicates, producing a sparse cells-by-genes matrix. The pipeline runs QC, normalize, pick variable genes, PCA, cluster, UMAP, then label by markers, in Seurat or Scanpy.
A worked example: the Scanpy step list
This is a high-level sketch of the Scanpy commands that match the pipeline above. It is here to make the structure concrete, not to run as is; a real analysis needs your own data and tuned parameters.
# High-level Scanpy outline (Python) -- orientation, not a runnable script
import scanpy as sc
adata = sc.read_10x_mtx("filtered_feature_bc_matrix/") # cells x genes (sparse)
# 1. Quality control: filter cells/genes, check mitochondrial percent
adata.var["mt"] = adata.var_names.str.startswith("MT-")
sc.pp.calculate_qc_metrics(adata, qc_vars=["mt"], inplace=True)
sc.pp.filter_cells(adata, min_genes=200)
sc.pp.filter_genes(adata, min_cells=3)
# 2. Normalize
sc.pp.normalize_total(adata, target_sum=1e4)
sc.pp.log1p(adata)
# 3. Highly variable genes
sc.pp.highly_variable_genes(adata, n_top_genes=2000)
# 4. PCA
sc.pp.pca(adata)
# 5. Graph-based clustering (Leiden)
sc.pp.neighbors(adata)
sc.tl.leiden(adata)
# 6. UMAP for visualization
sc.tl.umap(adata)
sc.pl.umap(adata, color="leiden")
# 7. Label clusters by marker genes
sc.tl.rank_genes_groups(adata, "leiden", method="wilcoxon")