AnnDataΒΆ
import holoviews as hv
from hv_anndata.interface import ACCESSOR as A
from hv_anndata.interface import register
register()
hv.extension("bokeh")
Create synthetic dataΒΆ
from string import ascii_lowercase
import numpy as np
import pandas as pd
import scipy.sparse as sp
from anndata import AnnData
gen = np.random.default_rng()
x = gen.random((100, 50), dtype=np.float32)
layers = dict(a=sp.random(100, 50, format="csr"))
obs = pd.DataFrame(
dict(type=gen.integers(0, 3, size=100)),
index=pd.Series(range(100)).astype(str).apply(lambda v: "cell-" + v),
)
var_grp = pd.Categorical(
gen.integers(0, 6, size=50), categories=list(ascii_lowercase[:5])
)
var = pd.DataFrame(
dict(grp=var_grp),
index=pd.Series(range(50)).astype(str).apply(lambda v: "gene-" + v),
)
obsm = dict(umap=gen.random((100, 2)))
varp = dict(cons=sp.csr_array(sp.random(50, 50)))
adata = AnnData(x, obs, var, layers=layers, obsm=obsm, varm={}, obsp={}, varp=varp)
Tabular modeΒΆ
We can select the data to display using the Accessor object A. Here it is important that the data must be indexed along either the obs or the var dimension.
Let us visualize the UMAP data to start:
hv.Scatter(adata, A.obsm["umap"][0], [A.obsm["umap"][1], A.obs["type"]]).opts(
color=A.obs["type"]
)
To make it easier to access data we can also specify the dimensions as strings:
scatter = hv.Scatter(adata, "obsm.umap.0", ["obsm.umap.1", "obs.type"]).opts(
color="A.obs['type']"
)
scatter
For an obs indexed dataset you can use the select method along the obs variables, e.g. we can select a specific type:
scatter.select({A.obs["type"]: 2}) # .select(dim(A.var["grp"]) == "a")
We can also use the .iloc method to index along the obs dimension:
scatter.iloc[:50]
We cannot can mix and match obs and var dimensions:
from holoviews.core.data.interface import DataError
try:
hv.Scatter(adata, A.obsm["umap"][0], A.var["index"])
except DataError as e:
print(e)
AnnData Dataset in tabular mode must reference data along either the obs or the var axis, not both.
Gridded DataΒΆ
AnnData can also hold gridded data and we can render that.
When rendering an Element that assumes continuous coordinates (e.g. Image) it will render the integer indices:
img = hv.Image(adata, [A.var["index"], A.obs["index"]], [A[:, :]])
img
When rendering into an element that assumes discrete values (e.g. HeatMap) the axes will be labelled:
hm = hv.HeatMap(adata, [A.obs["index"], A.var["index"]], [A[:, :]])
hm.opts(responsive=True, height=800, xrotation=90)