R语言ComplexHeatmap包实战:手把手教你绘制文献级圆形热图
2026/9/17 9:28:32 网站建设 项目流程

大家好,我是专注于R语言数据可视化的技术博主。在阅读生物信息学或组学相关的文献时,我们常常会被那些设计精美、信息密度极高的热图所吸引,尤其是那些突破传统矩形布局的圆形热图(Circular Heatmap),它们不仅能展示矩阵数据,还能揭示层次结构或周期规律,视觉冲击力十足。然而,当自己动手想复现时,却往往卡在复杂的布局调整和细节美化上,资料零散不成体系。

本文将以R语言中功能强大的ComplexHeatmap包为核心,手把手带你完整复现一篇文献中常见的圆形热图。从环境搭建、数据模拟、核心绘图到高级美化,每一步都提供可运行的代码和避坑指南。无论你是刚接触ComplexHeatmap的新手,还是想提升图表出版级颜值的老手,都能从这篇实战笔记中找到清晰的路径。

1. 背景与核心概念:为何选择ComplexHeatmap绘制圆形热图?

在数据可视化领域,热图是展示矩阵型数据(如基因表达矩阵、相关系数矩阵)的利器。传统的pheatmapggplot2geom_tile虽然基础,但在处理复杂注释、多图联动和自定义布局时往往力不从心。

ComplexHeatmap包由Zuguang Gu开发,是R语言中绘制高度定制化热图的“终极武器”。它的核心优势在于:

  • 模块化设计:将热图主体、行/列注释、图例等视为独立对象,自由组合。
  • 无缝拼接:可以轻松将多个热图、点图、条形图甚至网络图拼接在一起。
  • 极致定制:几乎每个图形元素(颜色、字体、边框、间距)都可以精细控制。
  • 支持环形布局:通过circos.heatmap等功能,可以天然地支持圆形热图的绘制,这对于展示周期性数据(如昼夜节律)、系统发育关系或仅仅是追求更美观的布局非常有用。

圆形热图不仅仅是把矩形热图弯曲成环。它通常与轨道(Track)的概念结合,在环状区域内分层展示不同类型的数据(如热图、条形图、点图),使得多维度数据能在同一幅图中协调呈现,极大提升了信息传达的效率。

本文的目标是:使用ComplexHeatmap,模拟一份类似文献中的基因表达数据(行是基因,列是样本或时间点),并为其添加样本分组注释和基因聚类信息,最终绘制成一幅具有多个注释轨道的出版级圆形热图。

2. 环境准备与版本说明

工欲善其事,必先利其器。首先确保你的R环境准备就绪。

2.1 R与RStudio

  • R语言:版本需不低于4.0.0。本文示例在R 4.2.0环境下测试通过。
  • RStudio:推荐使用最新版的RStudio Desktop作为集成开发环境,其图形设备对ComplexHeatmap的渲染支持更好。

你可以通过以下命令检查R版本:

R.version.string

2.2 安装必要的R包

我们将主要使用ComplexHeatmap包,同时会用到circlize包(它提供了底层的环形绘图框架)以及一些数据生成和处理的辅助包。

在R控制台中运行以下命令进行安装:

# 设置CRAN镜像,加速下载(可选) options(repos = c(CRAN = "https://mirrors.tuna.tsinghua.edu.cn/CRAN/")) # 安装核心绘图包 if (!requireNamespace("BiocManager", quietly = TRUE)) install.packages("BiocManager") BiocManager::install("ComplexHeatmap") # 安装circlize包及其依赖 install.packages("circlize") # 安装用于数据模拟和处理的辅助包(如未安装) install.packages("dplyr") install.packages("tibble")

安装完成后,加载它们:

library(ComplexHeatmap) library(circlize) library(dplyr) library(tibble)

重要提示ComplexHeatmap的安装方式是通过BiocManager,因为它托管在Bioconductor上。如果遇到安装问题,请检查网络连接或Bioconductor的镜像设置。

2.3 验证安装

运行一个最简单的命令,确保包加载成功且图形设备正常:

# 创建一个简单的矩阵 mat <- matrix(rnorm(100), 10, 10) # 绘制一个基础热图 Heatmap(mat)

