Plotting (velot.pl)

Visualization functions for the VelOT pipeline. Follows the scanpy/scvelo convention.

All functions accept show=True (display immediately) and save=None (path to save the figure).

Usage:

import velot

velot.pl.velocity_stream(adata, color="clusters")
velot.pl.windows(adata)
velot.pl.training_curves(adata)
velot.pl.dataset_overview_simple(adata, color='clusters', basis='umap', title='', show=True, save=False, save_path=None, figsize=(5, 5), ax=None, inframe=False)[source]

Overview of the dataset: embedding colored by clusters and pseudotime.

Parameters:
  • adata (AnnData) – Annotated data matrix with UMAP and pseudotime computed.

  • color (str) – Column in adata.obs for cluster coloring.

  • basis (str) – Embedding to plot ('umap' or 'pca').

  • show (bool) – Whether to display the figure.

  • save (bool) – File path to save the figure. None to skip.

  • figsize (tuple) – Figure size.

  • title (str | None)

  • save_path (str | None)

  • ax (Axes | None)

  • inframe (bool)

Return type:

matplotlib Figure.

velot.pl.dataset_overview(adata, color='clusters', basis='umap', title='', show=True, save=False, save_path=None, figsize=(5, 5), inframe=False, out_legend=False, vertical=False)[source]

Overview of the dataset: embedding colored by clusters and pseudotime.

Parameters:
  • adata (AnnData) – Annotated data matrix with UMAP and pseudotime computed.

  • color (str) – Column in adata.obs for cluster coloring.

  • basis (str) – Embedding to plot ('umap' or 'pca').

  • show (bool) – Whether to display the figure.

  • save (bool) – File path to save the figure. None to skip.

  • figsize (tuple) – Figure size.

  • title (str | None)

  • save_path (str | None)

  • inframe (bool)

  • out_legend (bool)

  • vertical (bool)

Return type:

matplotlib Figure.

velot.pl.add_umap_axis(ax, basis='umap', pos=(0, 0), length=0.2, fontsize=10)[source]

Draw equal-length axis arrows on a scatter plot.

The arrows are guaranteed to be the same physical length on screen regardless of the axes aspect ratio.

Parameters:
  • ax – Matplotlib Axes to draw on.

  • basis'umap' or 'pca' — controls the labels.

  • pos – Position of the arrow origin in axes fraction (0–1).

  • length – Arrow length in axes-fraction units (applied to the x-direction; the y-direction is adjusted to match).

  • fontsize – Label font size.

velot.pl.windows(adata, basis='umap', pairs_to_show=None, max_show=12, ncols=4, point_size=20, title=None, pair_title=False, frameon=False, show=True, save=False, save_path=None, figsize_per_panel=(3, 3))[source]

Visualize the spatial-temporal windows.

Each panel shows one window pair: source cells in blue, target cells in orange. Overlap is shown in green.

Parameters:
  • adata (AnnData) – Must have adata.uns['velot_windows'] from velot.tl.build_windows().

  • basis (str) – Embedding to plot in.

  • pairs_to_show (Optional[Sequence[int]]) – Specific pair indices to display. For example, [10, 13, 14, 15] shows only those four pairs. If None, shows the first max_show pairs.

  • max_show (int) – Maximum number of pairs when pairs_to_show is None.

  • ncols (int) – Number of columns in the grid.

  • point_size (int) – Scatter point size.

  • show (bool) – Whether to display.

  • save (bool) – File path to save.

  • title (str | None)

  • pair_title (bool)

  • frameon (bool)

  • save_path (str | None)

  • figsize_per_panel (tuple)

Return type:

matplotlib Figure.

Examples

Show first 8 pairs:

velot.pl.windows(adata, max_show=8)

Show specific pairs:

velot.pl.windows(adata, pairs_to_show=[10, 13, 14, 15])
velot.pl.window_transport(adata, pair_index, basis='umap', velocity_basis='X_pca', reg=0.05, lambda_time=1.0, lambda_knn=1.0, show_top_k=None, padding=0.3, background_alpha=0.4, background_size=15, background_color='lightgray', point_size=60, arrow_alpha=0.4, arrow_width=0.003, arrow_color='black', colorby_weight=True, cluster_key=None, frameon=False, show=True, save=False, save_path=None, figsize=(4, 4))[source]

Zoom into a window pair showing OT transport on the full dataset.

All cells are shown as context (gray or colored by cluster), with source and target cells highlighted and transport arrows overlaid. The axes are zoomed to the window region.

Parameters:
  • adata (AnnData) – Must have windows computed.

  • pair_index (int) – Index of the window pair to visualize.

  • basis (str) – Embedding for visualization.

  • velocity_basis (str) – Embedding where OT is computed (for recomputing the plan).

  • reg (float) – Sinkhorn regularization.

  • lambda_time (float) – Pseudotime backward penalty.

  • lambda_knn (float) – Non-neighbor penalty.

  • show_top_k (Optional[int]) – Show arrows only to top-k targets per source cell. None shows all above a threshold.

  • padding (float) – Fractional padding around the window for zoom.

  • background_alpha (float) – Transparency of background (non-window) cells.

  • background_size (int) – Point size of background cells.

  • background_color (str) – Color for background cells when cluster_key is None.

  • point_size (int) – Size of source/target cells.

  • arrow_alpha (float) – Arrow transparency.

  • arrow_width (float) – Arrow line width.

  • arrow_color (str) – Arrow color when colorby_weight=False.

  • colorby_weight (bool) – Color arrows by transport weight.

  • cluster_key (Optional[str]) – If provided, background cells are colored by cluster instead of uniform gray. Gives spatial context.

  • frameon (bool) – Show axes frame.

  • show (bool) – Display the figure.

  • save (bool) – File path to save.

  • save_path (str | None)

  • figsize (tuple)

Return type:

Figure

Examples

# With cluster context
velot.pl.window_transport(adata, 5, cluster_key="clusters")

# Clean, gray background
velot.pl.window_transport(adata, 5)

# Top-3 connections only
velot.pl.window_transport(adata, 5, show_top_k=3)
velot.pl.velocity_stream(adata, color='clusters', basis='umap', velocity_key='velot_velocity', title='VelOT velocity', show=True, save=False, save_path=None, figsize=(4, 4), ax=None, **kwargs)[source]

Stream plot of the velocity field.

Uses scVelo’s stream plotting if available, falls back to a quiver plot otherwise.

Parameters:
  • adata (AnnData) – Must have adata.obsm['velocity_umap'].

  • color (str) – Column in adata.obs for cell coloring.

  • basis (str) – Embedding basis.

  • velocity_key (str) – Key in adata.obsm containing the velocity to plot.

  • title (Optional[str]) – Plot title. Defaults to “VelOT velocity”.

  • show (bool) – Whether to display.

  • save (bool) – File path to save.

  • **kwargs – Passed to scvelo.pl.velocity_embedding_stream or quiver.

  • save_path (str | None)

  • figsize (tuple)

  • ax (Axes | None)

Return type:

matplotlib Figure.

velot.pl.velocity_quiver(adata, color='clusters', basis='umap', velocity_key='velocity_umap', title=None, spot_size=50, arrow_scale=1.0, subsample=None, arrow_color='black', arrow_alpha=0.7, normalize_arrows=False, show=True, save=False, save_path=None, figsize=(5, 5), ax=None, **scatter_kwargs)[source]

Quiver plot of velocity arrows overlaid on a scVelo/scanpy scatter.

Uses scVelo’s scatter as the base plot for consistent styling (colors, legends, layout). Falls back to scanpy, then to plain matplotlib if neither is available.

Parameters:
  • adata (AnnData) – Must have embedding and velocity computed.

  • color (str) – Column in adata.obs for coloring cells (passed to the base scatter plot).

  • basis (str) – Embedding to use: "umap", "pca", etc. Looks for adata.obsm[f"X_{basis}"].

  • velocity_key (str) – Key in adata.obsm with velocity vectors in the same coordinate system as the embedding. For UMAP basis, use projected UMAP velocities. For PCA basis, use PCA velocities (only the first 2 components are plotted).

  • title (Optional[str]) – Plot title.

  • arrow_scale (float) – Multiplier for arrow length. Increase to make arrows longer, decrease to shorten them.

  • subsample (Optional[int]) – Number of cells to show arrows for. None for all cells. Recommended ~500-1000 for readability.

  • arrow_color (str) – Color of the quiver arrows. Can be any matplotlib color.

  • arrow_alpha (float) – Transparency of arrows (0–1).

  • normalize_arrows (bool) – If True, all arrows have the same length (unit vectors), showing direction only. Useful when velocity magnitudes vary wildly.

  • show (bool) – Whether to display the plot.

  • save (bool) – Path to save the figure.

  • figsize (tuple) – Figure size in inches.

  • **scatter_kwargs – Extra keyword arguments passed to the base scatter plot (e.g., legend_loc, size, alpha, palette).

  • save_path (str | None)

  • ax (Axes | None)

