Skip to main content

Cellestial

GitHub PyPI codecov License: Apache 2.0 Powered by Polars Graphics: Lets-Plot DOI

Cellestial Logo

The Grammar of Graphics for single-cell omics.

Cellestial is an interactive and a highly customizable Single-Cell & Spatial omics data visualization library. Built on top Lets-Plot, it offers a ggplot-like layered and modular approach offering high customizability and publication-ready figures.

Cellestial is highly integrated with scverse's AnnData with room for integration with any upcoming single-cell omics data type in the Python single-cell omics ecosystem.

Cellestial leverages the performance of Polars ensuring speed and scalability.

Installation

pip install cellestial
uv add cellestial
poetry add cellestial

Quickstart

Cellestial accepts a standard AnnData directly. The same function plots a categorical column or a gene, and everything composes through + like ggplot.

from lets_plot import *
import cellestial as cl

data = cl.datasets.pbmc3k(cache_directory="data")

cl.umap(
    data,
    key="cell_type_lvl1",
    axis_type="arrow",
    legend_ondata=True,
) + scale_color_hue()

UMAP coloured by cell type

Examples

Spatial omics

Overlay categorical labels or gene expression on tissue coordinates.

Show code
import squidpy as sq

lymph_node = cl.datasets.human_lymph_node(cache_directory="data")
hne = sq.datasets.visium_hne_adata()

gggrid(
    [
        cl.spatial(lymph_node, key="clusters"),
        cl.spatial(hne, key="leiden"),
    ],
    ncol=2,
) + ggsize(1000, 400)

Spatial categorical overlay

Dimensionality reduction with layers

Cellestial ships single-cell-specific layers (cluster_outlines, stream, arrow_axis, ondata_legend) that compose with + like any geom.

Show code
velocity_data = cl.datasets.pancreas(cache_directory="data")

outlined = cl.umap(
    data,
    key="cell_type_lvl1",
    axis_type="arrow",
    size=1.5,
    legend_ondata=True,
) + scale_color_hue() + cl.cluster_outlines(groups=["Lymphocytes", "B Cells"])

streamed = cl.umap(
    velocity_data,
    key="clusters_coarse",
    axis_type="arrow",
    size=4,
    alpha=0.4,
    legend_ondata=True,
    ondata_color="black",
) + cl.stream()

gggrid([outlined, streamed])

UMAP with cluster outlines and velocity stream

Marker genes

Heatmaps, dotplots, matrixplots and stacked violins share the same call shape and ship with built-in dendrograms and group bars.

Show code
markers = [
    "PSAP", "LYZ", "CST3",          # Monocytes
    "CD79A", "CD79B",                # B cells
    "IL7R", "CD3D", "CD3E", "CD4",   # T cells (CD4+)
    "CD8A", "CD8B",                  # T cells (CD8+)
    "NKG7", "GNLY", "KLRD1",         # NK cells
    "HLA-DRA", "FCER1A",             # Dendritic cells
]

cl.heatmap(
    data,
    group_by="cell_type_lvl1",
    keys=markers,
    geom="raster",
    group_lines_size=0.5,
    group_lines_color="white",
    group_bars=True,
    group_bars_labels=True,
    dendrogram=True,
    dendrogram_size=1,
) + scale_fill_viridis()

Marker gene heatmap

Statistical comparisons

cl.bracket runs pairwise tests on a cl.boxplot or cl.violin and draws annotated significance brackets.

Show code
cl.boxplot(
    data,
    key="CD3D",
    fill="cell_type_lvl1",
    threshold=0.1,
) + scale_fill_hue() + cl.bracket(
    y_padding=0.2,
    label="pvalue",
    prefix="p",
    prefix_style="<",
    comparisons=[
        ("Lymphocytes", "Monocytes"),
        ("Monocytes", "Erythroid"),
        ("Monocytes", "B Cells"),
    ],
)

Boxplot with significance brackets

Ridge plots

Quick exploratory views of expression distributions across groups.

Show code
cl.ridge(
    data,
    key="B2M",
    alpha=0.6,
    group_by="cell_type_lvl1",
) + scale_fill_hue()

