Skip to main content

Python single-cell genomics toolkit — a port of Seurat's core data structures and analysis pipeline

Project description

Shanuz — Python Single-Cell Genomics Toolkit

PyPI Python 3.10+ License: MIT

Shanuz is a Python port of the Seurat single-cell RNA-seq analysis framework, implementing Seurat's core data structures, preprocessing pipeline, dimensionality reduction, clustering, and marker detection — entirely in Python.

The package is spiritually and algorithmically faithful to Seurat v5 while providing a pure-Python, pip-installable alternative that integrates naturally with NumPy, SciPy, and AnnData ecosystems.


Features

  • Shanuz object — mirrors the R Seurat S4 class with __slots__-based Python classes
  • Assay5 — sparse-matrix-backed multi-layer assay (counts, data, scale.data)
  • Preprocessingnormalize_data, find_variable_features (VST), scale_data, percentage_feature_set
  • SCTransformsctransform (regularized negative-binomial Pearson residuals)
  • Signature scoringadd_module_score, cell_cycle_scoring (S/G2M + Phase)
  • Dimensionality reductionrun_pca, run_ica, run_tsne (via scikit-learn)
  • Batch correction / integrationrun_harmony, integrate_layers (via harmonypy)
  • Nearest-neighbour graphfind_neighbors (KNN + SNN)
  • Multimodal WNNfind_multi_modal_neighbors (per-cell RNA/protein weights, joint wknn/wsnn graphs)
  • Clusteringfind_clusters (Louvain via python-igraph, Leiden via leidenalg)
  • UMAPrun_umap (via umap-learn; embeds a reduction or a precomputed graph)
  • PC significancejack_straw, score_jackstraw (JackStraw permutation test)
  • Differential expressionfind_markers, find_all_markers (wilcox tie-corrected, t, LR, negbinom, roc)
  • Plottingdim_plot, feature_plot, vln_plot, dot_plot, elbow_plot, do_heatmap, dim_heatmap, feature_scatter, variable_feature_plot, ridge_plot (matplotlib/seaborn)
  • AnnData interoperabilityas_anndata, from_anndata
  • Spatial (Xenium / Visium / CosMx)load_xenium/load_visium/load_cosmx, get_tissue_coordinates, nearest_neighbor_distance, local_neighborhood, build_niche_assay, composition_test, image_dim_plot, image_feature_plot
  • PBMC 3k tutorial — end-to-end validated against the official Seurat tutorial
  • PBMC 8k advanced tutorial — larger dataset + T/NK subclustering workflow
  • CITE-seq multimodal tutorial — RNA + surface protein (ADT) with CLR normalization and WNN joint clustering
  • Xenium spatial tutorial — spatial neighbourhood/niche analysis, verified to 8 s.f. against R Seurat

Installation

Shanuz is published on PyPIpip install shanuz just works. Installing from source (editable install) is only needed if you want to modify shanuz itself.

From PyPI (recommended)

pip install shanuz                 # core: object model, preprocessing, PCA, markers
pip install "shanuz[analysis]"     # + clustering, UMAP, plotting (matplotlib/seaborn)
pip install "shanuz[anndata]"      # + AnnData interoperability
pip install "shanuz[integration]"  # + Harmony batch correction (harmonypy)
pip install "shanuz[all]"          # everything (analysis + anndata + integration + dev/test tooling)

Or with uv:

uv pip install "shanuz[analysis]"

From source (for development)

git clone https://github.com/GenomicAI/shanuz.git
cd shanuz
uv venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
uv pip install -e ".[all]"  # editable install + tests/linting

With pip instead of uv:

git clone https://github.com/GenomicAI/shanuz.git
cd shanuz
pip install -e ".[analysis]"

Troubleshooting

ModuleNotFoundError: No module named 'numpy._core._multiarray_umath' (or a similar broken NumPy/SciPy import) means the virtual environment has a corrupt or partially-installed NumPy — usually left over from an interrupted install or from mixing installers. It is not a shanuz issue. Fix it by reinstalling NumPy, or by recreating the environment:

uv pip install --reinstall --no-cache numpy      # quick fix
# or start clean:
rm -rf .venv && uv venv && uv pip install "shanuz[all]"

Quick Start

import scipy.sparse as sp
import numpy as np
from shanuz import create_shanuz_object

# Create a Shanuz object from a counts matrix
counts = sp.random(2000, 500, density=0.2, format="csc")
sobj = create_shanuz_object(counts, project="my_project", min_cells=3, min_features=200)
print(sobj)
# Shanuz object — my_project
#   500 cells × 2000 features
#   Active assay: 'RNA'
#   Reductions: []
#   Version: 5.4.0

# Access metadata
print(sobj.meta_data.head())

Tutorials

Five end-to-end tutorials — from basic guided clustering through multimodal CITE-seq to Xenium spatial — each pairing R Seurat code side-by-side with the Python Shanuz equivalent. See tutorials/README.md for the full index.

