Metadata-Version: 2.4
Name: scplotkit
Version: 0.1.2
Summary: Publication-ready plotting toolkit for single-cell atlas analysis with scanpy
Project-URL: Homepage, https://github.com/philinscience/scplotkit
Project-URL: Documentation, https://scplotkit.readthedocs.io
Project-URL: Repository, https://github.com/philinscience/scplotkit
Project-URL: Issues, https://github.com/philinscience/scplotkit/issues
Author: scplotkit contributors
License: MIT
License-File: LICENSE
Keywords: anndata,bioinformatics,scanpy,single-cell,visualization
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
Classifier: Topic :: Scientific/Engineering :: Visualization
Requires-Python: >=3.10
Requires-Dist: anndata>=0.9
Requires-Dist: matplotlib>=3.7
Requires-Dist: numpy>=1.24
Requires-Dist: pandas>=1.5
Requires-Dist: pyyaml>=6.0
Requires-Dist: scanpy>=1.9
Requires-Dist: scipy>=1.10
Requires-Dist: seaborn>=0.12
Provides-Extra: dev
Requires-Dist: kaleido>=0.2; extra == 'dev'
Requires-Dist: plotly>=5.15; extra == 'dev'
Requires-Dist: pytest-cov>=4.1; extra == 'dev'
Requires-Dist: pytest>=7.4; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Provides-Extra: docs
Requires-Dist: myst-nb>=1.0; extra == 'docs'
Requires-Dist: sphinx-autodoc-typehints>=1.24; extra == 'docs'
Requires-Dist: sphinx-book-theme>=1.1; extra == 'docs'
Requires-Dist: sphinx>=7.0; extra == 'docs'
Provides-Extra: sankey
Requires-Dist: kaleido>=0.2; extra == 'sankey'
Requires-Dist: plotly>=5.15; extra == 'sankey'
Description-Content-Type: text/markdown

# scplotkit

<p align="center">
  <img src="docs/_static/logo.png" alt="scplotkit logo" width="220">
</p>

[![CI](https://github.com/philinscience/scplotkit/actions/workflows/ci.yml/badge.svg)](https://github.com/philinscience/scplotkit/actions/workflows/ci.yml)
[![Docs](https://github.com/philinscience/scplotkit/actions/workflows/docs.yml/badge.svg)](https://scplotkit.readthedocs.io)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![Python](https://img.shields.io/badge/python-3.10%2B-blue.svg)](pyproject.toml)

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](https://scanpy.readthedocs.io) and
[AnnData](https://anndata.readthedocs.io) — 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](#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

```bash
pip install scplotkit

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

Or from source:

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

## Quickstart

```python
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:

```python
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`:

```python
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/`](docs/) and are published at https://scplotkit.readthedocs.io. To build the docs
locally:

```bash
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.

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

## Citation

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

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

See [`CITATION.cff`](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](LICENSE).
