Migrating from legacy preprocessing recipes#
sc.pp.recipe_seurat, sc.pp.recipe_zheng17, and sc.pp.recipe_weinreb17 have been removed.
Compose individual preprocessing functions to make the transformations and their parameters explicit.
scanpy.experimental.pp.recipe_pearson_residuals() is unaffected.
The examples below start from non-logarithmized counts and reproduce the final expression matrices of the former Seurat and Zheng recipes with their default arguments and the ScanpyV1 preset.
They subset into a new AnnData object; start with adata = adata.copy() if you also need to preserve the input object.
Unlike the recipes, calling log1p() directly on .X also records .uns["log1p"].
Nondefault arguments, especially log=False, require separate consideration of the original transformation order.
Seurat#
import scanpy as sc
sc.pp.filter_cells(adata, min_genes=200)
sc.pp.filter_genes(adata, min_cells=3)
sc.pp.normalize_total(adata, target_sum=1e4)
sc.pp.log1p(adata)
hvg = sc.pp.highly_variable_genes(
adata, flavor="seurat", min_mean=0.0125, max_mean=3, min_disp=0.5, out=True
)
adata = adata[:, hvg["highly_variable"]].copy()
sc.pp.scale(adata, zero_center=True, max_value=10)
Zheng et al. (2017)#
import scanpy as sc
sc.pp.filter_genes(adata, min_counts=1)
normalized = sc.pp.normalize_total(adata, out=True)
adata.X = normalized.normalized
adata.obs["n_counts_all"] = normalized.norm_factor
sc.pp.log1p(adata)
hvg = sc.pp.highly_variable_genes(
adata, flavor="cell_ranger", n_top_genes=1000, out=True
)
adata = adata[:, hvg["highly_variable"]].copy()
sc.pp.scale(adata, zero_center=True)
The normalization target is the median nonzero cell total before highly variable gene selection.
n_counts_all retains the former recipe’s normalization factors (cell totals divided by that target), rather than raw counts.
Gene selection uses the log-normalized matrix, matching the former implementation.
With the default log=True, the recipe’s second normalization was discarded when it restored its saved log-transformed layer; do not add a second normalization to this workflow.
To inspect gene dispersion, call highly_variable_genes() on hvg before subsetting (log=True for Zheng, log=False for the default Seurat recipe).
Weinreb et al. (2017)#
There is no numerically equivalent replacement using only the standard preprocessing functions.
The former recipe optionally logged before normalization, excluded genes exceeding 5% of a cell’s total, and scaled by the mean total over all genes.
It selected genes by mean and coefficient of variation, then computed PCA using population standard deviations plus 0.0001 for standardization.
In contrast, scale() uses sample standard deviations, and highly_variable_genes() uses different selection criteria.
For new analyses, explicitly choose normalize_total(), log1p(), highly_variable_genes(), scale(), and pca() parameters appropriate to the data; this is a change of analysis, not an equivalent substitution.
To reproduce an existing Weinreb analysis exactly, retain the Scanpy version and parameters used for that analysis.