Skip to content

plot_scores

plot_scores

plot_scores(
    adata: AnnData,
    gene_sets: dict[str, list[str]],
    *,
    max_rank: int = 1500,
    chunk_size: int = 1000,
    n_jobs: int = -1,
    inplace: bool = True,
    clip_pct: float | tuple[float, float] | None = None,
    normalize: bool = False,
    prefix: str = "score-",
    suffix: str = "",
    method: str | Callable[..., NDArray] | None = None,
    colors: list[tuple[float, float, float]] | None = None,
    n_components: int = 3,
    component_prefix: str | None = None,
    basis: str = "X_umap",
    interactive: bool = False,
    show: bool = True,
    **kwargs: object,
) -> tuple[
    DataFrame, RGBResult, Axes | Figure | object | None
]

Score gene sets, map to RGB, and plot — all in one call.

This is a convenience wrapper around the 3-step pipeline: :func:score_gene_sets → :func:blend_to_rgb / :func:reduce_to_rgb → :func:plot_embedding / :func:plot_embedding_interactive.

Parameters:

Name Type Description Default
adata AnnData

Annotated data matrix (cells x genes) with a precomputed embedding in .obsm[basis].

required
gene_sets dict[str, list[str]]

Mapping of gene set names to lists of gene symbols.

required
max_rank int

Rank cap passed to pyUCell.

1500
chunk_size int

Number of cells processed per batch.

1000
n_jobs int

Parallelism (-1 = all cores).

-1
inplace bool

If True, scores are stored in adata.obs.

True
clip_pct float | tuple[float, float] | None

Percentile clipping — see :func:score_gene_sets.

None
normalize bool

Min-max rescaling — see :func:score_gene_sets.

False
prefix str

Column name prefix for score columns (default "score-"). Forwarded to scoring, color mapping, and interactive plotting.

'score-'
suffix str

Column name suffix for score columns (default ""). Forwarded to scoring, color mapping, and interactive plotting.

''
method str | Callable[..., NDArray] | None

Color-mapping method. None (default) auto-selects: "blend" for ≤ 3 gene sets, "pca" for > 3. Pass "blend" explicitly to force multiplicative blending, any string/callable for reduction.

None
colors list[tuple[float, float, float]] | None

Base colours for :func:blend_to_rgb.

None
n_components int

Number of components for reduction (max 3).

3
component_prefix str | None

Label prefix for reduction legend axes.

None
basis str

Full obsm key for the embedding (e.g. "X_umap").

'X_umap'
interactive bool

If True, use :func:plot_embedding_interactive (requires plotly).

False
show bool

If True (default), display the plot.

True
**kwargs object

Extra keyword arguments forwarded to the plotting function or reducer as appropriate.

{}

Returns:

Type Description
tuple[DataFrame, RGBResult, Axes | Figure | None]

(scores, rgb, plot_result) — the score DataFrame, the :class:RGBResult, and the plot return value (Axes, Plotly Figure, or None).

