基于gridExtra的分组误差棒图Y轴分组及行背景设置需求
解决方案
1. 基于category对Y轴path分组
要实现path按category分组,首先需要固定path的排序逻辑,确保同category的path连续排列,再通过分组标签和分隔线强化分组视觉效果:
数据预处理
先对数据按category和path排序,同时为每个path分配对应的Y轴数值位置(离散Y轴默认从1开始映射):
# 按category和path排序,固定path的因子顺序 dat_sorted <- dat %>% arrange(category, path) %>% mutate(path = factor(path, levels = unique(path))) # 映射每个path到对应的Y轴数值位置 path_y_pos <- setNames(1:length(levels(dat_sorted$path)), levels(dat_sorted$path)) dat_sorted$y_pos <- path_y_pos[dat_sorted$path] # 计算category分组的分隔线位置(每个category最后一个path的Y位置+0.5) category_bounds <- dat_sorted %>% group_by(category) %>% summarise(max_y = max(y_pos) + 0.5) %>% pull(max_y) %>% head(-1) # 移除最后一个边界,避免多余线条
改造左侧Y轴标签图
在左侧Y轴图中添加category分组标签和分隔线:
y_axis_plot <- ggplot(dat_sorted, aes(y = path, x = "")) + labs(y = "Path", x = "") + theme_minimal() + # 添加category分组标题 geom_text(aes(label = category), x = -0.2, color = "black", size = 4, hjust = 1) + # 添加category分组分隔线 geom_hline(yintercept = category_bounds, color = "black", linewidth = 1) + theme( panel.grid.major.x = element_blank(), plot.margin = unit(c(5,0,5,5), "pt"), text = element_text(size = 14), axis.text.y = element_text(size = 14) )
2. Y轴各行灰白交替背景
通过geom_rect绘制每个path对应的横向背景矩形,利用交替颜色实现灰白效果:
生成带背景的子图列表
plots_dat <- dat_sorted %>% group_by(tis) %>% group_split() %>% lapply(function(plotDat){ # 构造背景数据:每个path对应一个矩形,颜色交替 bg_data <- data.frame( y = unique(plotDat$y_pos), fill = rep(c("white", "grey90"), length.out = length(unique(plotDat$y_pos))) ) ggplot(plotDat, aes(x=NS, y=y_pos, group=dataset, col=dataset, fill=dataset)) + # 添加交替背景矩形(放在最底层) geom_rect(data = bg_data, aes(y = y, ymin = y - 0.45, ymax = y + 0.45, xmin = -Inf, xmax = Inf), fill = bg_data$fill, inherit.aes = FALSE) + theme_bw() + geom_point(position = position_dodge(0.7)) + geom_vline(xintercept = c(-1,1), colour="#FA8072", linetype = "longdash") + geom_vline(xintercept = c(0), colour="grey", linetype = "solid") + geom_errorbarh(height=.3, aes(xmin = min, xmax = max), position = position_dodge(0.7)) + # 添加category分组分隔线,和左侧Y轴图保持一致 geom_hline(yintercept = category_bounds, color = "black", linewidth = 1) + theme( axis.title.y=element_blank(), axis.text.y=element_blank(), axis.ticks.y=element_blank(), plot.margin = unit(c(5,5,5,5), "pt"), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), text = element_text(size = 14), legend.position = "top" ) + labs(x = "NS", title = plotDat$tis) + xlim(-2.5, 2.5) })
拼接所有图表
最后用gridExtra组合左侧Y轴图和子图:
gridExtra::grid.arrange(grobs = c(list(y_axis_plot), plots_dat), nrow = 1, widths = c(1.5, rep(1, length(plots_dat))))
关键说明
- 固定path的因子顺序是实现分组的核心,确保同category的path连续排列;
- 交替背景通过
geom_rect绘制,利用rep(c("white", "grey90"), ...)实现颜色循环; - 分组分隔线在左侧Y轴图和子图中同时添加,保证整体视觉统一性。
内容的提问来源于stack exchange,提问作者Nmgh
相关产品推荐
相关产品推荐

