Skip to content

piaso.pl — plotting

Embeddings, dot plots and the other figure functions.

FunctionWhat it does
createCustomCmapFromHexCreate a custom colormap from a list of hex colors. This function converts a sequence of hex colors into an RGB-based colormap that can be used for visualizations in Matplotlib.
dotplotPlot a dotplot of feature expression across cell groups.
embeddingPlot a 2-D embedding colored by a cell annotation or continuous value.
heatmapPlot an expression heatmap.
plot_dendrogramPlot a dendrogram of cell groups based on expression similarity.
plot_embeddings_splitPlot cell embeddings side by side based on a categorical variable.
plot_features_violinPlots a violin plot for each feature specified in feature_list.
plot_group_metricsPlot the per-group metrics DataFrame from :func:piaso.pp.calculateGroupMetrics.
plotConfusionMatrixPlot a normalized and reordered confusion matrix from clustering results.
plotDendrogramPlot a dendrogram of cell groups based on expression similarity.
plotDotplotPlot a dotplot of feature expression across cell groups.
plotEmbeddingPlot a 2-D embedding colored by a cell annotation or continuous value.
plotEmbeddingsSplitPlot cell embeddings side by side based on a categorical variable.
plotFeaturesViolinPlots a violin plot for each feature specified in feature_list.
plotGroupMetricsPlot the per-group metrics DataFrame from :func:piaso.pp.calculateGroupMetrics.
plotHeatmapPlot an expression heatmap.
plotLigandReceptorInteractionGenerates plots with a bar plot of top interactions and a heatmap showing ligand and receptor specificity, with an option for vertical orientation.
plotLigandReceptorLollipopGenerates advanced bidirectional lollipop plots for one or more cell-type interactions with support for both vertical and horizontal layouts.
plotSankeyPlot a Sankey (alluvial) diagram between two categorical columns.
plotScatterScatter plot of two features colored by a third variable.
plotUMAPConvenience wrapper for :func:plotEmbedding with basis='X_umap'.
sankeyPlot a Sankey (alluvial) diagram between two categorical columns.
scatterScatter plot of two features colored by a third variable.
split_embeddingPlot cell embeddings side by side based on a categorical variable.
stacked_barplotPlot a stacked barplot of cell composition.
stackedBarplotPlot a stacked barplot of cell composition.
umapConvenience wrapper for :func:plotEmbedding with basis='X_umap'.
violinPlots a violin plot for each feature specified in feature_list.

createCustomCmapFromHex

createCustomCmapFromHex(hex_colors)
Signature defaults

hex_colors

Create a custom colormap from a list of hex colors. This function converts a sequence of hex colors into an RGB-based colormap that can be used for visualizations in Matplotlib.

Parameters

hex_colors — list of str

A list of color codes in hexadecimal format (e.g., ['#faefef', '#e8aebc', '#d96998', '#b1257a', '#572266']).

Returns

LinearSegmentedColormap

A Matplotlib LinearSegmentedColormap object that can be applied to plots using the cmap parameter.

Example

>>> import matplotlib.pyplot as plt
>>> import numpy as np
>>> import piaso
>>> # Define custom hex colors
>>> hex_colors = ['#faefef', '#e8aebc', '#d96998', '#b1257a', '#572266']
>>>
>>> # Create the colormap
>>> c_color4 = piaso.pl.color.createCustomCmapFromHex(hex_colors)
>>>
>>> # Generate a gradient to visualize the colormap
>>> gradient = np.linspace(0, 1, 256).reshape(1, -1)
>>>
>>> # Display the colormap
>>> plt.figure(figsize=(6, 1))
>>> plt.imshow(gradient, aspect="auto", cmap=c_color4)
>>> plt.axis("off")
>>> plt.show()

dotplot

dotplot(
data,
features: list,
groupby: str = 'leiden',
layer: Optional[str] = None,
use_raw: Optional[bool] = None,
expression_cutoff: float = 0.0,
mean_only_expressed: bool = False,
standard_scale: Optional[str] = None,
log: bool = False,
cmap: str = 'Spectral_r',
dot_max: Optional[float] = None,
dot_min: float = 0,
size_scale: float = 200,
figsize: Optional[tuple] = None,
square: bool = True,
categories_order: Optional[list] = None,
var_names_order: Optional[list] = None,
var_group_labels: Optional[list] = None,
var_group_positions: Optional[list] = None,
dendrogram: bool = False,
dendro_method: str = 'ward',
use_rep: Optional[str] = None,
swap_axes: bool = False,
title: Optional[str] = None,
fontsize: Optional[float] = None,
grid: bool = False,
show_border: bool = True,
edgecolor: str = 'none',
show: bool = True,
save: Optional[str] = None,
ax: Optional[matplotlib.axes._axes.Axes] = None,
return_fig: bool = False,
palette=None,
modality: Optional[str] = None,
cytome_layer: str = 'counts',
compute_on_fly: bool = True,
use_cached_stats: bool = True,
)
Signature defaults

data, features, groupby='leiden', layer=None, use_raw=None, expression_cutoff=0.0, mean_only_expressed=False, standard_scale=None, log=False, cmap='Spectral_r', dot_max=None, dot_min=0, size_scale=200, figsize=None, square=True, categories_order=None, var_names_order=None, var_group_labels=None, var_group_positions=None, dendrogram=False, dendro_method='ward', use_rep=None, swap_axes=False, title=None, fontsize=None, grid=False, show_border=True, edgecolor='none', show=True, save=None, ax=None, return_fig=False, palette=None, modality=None, cytome_layer='counts', compute_on_fly=True, use_cached_stats=True

Plot a dotplot of feature expression across cell groups.

Parameters

data — AnnData or cytome Dataset/path

Input data.

features — list, dict, or DataFrame

Feature names. A plain list of strings, a dict mapping group labels to gene lists ({'Excitatory': ['Slc17a7', 'Satb2'], ...}), or a DataFrame with 'group' and 'gene'/'feature' columns. When a dict or DataFrame is provided, var_group_labels and var_group_positions are inferred automatically.

groupby — str

Column in obs/cells for grouping.

layer — str, optional

AnnData layer. Ignored for cytome.

use_raw — bool, optional

Use raw attribute. Ignored for cytome.

expression_cutoff — float

Threshold for “expressing” (default 0).

mean_only_expressed — bool

Compute mean over expressing cells only.

standard_scale — str, optional

Min-max standardise the colour (mean expression) to [0, 1] (scanpy semantics): 'var' per gene (column), 'group' per group (row), or None for raw means. (Previously z-scored, which produced negative values — now min-max, so the colour bar is always [0, 1].)

log — bool

Log1p transform expression values.

cmap — str

Colormap for mean expression. Default 'Spectral_r' (changed from 'Reds'), which separates the middle of the range more strongly and matches the co-specificity heatmaps.

.. note:: 'Spectral_r' is a rainbow map and is not colourblind-safe — its red and green ends are hard to tell apart for the most common form of colour vision deficiency. For figures headed for a manuscript, pass a sequential map: cmap='Reds' (the previous default), 'magma_r' or 'viridis'. That also fits the data better when standard_scale is set, since the values are then 0–1 with no meaningful midpoint for a diverging map to mark.

dot_max — float, optional

Max dot size (fraction). Default: data max.

dot_min — float

Min dot size (fraction).

size_scale — float

Scaling factor for dot size.

figsize — tuple, optional

Auto-calculated if None.

square — bool, default True

Make every grid block a square (uniform per-cell sizing + ax.set_aspect('equal')) so the dots sit centered in square cells. False restores the legacy width∝features / height∝groups sizing.

categories_order — list, optional

Custom group ordering on Y axis.

var_names_order — list, optional

Custom gene ordering on X axis.

var_group_labels — list, optional

Labels for gene groups (displayed as brackets).

var_group_positions — list of tuple, optional

Start/end positions for gene group brackets, e.g. [(0,3), (4,7)].

dendrogram — bool

Show dendrogram on group axis.

dendro_method — str

Linkage method for dendrogram (default: ‘ward’).

use_rep — str, optional

Key in adata.obsm for computing dendrogram from cell embeddings (e.g. ‘X_gdr’, ‘X_svd’). If None, uses mean expression of features.

swap_axes — bool

Genes on Y, groups on X.

title — str, optional

Plot title.

grid — bool

Show light grid lines.

show_border — bool

Show outer border around the plot area (default: True).

edgecolor — str

Edge color for dots (default: ‘none’).

show — bool

Call plt.show().

save — str, optional

Save path.

ax — Axes, optional

Pre-existing axes.

return_fig — bool

Return (fig, ax) tuple.

palette

Not used for dotplot (color is continuous). Reserved for API consistency.

fontsize — float, optional

Base font size for labels; None follows the figure settings.

modality — str, optional

Cytome only: which modality the data was stored under ('RNA', 'ATAC', 'tiles', 'GA'). None takes the store’s first modality.

cytome_layer — str, default ‘counts’

Cytome only: the layer to read the values from.

compute_on_fly — bool, default True

Cytome only: normalise the raw layer while streaming (INFOG for RNA, TF-IDF for ATAC) instead of requiring a materialised layer.

use_cached_stats — bool, default True

Cytome only: reuse normalisation statistics already stored in the cytome’s metadata rather than recomputing them.

embedding

plotEmbedding(
data,
color='leiden',
basis='X_umap',
layer=None,
title=None,
figsize=None,
point_size=None,
alpha=1.0,
frameon=None,
save=None,
show=True,
ax=None,
palette=None,
legend_loc='right',
legend_fontsize=10,
legend_fontoutline=None,
legend_fontbackground='white',
legend_fontbackground_alpha=0.7,
legend_ncol=None,
rasterized=True,
dpi=None,
vmin=None,
vmax=None,
vmin_pct=None,
vmax_pct=None,
cmap=None,
show_axes_arrow=False,
axes_arrow_loc='bottom_left',
modality=None,
cytome_layer='counts',
compute_on_fly=True,
use_cached_stats=True,
show_modality_in_title=False,
ncol=None,
col_size=4.0,
row_size=4.0,
fix_coordinate_ratio=True,
show_axis_ticks=False,
x_min=None,
x_max=None,
y_min=None,
y_max=None,
legend_marker_size=None,
hspace=None,
wspace=None,
groups=None,
na_color='lightgray',
na_label='other',
image=False,
img_key='hires',
image_alpha=1.0,
image_crop=True,
cell_mask=None,
return_fig=False,
linewidths: float = 0.0,
edgecolors='none',
**kwargs,
)
Signature defaults

data, color='leiden', basis='X_umap', layer=None, title=None, figsize=None, point_size=None, alpha=1.0, frameon=None, save=None, show=True, ax=None, palette=None, legend_loc='right', legend_fontsize=10, legend_fontoutline=None, legend_fontbackground='white', legend_fontbackground_alpha=0.7, legend_ncol=None, rasterized=True, dpi=None, vmin=None, vmax=None, vmin_pct=None, vmax_pct=None, cmap=None, show_axes_arrow=False, axes_arrow_loc='bottom_left', modality=None, cytome_layer='counts', compute_on_fly=True, use_cached_stats=True, show_modality_in_title=False, ncol=None, col_size=4.0, row_size=4.0, fix_coordinate_ratio=True, show_axis_ticks=False, x_min=None, x_max=None, y_min=None, y_max=None, legend_marker_size=None, hspace=None, wspace=None, groups=None, na_color='lightgray', na_label='other', image=False, img_key='hires', image_alpha=1.0, image_crop=True, cell_mask=None, return_fig=False, linewidths=0.0, edgecolors='none', **kwargs

Plot a 2-D embedding colored by a cell annotation or continuous value.

cell_mask : array-like, optional Plot only these cells: a boolean mask of length n_cells or integer indices. Applied after the coordinates and colour values are resolved, so both stay aligned — pairs with a cytome’s cells_in_region(x=, y=) for ROI views without writing a subset file. image : bool or str, default False Draw the library’s tissue image under the spots (basis='spatial' workflows). True auto-selects when exactly one library has an image (or the plotted cells span one) and raises naming the options otherwise; a string selects that library. Sources: AnnData uns['spatial'] or a cytome’s stored images (cytome ≥ 0.2.6). The y-axis follows the image convention (top of the tissue at the top) only when an image is drawn. img_key : str, default ‘hires’ Which image of the library to draw (‘hires’, ‘lowres’, …). image_alpha : float, default 1.0 Opacity of the tissue image. image_crop : bool, default True With an image, crop to the plotted cells’ bounding box padded by one spot diameter instead of showing the whole slide. Returns None by default — pass return_fig=True to get (fig, ax) back.

Supports both cytome.Dataset and AnnData objects.

Parameters

data

A cytome.Dataset or AnnData object.

color — str, list of str, ndarray, or pandas.Series

Column in cells / obs for colouring, or a feature name (gene, peak, tile, or GA gene — resolved via the cytome modality registry; pass modality= to disambiguate). A single str draws one panel; a list/tuple of strings draws a multi-panel grid (one panel per entry, scanpy sc.pl.umap-style).

May also be the values themselves — one per cell, in order — as a numpy array, a pandas Series, or a Categorical, for anything computed on the fly and not written back to the object. Numeric values get a colorbar, everything else a category legend; a Categorical’s own order is kept, and a named Series titles the panel. Note that a plain list/tuple still means multiple panels, so pass an array.

basis — str

Embedding key (e.g. 'X_umap', 'X_svd').

layer — str, optional

AnnData layer to read the feature value from when color is a feature name. If None, reads from adata.X.

title — str or list of str, optional

Plot title. Defaults to color. For a list color: a single string becomes a figure-level suptitle over the grid; a list of titles (length must match color) sets one title per panel.

figsize — tuple, optional

Figure size in inches. If None, uses rcParams['figure.figsize'] (set via piaso.settings.set_figure_params(figsize=...)).

point_size — float or None

Scatter point size. If None (default), automatically calculated from the number of cells: 22000 / n_cells clamped to [0.1, 3] (explicit value overrides).

alpha — float

Point transparency. Default 1.0 (opaque).

frameon — bool, optional

Whether to show axis frame (spines). None follows piaso.settings._frameon, which starts out False.

save — str, bool, or None

Figure save behavior:

  • None: don’t save.
  • Full path ('/path/to/fig.png'): save directly.
  • Suffix ('_leiden'): save to piaso.settings.figdir.
  • True: auto-name and save to piaso.settings.figdir.

show — bool

Whether to call plt.show().

ax — matplotlib Axes, optional

Pre-existing axes to draw on.

palette — list[str], optional

Color palette for categorical data. If None, checks adata.uns['{color}_colors'] first, then falls back to piaso.pl.color.d_color4.

groups — str or list of str, optional

For a categorical color: highlight only these category values — they keep their palette colour while all other cells are greyed out (drawn behind), like sc.pl.umap(groups=...). Palette indices come from the full category list, so colours match an unfiltered plot. Raises ValueError if a name is not among the categories.

The legend then lists the highlighted groups and one final entry for the grey — the colours on the plot, and nothing else.

na_color — str, default 'lightgray'

Colour for the greyed-out (non-groups) cells.

na_label — str, default 'other'

Legend label for that colour. Only appears when groups actually left something out.

legend_loc — str, default 'right'

Where to put the category labels. One of:

  • 'right' — legend box outside the axes, in the right margin.
  • 'on_data' — labels drawn at each category’s centroid.
  • 'both' — centroid labels and the right-margin legend, so you can name a cluster where the points are and still read its colour off the list. Neither alone does both jobs.
  • 'none' — no legend.

Any other value raises ValueError rather than silently drawing nothing.

legend_fontsize — int

Font size for legend labels.

legend_fontoutline — float or None

Width of text outline for legend_loc='on_data' labels.

legend_fontbackground — str or None, default 'white'

Colour of the patch drawn behind each 'on_data' label. None draws the text with no background. The default is readable over a cluster and invisible over the figure background, which is where a small or sparse cluster’s label ends up — pass a tinted colour ('0.9', '#fffbe6') when labels need to read in both places.

legend_fontbackground_alpha — float, default 0.7

Opacity of that patch. Raise it towards 1.0 to hide the points underneath a label; lower it to let them show through. Adds a contrasting stroke around text for readability. If None (default), no outline is drawn.

legend_ncol — int, optional

Number of legend columns. If None, auto-calculated (~12 per column).

rasterized — bool

Rasterize scatter points for smaller vector files.

linewidths — float, optional (default 0)

Marker stroke width, in points. Zero by default. Matplotlib otherwise strokes every point at rcParams['patch.linewidth'] (1.0 pt) in edgecolors='face', which for cell-sized markers is most of the dot: point_size=0.2 is a disc 0.45 pt across inside a 1.0 pt stroke, so it draws 3.2x the size asked for, and under alpha < 1 the stroke and fill composite twice around the rim — ringed dots with a washed-out core, visible once a PDF is enlarged. Pass a positive value to outline markers deliberately.

Changed in 1.2.4: was matplotlib’s 1.0 pt default.

edgecolors — color or ‘none’, optional (default ‘none’)

Marker stroke colour. Only meaningful with linewidths > 0.

Changed in 1.2.4: was matplotlib’s 'face'.

dpi — int, optional

Display DPI. If None, uses rcParams['figure.dpi']. vmin, vmax : float Limits for continuous color scale. vmin_pct, vmax_pct : float, optional Percentile (0-100) used to derive vmin/vmax for continuous features when the explicit limit is not given — e.g. vmax_pct=99 clips the top 1% of cells so a few outliers don’t wash out the colour scale. None (default) = no percentile clipping. Ignored for categorical colours and overridden by an explicit vmin/vmax.

cmap

Colormap for continuous data.

show_axes_arrow — bool

Draw small coordinate arrows at a corner of the plot.

axes_arrow_loc — str

Position of axes arrow: 'bottom_left' or 'bottom_right'.

modality — str, optional

Cytome modality for feature lookup: 'RNA', 'GA', 'ATAC', 'tiles', or None for auto-detect. Auto-detect raises ValueError if the feature is in multiple modalities; pass an explicit string to disambiguate. Ignored for AnnData inputs.

cytome_layer — str, default 'counts'

Cytome matrix suffix to read; combined with modality to form {modality}_{cytome_layer}. Common values: 'counts', 'log1p', 'infog', 'tfidf'.

compute_on_fly — bool, default True

If the requested {modality}_{cytome_layer} matrix isn’t materialised in the cytome, compute the value per-feature on the fly from {modality}_counts using cached / freshly-computed params. Supported on-the-fly layers: 'log1p', 'infog', 'tfidf'. Set False for strict mode (raise on missing matrix).

use_cached_stats — bool, default True

Reuse per-modality cached params from ds.metadata (e.g. '{modality}_infog_params') when computing on the fly. Set False to ignore the cache and recompute.

show_modality_in_title — bool, default False

Append (modality) to the panel title when the colour was resolved through a cytome modality (e.g. 'Sox2 (RNA)'). Affects feature colours only — obs columns are unchanged.

ncol — int, optional

Columns in the multi-panel grid when color is a list. Defaults to ceil(sqrt(n_colors)). Aliased as ncols (scanpy convention). Ignored when color is a single string.

col_size — float, default 4.0

Per-panel width in inches when color is a list.

row_size — float, default 4.0

Per-panel height in inches when color is a list.

fix_coordinate_ratio — bool, default True

If True, sets ax.set_aspect('equal') so x and y axes are scaled equally — appropriate for UMAP / t-SNE / spatial coords where distances are meaningful. Set False to use 'auto' (let matplotlib stretch to fit the axes).

show_axis_ticks — bool, default False

Whether to display axis tick marks and labels. Off by default for embedding-style plots where coordinates are abstract. x_min, x_max, y_min, y_max : float, optional Custom axis limits. Each is independently optional; pass only the ones you want to override (others use the data range).

legend_marker_size — float, optional

Marker scale for the legend (categorical colours only). If None, auto-computed from point_size as max(3, 12 / point_size).

hspace — float, optional

Vertical spacing between rows of the multi-panel grid (only applies when color is a list). If None (default), uses 0.1 when show_axis_ticks=False and 0.25 when show_axis_ticks=True. Pass an explicit value to override (e.g. 0.05 for very tight, 0.4 for wide spacing).

wspace — float, optional

Horizontal spacing between columns of the multi-panel grid (only applies when color is a list). If None (default), uses 0.2. Override to tighten or widen.

color accepts str (single panel) OR list[str] / tuple[str] (one panel per entry, on a ncol-column grid). When a list is given together with ax, raises ValueError since a single axes can’t host a multi-panel grid.

image — bool or str, default False

Draw the tissue image behind spatial coordinates: True for the first library, a string for that library. Sources: AnnData uns['spatial'] or a cytome’s stored images.

img_key — str, default ‘hires’

Which image of the library to draw.

image_alpha — float, default 1.0

Opacity of the tissue image.

image_crop — bool, default True

Crop the image to the plotted coordinates.

cell_mask — ndarray, optional

Cytome only: plot these cells only (boolean mask or sorted indices).

return_fig — bool, default False

Return the figure instead of showing it.

Returns

fig, ax For single-color: (fig, ax) where ax is the matplotlib Axes that was drawn into. fig, axs For list-color: (fig, [ax0, ax1, ...]) — one Axes per entry in color; trailing empty grid cells are hidden via set_visible(False).

heatmap

heatmap(
data,
features: list,
groupby: str = 'leiden',
layer: Optional[str] = None,
use_raw: Optional[bool] = None,
standard_scale: Optional[str] = None,
log: bool = False,
cmap: str = 'viridis',
figsize: Optional[tuple] = None,
categories_order: Optional[list] = None,
var_names_order: Optional[list] = None,
dendrogram: bool = False,
swap_axes: bool = False,
title: Optional[str] = None,
show_values: bool = False,
fmt: str = '.2f',
vmin: Optional[float] = None,
vmax: Optional[float] = None,
cell_level: bool = False,
max_cells_per_group: int = 100,
show_group_colors: bool = True,
show: bool = True,
save: Optional[str] = None,
ax: Optional[matplotlib.axes._axes.Axes] = None,
return_fig: bool = False,
modality: Optional[str] = None,
cytome_layer: str = 'counts',
compute_on_fly: bool = True,
use_cached_stats: bool = True,
)
Signature defaults

data, features, groupby='leiden', layer=None, use_raw=None, standard_scale=None, log=False, cmap='viridis', figsize=None, categories_order=None, var_names_order=None, dendrogram=False, swap_axes=False, title=None, show_values=False, fmt='.2f', vmin=None, vmax=None, cell_level=False, max_cells_per_group=100, show_group_colors=True, show=True, save=None, ax=None, return_fig=False, modality=None, cytome_layer='counts', compute_on_fly=True, use_cached_stats=True

Plot an expression heatmap.

Two modes:

  • Group-level (default): mean expression per group (groups x features).
  • Cell-level (cell_level=True): per-cell expression with group-stratified sampling, up to max_cells_per_group cells per group.

Parameters

data — AnnData or cytome Dataset/path

Input data.

features — list, dict, or DataFrame

Feature names. A plain list of strings, a dict mapping group labels to gene lists, or a DataFrame with 'group' and 'gene'/'feature' columns. When dict/DataFrame, gene groups are shown as colored brackets (cell-level) or vertical separators (group-level).

groupby — str

Grouping column. layer, use_raw AnnData layer / raw attribute. Ignored for cytome.

standard_scale — str, optional

'var' to z-score per feature, 'group' per group.

log — bool

Log1p transform.

cmap — str

Colormap.

figsize — tuple, optional

Auto-calculated if None.

categories_order — list, optional

Custom group order.

var_names_order — list, optional

Custom feature order.

dendrogram — bool

Cluster groups by hierarchical clustering (group-level only).

swap_axes — bool

Transpose: features on Y, groups on X.

title — str, optional

Title.

show_values — bool

Annotate cells with values (group-level only).

fmt — str

Number format for annotations. vmin, vmax : float, optional Colorscale limits.

cell_level — bool

If True, show per-cell expression instead of group means.

max_cells_per_group — int

Maximum cells per group when cell_level=True. Default 100.

show_group_colors — bool

Show colored sidebar for groups when cell_level=True. show, save, ax, return_fig Output options.

modality — str, optional

Cytome only: which modality the data was stored under ('RNA', 'ATAC', 'tiles', 'GA'). None takes the store’s first modality.

cytome_layer — str, default ‘counts’

Cytome only: the layer to read the values from.

compute_on_fly — bool, default True

Cytome only: normalise the raw layer while streaming (INFOG for RNA, TF-IDF for ATAC) instead of requiring a materialised layer.

use_cached_stats — bool, default True

Cytome only: reuse normalisation statistics already stored in the cytome’s metadata rather than recomputing them.

plot_dendrogram

plot_dendrogram(
data,
groupby: str = 'leiden',
features: Optional[list] = None,
use_rep: Optional[str] = 'auto',
layer: Optional[str] = None,
use_raw: Optional[bool] = None,
n_top_genes: int = 50,
method: str = 'average',
metric: str = 'euclidean',
orientation: str = 'top',
palette=None,
figsize: Optional[tuple] = None,
title: Optional[str] = None,
show: bool = True,
save: Optional[str] = None,
ax: Optional[matplotlib.axes._axes.Axes] = None,
return_fig: bool = False,
return_linkage: bool = False,
modality: Optional[str] = None,
cytome_layer: str = 'counts',
compute_on_fly: bool = True,
use_cached_stats: bool = True,
)
Signature defaults

data, groupby='leiden', features=None, use_rep='auto', layer=None, use_raw=None, n_top_genes=50, method='average', metric='euclidean', orientation='top', palette=None, figsize=None, title=None, show=True, save=None, ax=None, return_fig=False, return_linkage=False, modality=None, cytome_layer='counts', compute_on_fly=True, use_cached_stats=True

Plot a dendrogram of cell groups based on expression similarity.

Parameters

data — AnnData or cytome Dataset/path

Input data.

groupby — str

Grouping column.

features — list, optional

Features to use for clustering (marker-gene mode). If None, uses highly variable genes or top-variance genes. Only consulted when use_rep is None or resolves to no embedding.

use_rep — str or None, default 'auto'

Build the group tree from per-group centroids of a cell embedding (the standard scanpy-style dendrogram), which is usually what you want.

  • 'auto' (default): use the first available embedding from X_gdr → X_pca → X_svd → X_diffmap → X_umap; if none exist, fall back to marker-gene expression similarity.
  • an explicit key (e.g. 'X_gdr', 'X_svd'): use that embedding.
  • None: marker-gene mode — cluster groups by similarity of their mean expression over features (or the top-n_top_genes variable genes / numeric cells columns). Use this when you specifically want the tree to reflect marker-gene programs rather than the global embedding geometry (e.g. comparing COSG top-n_top_genes markers). layer, use_raw AnnData layer / raw. Ignored for cytome.

n_top_genes — int

Number of top genes to use in marker-gene mode when features is None.

method — str

Linkage method ('average', 'ward', 'complete', 'single').

metric — str

Distance metric.

orientation — str

Dendrogram orientation: 'top', 'bottom', 'left', 'right'.

palette — list or dict, optional

Colors for leaf labels.

figsize — tuple, optional

Figure size.

title — str, optional

Title. show, save, ax, return_fig Output options.

return_linkage — bool

Also return the linkage matrix Z.

modality — str, optional

Cytome only: which modality the data was stored under ('RNA', 'ATAC', 'tiles', 'GA'). None takes the store’s first modality.

cytome_layer — str, default ‘counts’

Cytome only: the layer to read the values from.

compute_on_fly — bool, default True

Cytome only: normalise the raw layer while streaming (INFOG for RNA, TF-IDF for ATAC) instead of requiring a materialised layer.

use_cached_stats — bool, default True

Cytome only: reuse normalisation statistics already stored in the cytome’s metadata rather than recomputing them.

Returns

Optionally (fig, ax) and/or linkage matrix.

plot_embeddings_split

plot_embeddings_split(
data,
color,
splitby,
ncol: int = None,
dpi: int = 80,
col_size: int = 5,
row_size: int = 5,
alpha: float = 1.0,
vmax: float = None,
vmin: float = None,
vmin_pct: float = None,
vmax_pct: float = None,
show_figure: bool = True,
save: bool = None,
layer: str = None,
basis: str = 'X_umap',
fix_coordinate_ratio: bool = True,
show_axis_ticks: bool = False,
margin_ratio: float = 0.05,
legend_fontsize: int = 10,
legend_fontoutline: int = 2,
legend_fontbackground='white',
legend_fontbackground_alpha: float = 0.7,
legend_loc: str = 'right',
legend_marker_size: float = 6.0,
groups=None,
point_size: float = None,
palette=None,
cmap=None,
frameon: bool = False,
rasterized: bool = True,
modality: str = None,
cytome_layer: str = 'counts',
compute_on_fly: bool = True,
use_cached_stats: bool = True,
show_modality_in_title: bool = False,
x_min=None,
x_max=None,
y_min=None,
y_max=None,
image=False,
img_key='hires',
image_alpha=1.0,
linewidths: float = 0.0,
edgecolors='none',
**kwargs,
)
Signature defaults

data, color, splitby, ncol=None, dpi=80, col_size=5, row_size=5, alpha=1.0, vmax=None, vmin=None, vmin_pct=None, vmax_pct=None, show_figure=True, save=None, layer=None, basis='X_umap', fix_coordinate_ratio=True, show_axis_ticks=False, margin_ratio=0.05, legend_fontsize=10, legend_fontoutline=2, legend_fontbackground='white', legend_fontbackground_alpha=0.7, legend_loc='right', legend_marker_size=6.0, groups=None, point_size=None, palette=None, cmap=None, frameon=False, rasterized=True, modality=None, cytome_layer='counts', compute_on_fly=True, use_cached_stats=True, show_modality_in_title=False, x_min=None, x_max=None, y_min=None, y_max=None, image=False, img_key='hires', image_alpha=1.0, linewidths=0.0, edgecolors='none', **kwargs

Plot cell embeddings side by side based on a categorical variable.

The plots are split by a specified categorical variable, with each unique category producing a separate subplot. Data points in each subplot are colored according to the color variable.

Supports AnnData, cytome Dataset, or path to .cytome file.

Parameters

data — AnnData, cytome.Dataset, or str

An AnnData object, cytome Dataset, or path to .cytome file.

color — str

Used to specify a gene name to plot, or a key in adata.obs used to assign colors to the cells in the embedding plot.

splitby — str

Key in adata.obs used to split the dataset into multiple panels. Each unique value under this key will result in a separate subplot.

ncol — int or None, optional (default: None)

If specified, defines the number of columns per row. If None, the number of columns is computed as the ceiling of n divided by the integer square root of n.

dpi — int, optional (default: 80)

Dots per inch (DPI) setting for the figure.

col_size — int, optional (default=5)

Width (in inches) of each subplot column.

row_size — int, optional (default=5)

Height (in inches) of each subplot row.

vmax — float or None, optional (default=None)

Maximum value for the color scale. If not provided, the upper limit is determined automatically.

vmin — float or None, optional (default=None)

Minimum value for the color scale. If not provided, the lower limit is determined automatically.

show_figure — bool, optional (default=True)

Whether to display the figure after plotting.

save — str or None, optional (default=None)

File path to save the resulting figure. If None, the figure will not be saved.

layer — str or None, optional (default=None)

If specified, the name of the layer in adata.layers from which to obtain the gene expression values.

basis — str, optional (default=‘X_umap’)

Key in adata.obsm that contains the embedding coordinates (e.g., X_umap or X_pca).

fix_coordinate_ratio — bool, optional (default=True)

If True, the aspect ratio of each subplot is fixed so that the x- and y-axes are scaled equally.

show_axis_ticks — bool, optional (default=False)

Whether to display axis ticks and tick labels on the plots.

margin_ratio — float, optional (default=0.05)

Margin ratio for both the x-axis and y-axis limits, relative to the range of the data. This provides additional spacing around the plotted points.

legend_fontsize — int, optional (default=10)

Font size in pt.

legend_fontoutline — int, optional (default=2)

Line width of the legend font outline in pt.

legend_fontbackground — str or None, optional (default=‘white’)

Colour of the patch behind each 'on_data' label; None for no patch.

legend_fontbackground_alpha — float, optional (default=0.7)

Opacity of that patch.

legend_loc — str, optional (default=‘right’)

Where to put the category labels. One of:

  • 'right' — a single shared legend in the figure’s right margin.
  • 'on_data' — labels drawn at each cluster’s centroid, in every panel.
  • 'both' — centroid labels and the shared right-margin legend. Use this while you are still working out what a cluster is: the on-data label tells you which cluster you are looking at, the margin legend lets you read a colour off the list. Neither alone does both.
  • 'none' — no legend.

Any other value raises ValueError rather than silently drawing nothing.

legend_marker_size — float, optional (default=6.0)

Legend dot size. In the right-margin legend it is the marker scale (relative to the data points); in the global/multi-panel legend it is the absolute marker size in points. None auto-sizes from the data point_size (capped to avoid oversized dots on large datasets).

x_min — float or None, optional (default=None)

Minimum limit for the x-axis. If None, the limit is computed automatically based on the data.

x_max — float or None, optional (default=None)

Maximum limit for the x-axis. If None, the limit is computed automatically based on the data.

y_min — float or None, optional (default=None)

Minimum limit for the y-axis. If None, the limit is computed automatically based on the data.

y_max — float or None, optional (default=None)

Maximum limit for the y-axis. If None, the limit is computed automatically based on the data.

point_size — float, optional

Scatter point size. An explicit value always overrides the auto-size. If None, auto-scaled (max(0.1, min(3, 22000 / n_cells)), clamped to [0.1, 8]). Accepts size= as an alias for scanpy-style call sites.

palette — list[str] or dict, optional

Categorical palette. If None, falls back to adata.uns['{color}_colors'] (or the cytome metadata equivalent), then to the PIASO default d_color4. Mapping is held consistent across panels so the same category gets the same colour in every subplot.

cmap — str or Colormap, optional

Colourmap for numeric color values. Forwarded to each panel.

frameon — bool, optional (default False)

Whether to show axis spines on each panel and on the global legend frame. Mirrors piaso.pl.plotEmbedding(frameon=...).

rasterized — bool, optional (default True)

Forward to per-panel scatter for compact vector output.

linewidths — float, optional (default 0)

