Skip to content

Plotting

Plotting utilities for ALHENA tile embeddings, annotations and evaluation results. Each drawing function accepts a Matplotlib Axes object and returns the same object, allowing the plots to be composed into larger figures. The functions that draw annotations take an AnnotationResult, or the table of cells it was written to, read as io.read_annotations() reads it.

Install the plotting dependencies with pip install "alhena[viz]". They are imported only when the plotting functions are used.

See them in use: overlay() in Tutorial 3, tile_regions() in Tutorial 4, custom class colors in Tutorial 5, and confusion() and confidence_curve() in Tutorial 6.

alhena.viz.overlay

overlay(tile, nuclei, result, tile_index=None, ax=None, alpha=0.6, shade_by_confidence=False, show_no_call=True, colors=None, title=None, name=None)

Draw one tile with every nucleus tinted by the class it was annotated with.

The nuclei, in any form encode_cells reads, meet their annotations by cell identifier; a nucleus without one keeps the color of NO_CALL_NAME. Outlines and label maps are tinted pixel for pixel, centroids over the disks the cell path pools, and a membership table token by token, each token to the cell holding most of its pixels, ties to the lowest identifier; a tile other than the canvas size is then warned about. A label map of instance numbers is numbered for the tile tile_index names, as read_label_maps numbers it, or tile 0 with a warning.

Parameters:

Name Type Description Default
tile TileSource | ndarray

The tile source the nuclei were read against, whose tile tile_index is drawn, or one (H, W, 3) tile, uint8 bytes or floats in [0, 1], as read rather than normalized.

required
nuclei Any

The nuclei as an alhena.io reader returns them, label maps one per tile, an (H, W) label map of this tile, or a membership table with MEMBERSHIP_COLUMNS.

required
result AnnotationResult | AnnData

Annotations covering the cells of this tile, or the table of cells holding them.

required
tile_index int | None

Tile drawn, by its index among the tiles the nuclei were read against. Tile 0 when None, which a source must then hold alone.

None
ax Axes | None

Axes to draw on. A figure is created when none is given.

None
alpha float

Opacity of the tint, in (0, 1].

0.6
shade_by_confidence bool

Scale each nucleus opacity by its confidence, from the confidence floor of the axis up to mass one.

False
show_no_call bool

Draw the nuclei without an annotation in the color of NO_CALL_NAME.

True
colors Mapping[str, Any] | None

Palette of a custom taxonomy, replacing the default palette.

None
title str | None

Title of the panel. The counts of annotated and unannotated nuclei are used when none is given.

None
name str | None

Annotation of a table to draw, the name it was stored under. May be left out where the table holds one.

None

Returns:

Type Description
Axes

The axes drawn on, carrying the tile and the tint as two images.

Raises:

Type Description
AlhenaValueError

If an input is not a form ALHENA reads, or the tile or alpha is invalid.

GeometryError

If the tile or a label map is malformed, or of another size than the nuclei.

MembershipError

If the membership table is malformed or holds no row of this tile.

alhena.viz.tile_regions

tile_regions(tiles, values, ax=None, image=None, extent=None, colors=None, cmap='viridis', alpha=0.5, legend=True, title=None)

Draw every tile region filled with the color of its value, over the image it was read from.

Categories, such as tile clusters, take their colors from colors, else from a qualitative palette in the order of the categories, with a legend; numbers take a color from cmap, with a colorbar. A region runs from its first pixel to its last, pixel centers at integer coordinates, as alhena.io.read_region places its image. A tile without a value is left unfilled.

Parameters:

Name Type Description Default
tiles TileEmbeddings | AnnData | ndarray

Tile embeddings carrying spatial bounds, their table as TileEmbeddings.to_anndata lays it out, or an (n_tiles, 4) array of x0, y0, x1, y1 bounds, upper bounds excluded.

required
values Any

One value per tile, in the order of the tiles, or the name of a column of the table. A pandas categorical, text or booleans are drawn as categories, numbers on a scale.

required
ax Axes | None

Axes to draw on. A figure is created when none is given.

None
image ndarray | None

