Skip to content

Repository files navigation

scplotkit

scplotkit logo

CI Docs License: MIT Python

This is just a pile of plotting functions I kept rewriting from scratch for every single-cell project, finally bundled up so I stop copy-pasting them between notebooks. Built on top of scanpy and AnnData — masked/highlighted UMAPs, composition bar plots and heatmaps, pseudobulk boxplots, marker gene panels, Sankeys/sunbursts/treemaps over annotation hierarchies, that kind of thing.

No fancy analysis happening here, just a package to create reproducible and uniformly styled plots for single cell data.

If you've got a plot you always reach for that isn't in here, please open a PR — genuinely happy to have other people's favorite ways of looking at single-cell (and maybe eventually spatial) data in here too. See Contributing below.

  • scanpy-native — works directly on AnnData objects, no wrangling in between.
  • One config, every plot — a single PlotConfig controls fonts, DPI, and color palettes, so figures don't end up looking like they came from six different notebooks.
  • Explicit over magic — column names, palettes, and grouping variables are always arguments you pass in; if you don't give a palette, a colorblind-friendly one gets generated for you.
  • Two ways to call it — plain functions (scplotkit.composition.stacked_barplots(...)) if you like the scanpy-style API, or scplotkit.ScPlotter if you're making a bunch of figures and don't want to pass config/output_dir every single time.

Worth being upfront about: masked_umap, masked_umap_highlight, and gene_expression_umap in scplotkit.embeddings, plus everything in scplotkit.markers, are thin wrappers around scanpy's own sc.pl.embedding / sc.pl.rank_genes_groups_dotplot / sc.pl.rank_genes_groups_matrixplot / sc.pl.matrixplot / sc.pl.stacked_violin. scplotkit just layers its masking/highlighting logic, shared PlotConfig styling, and save-to-disk convention on top — they're here purely for convenience (one consistent way to call and save every plot), not because scanpy's own plotting needed reinventing.

Installation

pip install scplotkit

# optional: Sankey/sunburst/treemap plots (needs plotly + kaleido)
pip install "scplotkit[sankey]"

Or from source:

git clone https://github.com/philinscience/scplotkit.git
cd scplotkit
pip install -e ".[dev]"

Quickstart

import scanpy as sc
import scplotkit as spk

adata = sc.read_h5ad("my_atlas.h5ad")

plotter = spk.ScPlotter(output_dir="figures")

# Highlight one lineage within the full UMAP
plotter.masked_umap(
    adata,
    color_by="cell_type",
    mask_values=["CD4 T", "CD8 T", "NK"],
    figure_name="Lymphocytes",
)

# Cell-type composition per sample, in three orderings (as-is, clustered,
# clustered within a metadata group)
plotter.stacked_barplots(
    adata,
    level_column="cell_type",
    sample_column="sample_id",
    order_by_column="condition",
)

# Dataset overview: samples & cells per category
plotter.sample_and_cell_counts_barplot(adata, level_column="cell_type")

Prefer a functional style? Every method above is also a plain function:

from scplotkit import composition, embeddings

embeddings.masked_umap(adata, color_by="cell_type", mask_values=[...], figure_name="Lymphocytes")
composition.stacked_barplots(adata, level_column="cell_type", sample_column="sample_id")

What's included

Module Plots
scplotkit.embeddings Masked UMAP, masked-and-highlighted UMAP overlay, gene expression on an embedding, two-gene co-expression color blend, per-group embedding density
scplotkit.composition Stacked composition bar plots (plain / clustered / clustered-within-group), a multi-metadata variant with color strips, a clustered composition heatmap, a cell-count bubble grid
scplotkit.overview Samples/cells-per-category bar plots (incl. broken-axis), cells-per-patient boxplot, cell abundance bar plots, dataset-vs-dataset comparisons (bars and paired boxplots)
scplotkit.markers rank_genes_groups dot/matrix plots, plus matrix and stacked-violin plots for your own marker gene sets
scplotkit.pseudobulk Per-sample pseudobulk boxplot for one gene, or several at once (optionally min-max scaled)
scplotkit.ridgeline Ridgeline (joy) plots of a continuous value across groups, with an optional per-condition overlay
scplotkit.enrichment Dot plot for over-representation analysis (ORA) results, e.g. from Enrichr/gseapy
scplotkit.sankey Sankeys, sunbursts, and treemaps over 1-3 nested annotation levels

Configuration

All styling (fonts, DPI, legend sizes) and any custom color palettes live in a PlotConfig:

from scplotkit import PlotConfig

config = PlotConfig.from_yaml("my_config.yml")
# or inline:
config = PlotConfig({
    "general": {"dpi_save": 400, "font_family": "Arial"},
    "palettes": {"cell_type": {"CD4 T": "#1f78b4", "CD8 T": "#33a02c"}},
})

plotter = spk.ScPlotter(config=config, output_dir="figures")

Categories without an explicit color are filled in automatically with a colorblind-friendly categorical palette, so you never need to enumerate every value up front.

Documentation & demonstrations

Full API reference and five demonstration notebooks (real-world examples, several parameter variations per plot) live in docs/ and are published at https://scplotkit.readthedocs.io. To build the docs locally:

pip install -e ".[docs]"
sphinx-build -b html docs docs/_build/html

Contributing

Got a plot you always end up making for single-cell (or spatial) data? Open a PR. No formal process here — just try to match the existing style (one function per plot, config/output_dir as the last two args, save via save_figure so it lands in the same place as everything else) and add it to __all__ and the table above. Bug reports and "this default looks bad" complaints are just as welcome as new plots.

pip install -e ".[dev]"
pytest
ruff check .

Citation

If you find scplotkit useful for your research, I'd appreciate a citation:

@software{Putze_scplotkit,
  author = {Putze, Philipp},
  title = {{scplotkit}},
  url = {https://github.com/philinscience/scplotkit},
  version = {0.1.0},
  year = {2026}
}

See CITATION.cff for the machine-readable version (GitHub also surfaces this via the "Cite this repository" button on the repo page).

License

MIT — see LICENSE.

About

single-cell plotting toolkit for single-cell atlas analysis, built on scanpy

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages