Vector fields (velocity / drift overlays)#
Cellucid “vector fields” are per-cell displacement vectors in embedding space.
They enable overlays such as:
RNA velocity particle flow (scVelo-style, if you already have vectors)
CellRank drift vectors derived from a transition matrix
This page documents:
Mental model (beginner-friendly)#
You have an explicitly dimensioned embedding such as
X_umap_2dwith shape(n_cells, 2).You compute (or already have) vectors with the same shape.
Cellucid visualizes those vectors as an animated overlay on top of the embedding.
Vectors are not absolute positions. Each row is a displacement at the corresponding cell, and the viewer integrates those displacements into animated particle flow.
Practical path (common workflows)#
1) From a CellRank transition matrix → drift vectors#
from cellucid import compute_transition_drift
drift = compute_transition_drift(T, adata.obsm["X_umap_2d"], normalize_rows=True)
Where:
Tis(n_cells, n_cells)(dense or sparse)adata.obsm["X_umap_2d"]is(n_cells, 2)
2) Store drift in adata.obsm using Cellucid naming conventions#
from cellucid import add_transition_drift_to_obsm
key = add_transition_drift_to_obsm(
adata,
T,
basis="umap",
field_prefix="T_fwd",
normalize_rows=True,
)
print("Wrote vector field to:", key)
This writes a key like:
T_fwd_umap_2dorT_fwd_umap_3d
3) Export the vectors so the viewer can load them#
from cellucid import prepare
prepare(
latent_space=adata.obsm["X_pca"],
obs=adata.obs,
var=adata.var,
gene_expression=adata.X,
X_umap_2d=adata.obsm["X_umap_2d"],
vector_fields={
# You can pass the new obsm entry directly
key: adata.obsm[key],
},
out_dir="./my_export",
dataset_name="My study",
dataset_id="my-study-v1",
obs_categorical_dtype="uint16",
)
Naming conventions (important)#
Every vector-field declaration key must follow
<field>_<basis>_<dim>d, for example velocity_umap_2d or
T_fwd_umap_3d. Unsuffixed keys are not discovered as vector fields.
API reference#
- cellucid.compute_transition_drift(transition_matrix, embedding, *, normalize_rows)[source]#
Compute exact per-cell transition drift in embedding space.
Edge cases (do not skip)#
Row normalization (transition matrices)#
Choose
normalize_rows=Trueto divide each transition row by its sum, ornormalize_rows=Falsewhen the matrix already has the exact row semantics you intend. The choice is required.Rows with sum 0 are handled safely (division-by-zero is avoided), but the resulting drift can be zero/undefined depending on the matrix.
Shape mismatches#
transition_matrixmust be(n_cells, n_cells)embeddingmust be(n_cells, dim)The product
T @ embeddingmust produce(n_cells, dim)
Dimension mismatch between export and vectors#
If you export
X_umap_3dbut only provide*_umap_2dvectors, the 3D overlay will not be available.
Troubleshooting (symptom → diagnosis → fix)#
Symptom: “embedding must be 2D”#
Fix:
Ensure you pass an array shaped
(n_cells, dim)(not a flattened vector).
Symptom: “T @ embedding produced shape …”#
Fix:
Confirm
Tis(n_cells, n_cells)and aligned to the same cell order as the embedding.
Symptom: “Vector overlay is not available / not visible in the viewer”#
Likely causes:
You did not export the vector field (or you are serving in AnnData mode without exposing it).
The key naming doesn’t match the embedding dimension currently shown (2D vs 3D).
How to confirm:
In an exported folder, check that
vectors/exists and contains files.In AnnData mode, confirm the vector field exists in
adata.obsmwith the expected key.
Fix:
Export vectors via
prepare(..., vector_fields={...}).Use exact dimension-suffixed keys such as
velocity_umap_2dandvelocity_umap_3d.
Symptom: “Drift vectors look backwards”#
Likely causes:
You used a backward transition matrix or the wrong convention for
field_prefix.
Fix:
Compute/label forward vs backward consistently (e.g.,
field_prefix="T_fwd"vs"T_bwd").Validate by checking a few expected transitions in a small subset.
See also#
Export / Data Preparation (prepare) for exporting vector fields via
prepare(...)