The (H, W, 3) image under the tiles, drawn first.

None
extent Sequence[float] | None

Left, right, bottom and top edges of the image in the frame of the bounds, as alhena.io.read_region returns them. The pixels of the image itself when None.

None
colors Mapping[Any, Any] | None

Color of each category, replacing the qualitative palette. For a column of the table, the colors scanpy stores beside it in uns when none are given.

None
cmap str

Colormap of numeric values.

'viridis'
alpha float

Opacity of the fill, in (0, 1].

0.5
legend bool

Draw the legend of the categories, or the colorbar of the numbers.

True
title str | None

Title of the panel.

None

Returns:

Type Description
Axes

The axes drawn on, carrying the image and one patch per tile with a value.

Raises:

Type Description
AlhenaValueError

If the tiles carry no bounds, or the values or a color do not fit them.

GeometryError

If the image is not an (H, W, 3) image.

alhena.viz.composition

composition(result, ax=None, normalize=True, show_no_call=True, missing_classes=None, colors=None, annotate=True, name=None)

Draw the share of cells annotated with each class, as bars.

Every class of the axis gets a bar, including the classes no cell was annotated with, so a class at zero reads as zero rather than as absent. A class the reference cannot express is hatched and named under the axis, because no cell could have been annotated with it.

Parameters:

Name Type Description Default
result AnnotationResult | AnnData

Annotations to summarize, or the table of cells holding them.

required
ax Axes | None

Axes to draw on. A figure is created when none is given.

None
normalize bool

Draw shares of the population rather than counts.

True
show_no_call bool

Add a bar for the cells without an annotation.

True
missing_classes Any

A Reference, or the names of the classes it holds no cell of. Read from the annotations when None; an empty sequence marks none.

None
colors Mapping[str, Any] | None

Palette of a custom taxonomy, replacing the default palette.

None
annotate bool

Write each bar's value above it, so a bar at zero stays legible.

True
name str | None

Annotation of a table to draw, the name it was stored under. May be left out where the table holds one.

None

Returns:

Type Description
Axes

The axes drawn on, carrying one bar per class and, when asked for, one for the cells

Axes

without an annotation.

Raises:

Type Description
AlhenaValueError

If the annotations or colors are unusable, or a missing class is unknown.

alhena.viz.confusion

confusion(score_report, ax=None, cmap='Blues', colorbar=True, missing_classes=None, annotate=True)

Draw a confusion matrix, normalizing each row over cells with a prediction.

Each row shows how cells with predictions from one known class are distributed across predicted classes. The diagonal equals recall only when every cell of that known class received a prediction. Cells without a prediction count as errors in recall, totaled below the x-axis. A row with no predictions is marked n=0, with undefined fractions displayed as -.

Parameters:

Name Type Description Default
score_report ScoreReport

Report to draw, supplying the matrix, the class order and the cell count.

required
ax Axes | None

Axes to draw on. A figure is created when none is given.

None
cmap str

Colormap of the shares.

'Blues'
colorbar bool

Draw the scale beside the matrix.

True
missing_classes Any

A Reference, or the names of the classes it holds no cell of. Read from the report when None; an empty sequence marks none.

None
annotate bool

Write each share in its cell.

True

Returns:

Type Description
Axes

The axes drawn on, carrying the matrix and, when asked for, the share written in each cell.

Raises:

Type Description
AlhenaValueError

If a named missing class is not a class of the axis.

alhena.viz.confidence_curve

confidence_curve(sweep, ax=None, metric='macro_f1', per_class=True, show_retained=True, missing_classes=None, colors=None)

Draw a confidence sweep, pooled and per class.

Per-class recall is drawn beside the pooled curve, and the legend names every class whose recall falls. Each sampled threshold carries a marker, joined to the next by a straight segment, nothing interpolated; a threshold where a class retains no cell leaves a gap.

Parameters:

Name Type Description Default
sweep DataFrame

The table metrics.confidence_sweep returns.

required
ax Axes | None

Axes to draw on. A figure is created when none is given.

None
metric str

Pooled column drawn against the per-class recalls.

'macro_f1'
per_class bool