Marker stroke width, in points. Zero by default. Matplotlib otherwise strokes every point at rcParams['patch.linewidth'] (1.0 pt) in edgecolors='face', which for cell-sized markers is most of the dot: point_size=0.2 is a disc 0.45 pt across inside a 1.0 pt stroke, so it draws 3.2x the size asked for, and under alpha < 1 the stroke and fill composite twice around the rim — ringed dots with a washed-out core, visible once a PDF is enlarged. Pass a positive value to outline markers deliberately.

Changed in 1.2.4: was matplotlib’s 1.0 pt default.

edgecolors — color or ‘none’, optional (default ‘none’)

Marker stroke colour. Only meaningful with linewidths > 0.

Changed in 1.2.4: was matplotlib’s 'face'.

**kwargs — dict

Accepts the aliases ncols (→ ncol), size (→ point_size) and show (→ show_figure). Anything else raises TypeError.

Changed in 1.2.4: unrecognised keywords used to be accepted and silently discarded, so a caller styling the panels got no error and no effect — and show=False, which every other piaso.pl function understands, displayed the figure regardless.

image — bool or str, default False

Draw the library’s tissue image under the spots (basis='spatial' workflows). True auto-selects when exactly one library has an image (or the plotted cells span one) and raises naming the options otherwise; a string selects that library. Sources: AnnData uns['spatial'] or a cytome’s stored images (cytome ≥ 0.2.6). The y-axis follows the image convention (top of the tissue at the top) only when an image is drawn.

img_key — str, default ‘hires’

Which image of the library to draw (‘hires’, ‘lowres’, …).

image_alpha — float, default 1.0

Opacity of the tissue image.

alpha — float, default 1.0

Point opacity. vmin_pct, vmax_pct : float, optional Colour-scale limits as percentiles of the values, when vmin / vmax are not given.

groups — sequence of str, optional

Which groups of splitby to draw; all when None.

show_modality_in_title — bool, default False

Cytome only: prefix panel titles with the modality.

modality — str, optional

Cytome only: which modality the data was stored under ('RNA', 'ATAC', 'tiles', 'GA'). None takes the store’s first modality.

cytome_layer — str, default ‘counts’

Cytome only: the layer to read the values from.

compute_on_fly — bool, default True

Cytome only: normalise the raw layer while streaming (INFOG for RNA, TF-IDF for ATAC) instead of requiring a materialised layer.

use_cached_stats — bool, default True

Cytome only: reuse normalisation statistics already stored in the cytome’s metadata rather than recomputing them.

Returns

None.

Examples

>>> import anndata
>>> import piaso
>>> adata = anndata.read_h5ad('pbmc3k.h5ad') # Load an example dataset
>>> # Plot embeddings colored by a gene expression value and split by clusters
>>> piaso.pl.plot_embeddings_split(adata, color='CDK9', splitby='louvain', col_size=6, row_size=6)
>>> # Save the figure to a file
>>> piaso.pl.plot_embeddings_split(adata, color='CDK9', splitby='louvain', save='./CST3_embeddingsSplit.pdf')

plot_features_violin

plot_features_violin(
data,
feature_list,
groupby: Optional[str] = None,
use_raw: Optional[bool] = None,
layer: Optional[str] = None,
palette=None,
jitter: bool = False,
width_single: float = None,
height_single: float = 2.0,
ncol: Optional[int] = None,
violin_width: float = 0.7,
size: float = 0.1,
show_grid: bool = True,
show_median: bool = True,
median_color: str = 'lightgrey',
show_figure: bool = True,
save: Optional[str] = None,
modality: Optional[str] = None,
cytome_layer: str = 'counts',
compute_on_fly: bool = True,
use_cached_stats: bool = True,
show: Optional[bool] = None,
return_fig: bool = False,
)
Signature defaults

data, feature_list, groupby=None, use_raw=None, layer=None, palette=None, jitter=False, width_single=None, height_single=2.0, ncol=None, violin_width=0.7, size=0.1, show_grid=True, show_median=True, median_color='lightgrey', show_figure=True, save=None, modality=None, cytome_layer='counts', compute_on_fly=True, use_cached_stats=True, show=None, return_fig=False

Plots a violin plot for each feature specified in feature_list.

Uses matplotlib directly (no scanpy dependency). Supports AnnData and cytome Dataset / .cytome file path.

show is accepted as an alias for show_figure: every other plotting function in piaso.pl takes show, and a call that works for pl.embedding and pl.dotplot should not raise here for the sake of one function’s parameter name. When both are given, show wins.

Parameters

data — anndata.AnnData, cytome.Dataset, or str

The data source. For AnnData, reads from obs, layers, or raw. For cytome, reads from the cells SQL table.

feature_list — List[str]

Feature names to visualize. For cytome, these must be column names in the cells table.

groupby — str, optional

Column to group data points by. Default is None.

use_raw — bool, optional

Use raw attribute of adata. Ignored for cytome.

layer — str, optional

AnnData layer to use. Ignored for cytome.

palette — list or dict, optional

Color palette for groups. If None, checks adata.uns['{groupby}_colors'] first, then falls back to the default PIASO palette.

jitter — bool, optional

Show jitter scatter points on violins. Default is False.

width_single — float, optional

Figure width in inches. None (default) derives it from the number of groups — 1.6 + 0.42 * n_groups, clamped to [3, 16] — so a two-sample plot is not the same width as a forty-cluster one. Pass a number to override. Width of each subplot. Default is 14.0.

violin_width — float, optional

Width of each violin body in x-axis units, where 1.0 is the spacing between groups. Default 0.7.

ncol — int, optional

Panels per row. None (default) puts ungrouped features two to a row and grouped ones one to a row, since a grouped panel is already as wide as its group count requires.

height_single — float, optional

Height of each subplot. Default is 2.0.

size — float, optional

Jitter point size (only used when jitter=True). Default is 0.1.

show_grid — bool, optional

Show grid lines. Default is True.

show_median — bool, optional

Show median line on violins. Default is True.

median_color — str, optional

Color of the median line. Default is 'lightgrey'.

show_figure — bool, optional

Show figure (plt.show()). Default is True.

save — str, optional

Path to save the figure. Default is None.

return_fig — bool, optional

Return (fig, axes) instead of closing the figure.

show — bool, optional

Show the figure; None follows show_figure.

modality — str, optional

Cytome only: which modality the data was stored under ('RNA', 'ATAC', 'tiles', 'GA'). None takes the store’s first modality.

cytome_layer — str, default ‘counts’

Cytome only: the layer to read the values from.

compute_on_fly — bool, default True

Cytome only: normalise the raw layer while streaming (INFOG for RNA, TF-IDF for ATAC) instead of requiring a materialised layer.

use_cached_stats — bool, default True

Cytome only: reuse normalisation statistics already stored in the cytome’s metadata rather than recomputing them.

plot_group_metrics

plotGroupMetrics(
df,
data=None,
groupby: Optional[str] = None,
metrics: Optional[list] = None,
kind: str = 'bar',
palette=None,
ncol: Optional[int] = None,
figsize: Optional[tuple] = None,
normalize: str = 'minmax',
annotate: bool = True,
cmap: str = 'Blues',
fontsize: Optional[float] = None,
rotation: float = 45,
save: Optional[str] = None,
show: bool = True,
return_fig: bool = False,
)
Signature defaults

df, data=None, groupby=None, metrics=None, kind='bar', palette=None, ncol=None, figsize=None, normalize='minmax', annotate=True, cmap='Blues', fontsize=None, rotation=45, save=None, show=True, return_fig=False

Plot the per-group metrics DataFrame from :func:piaso.pp.calculateGroupMetrics.

Parameters

df — pandas.DataFrame

Output of calculateGroupMetrics (rows = groups, cols = metrics). data, groupby : optional Source dataset + grouping column, only used to re-resolve cell-type colours when the df doesn’t already carry them in df.attrs['colors'].

metrics — list of str, optional

Subset / order of metric columns to plot. Default: all numeric columns.

kind — 'bar' | 'heatmap'

'bar' (default): one panel per metric. 'heatmap': groups × metrics with per-column normalisation.

palette — dict or list, optional

Override group colours ({group: hex} or an ordered list).

ncol — int, optional

Columns in the faceted bar grid (default: ~sqrt(n_metrics)).

figsize — tuple, optional

Auto-sized if None.

normalize — 'minmax' | 'zscore' | None

Per-column scaling for the heatmap (ignored for bars).

annotate — bool, default True

Write the raw value in each heatmap cell.

cmap — str, default 'Blues'

Heatmap colormap.

fontsize — float, optional

Base font size (defaults to rcParams['font.size']).

rotation — float, default 45

Group-label rotation (anchored to the ticks so names don’t overlap). save, show, return_fig Output options.

plotConfusionMatrix

plotConfusionMatrix(
data,
groupby_query,
groupby_reference,
order_query=None,
order_reference=None,
normalize='query',
figsize=None,
square=True,
cmap='Purples',
annot=False,
fmt='.2f',
title=None,
save_path=None,
dpi=300,
return_objects=False,
show_group_color_bars=False,
**kwargs,
)
Signature defaults

data, groupby_query, groupby_reference, order_query=None, order_reference=None, normalize='query', figsize=None, square=True, cmap='Purples', annot=False, fmt='.2f', title=None, save_path=None, dpi=300, return_objects=False, show_group_color_bars=False, **kwargs

Plot a normalized and reordered confusion matrix from clustering results.

This function creates a confusion matrix heatmap with automatic reordering for better visualization of cluster relationships: a clustered order shared by both axes when they carry the same labels, and an SVD order otherwise. The matrix can be normalized in different ways and customized extensively.

Parameters: data (pandas.DataFrame or AnnData): DataFrame or AnnData object containing the data. If AnnData, will use data.obs for the analysis. groupby_query (str): Column name for the query labels (typically predicted clusters). groupby_reference (str): Column name for the reference labels (typically true labels). order_query, order_reference: how to order each axis. An explicit sequence of labels, None (keep the categorical order), or a strategy name: ‘auto’ (the default — one clustered order on both axes when the two label sets match, otherwise SVD on both, or barycentre for the free axis when the other is pinned), ‘svd’, ‘hclust’ (average linkage on that axis’s own profiles), or ‘hclust_symmetric’ (one clustered order on both axes; requires matching label sets). normalize (str): How to normalize the confusion matrix. Options: - ‘query’: normalize by query (row-wise) - default - ‘reference’: normalize by reference (column-wise)
- ‘all’: normalize by total count - None: no normalization figsize (tuple): Figure size for the plot. Default is (11.5, 10). cmap (str): Colormap for the heatmap. Default is ‘Purples’. annot (bool): Whether to show annotations in cells. Default is False. fmt (str): Format for annotations. Default is ‘.2f’. title (str): Custom title for the plot. If None, generates automatic title. save_path (str): Path to save the figure. If None, only displays. dpi (int): DPI for saved figure. Default is 300. return_objects (bool): If True, returns (confusion_matrix, fig, ax). Default is False. show_group_color_bars (bool): If True, shows colored bars next to ticks for categories that have colors defined in adata.uns (e.g., ‘CellTypes_colors’). Default is False. figsize (tuple, optional): Figure size. None (default) derives it from the matrix shape so the cells come out square, which is what makes a confusion matrix readable: an off-diagonal block is judged by area, and a fixed 11.5x10 stretched a 30x6 matrix into cells five times wider than tall. square (bool): Force square cells (default True). Set False to let the heatmap fill whatever figsize is given. **kwargs: Additional arguments passed to sns.heatmap()

Returns: None (default) or tuple: If return_objects=True, returns (reordered_confusion_matrix, fig, ax) for further customization

Examples: Basic usage with AnnData object: >>> import anndata >>> import pandas as pd >>> # Load your data >>> adata = anndata.read_h5ad(‘your_data.h5ad’) >>> # Plot confusion matrix between cell types and Leiden clusters >>> plotConfusionMatrix(adata, groupby_query=‘CellTypes’, groupby_reference=‘Leiden’)

Using a pandas DataFrame:
>>> df = pd.DataFrame({
... 'CellTypes': ['T_cell', 'B_cell', 'Monocyte', 'T_cell', 'B_cell'],
... 'Leiden': ['0', '1', '2', '0', '1']
... })
>>> plotConfusionMatrix(df, groupby_query='CellTypes', groupby_reference='Leiden')
Different normalization methods:
>>> # Normalize by reference (column-wise)
>>> plotConfusionMatrix(adata, groupby_query='CellTypes', groupby_reference='Leiden',
... normalize='reference')
>>>
>>> # No normalization, show raw counts
>>> plotConfusionMatrix(adata, groupby_query='CellTypes', groupby_reference='Leiden',
... normalize=None)
>>>
>>> # Normalize by total count
>>> plotConfusionMatrix(adata, groupby_query='CellTypes', groupby_reference='Leiden',
... normalize='all')
Customization options:
>>> # Custom colors and show detailed values
>>> plotConfusionMatrix(adata, groupby_query='CellTypes', groupby_reference='Leiden',
... cmap='viridis', annot=True)
>>>
>>> # Custom figure size and save to file
>>> plotConfusionMatrix(adata, groupby_query='CellTypes', groupby_reference='Leiden',
... figsize=(15, 12),
... save_path='confusion_matrix.png',
... title='Cell Types vs Leiden Clusters')
Show detailed values in the plot:
>>> # Display percentage values in each cell
>>> plotConfusionMatrix(adata, groupby_query='CellTypes', groupby_reference='Leiden',
... annot=True, fmt='.1%')
>>>
>>> # Display raw counts (with no normalization)
>>> plotConfusionMatrix(adata, groupby_query='CellTypes', groupby_reference='Leiden',
... normalize=None, annot=True, fmt='d')
Show color bars for categories:
>>> # Display colored bars next to ticks (requires colors in adata.uns)
>>> plotConfusionMatrix(adata, groupby_query='CellTypes', groupby_reference='Leiden',
... show_group_color_bars=True)
>>> # This will look for 'CellTypes_colors' and 'Leiden_colors' in adata.uns
Advanced usage - getting results for further analysis:
>>> conf_matrix, fig, ax = plotConfusionMatrix(adata,
... groupby_query='CellTypes',
... groupby_reference='Leiden',
... return_objects=True)
>>> # Access the reordered confusion matrix
>>> print(conf_matrix.head())
>>> # Further customize the plot
>>> ax.set_title('Custom Title', fontsize=16)
>>> plt.show()
Using with different data sources:
>>> # From Seurat object converted to pandas
>>> seurat_df = pd.read_csv('seurat_metadata.csv')
>>> plotConfusionMatrix(seurat_df, groupby_query='CellTypes', groupby_reference='Leiden')
>>>
>>> # From flow cytometry data
>>> flow_df = pd.read_csv('flow_cytometry_results.csv')
>>> plotConfusionMatrix(flow_df, groupby_query='CellTypes', groupby_reference='Leiden',
... normalize='reference', cmap='Reds', annot=True)

plotDendrogram

plot_dendrogram(
data,
groupby: str = 'leiden',
features: Optional[list] = None,
use_rep: Optional[str] = 'auto',
layer: Optional[str] = None,
use_raw: Optional[bool] = None,
n_top_genes: int = 50,
method: str = 'average',
metric: str = 'euclidean',
orientation: str = 'top',
palette=None,
figsize: Optional[tuple] = None,
title: Optional[str] = None,
show: bool = True,
save: Optional[str] = None,
ax: Optional[matplotlib.axes._axes.Axes] = None,
return_fig: bool = False,
return_linkage: bool = False,
modality: Optional[str] = None,
cytome_layer: str = 'counts',
compute_on_fly: bool = True,
use_cached_stats: bool = True,
)
Signature defaults

data, groupby='leiden', features=None, use_rep='auto', layer=None, use_raw=None, n_top_genes=50, method='average', metric='euclidean', orientation='top', palette=None, figsize=None, title=None, show=True, save=None, ax=None, return_fig=False, return_linkage=False, modality=None, cytome_layer='counts', compute_on_fly=True, use_cached_stats=True

Plot a dendrogram of cell groups based on expression similarity.

Parameters

data — AnnData or cytome Dataset/path

Input data.

groupby — str

Grouping column.

features — list, optional

Features to use for clustering (marker-gene mode). If None, uses highly variable genes or top-variance genes. Only consulted when use_rep is None or resolves to no embedding.

use_rep — str or None, default 'auto'

Build the group tree from per-group centroids of a cell embedding (the standard scanpy-style dendrogram), which is usually what you want.

  • 'auto' (default): use the first available embedding from X_gdr → X_pca → X_svd → X_diffmap → X_umap; if none exist, fall back to marker-gene expression similarity.
  • an explicit key (e.g. 'X_gdr', 'X_svd'): use that embedding.
  • None: marker-gene mode — cluster groups by similarity of their mean expression over features (or the top-n_top_genes variable genes / numeric cells columns). Use this when you specifically want the tree to reflect marker-gene programs rather than the global embedding geometry (e.g. comparing COSG top-n_top_genes markers). layer, use_raw AnnData layer / raw. Ignored for cytome.

n_top_genes — int

Number of top genes to use in marker-gene mode when features is None.

method — str

Linkage method ('average', 'ward', 'complete', 'single').

metric — str

Distance metric.

orientation — str

Dendrogram orientation: 'top', 'bottom', 'left', 'right'.

palette — list or dict, optional

Colors for leaf labels.

figsize — tuple, optional

Figure size.

title — str, optional

Title. show, save, ax, return_fig Output options.