如果弹出一个图形窗口并显示热图,说明环境配置成功。

3. ComplexHeatmap核心语法与圆形布局原理

在进入实战前,我们需要理解ComplexHeatmap绘制圆形热图的核心函数与流程。

3.1 从矩形热图到圆形热图

ComplexHeatmap绘制标准热图的核心函数是Heatmap()。而要实现圆形布局,关键在于两点:

  1. 使用circos.heatmap()函数:这个函数专门用于在环形布局中绘制热图矩阵。
  2. 配合circlize包的环形初始化:需要在绘图前使用circlize::circos.par()设置环形画布的全局参数,并在最后用circlize::circos.clear()重置。

一个最简流程如下:

library(circlize) library(ComplexHeatmap) # 1. 初始化环形画布 circos.par(gap.after = c(10)) # 设置扇形间隙 # 2. 使用 circos.heatmap 绘图 circos.heatmap(your_matrix, ...) # ... 代表各种美化参数 # 3. 添加其他轨道(如注释) circos.track(...) # 4. 清除环形布局设置 circos.clear()

3.2 circos.heatmap核心参数解析

circos.heatmap函数控制着热图在环上的呈现,以下是一些关键参数:

  • mat: 输入的数值矩阵,行和列分别对应环的扇区和径向层次。
  • split: 一个因子向量,用于对行进行分割,不同组会显示在不同的扇形区域。
  • col: 颜色映射函数,用于将数值映射到颜色。通常使用colorRamp2()函数创建。
  • cluster: 是否对行进行聚类。可以是逻辑值,也可以是hclust对象。
  • dend.side: 聚类树状图绘制的位置(“inside” 或 “outside”)。
  • rownames.side: 行名(如基因名)绘制的位置。
  • track.height: 该热图轨道的高度(占整个环的比例)。

3.3 颜色映射函数colorRamp2

这是定义热图颜色渐变的核心。它允许你指定在哪些断点(break)使用哪些颜色(color)。

# 示例:定义从蓝色(低值)到白色(中值)再到红色(高值)的渐变 col_fun <- colorRamp2(c(-2, 0, 2), c("blue", "white", "red")) # 测试颜色函数 col_fun(c(-1, 0, 1)) # 会返回对应的颜色值

在热图中,矩阵中的每个值都会通过这个函数找到对应的颜色。

4. 完整实战:复现文献级圆形热图

现在,我们模拟一个经典的基因表达数据集来完整演练。假设我们有50个基因在12个时间点下的表达量,并且基因属于3个不同的功能模块(Pathway)。

4.1 创建模拟数据集

set.seed(123) # 设置随机种子保证结果可重复 # 1. 模拟基因表达矩阵:50个基因 x 12个时间点 n_genes <- 50 n_timepoints <- 12 expr_mat <- matrix(rnorm(n_genes * n_timepoints, mean = 0, sd = 1), nrow = n_genes, ncol = n_timepoints) # 为了让模式更明显,我们为其中一些基因添加时间趋势 for(i in 1:10) { expr_mat[i, ] <- expr_mat[i, ] + seq(-2, 2, length.out = n_timepoints) # 上升趋势 } for(i in 11:20) { expr_mat[i, ] <- expr_mat[i, ] + seq(2, -2, length.out = n_timepoints) # 下降趋势 } rownames(expr_mat) <- paste0("Gene", 1:n_genes) colnames(expr_mat) <- paste0("T", 1:n_timepoints) # 2. 创建基因分组信息(例如功能通路) gene_groups <- factor(rep(c("Pathway_A", "Pathway_B", "Pathway_C"), length.out = n_genes)) names(gene_groups) <- rownames(expr_mat) # 3. 创建样本(时间点)分组注释(例如实验阶段) sample_annotation <- data.frame( Stage = rep(c("Early", "Mid", "Late"), each = n_timepoints/3), row.names = colnames(expr_mat) ) # 查看数据前几行 head(expr_mat[, 1:4]) table(gene_groups) head(sample_annotation)

4.2 定义颜色方案与初始化环形画布

出版级图表的美观度很大程度上取决于协调的颜色方案。

