LIANA+ 单细胞通讯分析指南
LIANA+ 是一个面向 Python/AnnData 的细胞-细胞通讯(CCC)分析框架。核心优势是通过统一接口运行 CellPhoneDB、CellChat、NATMI 等多种方法,并聚合其排序;同时支持空间转录组和多样本比较。
快速开始(5 分钟)
如果你有标准的 scRNA-seq 数据(.h5ad)并已标注细胞类型:
import scanpy as sc
import liana as li
adata = sc.read_h5ad("your_data.h5ad")
sc.pp.normalize_total(adata)
sc.pp.log1p(adata)
li.mt.rank_aggregate(
adata,
groupby="cell_type", # 替换为你的细胞类型列名
resource_name="consensus", # 人类数据;小鼠改为 "mouseconsensus"
use_raw=False, # 使用刚刚处理的 adata.X
n_perms=1000,
inplace=True,
)
# 查看结果
liana_res = adata.uns["liana_res"]
print(liana_res.head())
# 可视化 Top 20
li.pl.dotplot(adata, top_n=20)
数据要求:
- ✅ AnnData 对象(.h5ad 文件)
- ✅
adata.obs中有细胞类型列(至少 2 种细胞类型) - ✅ 人类数据使用 Gene Symbol(非 Ensembl ID);小鼠使用小鼠 gene symbol
- ✅ 已做标准化和 log1p 变换,并明确选择
adata.X、adata.raw或某个layer作为分析矩阵
适用场景
- 需要多 CCC 方法联合的元分析
- 需要空间双变量指标(局部或全局)
- 需要按样本比较 CCC,并进行张量分解或 MOFA+
- 需要空间数据的 MISTy 多视图学习
- 数据流程基于 Python/AnnData
安装
pip install liana
工作流 A:基础 scRNA-seq CCC(rank_aggregate)
这是默认推荐方案:运行多种方法并聚合排序。
import scanpy as sc
import liana as li
adata = sc.read_h5ad("data.h5ad")
sc.pp.normalize_total(adata)
sc.pp.log1p(adata)
li.mt.rank_aggregate(
adata,
groupby="cell_type", # adata.obs 中的细胞类型列
resource_name="consensus", # 人类资源;小鼠使用 "mouseconsensus"
expr_prop=0.1, # 最低表达细胞比例
n_perms=1000, # 置换次数
use_raw=False, # 使用已标准化和 log1p 的 adata.X
inplace=True,
verbose=True,
)
liana_res = adata.uns["liana_res"]
结果包含 source、target、ligand_complex、receptor_complex、magnitude_rank 和 specificity_rank。两个 rank 均在 0-1 之间,数值越小表示排名越靠前。
只运行一种方法
li.mt.cellphonedb(
adata,
groupby="cell_type",
n_perms=1000,
inplace=True,
)
可用方法包括 cellphonedb、cellchat、natmi、connectome、logfc、singlecellsignalr 与 geometric_mean。
按样本推断
li.mt.rank_aggregate.by_sample(
adata,
groupby="cell_type",
sample_key="sample",
use_raw=False,
n_perms=None, # 多样本初筛可关闭置换以节省时间
return_all_lrs=True, # 为跨样本张量保留缺失/低表达 LR 对
inplace=True,
)
工作流 B:空间双变量分析
适用于 Visium、MERFISH、Slide-seq 等拥有 adata.obsm["spatial"] 坐标的空间数据。
前置条件:确保 adata.obsm["spatial"] 包含坐标信息。
import scanpy as sc
import liana as li
adata = sc.read_h5ad("spatial.h5ad")
li.ut.spatial_neighbors(
adata,
bandwidth=150,
cutoff=0.1,
kernel="gaussian",
set_diag=False,
spatial_key="spatial",
key_added="spatial",
)
lr_adata = li.mt.bivariate(
adata,
local_name="cosine",
global_name="morans",
resource_name="consensus",
connectivity_key="spatial_connectivities",
nz_prop=0.05,
add_categories=True,
n_perms=100,
)
lr_adata.X 保存每个 spot 的局部双变量分数;lr_adata.var 保存各配体-受体对的全局统计量;layers["cats"] 保存类别标记。
局部指标选择
cosine:通用、稳健的空间共表达指标pearson:线性空间相关,对异常值敏感spearman:基于秩,较稳健product:加权乘积,计算快速morans:Moran's R,经典空间统计masked_spearman:适合稀疏数据
工作流 C:空间邻近加权 CCC
li.mt.rank_aggregate(
adata,
groupby="cell_type",
spatial_key="spatial",
spatial_kwargs={"bandwidth": 150},
inplace=True,
)
工作流 D:空间流入(Inflow)分析
用于量化每类细胞经不同配体-受体对流入各 spot 的信号。
li.ut.spatial_neighbors(adata, bandwidth=150)
inflow_adata = li.mt.inflow(
adata,
groupby="cell_type",
connectivity_key="spatial_connectivities",
resource_name="consensus",
nz_prop=0.001,
)
工作流 E:MISTy 多视图学习
misty = li.mt.genericMistyData(
intra=adata,
spatial_key="spatial",
bandwidth=100,
add_para=True,
add_juxta=False,
)
misty(
model=li.mt.LinearModel(seed=42),
bypass_intra=False,
k_cv=10,
)
li.pl.target_metrics(misty)
li.pl.contributions(misty)
li.pl.interactions(misty)
若需要针对配体-受体对建模,可使用:
misty = li.mt.lrMistyData(
adata,
resource_name="consensus",
spatial_key="spatial",
bandwidth=100,
)
misty(model=li.mt.LinearModel(seed=42))
工作流 F:多样本张量分解
💡 适用场景:需要跨样本比较 CCC 模式。如需基于因子的降维,请使用工作流 G。
# 必须按样本运行;结果会含有 sample 列。
li.mt.rank_aggregate.by_sample(
adata,
groupby="cell_type",
sample_key="sample",
use_raw=False,
n_perms=None,
return_all_lrs=True,
inplace=True,
)
tensor = li.multi.to_tensor_c2c(
adata,
sample_key="sample",
score_key="magnitude_rank", # n_perms=None 时通常没有 specificity_rank
non_negative=True,
)
张量维度为 (样本数, 发送细胞类型数, 接收细胞类型数, 相互作用数),之后使用 cell2cell 或 tensorly 分解。
工作流 G:多样本 MOFA+
💡 适用场景:需要因子驱动的多样本 CCC 分析。如需张量分解,请使用工作流 F。
# 必须先按样本推断,确保 adata.uns["liana_res"] 含有 sample 列。
li.mt.rank_aggregate.by_sample(
adata,
groupby="cell_type",
sample_key="sample",
use_raw=False,
n_perms=None,
return_all_lrs=True,
inplace=True,
)
mdata = li.multi.lrs_to_views(
adata,
score_key="magnitude_rank", # n_perms=None 时通常没有 specificity_rank
sample_key="sample",
lr_prop=0.5,
lrs_per_view=20,
)
随后使用 mofapy2 或 muon 运行 MOFA+。
可视化
li.pl.dotplot(
adata,
colour="specificity_rank",
size="magnitude_rank",
inverse_colour=True,
inverse_size=True,
source_labels=["TypeA", "TypeB"],
target_labels=["TypeC"],
top_n=20,
orderby="specificity_rank",
orderby_ascending=True,
cmap="viridis",
figure_size=(8, 6),
)
其他常用图:
# dotplot_by_sample 需要先运行 rank_aggregate.by_sample()。
li.pl.dotplot_by_sample(adata, sample_key="sample")
li.pl.tileplot(adata, fill="magnitude_rank", top_n=20)
li.pl.circle_plot(adata, groupby="cell_type", score_key="magnitude_rank", inverse_score=True)
关键参数
| 参数 | 常用值 | 调整建议 |
|---|---:|---|
| resource_name | "consensus" | 用 li.rs.show_resources() 查看可用数据库 |
| expr_prop | 0.1 | 稀有细胞可降至 0.05;降噪可升至 0.2 |
| n_perms | 1000 | 快速测试用 100;不需要置换分数时用 None;发表分析建议 1000+ |
| use_raw | 视矩阵而定 | 若刚处理 adata.X,设为 False;仅当 .raw 保存正确的归一化、log1p 矩阵时使用 True,或指定 layer |
| bandwidth | 视技术而定 | Visium 约 150;MERFISH 约 50 |
| nz_prop | 0.05 | 稀疏数据降低;希望严格筛选则提高 |
配体-受体资源管理
li.rs.show_resources()
human_resource = li.rs.select_resource("consensus")
# 小鼠数据可直接在分析时使用 resource_name="mouseconsensus"。
import pandas as pd
custom_lr = pd.DataFrame({
"ligand": ["TGFB1", "CXCL12"],
"receptor": ["TGFBR1", "CXCR4"]
})
li.mt.rank_aggregate(adata, groupby="cell_type", resource=custom_lr)
# 对无内置资源的物种,先获得人类到目标物种的同源映射,再翻译资源。
mapping = li.rs.get_hcop_orthologs(target_organism="mouse")
translated = li.rs.translate_resource(
human_resource,
mapping[["human_symbol", "mouse_symbol"]],
columns=["ligand", "receptor"],
)
常见问题与注意事项
use_raw=True是默认行为。若仅对adata.X做了归一化和 log1p,请设use_raw=False;若要用adata.raw,应确认它保存的是适当的归一化、log1p 矩阵。也可明确指定layer。- 默认
"consensus"使用人类 gene symbols;小鼠优先使用"mouseconsensus"。若资源覆盖率过低,检查物种、基因命名格式与 Ensembl ID 转换,并考虑使用同源映射或自定义资源。 - 空间
bivariate和inflow前,必须通过li.ut.spatial_neighbors()或squidpy.gr.spatial_neighbors()在adata.obsp建立与connectivity_key对应的空间邻接图。rank_aggregate使用spatial_key时会自行计算空间 proximity 权重。 - LIANA 使用
^连接配体-受体对(例如TGFB1^TGFBR1),复合体亚基使用_连接。 - 使用
n_perms=None关闭置换检验;此时依赖置换的特异性分数和specificity_rank可能不存在。 magnitude_rank和specificity_rank是跨方法聚合的 0-1 RRA 排名分数,越小表示跨方法越稳定且排名越靠前;它们不是任一单方法的置换 p 值。若要用阈值筛选,应结合表达过滤、RRA 含义和研究设计预先设定并报告。
与用户协作流程
- 先明确目标属于基础 CCC、空间分析、多样本比较还是可视化,并选择对应工作流。
- 检查数据:细胞类型列、样本列、
adata.raw、基因命名格式,以及空间数据的adata.obsm["spatial"]。 - 输出可直接运行的代码,必须使用用户实际提供的文件路径和列名,不保留未填充的占位符。
- 主动提示
use_raw设置、基因名匹配和空间邻接图等关键前提。 - 解读结果时明确说明:排名越小越好,但 rank 不等同于 p 值。
工作流速查表
| 需求 | 推荐工作流 | 关键参数 |
|------|-----------|---------|
| 标准 scRNA-seq CCC | 工作流 A | groupby, n_perms |
| 仅运行一种方法 | 工作流 A - 单方法 | li.mt.cellphonedb() |
| 按样本分别推断 | 工作流 A - 按样本 | sample_key |
| 空间双变量分析 | 工作流 B | local_name, global_name |
| 空间邻近加权 CCC | 工作流 C | spatial_key, bandwidth |
| 空间信号流入 | 工作流 D | connectivity_key |
| MISTy 多视图学习 | 工作流 E | LinearModel |
| 多样本张量分解 | 工作流 F | sample_key |
| 多样本 MOFA+ | 工作流 G | lr_prop |
| 可视化结果 | 可视化 | li.pl.dotplot() |
Scan to join WeChat group