如何在ggplot2嵌套分面下堆叠热图与折线图
解决方案:批量生成子图拼接+嵌套布局
核心逻辑
不需要合并两个数据集,而是基于物种-区域-项目编号-年份的共同分组,为每个分组单独生成「折线图+热图」的垂直组合,再按嵌套分面的层级批量排列所有组合图。这种方式完全自动化,适配大规模数据集。
步骤1:匹配数据结构的模拟示例
假设你的数据集结构如下(可替换为实际数据):
library(tidyverse) library(ggplot2) library(ggh4x) # 用于嵌套分面 library(cowplot) # 模拟阳性样本百分比热图数据 heat_data <- expand_grid( species = c("A", "B"), region = c("North", "South"), project = c("P1", "P2"), year = 2020:2021, month = 1:12, sample_type = c("Type1", "Type2") ) %>% mutate(positive_pct = runif(n(), 0, 100)) # 模拟月度样本采集数量折线图数据 line_data <- expand_grid( species = c("A", "B"), region = c("North", "South"), project = c("P1", "P2"), year = 2020:2021, month = 1:12 ) %>% mutate(sample_count = sample(10:100, n(), replace = TRUE))
步骤2:编写子图生成函数
写一个批量处理函数,输入一组分组参数,生成精简的折线图(置于上方)和热图,再垂直拼接:
make_combined_plot <- function(spp, reg, proj, yr) { # 筛选当前分组的折线数据并绘图 line_sub <- line_data %>% filter(species == spp, region == reg, project == proj, year == yr) line_plot <- ggplot(line_sub, aes(x = month, y = sample_count)) + geom_line(color = "#2c3e50", size = 1) + scale_x_continuous(breaks = 1:12) + theme_minimal() + theme( axis.title = element_blank(), axis.text.y = element_text(size = 8), axis.text.x = element_blank(), plot.margin = margin(t = 5, r = 5, b = 0, l = 5) ) # 筛选当前分组的热图数据并绘图 heat_sub <- heat_data %>% filter(species == spp, region == reg, project == proj, year == yr) heat_plot <- ggplot(heat_sub, aes(x = month, y = sample_type, fill = positive_pct)) + geom_tile(color = "white") + scale_fill_viridis_c(option = "magma") + scale_x_continuous(breaks = 1:12) + labs(x = "Month", y = "Sample Type", fill = "Positive %") + theme_minimal() + theme( plot.margin = margin(t = 0, r = 5, b = 5, l = 5), axis.text = element_text(size = 8) ) # 垂直拼接并添加分组标题 plot_grid(line_plot, heat_plot, ncol = 1, rel_heights = c(1, 3), align = "v") + draw_label(paste0(spp, " | ", reg, " | ", proj, " | ", yr), x = 0.5, y = 1, vjust = 1, size = 10) }
步骤3:批量生成所有组合图
提取所有唯一分组,用purrr自动遍历生成所有子图:
# 获取所有唯一分组键 group_keys <- heat_data %>% distinct(species, region, project, year) %>% mutate(id = row_number()) # 批量生成组合图 combined_plots <- pmap(group_keys, make_combined_plot)
步骤4:按嵌套逻辑排列所有图
按物种>区域>项目>年份的层级排序后,排列成网格布局:
# 按嵌套层级排序分组 group_keys_sorted <- group_keys %>% arrange(species, region, project, year) # 同步排序组合图 combined_plots_sorted <- combined_plots[group_keys_sorted$id] # 排列成指定行列的网格(示例为每行2个图) plot_grid(plotlist = combined_plots_sorted, ncol = 2, align = "hv")
关键说明
- 无需合并数据集:两个数据集变量属性(百分比vs计数)、维度(热图多sample_type字段)差异大,合并会引入大量NA,分开生成子图更高效。
- 全自动化适配:无论数据集规模多大,只要分组键一致,
pmap会自动遍历所有分组,无需手动处理单个子图。 - 样式统一调整:所有子图的主题、颜色、比例可在
make_combined_plot函数中统一修改,保证整体风格一致。
内容的提问来源于stack exchange,提问作者mkmor
相关产品推荐
相关产品推荐

