别再只会画UMAP了!Scanpy核心绘图函数实战:从散点图到热图,手把手教你玩转单细胞数据可视化
Scanpy单细胞数据可视化实战:从基础图表到高级定制
单细胞RNA测序技术正在彻底改变我们对复杂生物系统的理解能力。随着数据量的爆炸式增长,如何将海量的基因表达数据转化为直观、信息丰富的可视化结果,成为每个单细胞研究者必须掌握的技能。Scanpy作为Python生态中最强大的单细胞分析工具之一,提供了丰富多样的可视化函数,但很多用户仅仅停留在UMAP和t-SNE等降维图上,未能充分发挥其可视化潜力。
1. 可视化基础:理解Scanpy的绘图逻辑
Scanpy的绘图系统建立在Matplotlib之上,但进行了高度封装和优化,专门针对单细胞数据的特殊需求。与常规的Python绘图库不同,Scanpy的绘图函数直接面向AnnData对象,能够自动提取细胞注释、基因表达和聚类结果等信息。
核心绘图参数解析:
color:决定图表着色依据,可以是基因名、细胞元数据列名或任何存储在obs中的注释信息groupby:分组依据,通常使用聚类结果或已知细胞类型layer:指定使用哪个数据层(如原始计数、标准化表达量或缩放后的值)cmap:颜色映射,控制从数值到颜色的转换方式size/alpha:调整点的大小和透明度,解决重叠点显示问题
# 基础绘图示例 import scanpy as sc adata = sc.datasets.pbmc3k() # 加载示例数据 sc.pl.umap(adata, color=['CD3D', 'n_genes'], size=10, alpha=0.6, cmap='viridis')提示:使用
sc.set_figure_params()可以全局设置图像参数,如DPI、默认颜色映射等,避免每次绘图重复设置
2. 选择合适的图表类型:从数据特征到视觉呈现
单细胞数据可视化不是简单的"画图",而是数据到信息的转化过程。不同的科学问题需要不同的可视化策略:
2.1 细胞群体关系展示
- UMAP/t-SNE:展示细胞在降维空间的全局分布
- Force-directed layout:强调细胞间的连接关系
- PAGA:显示群体间的过渡和发育轨迹
2.2 基因表达模式比较
| 图表类型 | 适用场景 | 优势 | 局限性 |
|---|---|---|---|
| 点图(dotplot) | 比较多个基因在不同群体中的表达 | 同时显示表达比例和强度 | 基因数过多时难以阅读 |
| 小提琴图(violin) | 展示单个基因的表达分布 | 清晰显示分布形态 | 占用空间较大 |
| 热图(heatmap) | 大规模基因集表达模式 | 适合展示整体模式 | 丢失细节信息 |
| 矩阵图(matrixplot) | 群体间基因表达比较 | 数值直观可比 | 需要标准化处理 |
# 基因表达可视化对比 genes = ['CD3D', 'CD79A', 'FCGR3A', 'NKG7'] sc.pl.dotplot(adata, genes, groupby='louvain', dendrogram=True, cmap='Reds') sc.pl.stacked_violin(adata, genes, groupby='louvain')2.3 群体标记基因识别
对于差异表达分析和标记基因可视化,Scanpy提供了一系列专用函数:
# 标记基因可视化流程 sc.tl.rank_genes_groups(adata, 'louvain', method='wilcoxon') sc.pl.rank_genes_groups_dotplot(adata, n_genes=4, values_to_plot='logfoldchanges') sc.pl.rank_genes_groups_matrixplot(adata, n_genes=3, cmap='bwr', vmin=-3, vmax=3)3. 高级定制技巧:超越默认参数
3.1 颜色映射的艺术
颜色是可视化中信息编码的核心元素。Scanpy支持所有Matplotlib的colormap,但不同场景需要不同策略:
- 连续型数据:
viridis,plasma,inferno(避免使用jet) - 发散型数据:
RdBu_r,coolwarm(适合有中心点的数据) - 分类数据:
Set1,tab20(确保颜色可区分)
# 高级颜色设置示例 from matplotlib.colors import LinearSegmentedColormap custom_cmap = LinearSegmentedColormap.from_list( 'mycmap', ['#2E86AB', '#F24236']) sc.pl.umap(adata, color='CD3D', cmap=custom_cmap, vmax='p99') # 使用99百分位作为上限3.2 多图组合与排版
科研论文常需要将多个相关图表组合展示。Scanpy提供了灵活的subplot系统:
# 多图组合示例 import matplotlib.pyplot as plt fig, axes = plt.subplots(1, 2, figsize=(12, 5)) sc.pl.umap(adata, color='louvain', ax=axes[0], show=False) sc.pl.dotplot(adata, marker_genes, groupby='louvain', ax=axes[1], show=False) plt.tight_layout()3.3 交互式可视化
虽然Scanpy主要生成静态图像,但可以轻松导出数据用于交互式可视化工具:
# 导出数据用于Plotly import plotly.express as px df = adata.obs.join(adata.to_df()) fig = px.scatter(df, x='UMAP1', y='UMAP2', color='CD3D', hover_data=['louvain', 'n_genes']) fig.show()4. 实战案例:完整可视化流程
让我们通过一个真实的研究场景,展示如何从原始数据到发表级图表:
4.1 数据准备与预处理
# 加载并预处理数据 adata = sc.read_10x_mtx('filtered_gene_bc_matrices/hg19/') sc.pp.filter_cells(adata, min_genes=200) sc.pp.filter_genes(adata, min_cells=3) sc.pp.normalize_total(adata, target_sum=1e4) sc.pp.log1p(adata) sc.pp.highly_variable_genes(adata) adata = adata[:, adata.var.highly_variable] sc.pp.scale(adata, max_value=10)4.2 降维与聚类
# 标准分析流程 sc.tl.pca(adata, svd_solver='arpack') sc.pp.neighbors(adata, n_pcs=30, n_neighbors=20) sc.tl.umap(adata) sc.tl.leiden(adata, resolution=0.5)4.3 标记基因识别与注释
# 差异表达与注释 sc.tl.rank_genes_groups(adata, 'leiden', method='t-test') marker_genes = { 'T cells': ['CD3D', 'CD8A'], 'B cells': ['CD79A', 'MS4A1'], 'Monocytes': ['CD14', 'FCGR3A'], 'NK cells': ['GNLY', 'NKG7'] }4.4 最终可视化组合
# 发表级图表生成 with plt.style.context('seaborn-whitegrid'): fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(15, 12)) # UMAP展示细胞类型 sc.pl.umap(adata, color='cell_type', ax=ax1, palette='tab20', frameon=False, show=False) # 点图展示标记基因 sc.pl.dotplot(adata, marker_genes, groupby='cell_type', ax=ax2, dendrogram=True, show=False) # 小提琴图展示关键标记基因 sc.pl.stacked_violin(adata, ['CD3D', 'CD79A', 'CD14', 'NKG7'], groupby='cell_type', ax=ax3, show=False) # 热图展示top差异基因 sc.pl.heatmap(adata, adata.uns['rank_genes_groups']['names'][:5], groupby='cell_type', ax=ax4, show=False, cmap='viridis', dendrogram=True) plt.tight_layout() fig.savefig('final_figure.pdf', dpi=300, bbox_inches='tight')在实际项目中,我发现最常需要调整的是颜色映射和字体大小,确保图表在不同媒介(屏幕、打印)上都能清晰呈现。对于包含大量基因的热图,使用swap_axes=True将基因放在y轴往往能获得更好的可读性。