# 1. 定义热图主色调(表达量高低) # 假设表达量标准化后,范围在-3到3之间 breaks <- seq(-3, 3, length.out = 100) # 使用 viridis 或 RColorBrewer 的色系更专业,这里用蓝-白-红经典色 library(RColorBrewer) heatmap_colors <- colorRamp2(breaks = c(-3, 0, 3), colors = c("#4575B4", "#FFFFBF", "#D73027")) # 2. 定义基因分组颜色 group_colors <- c("Pathway_A" = "#E69F00", "Pathway_B" = "#56B4E9", "Pathway_C" = "#009E73") # 3. 定义样本阶段颜色 stage_colors <- c("Early" = "#F0E442", "Mid" = "#0072B2", "Late" = "#D55E00") # 4. 初始化环形画布 # 清除可能存在的旧设置 circlize::circos.clear() # 设置环形参数:起始角度、扇形间隙等 circlize::circos.par(start.degree = 90, # 从12点钟方向开始 gap.after = c(rep(2, length(unique(gene_groups))-1), 10), # 最后一个间隙大一些,用于放图例 track.margin = c(0.01, 0.01)) # 轨道边距

4.3 绘制核心热图轨道

这是最关键的一步,我们将表达矩阵绘制到环形上,并按基因分组进行分割。

# 绘制热图轨道 ht <- circos.heatmap( mat = expr_mat, split = gene_groups, # 按基因分组分割扇形 col = heatmap_colors, # 应用颜色映射函数 dend.side = "inside", # 聚类树画在扇形内侧 rownames.side = "outside", # 基因名显示在外侧 track.height = 0.3, # 热图轨道高度 bg.border = "grey60", # 背景边框色 # 聚类方法配置 clustering.method = "complete", clustering_distance_rows = "euclidean", show.sector.labels = TRUE # 显示扇区标签(即分组名) )

4.4 添加样本注释轨道

在热图轨道的外围,我们可以添加轨道来展示样本(时间点)的属性,如实验阶段。

# 为每个扇区(基因分组)添加样本注释轨道 for(sn in get.all.sector.index()) { # 获取当前扇区对应的数据列索引 sector_data <- get.cell.meta.data("cell.xlim", sector.index = sn) # 这里简化处理,假设所有扇区的样本顺序一致 # 在实际中,可能需要根据`split`逻辑映射 # 添加一个轨道用于绘制样本分组条形 circos.track(ylim = c(0, 1), track.height = 0.05, bg.border = NA, panel.fun = function(x, y) { # 获取当前轨道的扇区信息 sector.index <- get.cell.meta.data("sector.index") # 绘制样本分组颜色条 n_samples <- ncol(expr_mat) col_assign <- stage_colors[sample_annotation$Stage] circos.rect(1:n_samples - 1, rep(0, n_samples), 1:n_samples, rep(1, n_samples), col = col_assign, border = NA) }) } # 添加轨道标签 circos.trackText(factors = get.all.sector.index(), track.index = get.current.track.index(), labels = "Stage", facing = "downward", niceFacing = TRUE)

4.5 添加图例并完成绘图

一个完整的图表离不开清晰的图例。

# 1. 创建热图(表达量)图例 lgd_heatmap <- Legend(title = "Expression Z-score", col_fun = heatmap_colors, at = c(-3, -1.5, 0, 1.5, 3)) # 2. 创建基因分组图例 lgd_gene_group <- Legend(title = "Gene Pathway", at = names(group_colors), legend_gp = gpar(fill = group_colors)) # 3. 创建样本阶段图例 lgd_stage <- Legend(title = "Time Stage", at = names(stage_colors), legend_gp = gpar(fill = stage_colors)) # 将所有图例组合在一起 pd <- packLegend(lgd_heatmap, lgd_gene_group, lgd_stage, direction = "vertical", max_height = unit(10, "cm")) # 在图形设备上绘制图例(需要先打开或指定一个图形设备) # 例如,使用grid图形系统绘制 library(grid) grid.draw(pd) # 最后,务必清除环形布局设置,以免影响后续绘图 circlize::circos.clear()

