| """Phase portrait plotting (unspliced vs spliced colored by gamma).""" |
|
|
| from __future__ import annotations |
|
|
| from typing import Sequence |
|
|
| import matplotlib.pyplot as plt |
| import numpy as np |
| from anndata import AnnData |
|
|
| from .._constants import SMOOTHED_UNSPLICED, SMOOTHED_SPLICED, GAMMA |
| from .._utils import get_layer, require_layers |
| from ._utils import setup_axes, save_or_show |
|
|
|
|
| def phase_portrait( |
| adata: AnnData, |
| genes: str | Sequence[str], |
| color_by: str = GAMMA, |
| ncols: int = 3, |
| figsize_per: tuple[float, float] = (4, 3.5), |
| cmap: str = "viridis", |
| save: str | None = None, |
| show: bool = True, |
| ax: plt.Axes | None = None, |
| ) -> plt.Figure | None: |
| """Plot phase portrait (unspliced vs spliced) colored by gamma. |
| |
| Parameters |
| ---------- |
| adata |
| Annotated data matrix. |
| genes |
| Gene name(s) to plot. |
| color_by |
| Layer to use for coloring. Default ``'gamma'``. |
| ncols |
| Number of columns in multi-gene grid. |
| figsize_per |
| Size per subplot panel. |
| cmap |
| Colormap name. |
| save |
| Path to save figure. |
| show |
| Whether to display the figure. |
| ax |
| Pre-existing axes (only for single gene). |
| """ |
| require_layers(adata, SMOOTHED_UNSPLICED, SMOOTHED_SPLICED) |
|
|
| if isinstance(genes, str): |
| genes = [genes] |
|
|
| u = get_layer(adata, SMOOTHED_UNSPLICED) |
| s = get_layer(adata, SMOOTHED_SPLICED) |
|
|
| if color_by in adata.layers: |
| colors = get_layer(adata, color_by) |
| else: |
| colors = None |
|
|
| n_genes = len(genes) |
|
|
| if n_genes == 1 and ax is not None: |
| fig, ax = setup_axes(ax) |
| axes_list = [ax] |
| else: |
| nrows = (n_genes + ncols - 1) // ncols |
| fig, axes = plt.subplots( |
| nrows, ncols, |
| figsize=(figsize_per[0] * ncols, figsize_per[1] * nrows), |
| squeeze=False, |
| ) |
| axes_list = axes.ravel().tolist() |
|
|
| gene_names = adata.var_names.tolist() |
|
|
| for i, gene in enumerate(genes): |
| if gene not in gene_names: |
| continue |
| gi = gene_names.index(gene) |
| ax_i = axes_list[i] |
|
|
| c = colors[:, gi] if colors is not None else None |
| sc = ax_i.scatter( |
| s[:, gi], u[:, gi], |
| c=c, cmap=cmap, s=3, alpha=0.6, rasterized=True, |
| ) |
| ax_i.set_xlabel("Spliced (Ms)") |
| ax_i.set_ylabel("Unspliced (Mu)") |
| ax_i.set_title(gene) |
| if c is not None: |
| plt.colorbar(sc, ax=ax_i, label=color_by) |
|
|
| |
| for j in range(n_genes, len(axes_list)): |
| axes_list[j].set_visible(False) |
|
|
| fig.tight_layout() |
| save_or_show(fig, save, show) |
| return fig if not show else None |
|
|