Skip to content

The AnnData Object

Scanpy is Python’s leading single-cell analysis framework. This chapter covers the equivalent workflow to Seurat.

# AnnData is the core data structure
# adata.X - count matrix (cells x genes)
# adata.obs - cell metadata (DataFrame)
# adata.var - gene metadata (DataFrame)
# adata.obsm - embeddings (PCA, UMAP)
# adata.layers - alternative matrices (raw, normalized)
# adata.uns - unstructured data
import scanpy as sc
sc.settings.verbosity = 3
# The PBMC 3k matrix ships in the section container at /opt/data/pbmc3k.
adata = sc.read_10x_mtx("/opt/data/pbmc3k", var_names="gene_symbols",
make_unique=True)
# Store the raw counts before anything modifies adata.X.
adata.layers["counts"] = adata.X.copy()
print(adata)
AnnData object with n_obs × n_vars = 2700 × 32738
var: 'gene_ids'
layers: None (.X), 'counts'
print(adata.var.head())
print(adata.X[:4, :4].toarray())
gene_ids
MIR1302-10 ENSG00000243485
FAM138A ENSG00000237613
OR4F5 ENSG00000186092
RP11-34P13.7 ENSG00000238009
RP11-34P13.8 ENSG00000239945
[[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]
[0. 0. 0. 0.]]

Typical scRNA-seq data is 90-95% zeros:

  • Low expression genes not detected
  • Technical dropout
  • True biological zeros
zero_fraction = 1.0 - adata.X.nnz / (adata.n_obs * adata.n_vars)
print(f"fraction of zero entries: {zero_fraction:.4f}")
fraction of zero entries: 0.9741
adata.write_h5ad("outputs/anndata-object_pbmc3k.h5ad")
adata_copy = sc.read_h5ad("outputs/anndata-object_pbmc3k.h5ad")
print(adata_copy)
AnnData object with n_obs × n_vars = 2700 × 32738
var: 'gene_ids'
layers: 'counts', None (.X)