注意:上述circos.track部分是一个简化示例。在实际的ComplexHeatmap高级用法中,更常见的做法是先使用HeatmapAnnotation函数创建复杂的注释对象,然后利用Heatmap对象的top_annotationleft_annotation参数进行添加,最后通过draw函数并指定heatmap_legend_side等参数来统一绘制热图和图例。对于极其复杂的环形多轨道图,可能需要更底层的circlize编程。

为了更直观、更符合ComplexHeatmap哲学地完成圆形热图,下面提供一个更完整、更实用的替代方案,它利用Heatmap对象本身强大的注释系统,然后通过draw函数的circular参数实现环形布局:

# 方案二:使用Heatmap对象的circular参数(更推荐) library(ComplexHeatmap) # 1. 创建列注释(样本注释) ha_column <- HeatmapAnnotation( Stage = sample_annotation$Stage, col = list(Stage = stage_colors), annotation_name_side = "left", show_annotation_name = TRUE ) # 2. 创建行注释(基因分组注释) ha_row <- rowAnnotation( Pathway = gene_groups, col = list(Pathway = group_colors), show_annotation_name = FALSE, width = unit(0.5, "cm") ) # 3. 绘制热图,并指定为环形布局 ht_obj <- Heatmap( expr_mat, name = "Z-score", # 图例标题 col = heatmap_colors, # 行设置 row_split = gene_groups, # 行分割 cluster_rows = TRUE, # 行聚类 clustering_distance_rows = "euclidean", clustering_method_rows = "complete", row_title = NULL, # 环形布局时不显示默认的行标题 # 列设置 column_split = sample_annotation$Stage, # 列分割 cluster_columns = FALSE, # 时间点通常不聚类 column_title = NULL, # 环形布局时不显示默认的列标题 # 注释 top_annotation = ha_column, left_annotation = ha_row, # 环形布局关键参数 rect_gp = gpar(col = NA), # 去除单元格边框 row_dend_side = "right", # 行聚类树位置 column_dend_side = "bottom", # 热图外观 show_row_names = TRUE, # 显示行名 row_names_side = "left", show_column_names = TRUE, # 显示列名 column_names_side = "bottom", row_names_gp = gpar(fontsize = 8), column_names_gp = gpar(fontsize = 8) ) # 4. 绘制图形,启用环形布局 draw(ht_obj, heatmap_legend_side = "right", # 图例位置 annotation_legend_side = "right", row_dend_side = "right", column_dend_side = "bottom", # 关键:启用环形布局并设置参数 circular = TRUE, gap = unit(5, "mm"), # 扇区间隙 start_degree = 90) # 起始角度

这种方法的代码更清晰,更易于管理多个注释,并且能自动处理图例的绘制和摆放,是复现文献中复杂圆形热图的更佳实践。

5. 常见问题与排查思路

在使用ComplexHeatmap绘制圆形热图时,你可能会遇到以下典型问题:

问题现象可能原因解决思路
图形设备不显示或报错“Error in .CircosEnv...”未正确初始化circlize环境或之前绘图未清除。1. 确保在绘图前调用了library(circlize)
2. 在绘制新图前,务必运行circos.clear()
热图颜色显示不正常,全是灰色或单一色。colorRamp2函数的断点(breaks)设置未覆盖数据的实际范围。使用range(your_matrix)检查数据范围,确保colorRamp2中的breaks参数能涵盖最小值和最大值。
行名或列名重叠,无法辨认。数据维度太高,标签太密集。1. 使用show_row_names = FALSE暂时关闭显示。
2. 通过row_names_gp = gpar(fontsize = 6)减小字体。
3. 仅显示部分标签(如每5行显示一个)。
环形布局下,扇区标签(如基因分组名)位置不对或缺失。circular=TRUE时,row_titlecolumn_title的设置可能冲突。Heatmap()函数中显式设置row_title = NULLcolumn_title = NULL,依赖环形布局自动生成的标签。
图例(legend)显示不全或跑到图形外面。图形设备(绘图窗口)尺寸太小。1. 在RStudio中,手动拖动绘图窗口放大。
2. 使用pdf()png()等函数输出到文件时,指定足够的宽度和高度(如pdf(“plot.pdf”, width=12, height=10))。
运行draw(..., circular=TRUE)时报错。ComplexHeatmap版本过低,不支持circular参数。升级ComplexHeatmap包:BiocManager::install(“ComplexHeatmap”)
添加多个轨道时,它们对不齐。track.height设置不当或circos.par中的track.margin影响。精细调整每个circos.tracktrack.height参数,并确保panel.fun内的绘图逻辑与数据索引正确对应。