Return type:

matplotlib Figure.

Examples

Basic quiver on UMAP:

velot.pl.velocity_quiver(adata, velocity_key="velocity_umap")

Quiver on PCA (first 2 components), subsampled:

velot.pl.velocity_quiver(
    adata, basis="pca", velocity_key="velot_velocity",
    subsample=500,
)

Normalized arrows colored red:

velot.pl.velocity_quiver(
    adata, normalize_arrows=True, arrow_color="red",
    arrow_scale=0.5, subsample=800,
)
velot.pl.confidence(adata, basis='umap', show=True, save=False, save_path=None, figsize=(7, 6))[source]

Plot per-cell velocity confidence (how many windows contributed).

Low confidence regions are where the OT velocity is uncertain or missing, and the smoothing network is interpolating.

Return type:

matplotlib Figure.

Parameters:
velot.pl.training_curves(adata, vertical=False, show=True, save=False, save_path=None, figsize=(10, 4))[source]

Plot training loss curves from the smoothing step.

Return type:

matplotlib Figure.

Parameters:
velot.pl.training_curves_single(adata, show=True, save=False, save_path=None, figsize=(7, 7))[source]

Plot training loss curves from the smoothing step.

Return type:

matplotlib Figure.

Parameters:
velot.pl.spatial_clusters(adata, basis='umap', show=True, save=False, save_path=None, figsize=(7, 6))[source]

Visualize the spatial clusters used for windowing.

Return type:

matplotlib Figure.

Parameters:
velot.pl.velocity_comparison(adata, velocity_keys, titles=None, color='clusters', basis='umap', show=True, save=False, save_path=None, figsize_per_panel=(6, 5))[source]

Side-by-side stream plots comparing multiple velocity fields.

Parameters:
  • adata (AnnData) – Annotated data matrix.

  • velocity_keys (Sequence[str]) – List of keys in adata.obsm with velocity fields to compare.

  • titles (Optional[Sequence[str]]) – Optional titles for each panel.

  • color (str)

  • basis (str)

  • show (bool)

  • save (bool)

  • save_path (str | None)

  • figsize_per_panel (tuple)

Return type:

matplotlib Figure.

Example

# Compare raw vs smoothed velocity
velot.pl.velocity_comparison(
    adata,
    velocity_keys=["velot_velocity_raw_umap", "velocity_umap"],
    titles=["Raw OT", "Smoothed"],
)
velot.pl.gridsearch_results(df, metric='iccoh_mean', param_x=None, param_hue=None, show=True, save=False, save_path=None, figsize=(12, 5))[source]

Visualize grid search results.

Parameters:
  • df – DataFrame returned by velot.tl.gridsearch().

  • metric (str) – Column to plot as the y-axis.

  • param_x (Optional[str]) – Parameter for x-axis grouping. If None, auto-detected.

  • param_hue (Optional[str]) – Parameter for color grouping. If None, auto-detected.

  • show (bool) – Whether to display.

  • save (bool) – File path to save.

  • save_path (str | None)

  • figsize (tuple)

Return type:

matplotlib Figure.

Example

results = velot.tl.gridsearch(adata, param_grid, ...)
velot.pl.gridsearch_results(results, metric="cbdir_mean")
velot.pl.trajectories(adata, trajectory_ids=None, color='clusters', basis='umap', line_color='black', line_alpha=0.7, line_width=1, line_style='--', start_marker='o', start_size=50, start_color='gray', end_marker='o', end_size=50, end_color='black', arrow_frequency=30, arrow_size=10, show_start=True, show_end=True, show_arrows=True, frameon=False, title=None, ax=None, show=True, save=False, save_path=None, figsize=(5, 5), **scanpy_kwargs)[source]

Plot cell trajectories on top of a scanpy embedding plot.