Source code in src/multiscoresplot/_pipeline.py
def plot_scores(
    adata: AnnData,
    gene_sets: dict[str, list[str]],
    *,
    # scoring
    max_rank: int = 1500,
    chunk_size: int = 1000,
    n_jobs: int = -1,
    inplace: bool = True,
    clip_pct: float | tuple[float, float] | None = None,
    normalize: bool = False,
    # prefix/suffix
    prefix: str = "score-",
    suffix: str = "",
    # color mapping
    method: str | Callable[..., NDArray] | None = None,
    colors: list[tuple[float, float, float]] | None = None,
    n_components: int = 3,
    component_prefix: str | None = None,
    # plotting
    basis: str = "X_umap",
    interactive: bool = False,
    show: bool = True,
    **kwargs: object,
) -> tuple[DataFrame, RGBResult, Axes | Figure | object | None]:
    """Score gene sets, map to RGB, and plot — all in one call.

    This is a convenience wrapper around the 3-step pipeline:
    :func:`score_gene_sets` → :func:`blend_to_rgb` / :func:`reduce_to_rgb`
    → :func:`plot_embedding` / :func:`plot_embedding_interactive`.

    Parameters
    ----------
    adata
        Annotated data matrix (cells x genes) with a precomputed embedding
        in ``.obsm[basis]``.
    gene_sets
        Mapping of gene set names to lists of gene symbols.
    max_rank
        Rank cap passed to pyUCell.
    chunk_size
        Number of cells processed per batch.
    n_jobs
        Parallelism (``-1`` = all cores).
    inplace
        If *True*, scores are stored in ``adata.obs``.
    clip_pct
        Percentile clipping — see :func:`score_gene_sets`.
    normalize
        Min-max rescaling — see :func:`score_gene_sets`.
    prefix
        Column name prefix for score columns (default ``"score-"``).
        Forwarded to scoring, color mapping, and interactive plotting.
    suffix
        Column name suffix for score columns (default ``""``).
        Forwarded to scoring, color mapping, and interactive plotting.
    method
        Color-mapping method.  ``None`` (default) auto-selects: ``"blend"``
        for ≤ 3 gene sets, ``"pca"`` for > 3.  Pass ``"blend"`` explicitly
        to force multiplicative blending, any string/callable for reduction.
    colors
        Base colours for :func:`blend_to_rgb`.
    n_components
        Number of components for reduction (max 3).
    component_prefix
        Label prefix for reduction legend axes.
    basis
        Full obsm key for the embedding (e.g. ``"X_umap"``).
    interactive
        If *True*, use :func:`plot_embedding_interactive` (requires plotly).
    show
        If *True* (default), display the plot.
    **kwargs
        Extra keyword arguments forwarded to the plotting function or
        reducer as appropriate.

    Returns
    -------
    tuple[DataFrame, RGBResult, Axes | Figure | None]
        ``(scores, rgb, plot_result)`` — the score DataFrame, the
        :class:`RGBResult`, and the plot return value (``Axes``, Plotly
        ``Figure``, or ``None``).
    """
    from multiscoresplot._colorspace import blend_to_rgb, reduce_to_rgb
    from multiscoresplot._interactive import plot_embedding_interactive
    from multiscoresplot._plotting import plot_embedding
    from multiscoresplot._scoring import score_gene_sets

    # --- Step 1: Score ---
    scores = score_gene_sets(
        adata,
        gene_sets,
        max_rank=max_rank,
        chunk_size=chunk_size,
        n_jobs=n_jobs,
        inplace=inplace,
        clip_pct=clip_pct,
        normalize=normalize,
        prefix=prefix,
        suffix=suffix,
    )

    # --- Step 2: Map to RGB ---
    n_sets = len(gene_sets)

    # Split kwargs into plot vs reducer buckets
    plot_kwargs: dict[str, object] = {}
    reduce_kwargs: dict[str, object] = {}
    for key, val in kwargs.items():
        if key in _PLOT_PARAMS:
            plot_kwargs[key] = val
        else:
            reduce_kwargs[key] = val

    if method is None:
        method = "blend" if n_sets <= 3 else "pca"

    if method == "blend":
        rgb = blend_to_rgb(scores, colors=colors, prefix=prefix, suffix=suffix)
    else:
        rgb = reduce_to_rgb(
            scores,
            method=method,
            n_components=n_components,
            component_prefix=component_prefix,
            prefix=prefix,
            suffix=suffix,
            **reduce_kwargs,
        )

    # --- Step 3: Plot ---
    if interactive:
        plot_result = plot_embedding_interactive(
            adata,
            rgb,
            basis=basis,
            prefix=prefix,
            suffix=suffix,
            show=show,
            **plot_kwargs,  # type: ignore[arg-type]
        )
    else:
        plot_result = plot_embedding(
            adata,
            rgb,
            basis=basis,
            show=show,
            **plot_kwargs,  # type: ignore[arg-type]
        )

    return scores, rgb, plot_result