return_linkage — bool

Also return the linkage matrix Z.

modality — str, optional

Cytome only: which modality the data was stored under ('RNA', 'ATAC', 'tiles', 'GA'). None takes the store’s first modality.

cytome_layer — str, default ‘counts’

Cytome only: the layer to read the values from.

compute_on_fly — bool, default True

Cytome only: normalise the raw layer while streaming (INFOG for RNA, TF-IDF for ATAC) instead of requiring a materialised layer.

use_cached_stats — bool, default True

Cytome only: reuse normalisation statistics already stored in the cytome’s metadata rather than recomputing them.

Returns

Optionally (fig, ax) and/or linkage matrix.

plotDotplot

dotplot(
data,
features: list,
groupby: str = 'leiden',
layer: Optional[str] = None,
use_raw: Optional[bool] = None,
expression_cutoff: float = 0.0,
mean_only_expressed: bool = False,
standard_scale: Optional[str] = None,
log: bool = False,
cmap: str = 'Spectral_r',
dot_max: Optional[float] = None,
dot_min: float = 0,
size_scale: float = 200,
figsize: Optional[tuple] = None,
square: bool = True,
categories_order: Optional[list] = None,
var_names_order: Optional[list] = None,
var_group_labels: Optional[list] = None,
var_group_positions: Optional[list] = None,
dendrogram: bool = False,
dendro_method: str = 'ward',
use_rep: Optional[str] = None,
swap_axes: bool = False,
title: Optional[str] = None,
fontsize: Optional[float] = None,
grid: bool = False,
show_border: bool = True,
edgecolor: str = 'none',
show: bool = True,
save: Optional[str] = None,
ax: Optional[matplotlib.axes._axes.Axes] = None,
return_fig: bool = False,
palette=None,
modality: Optional[str] = None,
cytome_layer: str = 'counts',
compute_on_fly: bool = True,
use_cached_stats: bool = True,
)
Signature defaults

data, features, groupby='leiden', layer=None, use_raw=None, expression_cutoff=0.0, mean_only_expressed=False, standard_scale=None, log=False, cmap='Spectral_r', dot_max=None, dot_min=0, size_scale=200, figsize=None, square=True, categories_order=None, var_names_order=None, var_group_labels=None, var_group_positions=None, dendrogram=False, dendro_method='ward', use_rep=None, swap_axes=False, title=None, fontsize=None, grid=False, show_border=True, edgecolor='none', show=True, save=None, ax=None, return_fig=False, palette=None, modality=None, cytome_layer='counts', compute_on_fly=True, use_cached_stats=True

Plot a dotplot of feature expression across cell groups.

Parameters

data — AnnData or cytome Dataset/path

Input data.

features — list, dict, or DataFrame

Feature names. A plain list of strings, a dict mapping group labels to gene lists ({'Excitatory': ['Slc17a7', 'Satb2'], ...}), or a DataFrame with 'group' and 'gene'/'feature' columns. When a dict or DataFrame is provided, var_group_labels and var_group_positions are inferred automatically.

groupby — str

Column in obs/cells for grouping.

layer — str, optional

AnnData layer. Ignored for cytome.

use_raw — bool, optional

Use raw attribute. Ignored for cytome.

expression_cutoff — float

Threshold for “expressing” (default 0).

mean_only_expressed — bool

Compute mean over expressing cells only.

standard_scale — str, optional

Min-max standardise the colour (mean expression) to [0, 1] (scanpy semantics): 'var' per gene (column), 'group' per group (row), or None for raw means. (Previously z-scored, which produced negative values — now min-max, so the colour bar is always [0, 1].)

log — bool

Log1p transform expression values.

cmap — str

Colormap for mean expression. Default 'Spectral_r' (changed from 'Reds'), which separates the middle of the range more strongly and matches the co-specificity heatmaps.

.. note:: 'Spectral_r' is a rainbow map and is not colourblind-safe — its red and green ends are hard to tell apart for the most common form of colour vision deficiency. For figures headed for a manuscript, pass a sequential map: cmap='Reds' (the previous default), 'magma_r' or 'viridis'. That also fits the data better when standard_scale is set, since the values are then 0–1 with no meaningful midpoint for a diverging map to mark.

dot_max — float, optional

Max dot size (fraction). Default: data max.

dot_min — float

Min dot size (fraction).

size_scale — float

Scaling factor for dot size.

figsize — tuple, optional

Auto-calculated if None.

square — bool, default True

Make every grid block a square (uniform per-cell sizing + ax.set_aspect('equal')) so the dots sit centered in square cells. False restores the legacy width∝features / height∝groups sizing.

categories_order — list, optional

Custom group ordering on Y axis.

var_names_order — list, optional

Custom gene ordering on X axis.

var_group_labels — list, optional

Labels for gene groups (displayed as brackets).

var_group_positions — list of tuple, optional

Start/end positions for gene group brackets, e.g. [(0,3), (4,7)].

dendrogram — bool

Show dendrogram on group axis.

dendro_method — str

Linkage method for dendrogram (default: ‘ward’).

use_rep — str, optional

Key in adata.obsm for computing dendrogram from cell embeddings (e.g. ‘X_gdr’, ‘X_svd’). If None, uses mean expression of features.

swap_axes — bool

Genes on Y, groups on X.

title — str, optional

Plot title.

grid — bool

Show light grid lines.

show_border — bool

Show outer border around the plot area (default: True).

edgecolor — str

Edge color for dots (default: ‘none’).

show — bool

Call plt.show().

save — str, optional

Save path.

ax — Axes, optional

Pre-existing axes.

return_fig — bool

Return (fig, ax) tuple.

palette

Not used for dotplot (color is continuous). Reserved for API consistency.

fontsize — float, optional

Base font size for labels; None follows the figure settings.

modality — str, optional

Cytome only: which modality the data was stored under ('RNA', 'ATAC', 'tiles', 'GA'). None takes the store’s first modality.

cytome_layer — str, default ‘counts’

Cytome only: the layer to read the values from.

compute_on_fly — bool, default True

Cytome only: normalise the raw layer while streaming (INFOG for RNA, TF-IDF for ATAC) instead of requiring a materialised layer.

use_cached_stats — bool, default True

Cytome only: reuse normalisation statistics already stored in the cytome’s metadata rather than recomputing them.

plotEmbedding

plotEmbedding(
data,
color='leiden',
basis='X_umap',
layer=None,
title=None,
figsize=None,
point_size=None,
alpha=1.0,
frameon=None,
save=None,
show=True,
ax=None,
palette=None,
legend_loc='right',
legend_fontsize=10,
legend_fontoutline=None,
legend_fontbackground='white',
legend_fontbackground_alpha=0.7,
legend_ncol=None,
rasterized=True,
dpi=None,
vmin=None,
vmax=None,
vmin_pct=None,
vmax_pct=None,
cmap=None,
show_axes_arrow=False,
axes_arrow_loc='bottom_left',
modality=None,
cytome_layer='counts',
compute_on_fly=True,
use_cached_stats=True,
show_modality_in_title=False,
ncol=None,
col_size=4.0,
row_size=4.0,
fix_coordinate_ratio=True,
show_axis_ticks=False,
x_min=None,
x_max=None,
y_min=None,
y_max=None,
legend_marker_size=None,
hspace=None,
wspace=None,
groups=None,
na_color='lightgray',
na_label='other',
image=False,
img_key='hires',
image_alpha=1.0,
image_crop=True,
cell_mask=None,
return_fig=False,
linewidths: float = 0.0,
edgecolors='none',
**kwargs,
)
Signature defaults

data, color='leiden', basis='X_umap', layer=None, title=None, figsize=None, point_size=None, alpha=1.0, frameon=None, save=None, show=True, ax=None, palette=None, legend_loc='right', legend_fontsize=10, legend_fontoutline=None, legend_fontbackground='white', legend_fontbackground_alpha=0.7, legend_ncol=None, rasterized=True, dpi=None, vmin=None, vmax=None, vmin_pct=None, vmax_pct=None, cmap=None, show_axes_arrow=False, axes_arrow_loc='bottom_left', modality=None, cytome_layer='counts', compute_on_fly=True, use_cached_stats=True, show_modality_in_title=False, ncol=None, col_size=4.0, row_size=4.0, fix_coordinate_ratio=True, show_axis_ticks=False, x_min=None, x_max=None, y_min=None, y_max=None, legend_marker_size=None, hspace=None, wspace=None, groups=None, na_color='lightgray', na_label='other', image=False, img_key='hires', image_alpha=1.0, image_crop=True, cell_mask=None, return_fig=False, linewidths=0.0, edgecolors='none', **kwargs

Plot a 2-D embedding colored by a cell annotation or continuous value.

cell_mask : array-like, optional Plot only these cells: a boolean mask of length n_cells or integer indices. Applied after the coordinates and colour values are resolved, so both stay aligned — pairs with a cytome’s cells_in_region(x=, y=) for ROI views without writing a subset file. image : bool or str, default False Draw the library’s tissue image under the spots (basis='spatial' workflows). True auto-selects when exactly one library has an image (or the plotted cells span one) and raises naming the options otherwise; a string selects that library. Sources: AnnData uns['spatial'] or a cytome’s stored images (cytome ≥ 0.2.6). The y-axis follows the image convention (top of the tissue at the top) only when an image is drawn. img_key : str, default ‘hires’ Which image of the library to draw (‘hires’, ‘lowres’, …). image_alpha : float, default 1.0 Opacity of the tissue image. image_crop : bool, default True With an image, crop to the plotted cells’ bounding box padded by one spot diameter instead of showing the whole slide. Returns None by default — pass return_fig=True to get (fig, ax) back.

Supports both cytome.Dataset and AnnData objects.

Parameters

data

A cytome.Dataset or AnnData object.

color — str, list of str, ndarray, or pandas.Series

Column in cells / obs for colouring, or a feature name (gene, peak, tile, or GA gene — resolved via the cytome modality registry; pass modality= to disambiguate). A single str draws one panel; a list/tuple of strings draws a multi-panel grid (one panel per entry, scanpy sc.pl.umap-style).

May also be the values themselves — one per cell, in order — as a numpy array, a pandas Series, or a Categorical, for anything computed on the fly and not written back to the object. Numeric values get a colorbar, everything else a category legend; a Categorical’s own order is kept, and a named Series titles the panel. Note that a plain list/tuple still means multiple panels, so pass an array.

basis — str

Embedding key (e.g. 'X_umap', 'X_svd').

layer — str, optional

AnnData layer to read the feature value from when color is a feature name. If None, reads from adata.X.

title — str or list of str, optional

Plot title. Defaults to color. For a list color: a single string becomes a figure-level suptitle over the grid; a list of titles (length must match color) sets one title per panel.

figsize — tuple, optional

Figure size in inches. If None, uses rcParams['figure.figsize'] (set via piaso.settings.set_figure_params(figsize=...)).

point_size — float or None

Scatter point size. If None (default), automatically calculated from the number of cells: 22000 / n_cells clamped to [0.1, 3] (explicit value overrides).

alpha — float

Point transparency. Default 1.0 (opaque).

frameon — bool, optional

Whether to show axis frame (spines). None follows piaso.settings._frameon, which starts out False.

save — str, bool, or None

Figure save behavior:

  • None: don’t save.
  • Full path ('/path/to/fig.png'): save directly.
  • Suffix ('_leiden'): save to piaso.settings.figdir.
  • True: auto-name and save to piaso.settings.figdir.

show — bool

Whether to call plt.show().

ax — matplotlib Axes, optional

Pre-existing axes to draw on.

palette — list[str], optional

Color palette for categorical data. If None, checks adata.uns['{color}_colors'] first, then falls back to piaso.pl.color.d_color4.

groups — str or list of str, optional

For a categorical color: highlight only these category values — they keep their palette colour while all other cells are greyed out (drawn behind), like sc.pl.umap(groups=...). Palette indices come from the full category list, so colours match an unfiltered plot. Raises ValueError if a name is not among the categories.

The legend then lists the highlighted groups and one final entry for the grey — the colours on the plot, and nothing else.

na_color — str, default 'lightgray'

Colour for the greyed-out (non-groups) cells.

na_label — str, default 'other'

Legend label for that colour. Only appears when groups actually left something out.

legend_loc — str, default 'right'

Where to put the category labels. One of:

  • 'right' — legend box outside the axes, in the right margin.
  • 'on_data' — labels drawn at each category’s centroid.
  • 'both' — centroid labels and the right-margin legend, so you can name a cluster where the points are and still read its colour off the list. Neither alone does both jobs.
  • 'none' — no legend.

Any other value raises ValueError rather than silently drawing nothing.

legend_fontsize — int

Font size for legend labels.

legend_fontoutline — float or None

Width of text outline for legend_loc='on_data' labels.

legend_fontbackground — str or None, default 'white'

Colour of the patch drawn behind each 'on_data' label. None draws the text with no background. The default is readable over a cluster and invisible over the figure background, which is where a small or sparse cluster’s label ends up — pass a tinted colour ('0.9', '#fffbe6') when labels need to read in both places.

legend_fontbackground_alpha — float, default 0.7

Opacity of that patch. Raise it towards 1.0 to hide the points underneath a label; lower it to let them show through. Adds a contrasting stroke around text for readability. If None (default), no outline is drawn.

legend_ncol — int, optional

Number of legend columns. If None, auto-calculated (~12 per column).

rasterized — bool

Rasterize scatter points for smaller vector files.

linewidths — float, optional (default 0)

Marker stroke width, in points. Zero by default. Matplotlib otherwise strokes every point at rcParams['patch.linewidth'] (1.0 pt) in edgecolors='face', which for cell-sized markers is most of the dot: point_size=0.2 is a disc 0.45 pt across inside a 1.0 pt stroke, so it draws 3.2x the size asked for, and under alpha < 1 the stroke and fill composite twice around the rim — ringed dots with a washed-out core, visible once a PDF is enlarged. Pass a positive value to outline markers deliberately.

Changed in 1.2.4: was matplotlib’s 1.0 pt default.

edgecolors — color or ‘none’, optional (default ‘none’)

Marker stroke colour. Only meaningful with linewidths > 0.

Changed in 1.2.4: was matplotlib’s 'face'.

dpi — int, optional

Display DPI. If None, uses rcParams['figure.dpi']. vmin, vmax : float Limits for continuous color scale. vmin_pct, vmax_pct : float, optional Percentile (0-100) used to derive vmin/vmax for continuous features when the explicit limit is not given — e.g. vmax_pct=99 clips the top 1% of cells so a few outliers don’t wash out the colour scale. None (default) = no percentile clipping. Ignored for categorical colours and overridden by an explicit vmin/vmax.

cmap

Colormap for continuous data.

show_axes_arrow — bool

Draw small coordinate arrows at a corner of the plot.

axes_arrow_loc — str

Position of axes arrow: 'bottom_left' or 'bottom_right'.

modality — str, optional

Cytome modality for feature lookup: 'RNA', 'GA', 'ATAC', 'tiles', or None for auto-detect. Auto-detect raises ValueError if the feature is in multiple modalities; pass an explicit string to disambiguate. Ignored for AnnData inputs.

cytome_layer — str, default 'counts'

Cytome matrix suffix to read; combined with modality to form {modality}_{cytome_layer}. Common values: 'counts', 'log1p', 'infog', 'tfidf'.

compute_on_fly — bool, default True

If the requested {modality}_{cytome_layer} matrix isn’t materialised in the cytome, compute the value per-feature on the fly from {modality}_counts using cached / freshly-computed params. Supported on-the-fly layers: 'log1p', 'infog', 'tfidf'. Set False for strict mode (raise on missing matrix).

use_cached_stats — bool, default True

Reuse per-modality cached params from ds.metadata (e.g. '{modality}_infog_params') when computing on the fly. Set False to ignore the cache and recompute.

show_modality_in_title — bool, default False

Append (modality) to the panel title when the colour was resolved through a cytome modality (e.g. 'Sox2 (RNA)'). Affects feature colours only — obs columns are unchanged.

ncol — int, optional

Columns in the multi-panel grid when color is a list. Defaults to ceil(sqrt(n_colors)). Aliased as ncols (scanpy convention). Ignored when color is a single string.

col_size — float, default 4.0

Per-panel width in inches when color is a list.

row_size — float, default 4.0

Per-panel height in inches when color is a list.

fix_coordinate_ratio — bool, default True

If True, sets ax.set_aspect('equal') so x and y axes are scaled equally — appropriate for UMAP / t-SNE / spatial coords where distances are meaningful. Set False to use 'auto' (let matplotlib stretch to fit the axes).

show_axis_ticks — bool, default False

Whether to display axis tick marks and labels. Off by default for embedding-style plots where coordinates are abstract. x_min, x_max, y_min, y_max : float, optional Custom axis limits. Each is independently optional; pass only the ones you want to override (others use the data range).

legend_marker_size — float, optional

Marker scale for the legend (categorical colours only). If None, auto-computed from point_size as max(3, 12 / point_size).

hspace — float, optional

Vertical spacing between rows of the multi-panel grid (only applies when color is a list). If None (default), uses 0.1 when show_axis_ticks=False and 0.25 when show_axis_ticks=True. Pass an explicit value to override (e.g. 0.05 for very tight, 0.4 for wide spacing).

wspace — float, optional