Parameters:
  • adata (AnnData) – Must have adata.uns['velot_trajectories'].

  • trajectory_ids (Optional[Sequence[int]]) – List of trajectory IDs to plot. If None, plots all. IDs are stored in each trajectory’s metadata "id" field. Use this to select specific trajectories after inspecting the metadata.

  • color (str) – Column passed to sc.pl.embedding.

  • basis (str) – Embedding basis.

  • line_color (str) – Color of trajectory lines.

  • line_alpha (float) – Line transparency.

  • line_width (float) – Line width.

  • line_style (str) – "-" solid, "--" dashed, ":" dotted.

  • start_marker (str) – Start point appearance.

  • start_size (int) – Start point appearance.

  • start_color (str) – Start point appearance.

  • end_marker (str) – End point appearance.

  • end_size (int) – End point appearance.

  • end_color (str) – End point appearance.

  • arrow_frequency (int) – Arrow every N steps.

  • arrow_size (float) – Arrowhead size.

  • show_start (bool) – Toggle visual elements.

  • show_end (bool) – Toggle visual elements.

  • show_arrows (bool) – Toggle visual elements.

  • frameon (bool) – Show axes frame.

  • title (Optional[str]) – Plot title.

  • ax (Optional[Axes]) – Pre-existing axes. If None, creates new figure with scatter background. If provided, draws scatter background and trajectories on it — useful for subplot grids.

  • show (bool) – Display the plot. Ignored when ax is provided (caller controls display).

  • save (bool) – Save path. Ignored when ax is provided.

  • **scanpy_kwargs – Passed to scv.pl.scatter for the background.

  • save_path (str | None)

  • figsize (tuple)

Return type:

matplotlib Axes.

Examples

Plot all trajectories:

velot.pl.trajectories(adata)

Plot specific trajectories by ID:

velot.pl.trajectories(adata, trajectory_ids=[0, 3, 7])

Grid of individual trajectories:

n = 10
cols = 5
rows = (n + cols - 1) // cols
fig, axes = plt.subplots(rows, cols, figsize=(5*cols, 5*rows))
for i in range(n):
    velot.pl.trajectories(
        adata, trajectory_ids=[i], ax=axes.flat[i],
        show=False, title=f"Trajectory {i}",
    )
for j in range(n, len(axes.flat)):
    axes.flat[j].axis("off")
plt.tight_layout()
plt.show()

Inspect metadata to choose which to plot:

meta = adata.uns["velot_trajectories"]["metadata"]
for m in meta:
    print(f"ID {m['id']}: {m['origin_cluster']} → "
          f"{m['terminal_cluster']} ({m['n_steps']} steps)")
velot.pl.trajectories(adata, trajectory_ids=[2, 5])
velot.pl.fate_summary(adata, show=True, save=False, save_path=None, figsize=(8, 4))[source]

Bar chart summarizing trajectory fate or origin.

For forward trajectories: shows terminal cluster distribution. For backward trajectories: shows origin cluster distribution.

Return type:

matplotlib Figure.

Parameters:
velot.pl.flow_simulation(adata, color='clusters', basis='umap', line_alpha=0.3, line_width=0.8, colorby='pseudotime', show_cells=True, cell_alpha=0.2, cell_size=8, show_start=True, show_end=True, frameon=False, title=None, show=True, save=False, save_path=None, figsize=(9, 8))[source]

Visualize the flow simulation — particles flowing through the velocity field like water through a river.

Parameters:
  • adata (AnnData) – Must have adata.uns['velot_flow'] from velot.tl.simulate_flow().

  • color (str) – Column for background cell coloring.

  • basis (str) – Embedding basis.

  • colorby (str) –

    How to color trajectories:
    • "pseudotime": color by pseudotime along trajectory (blue=early, red=late)

    • "cluster": color by starting cluster

    • "fate": color by terminal cluster

  • show_cells (bool) – Show background cells.

  • cell_alpha (float) – Background cell transparency.

  • cell_size (int) – Background cell size.

  • show_start (bool) – Mark starting positions with stars.

  • show_end (bool) – Mark ending positions with dots.

  • frameon (bool) – Show axes frame.

  • title (Optional[str]) – Plot title.

  • show (bool) – Display the plot.

  • save (bool) – File path to save.

  • line_alpha (float)

  • line_width (float)

  • save_path (str | None)

  • figsize (tuple)

Return type:

matplotlib Figure.

velot.pl.metric_summary(metrics, orientation='horizontal', layout='row', figsize=None, palette_name='Set2', median_color='black', frameon=True, show=True, save=False, save_path=None)[source]

Box plots of ICCoh and CBDir metrics from a precomputed summary.

Parameters:
  • metrics (dict) – Dictionary returned by velot.metrics.summary().

  • orientation (str) – "horizontal" or "vertical" box plots.

  • layout (str) – "row" or "column".

  • figsize (Optional[tuple]) – Custom figure size.

  • palette_name (str) – Seaborn color palette name. First color for ICCoh, second for CBDir.

  • median_color (str) – Median line color.

  • frameon (bool) – Show axes frame.

  • show (bool) – Display the figure.

  • save (bool) – File path to save.

  • save_path (str | None)

Return type:

matplotlib Figure.