如何在ggplot网格布局中为每个误差棒图下方添加对应表格?
解决ggplot网格布局中每个图下方匹配对应表格的问题
我完全懂你的痛点:单个误差棒图加表格的布局调得好好的,可把这些组合单元放进网格后,整个排版就彻底变形了。咱们来一步步实现每个图下方整齐对应表格的网格布局,保证排版干净优雅。
第一步:修正并准备数据
首先先把你数据里的小问题修正下(比如cilower的seq参数写错了,步长10会导致只有一个值),同时准备好多个子图需要的数据集:
# 基础数据 point <- c(1:10) ciupper <- seq(2,20,2) cilower <- seq(0.1, 1, length.out = 10) # 修正步长问题,生成10个匹配值 year <- c("2005/06", "2007", "2008", "2009", "2010", "2011", "2012", "2013", "2014", "2015") label <- c("Ref", paste0("val ", 1:9)) # 简化label生成,若需表达式可保留bquote写法 # 生成3组不同的绘图数据(模拟多个子图的数据源) data_list <- list( data9 = data.frame(point, cilower, ciupper, year), data10 = data.frame(point = point + 2, cilower = cilower + 0.5, ciupper = ciupper + 2, year), data11 = data.frame(point = point - 1, cilower = cilower - 0.2, ciupper = ciupper - 1, year) ) # 对应的表格数据 tabl_list <- lapply(data_list, function(df) data.frame(year = df$year, label = label))
第二步:定义单个图+表格的组合函数
核心是把每个图和对应的表格先做成一个对齐的独立单元,保证宽度完全匹配:
library(ggplot2) library(ggpubr) library(gridExtra) library(grid) # 定义生成带表格的组合单元函数 plot_with_table <- function(plot_data, table_data) { # 绘制误差棒图 p <- ggplot(data=plot_data, aes(x=year, y=point)) + geom_point(size=3) + geom_errorbar(ymax=plot_data$ciupper, ymin=plot_data$cilower, width=0.1) + geom_hline(yintercept = 0, linetype = "dashed") + ylim(-5, 30) + labs(x="", y="", title="Subtitle") + theme_pubr() + labs_pubr() + theme(axis.text.x = element_text(angle=45, hjust=1)) # 旋转x轴标签避免重叠 # 生成表格Grob,设置和图一致的宽度 tt <- ttheme_default(padding = unit(c(6,4), "mm"), core = list(fg_params = list(fontsize=10)), colhead = list(fg_params = list(fontsize=10))) tb <- tableGrob(t(table_data), theme=tt, rows=NULL) # 强制表格宽度和绘图区域宽度完全匹配 tb$widths <- p$theme$axis.text.x$width %||% unit(1, "null") # 组合图和表格,垂直对齐并设置高度比例 ggarrange(p, tb, nrow=2, heights=c(4,1), align="v") }
第三步:生成所有组合单元并拼成大网格
现在把每个数据源对应的组合单元生成,再用ggarrange拼成网格,同时设置全局对齐:
# 生成所有带表格的组合单元 plot_table_list <- mapply(plot_with_table, data_list, tabl_list, SIMPLIFY=FALSE) # 拼成3列的网格布局,设置全局水平+垂直对齐 attend <- ggarrange(plotlist = plot_table_list, labels="AUTO", ncol=3, nrow=1, align="hv") # 保证所有单元在横竖方向都对齐,避免错位 # 添加全局标题和轴标签 annotate_figure(attend, top=text_grob("Overall Title", size=20), left=text_grob("Y Axis", size=20, rot=90), bottom=text_grob("Year", size=20))
关键要点解释
- 先做独立对齐单元:每个图和表格先组合成一个宽度一致的块,避免直接拼网格时宽度不匹配
- 强制表格宽度匹配:通过
tb$widths <- p$theme$axis.text.x$width %||% unit(1, "null")让表格和绘图区域宽度完全一致 - 全局对齐参数:
ggarrange的align="hv"保证所有组合单元在水平和垂直方向上都对齐,不会出现错位 - 调整高度比例:
heights=c(4,1)让图的高度远大于表格,符合视觉习惯
这样就能实现每个误差棒图下方整齐对应表格,整个网格布局干净美观的效果了。
内容的提问来源于stack exchange,提问作者TimF
相关产品推荐
相关产品推荐