# Tutorial Dataset Complexity
1 PBMC 3k — Guided Clustering 3k PBMCs · 10x Genomics Beginner
2 PBMC 8k — Advanced Subclustering 8k PBMCs · GRCh38 Intermediate
3 CBMC CITE-seq — Multimodal 8,600 CBMCs · RNA + 13 proteins Advanced
4 PBMC 3k — SCTransform 3k PBMCs · 10x Genomics Advanced
5 Xenium — Spatial (R vs Python) 36k cells · 10x Xenium mouse brain Spatial
# Tutorial 1 — PBMC 3k
python tutorials/pbmc3k_tutorial.py && python tutorials/generate_plots.py

# Tutorial 2 — PBMC 8k subclustering
python tutorials/pbmc8k_subclustering_tutorial.py && python tutorials/generate_advanced_plots.py

# Tutorial 3 — CITE-seq multimodal
python tutorials/cbmc_citeseq_tutorial.py && python tutorials/generate_multimodal_plots.py

# Tutorial 4 — SCTransform
python tutorials/pbmc3k_sctransform_tutorial.py && python tutorials/generate_sctransform_plots.py

# Tutorial 5 — Xenium spatial (auto-downloads ~20 MB)
python tutorials/generate_spatial_plots.py

API Reference

Object creation

from shanuz import create_shanuz_object

pbmc = create_shanuz_object(
    counts,             # scipy.sparse CSC/CSR or numpy ndarray (genes × cells)
    project="pbmc3k",
    min_cells=3,        # filter genes present in fewer than N cells
    min_features=200,   # filter cells with fewer than N detected genes
)

Preprocessing

from shanuz.preprocessing import (
    normalize_data,
    find_variable_features,
    scale_data,
    percentage_feature_set,
)

percentage_feature_set(pbmc, pattern=r"^MT-", col_name="percent.mt")
normalize_data(pbmc, normalization_method="LogNormalize", scale_factor=10000)
find_variable_features(pbmc, selection_method="vst", nfeatures=2000)
scale_data(pbmc)

Dimensionality reduction & clustering

from shanuz.reduction import run_pca
from shanuz.neighbors import find_neighbors
from shanuz.clustering import find_clusters
from shanuz.umap import run_umap

run_pca(pbmc, n_pcs=50)
find_neighbors(pbmc, dims=range(10), k_param=20)
find_clusters(pbmc, resolution=0.5)
run_umap(pbmc, dims=range(10))

Differential expression

from shanuz.markers import find_markers, find_all_markers

markers = find_markers(pbmc, ident_1=1)
all_markers = find_all_markers(pbmc, only_pos=True, logfc_threshold=0.25)

Plotting

All plotting functions return a matplotlib.figure.Figure — save or display as needed.

from shanuz.plotting import (
    dim_plot,            # DimPlot   — cells on UMAP/PCA coloured by ident
    feature_plot,        # FeaturePlot — gene expression on embedding
    vln_plot,            # VlnPlot   — violin plots per cluster
    elbow_plot,          # ElbowPlot — stdev per PC
    feature_scatter,     # FeatureScatter — two features vs each other
    variable_feature_plot, # VariableFeaturePlot — mean-variance HVG plot
    dim_heatmap,         # DimHeatmap — top loading genes per PC
    do_heatmap,          # DoHeatmap  — expression heatmap sorted by cluster
    ridge_plot,          # RidgePlot  — ridgeline plots per cluster
)

# Quick examples
fig = dim_plot(pbmc, reduction="umap", label=True)
fig = feature_plot(pbmc, ["LYZ", "MS4A1", "NKG7"], reduction="umap", ncol=3)
fig = vln_plot(pbmc, ["LYZ", "CD3D", "PPBP"], group_by=None)
fig = elbow_plot(pbmc, ndims=20)
fig = do_heatmap(pbmc, top_marker_genes)
fig.savefig("output.png", dpi=150, bbox_inches="tight")
Shanuz function R Seurat equivalent
dim_plot DimPlot
feature_plot FeaturePlot
vln_plot VlnPlot
dot_plot DotPlot
elbow_plot ElbowPlot
feature_scatter FeatureScatter
variable_feature_plot VariableFeaturePlot
dim_heatmap DimHeatmap
do_heatmap DoHeatmap
ridge_plot RidgePlot

Data Structures

Shanuz
├── assays: dict[str, Assay5]
│   └── "RNA"
│       ├── layers["counts"]    # raw integer counts (genes × cells)
│       ├── layers["data"]      # log-normalized (genes × cells)
│       └── layers["scale.data"] # z-scored (genes × cells)
├── meta_data: pd.DataFrame     # per-cell metadata
├── reductions: dict
│   ├── "pca": DimReduc         # PCA embeddings + loadings
│   └── "umap": DimReduc        # UMAP embeddings
├── graphs: dict
│   ├── "RNA_nn": Graph         # KNN graph
│   └── "RNA_snn": Graph        # SNN graph
└── commands: list[ShanuzCommand]  # audit log