Horizontal spacing between columns of the multi-panel grid (only applies when color is a list). If None (default), uses 0.2. Override to tighten or widen.

color accepts str (single panel) OR list[str] / tuple[str] (one panel per entry, on a ncol-column grid). When a list is given together with ax, raises ValueError since a single axes can’t host a multi-panel grid.

image — bool or str, default False

Draw the tissue image behind spatial coordinates: True for the first library, a string for that library. Sources: AnnData uns['spatial'] or a cytome’s stored images.

img_key — str, default ‘hires’

Which image of the library to draw.

image_alpha — float, default 1.0

Opacity of the tissue image.

image_crop — bool, default True

Crop the image to the plotted coordinates.

cell_mask — ndarray, optional

Cytome only: plot these cells only (boolean mask or sorted indices).

return_fig — bool, default False

Return the figure instead of showing it.

Returns

fig, ax For single-color: (fig, ax) where ax is the matplotlib Axes that was drawn into. fig, axs For list-color: (fig, [ax0, ax1, ...]) — one Axes per entry in color; trailing empty grid cells are hidden via set_visible(False).

plotEmbeddingsSplit

plot_embeddings_split(
data,
color,
splitby,
ncol: int = None,
dpi: int = 80,
col_size: int = 5,
row_size: int = 5,
alpha: float = 1.0,
vmax: float = None,
vmin: float = None,
vmin_pct: float = None,
vmax_pct: float = None,
show_figure: bool = True,
save: bool = None,
layer: str = None,
basis: str = 'X_umap',
fix_coordinate_ratio: bool = True,
show_axis_ticks: bool = False,
margin_ratio: float = 0.05,
legend_fontsize: int = 10,
legend_fontoutline: int = 2,
legend_fontbackground='white',
legend_fontbackground_alpha: float = 0.7,
legend_loc: str = 'right',
legend_marker_size: float = 6.0,
groups=None,
point_size: float = None,
palette=None,
cmap=None,
frameon: bool = False,
rasterized: bool = True,
modality: str = None,
cytome_layer: str = 'counts',
compute_on_fly: bool = True,
use_cached_stats: bool = True,
show_modality_in_title: bool = False,
x_min=None,
x_max=None,
y_min=None,
y_max=None,
image=False,
img_key='hires',
image_alpha=1.0,
linewidths: float = 0.0,
edgecolors='none',
**kwargs,
)
Signature defaults

data, color, splitby, ncol=None, dpi=80, col_size=5, row_size=5, alpha=1.0, vmax=None, vmin=None, vmin_pct=None, vmax_pct=None, show_figure=True, save=None, layer=None, basis='X_umap', fix_coordinate_ratio=True, show_axis_ticks=False, margin_ratio=0.05, legend_fontsize=10, legend_fontoutline=2, legend_fontbackground='white', legend_fontbackground_alpha=0.7, legend_loc='right', legend_marker_size=6.0, groups=None, point_size=None, palette=None, cmap=None, frameon=False, rasterized=True, modality=None, cytome_layer='counts', compute_on_fly=True, use_cached_stats=True, show_modality_in_title=False, x_min=None, x_max=None, y_min=None, y_max=None, image=False, img_key='hires', image_alpha=1.0, linewidths=0.0, edgecolors='none', **kwargs

Plot cell embeddings side by side based on a categorical variable.

The plots are split by a specified categorical variable, with each unique category producing a separate subplot. Data points in each subplot are colored according to the color variable.

Supports AnnData, cytome Dataset, or path to .cytome file.

Parameters

data — AnnData, cytome.Dataset, or str

An AnnData object, cytome Dataset, or path to .cytome file.

color — str

Used to specify a gene name to plot, or a key in adata.obs used to assign colors to the cells in the embedding plot.

splitby — str

Key in adata.obs used to split the dataset into multiple panels. Each unique value under this key will result in a separate subplot.

ncol — int or None, optional (default: None)

If specified, defines the number of columns per row. If None, the number of columns is computed as the ceiling of n divided by the integer square root of n.

dpi — int, optional (default: 80)

Dots per inch (DPI) setting for the figure.

col_size — int, optional (default=5)

Width (in inches) of each subplot column.

row_size — int, optional (default=5)

Height (in inches) of each subplot row.

vmax — float or None, optional (default=None)

Maximum value for the color scale. If not provided, the upper limit is determined automatically.

vmin — float or None, optional (default=None)

Minimum value for the color scale. If not provided, the lower limit is determined automatically.

show_figure — bool, optional (default=True)

Whether to display the figure after plotting.

save — str or None, optional (default=None)

File path to save the resulting figure. If None, the figure will not be saved.

layer — str or None, optional (default=None)

If specified, the name of the layer in adata.layers from which to obtain the gene expression values.

basis — str, optional (default=‘X_umap’)

Key in adata.obsm that contains the embedding coordinates (e.g., X_umap or X_pca).

fix_coordinate_ratio — bool, optional (default=True)

If True, the aspect ratio of each subplot is fixed so that the x- and y-axes are scaled equally.

show_axis_ticks — bool, optional (default=False)

Whether to display axis ticks and tick labels on the plots.

margin_ratio — float, optional (default=0.05)

Margin ratio for both the x-axis and y-axis limits, relative to the range of the data. This provides additional spacing around the plotted points.

legend_fontsize — int, optional (default=10)

Font size in pt.

legend_fontoutline — int, optional (default=2)

Line width of the legend font outline in pt.

legend_fontbackground — str or None, optional (default=‘white’)

Colour of the patch behind each 'on_data' label; None for no patch.

legend_fontbackground_alpha — float, optional (default=0.7)

Opacity of that patch.

legend_loc — str, optional (default=‘right’)

Where to put the category labels. One of:

  • 'right' — a single shared legend in the figure’s right margin.
  • 'on_data' — labels drawn at each cluster’s centroid, in every panel.
  • 'both' — centroid labels and the shared right-margin legend. Use this while you are still working out what a cluster is: the on-data label tells you which cluster you are looking at, the margin legend lets you read a colour off the list. Neither alone does both.
  • 'none' — no legend.

Any other value raises ValueError rather than silently drawing nothing.

legend_marker_size — float, optional (default=6.0)

Legend dot size. In the right-margin legend it is the marker scale (relative to the data points); in the global/multi-panel legend it is the absolute marker size in points. None auto-sizes from the data point_size (capped to avoid oversized dots on large datasets).

x_min — float or None, optional (default=None)

Minimum limit for the x-axis. If None, the limit is computed automatically based on the data.

x_max — float or None, optional (default=None)

Maximum limit for the x-axis. If None, the limit is computed automatically based on the data.

y_min — float or None, optional (default=None)

Minimum limit for the y-axis. If None, the limit is computed automatically based on the data.

y_max — float or None, optional (default=None)

Maximum limit for the y-axis. If None, the limit is computed automatically based on the data.

point_size — float, optional

Scatter point size. An explicit value always overrides the auto-size. If None, auto-scaled (max(0.1, min(3, 22000 / n_cells)), clamped to [0.1, 8]). Accepts size= as an alias for scanpy-style call sites.

palette — list[str] or dict, optional

Categorical palette. If None, falls back to adata.uns['{color}_colors'] (or the cytome metadata equivalent), then to the PIASO default d_color4. Mapping is held consistent across panels so the same category gets the same colour in every subplot.

cmap — str or Colormap, optional

Colourmap for numeric color values. Forwarded to each panel.

frameon — bool, optional (default False)

Whether to show axis spines on each panel and on the global legend frame. Mirrors piaso.pl.plotEmbedding(frameon=...).

rasterized — bool, optional (default True)

Forward to per-panel scatter for compact vector output.

linewidths — float, optional (default 0)

Marker stroke width, in points. Zero by default. Matplotlib otherwise strokes every point at rcParams['patch.linewidth'] (1.0 pt) in edgecolors='face', which for cell-sized markers is most of the dot: point_size=0.2 is a disc 0.45 pt across inside a 1.0 pt stroke, so it draws 3.2x the size asked for, and under alpha < 1 the stroke and fill composite twice around the rim — ringed dots with a washed-out core, visible once a PDF is enlarged. Pass a positive value to outline markers deliberately.

Changed in 1.2.4: was matplotlib’s 1.0 pt default.

edgecolors — color or ‘none’, optional (default ‘none’)

Marker stroke colour. Only meaningful with linewidths > 0.

Changed in 1.2.4: was matplotlib’s 'face'.

**kwargs — dict

Accepts the aliases ncols (→ ncol), size (→ point_size) and show (→ show_figure). Anything else raises TypeError.

Changed in 1.2.4: unrecognised keywords used to be accepted and silently discarded, so a caller styling the panels got no error and no effect — and show=False, which every other piaso.pl function understands, displayed the figure regardless.

image — bool or str, default False

Draw the library’s tissue image under the spots (basis='spatial' workflows). True auto-selects when exactly one library has an image (or the plotted cells span one) and raises naming the options otherwise; a string selects that library. Sources: AnnData uns['spatial'] or a cytome’s stored images (cytome ≥ 0.2.6). The y-axis follows the image convention (top of the tissue at the top) only when an image is drawn.

img_key — str, default ‘hires’

Which image of the library to draw (‘hires’, ‘lowres’, …).

image_alpha — float, default 1.0

Opacity of the tissue image.

alpha — float, default 1.0

Point opacity. vmin_pct, vmax_pct : float, optional Colour-scale limits as percentiles of the values, when vmin / vmax are not given.

groups — sequence of str, optional

Which groups of splitby to draw; all when None.

show_modality_in_title — bool, default False

Cytome only: prefix panel titles with the modality.

modality — str, optional

Cytome only: which modality the data was stored under ('RNA', 'ATAC', 'tiles', 'GA'). None takes the store’s first modality.

cytome_layer — str, default ‘counts’

Cytome only: the layer to read the values from.

compute_on_fly — bool, default True

Cytome only: normalise the raw layer while streaming (INFOG for RNA, TF-IDF for ATAC) instead of requiring a materialised layer.

use_cached_stats — bool, default True

Cytome only: reuse normalisation statistics already stored in the cytome’s metadata rather than recomputing them.

Returns

None.

Examples

>>> import anndata
>>> import piaso
>>> adata = anndata.read_h5ad('pbmc3k.h5ad') # Load an example dataset
>>> # Plot embeddings colored by a gene expression value and split by clusters
>>> piaso.pl.plot_embeddings_split(adata, color='CDK9', splitby='louvain', col_size=6, row_size=6)
>>> # Save the figure to a file
>>> piaso.pl.plot_embeddings_split(adata, color='CDK9', splitby='louvain', save='./CST3_embeddingsSplit.pdf')

plotFeaturesViolin

plot_features_violin(
data,
feature_list,
groupby: Optional[str] = None,
use_raw: Optional[bool] = None,
layer: Optional[str] = None,
palette=None,
jitter: bool = False,
width_single: float = None,
height_single: float = 2.0,
ncol: Optional[int] = None,
violin_width: float = 0.7,
size: float = 0.1,
show_grid: bool = True,
show_median: bool = True,
median_color: str = 'lightgrey',
show_figure: bool = True,
save: Optional[str] = None,
modality: Optional[str] = None,
cytome_layer: str = 'counts',
compute_on_fly: bool = True,
use_cached_stats: bool = True,
show: Optional[bool] = None,
return_fig: bool = False,
)
Signature defaults

data, feature_list, groupby=None, use_raw=None, layer=None, palette=None, jitter=False, width_single=None, height_single=2.0, ncol=None, violin_width=0.7, size=0.1, show_grid=True, show_median=True, median_color='lightgrey', show_figure=True, save=None, modality=None, cytome_layer='counts', compute_on_fly=True, use_cached_stats=True, show=None, return_fig=False

Plots a violin plot for each feature specified in feature_list.

Uses matplotlib directly (no scanpy dependency). Supports AnnData and cytome Dataset / .cytome file path.

show is accepted as an alias for show_figure: every other plotting function in piaso.pl takes show, and a call that works for pl.embedding and pl.dotplot should not raise here for the sake of one function’s parameter name. When both are given, show wins.

Parameters

data — anndata.AnnData, cytome.Dataset, or str

The data source. For AnnData, reads from obs, layers, or raw. For cytome, reads from the cells SQL table.

feature_list — List[str]

Feature names to visualize. For cytome, these must be column names in the cells table.

groupby — str, optional

Column to group data points by. Default is None.

use_raw — bool, optional

Use raw attribute of adata. Ignored for cytome.

layer — str, optional

AnnData layer to use. Ignored for cytome.

palette — list or dict, optional

Color palette for groups. If None, checks adata.uns['{groupby}_colors'] first, then falls back to the default PIASO palette.

jitter — bool, optional

Show jitter scatter points on violins. Default is False.

width_single — float, optional

Figure width in inches. None (default) derives it from the number of groups — 1.6 + 0.42 * n_groups, clamped to [3, 16] — so a two-sample plot is not the same width as a forty-cluster one. Pass a number to override. Width of each subplot. Default is 14.0.

violin_width — float, optional

Width of each violin body in x-axis units, where 1.0 is the spacing between groups. Default 0.7.

ncol — int, optional

Panels per row. None (default) puts ungrouped features two to a row and grouped ones one to a row, since a grouped panel is already as wide as its group count requires.

height_single — float, optional

Height of each subplot. Default is 2.0.

size — float, optional

Jitter point size (only used when jitter=True). Default is 0.1.

show_grid — bool, optional

Show grid lines. Default is True.

show_median — bool, optional

Show median line on violins. Default is True.

median_color — str, optional

Color of the median line. Default is 'lightgrey'.

show_figure — bool, optional

Show figure (plt.show()). Default is True.

save — str, optional

Path to save the figure. Default is None.

return_fig — bool, optional

Return (fig, axes) instead of closing the figure.

show — bool, optional

Show the figure; None follows show_figure.

modality — str, optional

Cytome only: which modality the data was stored under ('RNA', 'ATAC', 'tiles', 'GA'). None takes the store’s first modality.

cytome_layer — str, default ‘counts’

Cytome only: the layer to read the values from.

compute_on_fly — bool, default True

Cytome only: normalise the raw layer while streaming (INFOG for RNA, TF-IDF for ATAC) instead of requiring a materialised layer.

use_cached_stats — bool, default True

Cytome only: reuse normalisation statistics already stored in the cytome’s metadata rather than recomputing them.

plotGroupMetrics

plotGroupMetrics(
df,
data=None,
groupby: Optional[str] = None,
metrics: Optional[list] = None,
kind: str = 'bar',
palette=None,
ncol: Optional[int] = None,
figsize: Optional[tuple] = None,
normalize: str = 'minmax',
annotate: bool = True,
cmap: str = 'Blues',
fontsize: Optional[float] = None,
rotation: float = 45,
save: Optional[str] = None,
show: bool = True,
return_fig: bool = False,
)
Signature defaults

df, data=None, groupby=None, metrics=None, kind='bar', palette=None, ncol=None, figsize=None, normalize='minmax', annotate=True, cmap='Blues', fontsize=None, rotation=45, save=None, show=True, return_fig=False

Plot the per-group metrics DataFrame from :func:piaso.pp.calculateGroupMetrics.

Parameters

df — pandas.DataFrame

Output of calculateGroupMetrics (rows = groups, cols = metrics). data, groupby : optional Source dataset + grouping column, only used to re-resolve cell-type colours when the df doesn’t already carry them in df.attrs['colors'].

metrics — list of str, optional

Subset / order of metric columns to plot. Default: all numeric columns.

kind — 'bar' | 'heatmap'

'bar' (default): one panel per metric. 'heatmap': groups × metrics with per-column normalisation.

palette — dict or list, optional

Override group colours ({group: hex} or an ordered list).

ncol — int, optional

Columns in the faceted bar grid (default: ~sqrt(n_metrics)).

figsize — tuple, optional

Auto-sized if None.

normalize — 'minmax' | 'zscore' | None

Per-column scaling for the heatmap (ignored for bars).

annotate — bool, default True

Write the raw value in each heatmap cell.

cmap — str, default 'Blues'

Heatmap colormap.

fontsize — float, optional

Base font size (defaults to rcParams['font.size']).

rotation — float, default 45

Group-label rotation (anchored to the ticks so names don’t overlap). save, show, return_fig Output options.

plotHeatmap

heatmap(
data,
features: list,
groupby: str = 'leiden',
layer: Optional[str] = None,
use_raw: Optional[bool] = None,
standard_scale: Optional[str] = None,
log: bool = False,
cmap: str = 'viridis',
figsize: Optional[tuple] = None,
categories_order: Optional[list] = None,
var_names_order: Optional[list] = None,
dendrogram: bool = False,
swap_axes: bool = False,
title: Optional[str] = None,
show_values: bool = False,
fmt: str = '.2f',
vmin: Optional[float] = None,
vmax: Optional[float] = None,
cell_level: bool = False,
max_cells_per_group: int = 100,
show_group_colors: bool = True,
show: bool = True,
save: Optional[str] = None,
ax: Optional[matplotlib.axes._axes.Axes] = None,
return_fig: bool = False,
modality: Optional[str] = None,
cytome_layer: str = 'counts',
compute_on_fly: bool = True,
use_cached_stats: bool = True,
)
Signature defaults