6. 最佳实践与工程建议

要将此类分析融入实际的生物信息学或数据分析项目,遵循以下最佳实践能提升效率与可重复性。

6.1 项目组织与代码规范

  • 脚本模块化:将数据准备、颜色定义、绘图函数、保存输出分别写成独立的R脚本或函数,通过source()调用。例如,01_prepare_data.R,02_plot_functions.R,03_main_analysis.R
  • 使用R Markdown或Jupyter Notebook:将分析过程、代码和结果(图形)整合在一个动态文档中,便于记录和分享。
  • 设置随机种子:任何涉及随机数生成的操作(如rnorm,sample)前,务必使用set.seed(),确保结果可重现。

6.2 数据处理与可视化

  • 数据标准化:在绘制表达热图前,通常需要对行(基因)或列(样本)进行标准化(如Z-score标准化),以消除量纲影响,使模式更清晰。可以使用scale()函数。
    expr_mat_scaled <- t(scale(t(expr_mat))) # 对行(基因)进行Z-score标准化
  • 颜色选择:优先使用色盲友好的调色板(如viridis,RColorBrewer的Set2、Set3、Paired等)。避免使用红绿对比,可以使用dichromat包模拟色盲视图进行检查。
  • 图形输出:用于出版的图形,建议使用矢量格式(如PDF、SVG),以保证无限缩放不失真。使用pdf()svg()函数,并指定高分辨率。
    pdf("circular_heatmap.pdf", width = 10, height = 8) draw(ht_obj, circular = TRUE, ...) dev.off()

6.3 性能优化

  • 大数据集处理:当基因数(行数)超过数千时,聚类和绘图可能变慢。可以考虑:
    1. 在绘图前先对数据进行子集筛选(如选择差异表达最显著的基因)。
    2. 使用cluster_rows = FALSE关闭实时聚类,预先使用fastcluster::hclust等快速算法生成聚类对象,再传递给cluster_rows参数。
    3. 关闭行/列名的显示(show_row_names = FALSE)。
  • 内存管理:极大规模矩阵绘图可能消耗大量内存。确保R会话有足够的内存,并考虑将中间结果保存为RData文件。

6.4 版本控制与协作

  • 使用sessionInfo()记录完整的R环境信息,包括所有包的版本。这能帮助他人或未来的你复现结果。
    sessionInfo()
  • 将关键的绘图参数(如颜色函数、图形尺寸、字体大小)集中定义为变量或列表,方便统一调整和维护。

通过本文的梳理,你应该已经掌握了使用R语言ComplexHeatmap包复现文献中精美圆形热图的完整流程。从环境搭建、数据模拟、核心绘图函数解读,到一步步完成一个多轨道的环形热图,并添加了专业的注释和图例。更重要的是,我们探讨了更符合ComplexHeatmap设计哲学的circular参数绘制方法,以及实践中会遇到的各种问题与解决方案。

复现文献图表是提升数据可视化能力的绝佳途径。下一步,你可以尝试:

  1. 应用真实数据:将本例中的模拟矩阵替换为你自己的基因表达矩阵、相关系数矩阵或任何数值矩阵。
  2. 探索更多注释类型ComplexHeatmap支持点图、条形图、箱线图、折线图等多种注释图形,尝试将它们添加到环形轨道中。
  3. 深度定制:研究ComplexHeatmapcirclize的官方文档,调整扇区大小、轨道顺序、标签旋转角度等,实现完全符合你审美的定制化图表。
  4. 组合其他图形:尝试将环形热图与传统的矩形热图、密度图等组合在一张画布上,利用ComplexHeatmap%v%%h%操作符。

如果在实践中遇到新的问题,多查阅?ComplexHeatmap?circlize的帮助文档,以及在Bioconductor和GitHub上的官方Issue区寻找灵感。动手实践,不断调试,你也能创造出令人惊艳的科学可视化作品。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询