Ridge plot of B2M expression

Migrating from Scanpy

Cellestial mirrors most of scanpy.pl with a few naming shifts:

  • color= becomes key=.
  • Multi-panel calls use a plural function (cl.umaps, cl.violins, ...).
  • groupby becomes group_by, var_names becomes keys.
  • Saving is a separate cl.save(plot, "umap.png") call.

See the migration guide for a side-by-side mapping.

Documentation

Citation

If you use Cellestial, please cite:

@misc{https://doi.org/10.5281/zenodo.21710312,
  doi = {10.5281/ZENODO.21710312},
  url = {https://zenodo.org/doi/10.5281/zenodo.21710312},
  author = {Kosar, Zafer},
  title = {Cellestial: A grammar of graphics for single-cell omics},
  publisher = {Zenodo},
  year = {2026},
  copyright = {Apache License 2.0}
}

License

Apache 2.0. See LICENSE.

Download files

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

Source Distribution

cellestial-0.58.2.tar.gz (113.9 kB view details)

Uploaded Source

Built Distribution

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

cellestial-0.58.2-py3-none-any.whl (162.2 kB view details)

Uploaded Python 3

File details

Details for the file cellestial-0.58.2.tar.gz.

File metadata

  • Download URL: cellestial-0.58.2.tar.gz
  • Upload date:
  • Size: 113.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.4.1 CPython/3.14.6 Darwin/25.6.0

File hashes

Hashes for cellestial-0.58.2.tar.gz
Algorithm Hash digest
SHA256 6b8acd8add188bbe1a04968e7bec4e93786e2d75f704de254eb68e9d90e3b302
MD5 bafee387591b6324d160f7ab64ca4b7a
BLAKE2b-256 86cd8a2ace4f80c869aa2d174c04f902233ff3de1b78f2e59b8864dd9d93a909

See more details on using hashes here.

File details

Details for the file cellestial-0.58.2-py3-none-any.whl.

File metadata

  • Download URL: cellestial-0.58.2-py3-none-any.whl
  • Upload date:
  • Size: 162.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.4.1 CPython/3.14.6 Darwin/25.6.0

File hashes

Hashes for cellestial-0.58.2-py3-none-any.whl
Algorithm Hash digest
SHA256 3a26582c914f2094bde43fbd9dcf9c2f45f375fdc101331286ea79c6ed17e379
MD5 7416f52b90bdc0670c86eca0441582c0
BLAKE2b-256 046bec0c39482dd2b11d950722e2deff25b2656224d9f0864c8bf1f2a0e23d9e

See more details on using hashes here.

Release history Release notifications | RSS feed

0.60.0

2 files

0.59.0

2 files

This release

0.58.2 This release

2 files

0.58.1

2 files

0.58.0

2 files

0.57.1

2 files

0.57.0

2 files

0.55.0

2 files

0.53.1

2 files

0.53.0

2 files

0.52.0

2 files

0.51.0

2 files

0.50.1

2 files

0.49.3

2 files

0.49.2

2 files

0.49.1

2 files

0.49.0

2 files

0.48.4

2 files

0.48.3

2 files

0.48.2

2 files

0.48.1

2 files

0.48.0

2 files

0.47.1

2 files

0.47.0

2 files

0.46.0

2 files

0.45.0

2 files

0.44.0

2 files

0.43.0

2 files

0.42.0

2 files

0.41.0

2 files

0.40.0

2 files

0.39.0

2 files

0.33.0

2 files

0.32.0

2 files

0.30.0

2 files

0.20.0

2 files

0.14.0

2 files

0.13.1

2 files

0.13.0

2 files

0.12.0

2 files

0.11.0

2 files

0.10.4

2 files

0.10.3

2 files

0.10.2

2 files

0.10.1

2 files

0.10.0

2 files

0.8.0

2 files

0.7.1

2 files

0.7.0

2 files

0.5.1

2 files

0.5.0

2 files

0.4.0

2 files

0.3.3

2 files

0.3.2

2 files

0.3.1

2 files

0.3.0

2 files

0.2.0

2 files

0.1.4

2 files

0.1.3

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Supported by

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