You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用原生ggplot为相关性热图坐标轴添加多层注释条

原生ggplot实现热图轴堆叠注释条方案

步骤1:拆分元数据并准备注释数据集

首先从cor.df的x(或y,两者命名规则一致)列拆分出celltype、disease、origin三类元数据,同时确保注释数据的顺序和热图轴的顺序完全匹配:

library(tidyverse)

# 拆分x列的元数据,生成注释用基础数据集
annot_df <- cor.df %>%
  distinct(x) %>%
  separate(x, into = c("celltype", "disease", "origin"), sep = "_") %>%
  mutate(x = factor(x, levels = cor.df$x))  # 强制保持与热图x轴一致的顺序

# 构造x轴上方的堆叠注释数据(三层对应三类元数据)
x_annot <- annot_df %>%
  pivot_longer(cols = c(celltype, disease, origin), names_to = "annot_type", values_to = "annot_value") %>%
  mutate(y_pos = case_when(
    annot_type == "celltype" ~ 1,
    annot_type == "disease" ~ 2,
    annot_type == "origin" ~ 3
  ))

# 构造y轴右侧的堆叠注释数据(三层对应三类元数据)
y_annot <- annot_df %>%
  pivot_longer(cols = c(celltype, disease, origin), names_to = "annot_type", values_to = "annot_value") %>%
  mutate(x_pos = case_when(
    annot_type == "celltype" ~ 1,
    annot_type == "disease" ~ 2,
    annot_type == "origin" ~ 3
  ))

步骤2:绘制带注释条的热图

通过分层绘图,先绘制基础热图,再叠加x轴上方和y轴右侧的注释条,最后调整主题布局适配注释:

# 绘制基础相关性热图
p <- ggplot(cor.df, aes(x = x, y = y, fill = correlation)) +
  geom_tile(color = "black") +
  scale_fill_gradient2(low = "dodgerblue4", high = "red4", mid = "white",
                       midpoint = 0.5, limit = c(0,1), space = "Lab", 
                       name="Pearson\nCorrelation") +
  theme_bw() +
  theme(
    axis.text.x = element_text(angle = 70, vjust = 1, hjust = 1),
    axis.title = element_blank(),
    plot.margin = unit(c(3, 3, 1, 1), "lines")  # 预留注释条的显示空间
  )

# 叠加x轴上方的堆叠注释条
p <- p +
  geom_tile(data = x_annot, aes(x = x, y = y_pos, fill = annot_value), inherit.aes = FALSE, height = 0.9) +
  scale_y_continuous(breaks = 1:3, labels = c("Celltype", "Disease", "Origin"),
                     sec.axis = dup_axis(name = "", labels = NULL)) +
  coord_cartesian(ylim = c(1, n_distinct(cor.df$y)), clip = "off")  # 允许显示主图范围外的注释

# 叠加y轴右侧的堆叠注释条
p <- p +
  geom_tile(data = y_annot, aes(x = x_pos, y = x, fill = annot_value), inherit.aes = FALSE, width = 0.9) +
  scale_x_continuous(breaks = 1:3, labels = c("Celltype", "Disease", "Origin"),
                     sec.axis = dup_axis(name = "", labels = NULL)) +
  coord_cartesian(xlim = c(1, n_distinct(cor.df$x)), clip = "off")

# 可选:给注释条设置独立配色(避免与热图填充色冲突)
p <- p +
  scale_fill_manual(values = c(
    "cell1" = "#E69F00", "cell2" = "#56B4E9", "cell3" = "#009E73", "cell4" = "#F0E442", "cell5" = "#0072B2",
    "disease1" = "#D55E00", "disease2" = "#CC79A7",
    "origin1" = "#999999", "origin2" = "#E6E6E6", "origin3" = "#000000"
  ), limits = force)

print(p)

关键细节说明

  • inherit.aes = FALSE:强制注释条的fill映射独立于热图的相关性填充,避免颜色映射冲突。
  • coord_cartesian(clip = "off"):允许显示主图范围外的注释条,配合plot.margin预留的空间实现完整显示。
  • 注释条的height/width设为0.9是为了和热图主体tiles留出细微间隙,提升视觉层次感。
  • 如果需要给不同注释类型设置完全独立的配色体系,可以使用ggnewscale包添加多组scale_fill_*,实现热图与注释条的配色分离。

内容的提问来源于stack exchange,提问作者Dragonmasterx87

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 11:35:38