Roadmap

See ROADMAP.md for the full development plan. Milestones:

Milestone Focus
v0.2.0 Batch correction — Harmony + IntegrateLayers(delivered); remaining: CCA/RPCA anchors
v0.3.0 Reference mapping — FindTransferAnchors, TransferData, MapQuery
v0.4.0 Multimodal WNN — FindMultiModalNeighbors, joint UMAP/clustering ✅ (delivered — see Tutorial 3)
v0.5.0 Additional reductions — t-SNE, ICA ✅ (delivered); remaining: SPCA, GLM-PCA
v0.6.0 Pseudobulk DE — AggregateExpression, DESeq2, MAST, FindConservedMarkers
v0.7.0 Spatial — Xenium/Visium/CosMx loaders, niche/neighbourhood analysis, image_* plots ✅ (largely delivered — see Tutorial 5); remaining: MERSCOPE loader, FindSpatiallyVariableFeatures (Moran's I), Visium tissue-image plots
v0.8.0 Scale — BPCells-style lazy matrices, SketchData, ProjectData
v0.9.0 Specialized — HTODemux, Mixscape (CRISPR screens)
v0.10.0 Infrastructure — PyPI, GitHub Actions CI, type annotations, MkDocs site

Running Tests

uv pip install -e ".[dev]"
pytest tests/ -v

All 156 unit tests pass.


Dependencies

Package Purpose
numpy, scipy, pandas Core numerics and data frames
statsmodels LOESS smoothing for VST
scikit-learn PCA
umap-learn UMAP embedding
python-igraph Louvain clustering
leidenalg Leiden clustering
packaging Version handling

Credits

Development assistance: This package was developed with the help of Claude (Anthropic's AI assistant, claude-sonnet-4-6), which assisted in porting the R Seurat codebase to Python, implementing the VST algorithm, degree-2 LOESS, Louvain clustering, and validating results against the official PBMC 3k tutorial.

Original R Seurat package:
The algorithms and data structures in Shanuz are direct Python translations of the R Seurat package by the Satija Lab. Please cite the original Seurat papers if you use Shanuz in published work:

Hao Y, Stuart T, Kowalski MH, et al. (2024). Dictionary learning for integrative, multimodal and scalable single-cell analysis. Nature Biotechnology, 42, 293–304. https://doi.org/10.1038/s41587-023-01767-y

Hao Y, Hao S, Andersen-Nissen E, et al. (2021). Integrated analysis of multimodal single-cell data. Cell, 184(13), 3573–3587. https://doi.org/10.1016/j.cell.2021.04.048

Stuart T, Butler A, Hoffman P, et al. (2019). Comprehensive Integration of Single-Cell Data. Cell, 177(7), 1888–1902. https://doi.org/10.1016/j.cell.2019.05.031

Butler A, Hoffman P, Smibert P, Papalexi E, Satija R. (2018). Integrating single-cell transcriptomic data across different conditions, technologies, and species. Nature Biotechnology, 36, 411–420. https://doi.org/10.1038/nbt.4096

PBMC 3k dataset:
10x Genomics. (2016). 3k PBMCs from a Healthy Donor. https://www.10xgenomics.com/resources/datasets/3-k-pb-mcs-from-a-healthy-donor-1-standard-1-1-0


License

MIT License — see LICENSE for details.

This software is an independent reimplementation for educational and research purposes. It is not affiliated with, endorsed by, or maintained by the Satija Lab or 10x Genomics.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

shanuz-0.2.0.tar.gz (10.9 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

shanuz-0.2.0-py3-none-any.whl (104.5 kB view details)

Uploaded Python 3

File details

Details for the file shanuz-0.2.0.tar.gz.

File metadata

  • Download URL: shanuz-0.2.0.tar.gz
  • Upload date:
  • Size: 10.9 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for shanuz-0.2.0.tar.gz
Algorithm Hash digest
SHA256 3820273b716642ed0b1ff4792531101c4df2ef5995ee03d3f183b7f3b9cee09d
MD5 ebadfb01db1c6c7af995435f79f2b024
BLAKE2b-256 8886a3c6790bc1087e22793ff72152e3186684f0b0f585c8facbb20f521fbd1a

See more details on using hashes here.

File details

Details for the file shanuz-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: shanuz-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 104.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for shanuz-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3e5876bc81cb2b95270de146917202de13cadf74baa3cbb6996992dbea49b82e
MD5 0249eca28aca8f7ca8ff0f8aa73fd9bd
BLAKE2b-256 580a328f8a2a146bd63a3ef5f522fda4d0fe25f367925d2413b6fa6cfec0906c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page