Source code for spatialtis.spatial.network
from ast import literal_eval
from typing import Any, Dict, Optional
import pandas as pd
from anndata import AnnData
from scipy.spatial.distance import euclidean
from spatialtis.abc import AnalysisBase
from spatialtis.config import CONFIG
from spatialtis.spatial.utils import NeighborsNotFoundError
from spatialtis.utils import col2adata_obs, doc
from spatialtis.utils.log import pbar_iter
[docs]@doc
class cell_community(AnalysisBase):
"""Spatial communities detection
Here we use Leiden graph cluster algorithm
Args:
data: {adata}
partition_type: The leidenalg partition type
partition_kwargs: Pass to leidenalg.find_partition
**kwargs: {analysis_kwargs}
"""
def __init__(
self,
data: AnnData,
partition_type: Optional[Any] = None,
partition_kwargs: Optional[Dict] = None,
**kwargs,
):
super().__init__(data, task_name="cell_community", **kwargs)
try:
import leidenalg
except ImportError:
raise ImportError("Required leidenalg, try pip install leidenalg.")
try:
import igraph as ig
except ImportError:
raise ImportError(
"Required python-igraph, try `pip install python-igraph`."
)
if not self.neighbors_exists:
raise NeighborsNotFoundError("Run `find_neighbors` first before continue.")
if partition_type is None:
partition_type = leidenalg.CPMVertexPartition
if partition_kwargs is None:
partition_kwargs = {"resolution_parameter": 0.05}
else:
partition_kwargs = {"resolution_parameter": 0.05, **partition_kwargs}
need_eval_cent = self.is_col_str(self.centroid_key)
need_eval_neigh = self.is_col_str(self.neighbors_key)
graphs = []
names = []
for n, g in data.obs.groupby(self.exp_obs):
if need_eval_cent:
centroids = [literal_eval(c) for c in g[self.centroid_key]]
else:
centroids = [c for c in g[self.centroid_key]]
if need_eval_neigh:
neighbors = [literal_eval(n) for n in g[self.neighbors_key]]
else:
neighbors = [n for n in g[self.neighbors_key]]
vertices = []
edge_mapper = {}
for i, (x, y) in zip(g[CONFIG.neighbors_ix_key], centroids):
vertices.append({"name": i, "x": x, "y": y})
edge_mapper[i] = (x, y)
graph_edges = []
for k, vs in zip(g[CONFIG.neighbors_ix_key], neighbors):
if len(vs) > 0:
for v in vs:
if k != v:
distance = euclidean(edge_mapper[k], edge_mapper[v])
graph_edges.append(
{"source": k, "target": v, "weight": distance}
)
graphs.append(ig.Graph.DictList(vertices, graph_edges))
names.append(n)
neighbors_graphs = dict(zip(names, graphs))
sub_comm = []
for _, graph in pbar_iter(
neighbors_graphs.items(), desc="Communities detection",
):
part = leidenalg.find_partition(graph, partition_type, **partition_kwargs)
sub_comm += part.membership
sub_comm = pd.Series(sub_comm, index=data.obs.index)
col2adata_obs(sub_comm, self.data, self.export_key)
self.stop_timer()