data, features, groupby='leiden', layer=None, use_raw=None, standard_scale=None, log=False, cmap='viridis', figsize=None, categories_order=None, var_names_order=None, dendrogram=False, swap_axes=False, title=None, show_values=False, fmt='.2f', vmin=None, vmax=None, cell_level=False, max_cells_per_group=100, show_group_colors=True, show=True, save=None, ax=None, return_fig=False, modality=None, cytome_layer='counts', compute_on_fly=True, use_cached_stats=True

Plot an expression heatmap.

Two modes:

  • Group-level (default): mean expression per group (groups x features).
  • Cell-level (cell_level=True): per-cell expression with group-stratified sampling, up to max_cells_per_group cells per group.

Parameters

data — AnnData or cytome Dataset/path

Input data.

features — list, dict, or DataFrame

Feature names. A plain list of strings, a dict mapping group labels to gene lists, or a DataFrame with 'group' and 'gene'/'feature' columns. When dict/DataFrame, gene groups are shown as colored brackets (cell-level) or vertical separators (group-level).

groupby — str

Grouping column. layer, use_raw AnnData layer / raw attribute. Ignored for cytome.

standard_scale — str, optional

'var' to z-score per feature, 'group' per group.

log — bool

Log1p transform.

cmap — str

Colormap.

figsize — tuple, optional

Auto-calculated if None.

categories_order — list, optional

Custom group order.

var_names_order — list, optional

Custom feature order.

dendrogram — bool

Cluster groups by hierarchical clustering (group-level only).

swap_axes — bool

Transpose: features on Y, groups on X.

title — str, optional

Title.

show_values — bool

Annotate cells with values (group-level only).

fmt — str

Number format for annotations. vmin, vmax : float, optional Colorscale limits.

cell_level — bool

If True, show per-cell expression instead of group means.

max_cells_per_group — int

Maximum cells per group when cell_level=True. Default 100.

show_group_colors — bool

Show colored sidebar for groups when cell_level=True. show, save, ax, return_fig Output options.

modality — str, optional

Cytome only: which modality the data was stored under ('RNA', 'ATAC', 'tiles', 'GA'). None takes the store’s first modality.

cytome_layer — str, default ‘counts’

Cytome only: the layer to read the values from.

compute_on_fly — bool, default True

Cytome only: normalise the raw layer while streaming (INFOG for RNA, TF-IDF for ATAC) instead of requiring a materialised layer.

use_cached_stats — bool, default True

Cytome only: reuse normalisation statistics already stored in the cytome’s metadata rather than recomputing them.

plotLigandReceptorInteraction

plotLigandReceptorInteraction(
interactions_df: pandas.core.frame.DataFrame,
specificity_df: pandas.core.frame.DataFrame,
cell_type_pairs: list,
top_n: int = 50,
y_max: int = 10,
cell_type_sep: str = '@',
ligand_receptor_sep: str = '-->',
heatmap_height_ratio: float = 1.5,
heatmap_cmap: str = 'Purples',
heatmap_cmap_ligand: str = None,
heatmap_cmap_receptor: str = None,
shared_legend: bool = False,
heatmap_vmax: float = None,
save_path: str = None,
fig_width: int = 24,
fig_height_per_pair: int = 9,
col_interaction_score: str = 'interaction_score',
col_ligand_receptor_pair: str = 'ligandXreceptor',
col_cell_type_pair: str = 'CellTypeXCellType',
col_annotation: str = 'annotation',
col_ligand: str = 'ligand',
col_receptor: str = 'receptor',
vertical_layout: bool = False,
color_labels_by_annotation: bool = False,
barplot_palette: str = 'Paired',
sort_by_category: bool = False,
category_agg_method: str = 'sum',
preserve_input_order: bool = False,
)
Signature defaults

interactions_df, specificity_df, cell_type_pairs, top_n=50, y_max=10, cell_type_sep='@', ligand_receptor_sep='-->', heatmap_height_ratio=1.5, heatmap_cmap='Purples', heatmap_cmap_ligand=None, heatmap_cmap_receptor=None, shared_legend=False, heatmap_vmax=None, save_path=None, fig_width=24, fig_height_per_pair=9, col_interaction_score='interaction_score', col_ligand_receptor_pair='ligandXreceptor', col_cell_type_pair='CellTypeXCellType', col_annotation='annotation', col_ligand='ligand', col_receptor='receptor', vertical_layout=False, color_labels_by_annotation=False, barplot_palette='Paired', sort_by_category=False, category_agg_method='sum', preserve_input_order=False

Generates plots with a bar plot of top interactions and a heatmap showing ligand and receptor specificity, with an option for vertical orientation.