Draw one recall curve per class.

True
show_retained bool

Draw the retained fraction of the population on a right-hand axis, which a rising pooled curve is read against.

True
missing_classes Any

A Reference, the annotations swept, or the names of the classes the reference holds no cell of. Read from the sweep when None.

None
colors Mapping[str, Any] | None

Palette of a custom taxonomy, replacing the default palette.

None

Returns:

Type Description
Axes

The axes drawn on, carrying the pooled curve and one line per class.

Raises:

Type Description
AlhenaValueError

If the sweep is not a table, is empty, or lacks a column being drawn.

alhena.viz.legend

legend(axis=DEFAULT_AXIS, ax=None, missing_classes=None, show_no_call=True, colors=None, ncols=1, title=None, name=None)

Draw a standalone class legend, for the overlays that carry none.

A class the reference cannot express is hatched and named.

Parameters:

Name Type Description Default
axis str | Sequence[str] | AnnotationResult | AnnData

Name of a class axis, the class names themselves, or annotations or the table of cells holding them, whose classes and missing classes the legend names.

DEFAULT_AXIS
ax Axes | None

Axes to draw on. A figure is created when none is given.

None
missing_classes Any

A Reference, or the names of the classes it holds no cell of. Read from annotations given as axis when None.

None
show_no_call bool

Add an entry for the cells without an annotation.

True
colors Mapping[str, Any] | None

Palette of a custom taxonomy, replacing the default palette.

None
ncols int

Columns of the legend.

1
title str | None

Title of the legend.

None
name str | None

Annotation of a table given as axis, the name it was stored under. May be left out where the table holds one.

None

Returns:

Type Description
Axes

The axes drawn on, carrying the legend and no ticks.

Raises:

Type Description
AlhenaValueError

If the axis or annotations are unusable, or a missing class is unknown.

alhena.viz.class_color

class_color(name, colors=None)

Return the palette color of one class.

Parameters:

Name Type Description Default
name str

Class name. The empty string, which a result carries where no annotation was assigned, takes the color of NO_CALL_NAME.

required
colors Mapping[str, Any] | None

Palette of a custom taxonomy, replacing the default palette. Integer triples are read on the byte scale and everything else as a matplotlib color.

None

Returns:

Type Description
RGB

Red, green and blue on the unit scale.

Raises:

Type Description
AlhenaValueError

If the palette in force declares no color for the class.

alhena.viz.class_palette

class_palette(names, colors=None)

Return the palette colors of several classes, in the order given.

Parameters:

Name Type Description Default
names Sequence[str]

Class names.

required
colors Mapping[str, Any] | None

Palette of a custom taxonomy, replacing the default palette.

None

Returns:

Type Description
list[RGB]

One RGB triple per name.

Raises:

Type Description
AlhenaValueError

If the palette in force declares no color for one of the classes.

alhena.viz.missing_class_names

missing_class_names(source, class_order=None)

Return the classes a reference holds no cell of.

Parameters:

Name Type Description Default
source Any

A Reference, a ReferenceInfo, an AnnotationResult or a ScoreReport, which record them, a sequence of class names, or None.

required
class_order Sequence[str] | None

Classes of the figure being drawn. When given, every name must be one of them, so a misspelling is caught rather than quietly marking nothing.

None

Returns:

Type Description
tuple[str, ...]

The class names, in the order they were declared in.

Raises:

Type Description
AlhenaValueError

If a name is given alone rather than in a sequence, or is not a class.

alhena.viz.NO_CALL_NAME module-attribute

NO_CALL_NAME = 'no annotation'

Name given in a legend or a composition bar to the cells without an annotation.

alhena.viz.NOT_IN_REFERENCE module-attribute

NOT_IN_REFERENCE = 'not in reference'

Note attached to a class the reference holds no cell of.

alhena.viz.MISSING_HATCH module-attribute

MISSING_HATCH = '///'

Hatch marking a bar or a patch standing for a class the reference cannot express.

alhena.viz.RGB module-attribute

RGB = 'tuple[float, float, float]'

Red, green and blue on the unit scale.


Next: Types