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.

Metadata

Release files for cellestial 0.60.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 cellestial 0.60.0
File Size Uploaded
cellestial-0.60.0.tar.gz 120.8 kB Details

Built distribution (wheel)

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

Total release size: 291.8 kB

Release files / cellestial-0.60.0.tar.gz

Download URL cellestial-0.60.0.tar.gz
Size 120.8 kB
Tags Source
SHA-256 checksum
How to use checksums
b18e43d7ba9f0ff7713556400f8fa092c311587d990c94b7c4fe5294a7cec4a5
BLAKE2b-256 checksum
How to use checksums
920ef93571f8ebce8937b7f00b0b8d3416cd975260e0dc0d8f0f0223c5a8f72e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.4.1 CPython/3.14.6 Darwin/25.6.0

Release files / cellestial-0.60.0-py3-none-any.whl

Download URL cellestial-0.60.0-py3-none-any.whl
Size 171.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6362eb2da52838a54a55c176c2bbe50ee89d8e981385dfc763b11ec977749c95
BLAKE2b-256 checksum
How to use checksums
dfb63d6e23e8abc0db4e82654ce01c826db98399b44236c73be640d67e8cd11f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.4.1 CPython/3.14.6 Darwin/25.6.0

Release history Release notifications | RSS feed

This release

0.60.0 This release

2 release files

0.58.1

2 release files

0.58.0

2 release files

0.57.1

2 release files

0.55.0

2 release files

0.51.0

2 release files

0.50.1

2 release files

0.49.3

2 release files

0.49.2

2 release files

0.49.1

2 release files

0.49.0

2 release files

0.48.4

2 release files

0.48.3

2 release files

0.48.2

2 release files

0.48.1

2 release files

0.48.0

2 release files

0.47.1

2 release files

0.47.0

2 release files

0.46.0

2 release files

0.45.0

2 release files

0.44.0

2 release files

0.43.0

2 release files

0.42.0

2 release files

0.41.0

2 release files

0.40.0

2 release files

0.32.0

2 release files

0.30.0

2 release files

0.20.0

2 release files

0.14.0

2 release files

0.13.0

2 release files

0.12.0

2 release files

0.11.0

2 release files

0.10.4

2 release files

0.10.3

2 release files

0.10.2

2 release files

0.10.1

2 release files

0.10.0

2 release files

0.8.0

2 release files

0.7.1

2 release files

0.7.0

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

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