Args: interactions_df (pd.DataFrame): DataFrame with interaction scores. specificity_df (pd.DataFrame): DataFrame with gene specificity scores. cell_type_pairs (list): A list of ‘CellTypeXCellType’ strings to plot. top_n (int): The number of top interactions to display. y_max (int): The maximum y-axis value for the bar plot. cell_type_sep (str): The separator for sender/receiver cell types. ligand_receptor_sep (str): The separator for ligand/receptor genes. heatmap_height_ratio (float): The height/width ratio of the heatmap relative to the bar plot. heatmap_cmap (str): The colormap for the specificity heatmap (used when ligand/receptor cmaps not specified). heatmap_cmap_ligand (str): The colormap for ligand specificity. If None, uses heatmap_cmap. heatmap_cmap_receptor (str): The colormap for receptor specificity. If None, uses heatmap_cmap. shared_legend (bool): If True, a single legend/colorbar is shown for all plots. heatmap_vmax (float): The maximum value for the heatmap color scale. save_path (str, optional): Path to save the figure (e.g., ‘plot.pdf’). fig_width (int): For horizontal layout, the total figure width. For vertical, this controls the total figure HEIGHT. fig_height_per_pair (int): For horizontal layout, height per subplot. For vertical, this controls the WIDTH of each subplot group. col_interaction_score (str): Column name for interaction scores. col_ligand_receptor_pair (str): Column name for ligand-receptor pair strings. col_cell_type_pair (str): Column name for cell type pair strings. col_annotation (str): Column name for pathway/annotation data. col_ligand (str): Column name for ligand after splitting. col_receptor (str): Column name for receptor after splitting. vertical_layout (bool): If True, plots are arranged horizontally (rotated 90 degrees). color_labels_by_annotation (bool): If True, color ligand-receptor labels by their annotation category. barplot_palette (str or list): Color palette for bar plots. Can be a seaborn palette name (e.g., ‘Paired’, ‘Set1’) or a list of hex colors (e.g., [‘#F198CC’, ‘#D6DAB9’, ‘#BC938B’]). sort_by_category (bool): If True, sort interactions by category first, then by interaction score within category. category_agg_method (str): Method to aggregate interaction scores by category (‘sum’ or ‘mean’) when sort_by_category=True. preserve_input_order (bool): If True, preserve the original order from interactions_df without any sorting.

Examples: # Preserve original input order plotLigandReceptorInteraction( interactions_df=specific_interactions, specificity_df=cosg_scores, cell_type_pairs=[‘L5 NP@SST-Chrna2’], preserve_input_order=True, # Use original DataFrame order vertical_layout=False )

# Horizontal layout with category sorting
plotLigandReceptorInteraction(
interactions_df=specific_interactions,
specificity_df=cosg_scores,
cell_type_pairs=['L5 NP@SST-Chrna2', 'L5 PT@SST-Chrna2'],
ligand_receptor_sep='-->',
top_n=50,
y_max=10,
heatmap_cmap_ligand='Blues',
heatmap_cmap_receptor='Reds',
shared_legend=True,
vertical_layout=False,
sort_by_category=True,
category_agg_method='sum',
color_labels_by_annotation=True
)
# Vertical layout with custom hex colors
plotLigandReceptorInteraction(
interactions_df=specific_interactions_cellchat,
specificity_df=cosg_scores,
cell_type_pairs=['L5 NP@SST-Chrna2'],
ligand_receptor_sep='-->',
top_n=50,
y_max=10,
heatmap_cmap_ligand='Purples',
heatmap_cmap_receptor='Reds',
shared_legend=True,
vertical_layout=True,
barplot_palette=['#F198CC', '#D6DAB9', '#BC938B', '#93DCFC', '#F4DBCD', '#bcf60c'],
sort_by_category=True,
category_agg_method='mean'
)

Raises: ValueError: If required columns are missing from DataFrames or if data is inconsistent. KeyError: If specified cell type pairs are not found in the data.

plotLigandReceptorLollipop

plotLigandReceptorLollipop(
interactions_df: pandas.core.frame.DataFrame,
cell_type_pairs: List[str],
top_n: int = 25,
sort_by_category: bool = False,
preserve_input_order: bool = False,
palette: str = 'tab20',
vertical_layout: bool = True,
fig_width: int = 10,
fig_height_per_pair: int = 6,
save_path: str = None,
cell_type_sep: str = '@',
ligand_receptor_sep: str = '-->',
col_interaction_score: str = 'interaction_score',
col_ligand_specificity: str = 'ligand_specificity',
col_receptor_specificity: str = 'receptor_specificity',
col_ligand_receptor_pair: str = 'ligandXreceptor',
col_cell_type_pair: str = 'CellTypeXCellType',
col_annotation: str = 'annotation',
category_agg_method: str = 'sum',
color_labels_by_annotation: bool = False,
max_label_length: int = 25,
background_colors: bool = False,
col_circle_size: str = 'avg_log2FC',
circle_size_title: str = 'avg_log2FC',
base_circle_size: float = 15,
circle_size_scale: float = 20,
logfc_range: float = 1.0,
size_dramatic_level: float = 1.5,
show_grid: bool = True,
score_range_min: float = None,
score_range_max: float = None,
range_padding: float = 0.15,
specificity_df: pandas.core.frame.DataFrame = None,
)
Signature defaults

interactions_df, cell_type_pairs, top_n=25, sort_by_category=False, preserve_input_order=False, palette='tab20', vertical_layout=True, fig_width=10, fig_height_per_pair=6, save_path=None, cell_type_sep='@', ligand_receptor_sep='-->', col_interaction_score='interaction_score', col_ligand_specificity='ligand_specificity', col_receptor_specificity='receptor_specificity', col_ligand_receptor_pair='ligandXreceptor', col_cell_type_pair='CellTypeXCellType', col_annotation='annotation', category_agg_method='sum', color_labels_by_annotation=False, max_label_length=25, background_colors=False, col_circle_size='avg_log2FC', circle_size_title='avg_log2FC', base_circle_size=15, circle_size_scale=20, logfc_range=1.0, size_dramatic_level=1.5, show_grid=True, score_range_min=None, score_range_max=None, range_padding=0.15, specificity_df=None

Generates advanced bidirectional lollipop plots for one or more cell-type interactions with support for both vertical and horizontal layouts.

Args: interactions_df (pd.DataFrame): DataFrame with interaction and specificity data. cell_type_pairs (List[str]): A list of ‘CellTypeXCellType’ strings to plot. top_n (int): The number of top interactions to display per plot. sort_by_category (bool): If True, sort interactions by category first, then by score. preserve_input_order (bool): If True, use the original DataFrame order. palette (str): Seaborn color palette name for coloring categories. vertical_layout (bool): If True, subplots are arranged vertically. Otherwise, horizontally. fig_width (int): Base width for the figure (for vertical layout) or width per subplot (for horizontal). fig_height_per_pair (int): Height per subplot (for vertical layout) or base height (for horizontal). save_path (str, optional): Path to save the figure (e.g., ‘plot.png’). cell_type_sep (str): Separator for sender/receiver cell types (e.g., ’@’). ligand_receptor_sep (str): Separator for ligand/receptor pairs (e.g., ’—>’). col_interaction_score (str): Column name for interaction scores. col_ligand_specificity (str): Column name for ligand specificity scores. col_receptor_specificity (str): Column name for receptor specificity scores. col_ligand_receptor_pair (str): Column name for ligand-receptor pair strings. col_cell_type_pair (str): Column name for cell type pair strings. col_annotation (str): Column name for pathway/annotation data (default: ‘annotation’). category_agg_method (str): Method to aggregate interaction scores by category (‘sum’ or ‘mean’). color_labels_by_annotation (bool): If True, color ligand-receptor labels by their annotation. max_label_length (int): Maximum length for y-axis labels before truncation. background_colors (bool): If True, add transparent background colors to distinguish ligand/receptor sides. col_circle_size (str): Column name for controlling circle sizes (default: ‘avg_log2FC’). circle_size_title (str): Title for the circle size legend. base_circle_size (float): Base size for circles when col_circle_size value is 0. circle_size_scale (float): Scaling factor for circle sizes based on col_circle_size values. logfc_range (float): Expected range of logFC values for proper scaling (e.g., 1.0 for -1 to +1 range). size_dramatic_level (float): Controls how dramatic the size differences are (0.5=subtle, 1.0=moderate, 2.0=very dramatic). show_grid (bool): If True, show grid lines on the plot. score_range_min (float, optional): Minimum value for interaction score axis. Values below this will be clipped. score_range_max (float, optional): Maximum value for interaction score axis. Values above this will be clipped. range_padding (float): Padding to add beyond the score range to accommodate circles (default 0.15 = 15%). specificity_df (pd.DataFrame, optional): DataFrame with gene names as index and cell types as columns containing specificity scores. If provided, will override col_ligand_specificity and col_receptor_specificity columns.

Examples: # Vertical layout with default settings plotLigandReceptorLollipop( interactions_df=specific_interactions, cell_type_pairs=[‘L5 NP@SST-Chrna2’], vertical_layout=True )

# Using external specificity dataframe
plotLigandReceptorLollipop(
interactions_df=specific_interactions,
cell_type_pairs=['L5 NP@SST-Chrna2', 'L5 PT@SST-Chrna2'],
specificity_df=gene_specificity_matrix,
vertical_layout=False,
save_path='lollipop_plot.png'
)

plotSankey

sankey(
data,
left: str,
right: str,
palette=None,
color_by: str = 'left',
left_order: Optional[Sequence] = None,
right_order: Optional[Sequence] = None,
layout: str = 'horizontal',
flow_scale: str = 'linear',
min_flow_width: Optional[float] = None,
node_scale: str = 'linear',
min_node_size: Optional[float] = None,
show_size_legend: Optional[bool] = None,
size_legend_loc: str = 'lower right',
figsize: Optional[tuple] = None,
alpha: float = 0.4,
node_width: float = 0.08,
gap: float = 0.03,
title: Optional[str] = None,
fontsize: int = 9,
show: bool = True,
save: Optional[str] = None,
ax: Optional[matplotlib.axes._axes.Axes] = None,
return_fig: bool = False,
)
Signature defaults

data, left, right, palette=None, color_by='left', left_order=None, right_order=None, layout='horizontal', flow_scale='linear', min_flow_width=None, node_scale='linear', min_node_size=None, show_size_legend=None, size_legend_loc='lower right', figsize=None, alpha=0.4, node_width=0.08, gap=0.03, title=None, fontsize=9, show=True, save=None, ax=None, return_fig=False

Plot a Sankey (alluvial) diagram between two categorical columns.

Parameters

data — AnnData or cytome Dataset/path

Input data.

left — str

Left-side category column.

right — str

Right-side category column.

palette — list or dict, optional

Colors. If None, uses d_color4.

color_by — str

Color flows by 'left' or 'right' categories.

flow_scale — {‘linear’, ‘sqrt’, ‘log’}, default 'linear'

Shape of the count-to-width map. 'linear' is proportional and is what a Sankey normally promises. 'sqrt' and 'log' (log1p) compress the range so the thin end stays legible, at the cost of the thick end. Reach for one when the flows span orders of magnitude: on a 2000-fold range half the ribbons come out under a hairline, and no figure size fixes that, because it is each flow’s share of the diagram that is too small.

min_flow_width — float, optional

Thickness of the thinnest ribbon, in points. This is an affine offset applied to every flow — width = m * f(count) + b, solved so the ribbons still fill the rail — not a clamp, so nothing is tied and no flow overtakes another. It costs n_flows * min_flow_width of the diagram, which means what limits it is the flow count; a request that does not fit raises, having done that arithmetic for you. Composes with flow_scale: 'sqrt' shrinks the range first, so it needs far less of a baseline than 'linear' to clear the same hairline.

node_scale — {‘linear’, ‘sqrt’, ‘log’}, default 'linear'

Shape of the size-to-height map for the category blocks, mirroring flow_scale. 'linear' is the default because a node has no height of its own: it is the sum of its ribbons, which is what makes them meet.

Added in 1.2.4.

min_node_size — float, optional

Height of the shortest category block, in points — the node-level parallel of min_flow_width, solved the same affine way, so blocks stay monotone in group size and nothing is tied. It costs n_nodes * min_node_size of the rail and raises with that arithmetic when it does not fit.

Reach for it when a small category is invisible: without it a node’s height is m * size + b * fan_out, so how tall a small group draws depends on how many ways it splits, which is the wrong variable.

What it costs. Each node’s ribbons are renormalised to fill its new height, so the count-to-thickness map becomes per-node: the same flow can be drawn at two thicknesses at its two ends. Ribbon widths therefore stop being comparable across nodes, min_flow_width stops being exact, and the size key switches to describing nodes (see show_size_legend).

Added in 1.2.4.

show_size_legend — bool, optional

Draw a key mapping a drawn thickness back to a cell count. None (default) turns it on exactly when a map stops being proportional, because a non-proportional size with no key invites the reader to divide two of them and get the wrong ratio.

One key, never two, because only one map is global at a time:

=========================== ========================================== state key =========================== ========================================== both maps proportional none (True forces the flow key) flows non-proportional flows — “cells per flow” nodes non-proportional nodes — “cells per node”; the flow key is suppressed, since per-node renormalisation has made it untrue =========================== ==========================================

Renamed in 1.2.4 from show_width_legend.

size_legend_loc — str, default 'lower right'

Corner for the key: 'lower right', 'lower left', 'upper right' or 'upper left'. It is drawn inside the axes, so move it if it lands on a ribbon.

Renamed in 1.2.4 from width_legend_loc.

figsize — tuple, optional

Figure size.

alpha — float

Flow ribbon transparency.

node_width — float

Width of category bars (in data coords).

gap — float

Vertical gap between bars (fraction of total height).

title — str, optional

Title.

fontsize — int

Label font size. show, save, ax, return_fig Output options.

Notes

Three properties — node height proportional to size, ribbon width proportional to flow, node height equal to the sum of its ribbons — and any mechanism for making something thin visible costs one of them. The default keeps all three and pays in visibility instead.

A node is exactly as tall as the ribbons landing on it, so the moment the width map stops being proportional, node height stops tracking group size: it becomes m * size + b * fan_out, and a category that splits many ways is drawn taller than an equally large one that maps cleanly. min_node_size fixes that by giving the node the affine map and splitting its height across its ribbons — which spends the third property instead, since a ribbon’s thickness then depends on which node it leaves.

So at most one of the two maps is ever global, and exactly the global one gets a key. That is why there is one show_size_legend rather than a node key and a flow key that could be drawn together: two keys in a corner would not be clutter, they would be a contradiction.

plotScatter

scatter(
data,
x: str,
y: str,
color: Optional[str] = None,
on: str = 'cells',
layer: Optional[str] = None,
use_raw: Optional[bool] = None,
palette=None,
cmap=None,
point_size: Optional[float] = None,
alpha: float = 1.0,
density: str = 'auto',
density_threshold: int = 20000,
gridsize: int = 60,
logx: bool = False,
logy: bool = False,
marginals: bool = False,
vlines=None,
hlines=None,
figsize: Optional[tuple] = None,
title: Optional[str] = None,
xlabel: Optional[str] = None,
ylabel: Optional[str] = None,
legend_loc: str = 'right',
legend_fontsize: int = 9,
legend_marker_size: float = 6.0,
square: bool = True,
rasterized: bool = True,
frameon: Optional[bool] = True,
vmin: Optional[float] = None,
vmax: Optional[float] = None,
show: bool = True,
save: Optional[str] = None,
ax: Optional[matplotlib.axes._axes.Axes] = None,
return_fig: bool = False,
modality: Optional[str] = None,
cytome_layer: str = 'counts',
compute_on_fly: bool = True,
use_cached_stats: bool = True,
linewidths: float = 0.0,
edgecolors='none',
)
Signature defaults

data, x, y, color=None, on='cells', layer=None, use_raw=None, palette=None, cmap=None, point_size=None, alpha=1.0, density='auto', density_threshold=20000, gridsize=60, logx=False, logy=False, marginals=False, vlines=None, hlines=None, figsize=None, title=None, xlabel=None, ylabel=None, legend_loc='right', legend_fontsize=9, legend_marker_size=6.0, square=True, rasterized=True, frameon=True, vmin=None, vmax=None, show=True, save=None, ax=None, return_fig=False, modality=None, cytome_layer='counts', compute_on_fly=True, use_cached_stats=True, linewidths=0.0, edgecolors='none'

Scatter plot of two features colored by a third variable.

Parameters

data — AnnData or cytome Dataset/path

Input data.

x — str

Feature for X axis (gene name, obs column, or peak).

y — str

Feature for Y axis.

color — str, optional

Column for coloring points. Can be categorical (e.g. 'leiden') or continuous (e.g. a gene name). If None, all points are grey.

layer — str, optional

AnnData layer. Ignored for cytome.

use_raw — bool, optional

Use raw attribute. Ignored for cytome.

palette — list or dict, optional

Colors for categorical data. Falls back to PIASO default.

cmap — str, optional

Colormap. Defaults to 'magma_r' when color is continuous (sequential, perceptually uniform, colourblind-safe) and to PIASO’s density map when density=True. Colormap for continuous data.

point_size — float or None

Point size. If None, auto-calculated from cell count.

alpha — float

Point transparency.

figsize — tuple, optional

Figure size.

title — str, optional

Plot title. xlabel, ylabel : str, optional Axis labels. Default to feature names.

legend_loc — str

'right', 'on_data', or 'none'.

legend_fontsize — int

Legend font size.

legend_marker_size — float

Fixed legend dot size (pt), independent of point_size.

square — bool, default True

Keep the scatter axes square (set_box_aspect(1)) and, for a categorical color with legend_loc='right', put the legend in its own panel so a long category legend no longer squeezes the plot.

rasterized — bool

Rasterize points for smaller vector files.

frameon — bool, optional

Show axis frame. If None, uses piaso.settings._frameon. vmin, vmax : float, optional Continuous colorscale limits.

on — str, default 'cells'

What each point is. 'cells' → one point per cell, x/y are per-cell features (gene/peak/tile name or a cells column). A feature entity ('peaks' / 'genes' / 'tiles' / 'GA_genes' for a cytome, or 'var'/any for AnnData) → one point per feature, x/y are columns of that entity’s table (e.g. 'neg_log10_pvalue', 'score', or the derived 'width' = end_ - start).

density — 'auto' | 'scatter' | 'hexbin'

'auto' switches to a log-count hexbin above density_threshold points (unless colour is categorical). 'scatter' forces points; 'hexbin' forces density. With a continuous color the hexbin shows the per-cell mean.

density_threshold — int

Point count above which density='auto' uses hexbin.

gridsize — int

Hexbin grid resolution. logx, logy : bool Log-scale the X / Y axis.

marginals — bool

Add marginal histograms of x/y (only when ax is None). vlines, hlines : list of float, optional Vertical / horizontal reference lines (e.g. a min_length or score_cutoff threshold). show, save, ax, return_fig Output options.

linewidths — float, default 0.0

Marker edge width.

edgecolors — str, default ‘none’

Marker edge colour.

modality — str, optional

Cytome only: which modality the data was stored under ('RNA', 'ATAC', 'tiles', 'GA'). None takes the store’s first modality.

cytome_layer — str, default ‘counts’

Cytome only: the layer to read the values from.

compute_on_fly — bool, default True

Cytome only: normalise the raw layer while streaming (INFOG for RNA, TF-IDF for ATAC) instead of requiring a materialised layer.

use_cached_stats — bool, default True

Cytome only: reuse normalisation statistics already stored in the cytome’s metadata rather than recomputing them.

Returns

Optionally (fig, ax).

plotUMAP

plotUMAP(data, color='leiden', **kwargs)
Signature defaults

data, color='leiden', **kwargs

Convenience wrapper for :func:plotEmbedding with basis='X_umap'.

sankey

sankey(
data,
left: str,
right: str,
palette=None,
color_by: str = 'left',
left_order: Optional[Sequence] = None,
right_order: Optional[Sequence] = None,
layout: str = 'horizontal',
flow_scale: str = 'linear',
min_flow_width: Optional[float] = None,
node_scale: str = 'linear',
min_node_size: Optional[float] = None,
show_size_legend: Optional[bool] = None,
size_legend_loc: str = 'lower right',
figsize: Optional[tuple] = None,
alpha: float = 0.4,
node_width: float = 0.08,
gap: float = 0.03,
title: Optional[str] = None,
fontsize: int = 9,
show: bool = True,
save: Optional[str] = None,
ax: Optional[matplotlib.axes._axes.Axes] = None,
return_fig: bool = False,
)
Signature defaults

data, left, right, palette=None, color_by='left', left_order=None, right_order=None, layout='horizontal', flow_scale='linear', min_flow_width=None, node_scale='linear', min_node_size=None, show_size_legend=None, size_legend_loc='lower right', figsize=None, alpha=0.4, node_width=0.08, gap=0.03, title=None, fontsize=9, show=True, save=None, ax=None, return_fig=False

Plot a Sankey (alluvial) diagram between two categorical columns.

Parameters

data — AnnData or cytome Dataset/path

Input data.

left — str

Left-side category column.

right — str

Right-side category column.

palette — list or dict, optional

Colors. If None, uses d_color4.

color_by — str

Color flows by 'left' or 'right' categories.

flow_scale — {‘linear’, ‘sqrt’, ‘log’}, default 'linear'

Shape of the count-to-width map. 'linear' is proportional and is what a Sankey normally promises. 'sqrt' and 'log' (log1p) compress the range so the thin end stays legible, at the cost of the thick end. Reach for one when the flows span orders of magnitude: on a 2000-fold range half the ribbons come out under a hairline, and no figure size fixes that, because it is each flow’s share of the diagram that is too small.

min_flow_width — float, optional

Thickness of the thinnest ribbon, in points. This is an affine offset applied to every flow — width = m * f(count) + b, solved so the ribbons still fill the rail — not a clamp, so nothing is tied and no flow overtakes another. It costs n_flows * min_flow_width of the diagram, which means what limits it is the flow count; a request that does not fit raises, having done that arithmetic for you. Composes with flow_scale: 'sqrt' shrinks the range first, so it needs far less of a baseline than 'linear' to clear the same hairline.

node_scale — {‘linear’, ‘sqrt’, ‘log’}, default 'linear'

Shape of the size-to-height map for the category blocks, mirroring flow_scale. 'linear' is the default because a node has no height of its own: it is the sum of its ribbons, which is what makes them meet.

Added in 1.2.4.

min_node_size — float, optional

Height of the shortest category block, in points — the node-level parallel of min_flow_width, solved the same affine way, so blocks stay monotone in group size and nothing is tied. It costs n_nodes * min_node_size of the rail and raises with that arithmetic when it does not fit.

Reach for it when a small category is invisible: without it a node’s height is m * size + b * fan_out, so how tall a small group draws depends on how many ways it splits, which is the wrong variable.

What it costs. Each node’s ribbons are renormalised to fill its new height, so the count-to-thickness map becomes per-node: the same flow can be drawn at two thicknesses at its two ends. Ribbon widths therefore stop being comparable across nodes, min_flow_width stops being exact, and the size key switches to describing nodes (see show_size_legend).

Added in 1.2.4.

show_size_legend — bool, optional

Draw a key mapping a drawn thickness back to a cell count. None (default) turns it on exactly when a map stops being proportional, because a non-proportional size with no key invites the reader to divide two of them and get the wrong ratio.

One key, never two, because only one map is global at a time:

=========================== ========================================== state key =========================== ========================================== both maps proportional none (True forces the flow key) flows non-proportional flows — “cells per flow” nodes non-proportional nodes — “cells per node”; the flow key is suppressed, since per-node renormalisation has made it untrue =========================== ==========================================

Renamed in 1.2.4 from show_width_legend.

size_legend_loc — str, default 'lower right'

Corner for the key: 'lower right', 'lower left', 'upper right' or 'upper left'. It is drawn inside the axes, so move it if it lands on a ribbon.

Renamed in 1.2.4 from width_legend_loc.

figsize — tuple, optional

Figure size.

alpha — float

Flow ribbon transparency.

node_width — float

Width of category bars (in data coords).

gap — float

Vertical gap between bars (fraction of total height).

title — str, optional

Title.

fontsize — int

Label font size. show, save, ax, return_fig Output options.

Notes

Three properties — node height proportional to size, ribbon width proportional to flow, node height equal to the sum of its ribbons — and any mechanism for making something thin visible costs one of them. The default keeps all three and pays in visibility instead.

A node is exactly as tall as the ribbons landing on it, so the moment the width map stops being proportional, node height stops tracking group size: it becomes m * size + b * fan_out, and a category that splits many ways is drawn taller than an equally large one that maps cleanly. min_node_size fixes that by giving the node the affine map and splitting its height across its ribbons — which spends the third property instead, since a ribbon’s thickness then depends on which node it leaves.

So at most one of the two maps is ever global, and exactly the global one gets a key. That is why there is one show_size_legend rather than a node key and a flow key that could be drawn together: two keys in a corner would not be clutter, they would be a contradiction.

scatter

scatter(
data,
x: str,
y: str,
color: Optional[str] = None,
on: str = 'cells',
layer: Optional[str] = None,
use_raw: Optional[bool] = None,
palette=None,
cmap=None,
point_size: Optional[float] = None,
alpha: float = 1.0,
density: str = 'auto',
density_threshold: int = 20000,
gridsize: int = 60,
logx: bool = False,
logy: bool = False,
marginals: bool = False,
vlines=None,
hlines=None,
figsize: Optional[tuple] = None,
title: Optional[str] = None,
xlabel: Optional[str] = None,
ylabel: Optional[str] = None,
legend_loc: str = 'right',
legend_fontsize: int = 9,
legend_marker_size: float = 6.0,
square: bool = True,
rasterized: bool = True,
frameon: Optional[bool] = True,
vmin: Optional[float] = None,
vmax: Optional[float] = None,
show: bool = True,
save: Optional[str] = None,
ax: Optional[matplotlib.axes._axes.Axes] = None,
return_fig: bool = False,
modality: Optional[str] = None,
cytome_layer: str = 'counts',
compute_on_fly: bool = True,
use_cached_stats: bool = True,
linewidths: float = 0.0,
edgecolors='none',
)
Signature defaults

data, x, y, color=None, on='cells', layer=None, use_raw=None, palette=None, cmap=None, point_size=None, alpha=1.0, density='auto', density_threshold=20000, gridsize=60, logx=False, logy=False, marginals=False, vlines=None, hlines=None, figsize=None, title=None, xlabel=None, ylabel=None, legend_loc='right', legend_fontsize=9, legend_marker_size=6.0, square=True, rasterized=True, frameon=True, vmin=None, vmax=None, show=True, save=None, ax=None, return_fig=False, modality=None, cytome_layer='counts', compute_on_fly=True, use_cached_stats=True, linewidths=0.0, edgecolors='none'

Scatter plot of two features colored by a third variable.

Parameters

data — AnnData or cytome Dataset/path

Input data.

x — str

Feature for X axis (gene name, obs column, or peak).

y — str

Feature for Y axis.

color — str, optional

Column for coloring points. Can be categorical (e.g. 'leiden') or continuous (e.g. a gene name). If None, all points are grey.

layer — str, optional

AnnData layer. Ignored for cytome.

use_raw — bool, optional

Use raw attribute. Ignored for cytome.

palette — list or dict, optional

Colors for categorical data. Falls back to PIASO default.

cmap — str, optional

Colormap. Defaults to 'magma_r' when color is continuous (sequential, perceptually uniform, colourblind-safe) and to PIASO’s density map when density=True. Colormap for continuous data.

point_size — float or None

Point size. If None, auto-calculated from cell count.

alpha — float

Point transparency.

figsize — tuple, optional

Figure size.

title — str, optional

Plot title. xlabel, ylabel : str, optional Axis labels. Default to feature names.

legend_loc — str

'right', 'on_data', or 'none'.

legend_fontsize — int

Legend font size.

legend_marker_size — float

Fixed legend dot size (pt), independent of point_size.

square — bool, default True

Keep the scatter axes square (set_box_aspect(1)) and, for a categorical color with legend_loc='right', put the legend in its own panel so a long category legend no longer squeezes the plot.

rasterized — bool

Rasterize points for smaller vector files.

frameon — bool, optional

Show axis frame. If None, uses piaso.settings._frameon. vmin, vmax : float, optional Continuous colorscale limits.

on — str, default 'cells'

What each point is. 'cells' → one point per cell, x/y are per-cell features (gene/peak/tile name or a cells column). A feature entity ('peaks' / 'genes' / 'tiles' / 'GA_genes' for a cytome, or 'var'/any for AnnData) → one point per feature, x/y are columns of that entity’s table (e.g. 'neg_log10_pvalue', 'score', or the derived 'width' = end_ - start).

density — 'auto' | 'scatter' | 'hexbin'

'auto' switches to a log-count hexbin above density_threshold points (unless colour is categorical). 'scatter' forces points; 'hexbin' forces density. With a continuous color the hexbin shows the per-cell mean.

density_threshold — int

Point count above which density='auto' uses hexbin.

gridsize — int

Hexbin grid resolution. logx, logy : bool Log-scale the X / Y axis.

marginals — bool

Add marginal histograms of x/y (only when ax is None). vlines, hlines : list of float, optional Vertical / horizontal reference lines (e.g. a min_length or score_cutoff threshold). show, save, ax, return_fig Output options.

linewidths — float, default 0.0

Marker edge width.

edgecolors — str, default ‘none’

Marker edge colour.

modality — str, optional

Cytome only: which modality the data was stored under ('RNA', 'ATAC', 'tiles', 'GA'). None takes the store’s first modality.

cytome_layer — str, default ‘counts’

Cytome only: the layer to read the values from.

compute_on_fly — bool, default True

Cytome only: normalise the raw layer while streaming (INFOG for RNA, TF-IDF for ATAC) instead of requiring a materialised layer.

use_cached_stats — bool, default True

Cytome only: reuse normalisation statistics already stored in the cytome’s metadata rather than recomputing them.

Returns

Optionally (fig, ax).

split_embedding

plot_embeddings_split(
data,
color,
splitby,
ncol: int = None,
dpi: int = 80,
col_size: int = 5,
row_size: int = 5,
alpha: float = 1.0,
vmax: float = None,
vmin: float = None,
vmin_pct: float = None,
vmax_pct: float = None,
show_figure: bool = True,
save: bool = None,
layer: str = None,
basis: str = 'X_umap',
fix_coordinate_ratio: bool = True,
show_axis_ticks: bool = False,
margin_ratio: float = 0.05,
legend_fontsize: int = 10,
legend_fontoutline: int = 2,
legend_fontbackground='white',
legend_fontbackground_alpha: float = 0.7,
legend_loc: str = 'right',
legend_marker_size: float = 6.0,
groups=None,
point_size: float = None,
palette=None,
cmap=None,
frameon: bool = False,
rasterized: bool = True,
modality: str = None,
cytome_layer: str = 'counts',
compute_on_fly: bool = True,
use_cached_stats: bool = True,
show_modality_in_title: bool = False,
x_min=None,
x_max=None,
y_min=None,
y_max=None,
image=False,
img_key='hires',
image_alpha=1.0,
linewidths: float = 0.0,
edgecolors='none',
**kwargs,
)
Signature defaults

data, color, splitby, ncol=None, dpi=80, col_size=5, row_size=5, alpha=1.0, vmax=None, vmin=None, vmin_pct=None, vmax_pct=None, show_figure=True, save=None, layer=None, basis='X_umap', fix_coordinate_ratio=True, show_axis_ticks=False, margin_ratio=0.05, legend_fontsize=10, legend_fontoutline=2, legend_fontbackground='white', legend_fontbackground_alpha=0.7, legend_loc='right', legend_marker_size=6.0, groups=None, point_size=None, palette=None, cmap=None, frameon=False, rasterized=True, modality=None, cytome_layer='counts', compute_on_fly=True, use_cached_stats=True, show_modality_in_title=False, x_min=None, x_max=None, y_min=None, y_max=None, image=False, img_key='hires', image_alpha=1.0, linewidths=0.0, edgecolors='none', **kwargs

Plot cell embeddings side by side based on a categorical variable.

The plots are split by a specified categorical variable, with each unique category producing a separate subplot. Data points in each subplot are colored according to the color variable.

Supports AnnData, cytome Dataset, or path to .cytome file.

Parameters

data — AnnData, cytome.Dataset, or str

An AnnData object, cytome Dataset, or path to .cytome file.

color — str

Used to specify a gene name to plot, or a key in adata.obs used to assign colors to the cells in the embedding plot.

splitby — str

Key in adata.obs used to split the dataset into multiple panels. Each unique value under this key will result in a separate subplot.

ncol — int or None, optional (default: None)

If specified, defines the number of columns per row. If None, the number of columns is computed as the ceiling of n divided by the integer square root of n.

dpi — int, optional (default: 80)

Dots per inch (DPI) setting for the figure.

col_size — int, optional (default=5)

Width (in inches) of each subplot column.

row_size — int, optional (default=5)

Height (in inches) of each subplot row.

vmax — float or None, optional (default=None)

Maximum value for the color scale. If not provided, the upper limit is determined automatically.

vmin — float or None, optional (default=None)

Minimum value for the color scale. If not provided, the lower limit is determined automatically.

show_figure — bool, optional (default=True)

Whether to display the figure after plotting.

save — str or None, optional (default=None)

File path to save the resulting figure. If None, the figure will not be saved.

layer — str or None, optional (default=None)

If specified, the name of the layer in adata.layers from which to obtain the gene expression values.

basis — str, optional (default=‘X_umap’)

Key in adata.obsm that contains the embedding coordinates (e.g., X_umap or X_pca).

fix_coordinate_ratio — bool, optional (default=True)

If True, the aspect ratio of each subplot is fixed so that the x- and y-axes are scaled equally.

show_axis_ticks — bool, optional (default=False)

Whether to display axis ticks and tick labels on the plots.

margin_ratio — float, optional (default=0.05)

Margin ratio for both the x-axis and y-axis limits, relative to the range of the data. This provides additional spacing around the plotted points.

legend_fontsize — int, optional (default=10)

Font size in pt.

legend_fontoutline — int, optional (default=2)

Line width of the legend font outline in pt.

legend_fontbackground — str or None, optional (default=‘white’)

Colour of the patch behind each 'on_data' label; None for no patch.

legend_fontbackground_alpha — float, optional (default=0.7)

Opacity of that patch.

legend_loc — str, optional (default=‘right’)

Where to put the category labels. One of:

  • 'right' — a single shared legend in the figure’s right margin.
  • 'on_data' — labels drawn at each cluster’s centroid, in every panel.
  • 'both' — centroid labels and the shared right-margin legend. Use this while you are still working out what a cluster is: the on-data label tells you which cluster you are looking at, the margin legend lets you read a colour off the list. Neither alone does both.
  • 'none' — no legend.

Any other value raises ValueError rather than silently drawing nothing.

legend_marker_size — float, optional (default=6.0)

Legend dot size. In the right-margin legend it is the marker scale (relative to the data points); in the global/multi-panel legend it is the absolute marker size in points. None auto-sizes from the data point_size (capped to avoid oversized dots on large datasets).

x_min — float or None, optional (default=None)

Minimum limit for the x-axis. If None, the limit is computed automatically based on the data.

x_max — float or None, optional (default=None)

Maximum limit for the x-axis. If None, the limit is computed automatically based on the data.

y_min — float or None, optional (default=None)

Minimum limit for the y-axis. If None, the limit is computed automatically based on the data.

y_max — float or None, optional (default=None)

Maximum limit for the y-axis. If None, the limit is computed automatically based on the data.

point_size — float, optional

Scatter point size. An explicit value always overrides the auto-size. If None, auto-scaled (max(0.1, min(3, 22000 / n_cells)), clamped to [0.1, 8]). Accepts size= as an alias for scanpy-style call sites.

palette — list[str] or dict, optional

Categorical palette. If None, falls back to adata.uns['{color}_colors'] (or the cytome metadata equivalent), then to the PIASO default d_color4. Mapping is held consistent across panels so the same category gets the same colour in every subplot.

cmap — str or Colormap, optional

Colourmap for numeric color values. Forwarded to each panel.

frameon — bool, optional (default False)

Whether to show axis spines on each panel and on the global legend frame. Mirrors piaso.pl.plotEmbedding(frameon=...).

rasterized — bool, optional (default True)

Forward to per-panel scatter for compact vector output.

linewidths — float, optional (default 0)

Marker stroke width, in points. Zero by default. Matplotlib otherwise strokes every point at rcParams['patch.linewidth'] (1.0 pt) in edgecolors='face', which for cell-sized markers is most of the dot: point_size=0.2 is a disc 0.45 pt across inside a 1.0 pt stroke, so it draws 3.2x the size asked for, and under alpha < 1 the stroke and fill composite twice around the rim — ringed dots with a washed-out core, visible once a PDF is enlarged. Pass a positive value to outline markers deliberately.

Changed in 1.2.4: was matplotlib’s 1.0 pt default.

edgecolors — color or ‘none’, optional (default ‘none’)

Marker stroke colour. Only meaningful with linewidths > 0.

Changed in 1.2.4: was matplotlib’s 'face'.

**kwargs — dict

Accepts the aliases ncols (→ ncol), size (→ point_size) and show (→ show_figure). Anything else raises TypeError.

Changed in 1.2.4: unrecognised keywords used to be accepted and silently discarded, so a caller styling the panels got no error and no effect — and show=False, which every other piaso.pl function understands, displayed the figure regardless.

image — bool or str, default False

Draw the library’s tissue image under the spots (basis='spatial' workflows). True auto-selects when exactly one library has an image (or the plotted cells span one) and raises naming the options otherwise; a string selects that library. Sources: AnnData uns['spatial'] or a cytome’s stored images (cytome ≥ 0.2.6). The y-axis follows the image convention (top of the tissue at the top) only when an image is drawn.

img_key — str, default ‘hires’

Which image of the library to draw (‘hires’, ‘lowres’, …).

image_alpha — float, default 1.0

Opacity of the tissue image.

alpha — float, default 1.0

Point opacity. vmin_pct, vmax_pct : float, optional Colour-scale limits as percentiles of the values, when vmin / vmax are not given.

groups — sequence of str, optional

Which groups of splitby to draw; all when None.

show_modality_in_title — bool, default False

Cytome only: prefix panel titles with the modality.

modality — str, optional

Cytome only: which modality the data was stored under ('RNA', 'ATAC', 'tiles', 'GA'). None takes the store’s first modality.

cytome_layer — str, default ‘counts’

Cytome only: the layer to read the values from.

compute_on_fly — bool, default True

Cytome only: normalise the raw layer while streaming (INFOG for RNA, TF-IDF for ATAC) instead of requiring a materialised layer.

use_cached_stats — bool, default True

Cytome only: reuse normalisation statistics already stored in the cytome’s metadata rather than recomputing them.

Returns

None.

Examples

>>> import anndata
>>> import piaso
>>> adata = anndata.read_h5ad('pbmc3k.h5ad') # Load an example dataset
>>> # Plot embeddings colored by a gene expression value and split by clusters
>>> piaso.pl.plot_embeddings_split(adata, color='CDK9', splitby='louvain', col_size=6, row_size=6)
>>> # Save the figure to a file
>>> piaso.pl.plot_embeddings_split(adata, color='CDK9', splitby='louvain', save='./CST3_embeddingsSplit.pdf')

stacked_barplot

stacked_barplot(
data,
groupby: str = 'leiden',
splitby: str = 'batch',
normalize: bool = True,
sort_groups: bool = False,
palette=None,
figsize: Optional[tuple] = None,
title: Optional[str] = None,
legend_ncol: Optional[int] = None,
legend_fontsize: int = 9,
show: bool = True,
save: Optional[str] = None,
ax: Optional[matplotlib.axes._axes.Axes] = None,
return_fig: bool = False,
)
Signature defaults

data, groupby='leiden', splitby='batch', normalize=True, sort_groups=False, palette=None, figsize=None, title=None, legend_ncol=None, legend_fontsize=9, show=True, save=None, ax=None, return_fig=False

Plot a stacked barplot of cell composition.

Parameters

data — AnnData or cytome Dataset/path

Input data.

groupby — str

Column for cell groups (bar segments).

splitby — str

Column for conditions/samples (bar positions on X axis).

normalize — bool

Normalize to fractions per splitby category.

sort_groups — bool

Order the stacked segments largest-proportion-first instead of following the group’s category order. Default False: the segment order then matches the legend, and the same colour sits at the same height in every bar, which is what makes two bars comparable by eye. Set True when a single bar’s composition is the question and the ranking is the answer. The ranking uses the mean proportion across splitby categories, so one order applies to the whole plot; a per-bar ranking would put a different cell type at the bottom of every bar and make the plot unreadable.

palette — list or dict, optional

Colors for groups. Falls back to adata.uns then d_color4.

figsize — tuple, optional

Figure size.

title — str, optional

Plot title.

legend_ncol — int, optional

Legend columns. Auto-calculated if None.

legend_fontsize — int

Legend font size.

show — bool

Call plt.show().

save — str, optional

Save path.

ax — Axes, optional

Pre-existing axes.

return_fig — bool

Return (fig, ax).

stackedBarplot

stacked_barplot(
data,
groupby: str = 'leiden',
splitby: str = 'batch',
normalize: bool = True,
sort_groups: bool = False,
palette=None,
figsize: Optional[tuple] = None,
title: Optional[str] = None,
legend_ncol: Optional[int] = None,
legend_fontsize: int = 9,
show: bool = True,
save: Optional[str] = None,
ax: Optional[matplotlib.axes._axes.Axes] = None,
return_fig: bool = False,
)
Signature defaults

data, groupby='leiden', splitby='batch', normalize=True, sort_groups=False, palette=None, figsize=None, title=None, legend_ncol=None, legend_fontsize=9, show=True, save=None, ax=None, return_fig=False

Plot a stacked barplot of cell composition.

Parameters

data — AnnData or cytome Dataset/path

Input data.

groupby — str

Column for cell groups (bar segments).

splitby — str

Column for conditions/samples (bar positions on X axis).

normalize — bool

Normalize to fractions per splitby category.

sort_groups — bool

Order the stacked segments largest-proportion-first instead of following the group’s category order. Default False: the segment order then matches the legend, and the same colour sits at the same height in every bar, which is what makes two bars comparable by eye. Set True when a single bar’s composition is the question and the ranking is the answer. The ranking uses the mean proportion across splitby categories, so one order applies to the whole plot; a per-bar ranking would put a different cell type at the bottom of every bar and make the plot unreadable.

palette — list or dict, optional

Colors for groups. Falls back to adata.uns then d_color4.

figsize — tuple, optional

Figure size.

title — str, optional

Plot title.

legend_ncol — int, optional

Legend columns. Auto-calculated if None.

legend_fontsize — int

Legend font size.

show — bool

Call plt.show().

save — str, optional

Save path.

ax — Axes, optional

Pre-existing axes.

return_fig — bool

Return (fig, ax).

umap

plotUMAP(data, color='leiden', **kwargs)
Signature defaults

data, color='leiden', **kwargs

Convenience wrapper for :func:plotEmbedding with basis='X_umap'.

violin

plot_features_violin(
data,
feature_list,
groupby: Optional[str] = None,
use_raw: Optional[bool] = None,
layer: Optional[str] = None,
palette=None,
jitter: bool = False,
width_single: float = None,
height_single: float = 2.0,
ncol: Optional[int] = None,
violin_width: float = 0.7,
size: float = 0.1,
show_grid: bool = True,
show_median: bool = True,
median_color: str = 'lightgrey',
show_figure: bool = True,
save: Optional[str] = None,
modality: Optional[str] = None,
cytome_layer: str = 'counts',
compute_on_fly: bool = True,
use_cached_stats: bool = True,
show: Optional[bool] = None,
return_fig: bool = False,
)
Signature defaults

data, feature_list, groupby=None, use_raw=None, layer=None, palette=None, jitter=False, width_single=None, height_single=2.0, ncol=None, violin_width=0.7, size=0.1, show_grid=True, show_median=True, median_color='lightgrey', show_figure=True, save=None, modality=None, cytome_layer='counts', compute_on_fly=True, use_cached_stats=True, show=None, return_fig=False

Plots a violin plot for each feature specified in feature_list.

Uses matplotlib directly (no scanpy dependency). Supports AnnData and cytome Dataset / .cytome file path.

show is accepted as an alias for show_figure: every other plotting function in piaso.pl takes show, and a call that works for pl.embedding and pl.dotplot should not raise here for the sake of one function’s parameter name. When both are given, show wins.

Parameters

data — anndata.AnnData, cytome.Dataset, or str

The data source. For AnnData, reads from obs, layers, or raw. For cytome, reads from the cells SQL table.

feature_list — List[str]

Feature names to visualize. For cytome, these must be column names in the cells table.

groupby — str, optional

Column to group data points by. Default is None.

use_raw — bool, optional

Use raw attribute of adata. Ignored for cytome.

layer — str, optional

AnnData layer to use. Ignored for cytome.

palette — list or dict, optional

Color palette for groups. If None, checks adata.uns['{groupby}_colors'] first, then falls back to the default PIASO palette.

jitter — bool, optional

Show jitter scatter points on violins. Default is False.

width_single — float, optional

Figure width in inches. None (default) derives it from the number of groups — 1.6 + 0.42 * n_groups, clamped to [3, 16] — so a two-sample plot is not the same width as a forty-cluster one. Pass a number to override. Width of each subplot. Default is 14.0.

violin_width — float, optional

Width of each violin body in x-axis units, where 1.0 is the spacing between groups. Default 0.7.

ncol — int, optional

Panels per row. None (default) puts ungrouped features two to a row and grouped ones one to a row, since a grouped panel is already as wide as its group count requires.

height_single — float, optional

Height of each subplot. Default is 2.0.

size — float, optional

Jitter point size (only used when jitter=True). Default is 0.1.

show_grid — bool, optional

Show grid lines. Default is True.

show_median — bool, optional

Show median line on violins. Default is True.

median_color — str, optional

Color of the median line. Default is 'lightgrey'.

show_figure — bool, optional

Show figure (plt.show()). Default is True.

save — str, optional

Path to save the figure. Default is None.

return_fig — bool, optional

Return (fig, axes) instead of closing the figure.

show — bool, optional

Show the figure; None follows show_figure.

modality — str, optional

Cytome only: which modality the data was stored under ('RNA', 'ATAC', 'tiles', 'GA'). None takes the store’s first modality.

cytome_layer — str, default ‘counts’

Cytome only: the layer to read the values from.

compute_on_fly — bool, default True

Cytome only: normalise the raw layer while streaming (INFOG for RNA, TF-IDF for ATAC) instead of requiring a materialised layer.

use_cached_stats — bool, default True

Cytome only: reuse normalisation statistics already stored in the cytome’s metadata rather than recomputing them.

Moved to cytorete

These names still work, but the method they call now lives in cytorete — pip install cytorete, then use it directly as cytorete.tl.<name>. Calling them through PIASO raises a pointer to that package if it is not installed.

regulonActivity, regulonEmbedding, regulonNetwork, regulonSpecificityScatter