obs (cell metadata)#
Audience: everyone
Time: 10 minutes
Goal: know how each obs column is stored and shown
obs is a pandas DataFrame with one row per cell, in the cell order of the
embeddings. Its index names the cells (Input requirements (global)).
Every column is stored; the viewer lists them as fields to colour and filter
by.
How each column is stored#
The rules are anndata’s own encodings, applied the same way by
cellucid_prepare() in R:
Column |
Stored as |
|---|---|
text, where a value repeats or is missing |
|
text, every value distinct and present (barcodes, ids) |
|
pandas |
|
float |
its float dtype, NaN as missing |
integer |
its integer dtype |
boolean |
|
pandas nullable |
|
Refused, with the conversion that makes them storable:
infinities in a float column (
replace it with NaN);text mixed with other values in one column (
.astype(str));dates, times, intervals, complex numbers and other types with no AnnData encoding Cellucid writes (
.astype(str)or.astype(float));categories that are not text or numbers.
Category labels are stored exactly as given. 'Liver' and 'Liver ' are two
categories; clean labels before preparing if they should be one.
Choosing and ordering fields: obs_keys=#
cellucid.prepare(
"data.h5ad",
format="h5ad",
embeddings={"X_umap": umap},
dataset_id="pbmc-3k",
dataset_name="PBMC 3k",
obs=adata.obs,
obs_keys=["cell_type", "leiden", "total_counts"],
)
obs_keys is written to uns['cellucid']['defaults']['obsKeys']: the viewer
lists those columns, in that order. Every obs column is stored either way, so
other tools still read them. Each key must be a column of obs, named once.
To leave columns out of the file, drop them from obs before the call.
Centroids and outliers#
Categorical centroids and their labels are computed by the browser from the embeddings; nothing about them is stored.
Latent-space outlier quantiles are stored when you name a latent space with
latent_key: for every categorical obs column (categorical, text, boolean
or nullable boolean), each cell’s distance to its category’s centre in that
latent space, as the share of its category at that distance or closer, in
uns['cellucid']['outlierQuantiles']. A category with fewer than
centroid_min_points cells (10 when None) gets none, and a column none of
whose categories reaches it gets no entry. The viewer’s outlier filter then
works at once; without them it computes the same values in the browser on
first use (Embeddings and coordinates,
Outlier filtering (per categorical field)).
Next#
The same topic for R,
cellucid_prepare(): obs: cell metadata