Skip to main content

spanormpy

CI PyPI version PyPI monthly downloads PyPI total downloads conda-forge downloads

A faithful Python / scverse port of the R package SpaNorm (spatially-aware normalisation for spatial transcriptomics data). It operates on AnnData (and optionally SpatialData) with a PyTorch backend that runs on CPU and CUDA (Apple Metal in float32).

Documentation: https://bhuvalab.github.io/SpaNorm/ (one site covering both the R package and spanormpy, with side-by-side R and Python tutorials and the API reference for each).

Version 0.1.0 (beta). Ports SpaNorm 1.7.16 (R commit f233b7b, Bioconductor devel); see CHANGELOG.md.

Install

pip install spanormpy
pip install git+https://github.com/BhuvaLab/spanormpy   # development version

Optional extras: pip install "spanormpy[spatial]" for SpatialData input and pip install "spanormpy[dev]" for the test and tutorial tools. For a GPU, install the CUDA build of PyTorch first (see https://pytorch.org), then use backend="gpu" or the default backend="auto". See docs/benchmark.md (about 2.7x faster spanorm on an H100 MIG slice).

Quickstart

import anndata as ad
import spanormpy as sn

adata = ad.read_h5ad("visium.h5ad")        # raw counts in X, coordinates in obsm["spatial"]
sn.filter_genes(adata, prop=0.2)           # keep genes expressed in >= 20% of spots (in place)

sn.spanorm(adata)                          # normalised data -> adata.layers["logcounts"]
sn.pl.plot_spatial(adata, what="expression", color="MOBP", layer="logcounts")

sn.spanorm_svg(adata)                      # spatially variable genes -> adata.var["svg_*"]
sn.top_svgs(adata, n=10)
sn.spanorm_pca(adata)                      # GLM-PCA approximation -> adata.obsm["X_spanorm_pca"]
sn.polish_spanorm(adata)                   # optional: converge every gene separately

The fit is stored in the object (var, varm, obsm, and scalars in uns["spanorm"]), so re-running with another adj_method only redoes the adjustment. A full walk-through is in docs/tutorial.ipynb (a squidpy mouse-brain Visium walk-through of the R vignette; the HumanDLPFC version identical to the R vignette is on the website). Every R export and its Python name are listed in docs/r-to-python.md.

Differences from R

The full list, with reasons, is in docs/r-discrepancies.md. The intentional ones:

  • Gene subsets reuse the stored fit (a deviation). R refits when the object is subset by genes (fit$ngenes != nrow). After adata[:, genes], spanorm instead reuses the matching slice of the stored fit (as R's subsetFitGenes would), which equals R's adjustment of the full fit on those genes; overwrite=True reproduces R's refit. A spot subset refits, as in R. polish_spanorm and spanorm_svg have their own subset rules (see the discrepancies page). Views are converted to real objects without a warning.
  • Explicit size_factors argument. Pass size factors directly; obs["size_factors"] is never read implicitly.
  • Default pipeline matches R only approximately. Default size factors come from a built-in scran-like method (own quick_cluster) written to obs["spanorm_size_factors"], and spot sampling uses a numpy RNG (random_state replaces set.seed). Results agree with R to numerical closeness; exact parity is obtained when R's size factors and sampling are supplied.
  • Adjustment honours backend. R's adjustment step uses any available accelerator regardless of the requested backend; here backend="cpu" keeps everything on the CPU.
  • logcounts follows the input. layers["logcounts"] is dense for dense counts and sparse for sparse counts (R always stores sparse).
  • n_jobs replaces BPPARAM.

Download statistics

The badges above show download counts from PyPI (via pepy.tech) and conda-forge. They appear once the package is published there. spanormpy contains no telemetry and makes no network calls.

Citation

Salim A, Bhuva DD, Chen C, Tan CW, Yang P, Davis MJ, Yang JYH. SpaNorm: spatially-aware normalization for spatial transcriptomics data. Genome Biology 2025, 26(1):109. doi:10.1186/s13059-025-03565-y

Licence

GPL-3.0-or-later, as for SpaNorm.

Metadata

Release files for spanormpy 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for spanormpy 0.1.0
File Size Uploaded Provenance
spanormpy-0.1.0.tar.gz 1.3 MB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for spanormpy 0.1.0
File Interpreter ABI Platform
spanormpy-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 1.4 MB

Release files / spanormpy-0.1.0.tar.gz

Download URL spanormpy-0.1.0.tar.gz
Size 1.3 MB
Tags Source
SHA-256 checksum
How to use checksums
d0664777ff9557a1f23ac23493876bebc3db21449a3d697709addff8084dada4
BLAKE2b-256 checksum
How to use checksums
822ead38b54a4816efe091d2a32799ff62d775c00152474c71112e58b5c020f3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

Release files / spanormpy-0.1.0-py3-none-any.whl

Download URL spanormpy-0.1.0-py3-none-any.whl
Size 146.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f4a4324e4524e399fb40c173ff9427c3f641ae89c5f77e3bd918a1b0019a80e7
BLAKE2b-256 checksum
How to use checksums
7782f2518608cdbb4d8561d3fb88222324c04a82796a3d64dca1faf7f67611f6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

Security for spanormpy 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for spanormpy-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page