如何在ggplot分面图中为每个分组添加适配的次坐标轴?
问题描述
现有如下数据框:
dd=structure(list(req = c(0, 6.24296787098387e-05, 0.000124859357419677, 0.000187289036129516, 0.000249718714839355, 0.000312148393549194 ), st = c(4.20392459337459, 3.101869731322, 3.05827365904846, 2.55875394873998, 1.61722938145694, 0.969328686413803), tt = c(1.66320917439717, 1.46619835076717, 1.47423709334019, 1.39210979230404, 1.24099973128753, 1.15120693233888), nn = c(2.09771326762665, 1.74025312387583, 1.74965887129391, 1.64515722021115, 1.38734468460281, 1.30261082263608 )), row.names = c(NA, 6L), class = "data.frame") df=dd df$sou="A" df$req=df$req+0.05 dd$sou="B" out=rbind(df,dd)
需要绘制带次坐标轴的分面图,原实现代码仅针对sou="B"分组计算了次坐标轴参数fs和pers,导致sou="A"分面的次坐标轴无法匹配自身数据:
fs <- pretty(dd[["req"]]) pers <- round(1 / fs, 2) ggplot(data =out, aes(x=req)) + geom_line(aes(y=st , color = "SS"), size = .8) + scale_x_continuous(sec.axis = sec_axis(~., labels = pers, breaks = fs))+ facet_wrap(~sou, scales = "free")
解决方案
ggplot2原生分面功能不支持为每个分面单独配置次坐标轴,因此我们可以为每个sou分组单独绘图,再用patchwork包拼接成分面样式,具体步骤如下:
1. 安装并加载依赖包
install.packages("patchwork") library(ggplot2) library(patchwork)
2. 按分组计算次坐标轴参数
拆分数据并为每个分组生成适配的fs(主坐标轴断点)和pers(次坐标轴标签):
# 按sou拆分数据 grouped_data <- split(out, out$sou) # 计算每个分组的坐标轴参数,排除0避免除以0报错 axis_params <- lapply(grouped_data, function(df) { fs <- pretty(df[["req"]]) fs <- fs[fs != 0] pers <- round(1 / fs, 2) list(fs = fs, pers = pers) })
3. 生成每个分组的独立图形
为每个分组绘制带专属次坐标轴的图形:
plot_list <- lapply(names(grouped_data), function(sou) { df <- grouped_data[[sou]] params <- axis_params[[sou]] ggplot(df, aes(x = req)) + geom_line(aes(y = st, color = "SS"), size = .8) + scale_x_continuous( sec.axis = sec_axis(~., labels = params$pers, breaks = params$fs), expand = c(0, 0) ) + labs(title = sou) + theme_bw() })
4. 拼接图形为分面样式
将多个图形拼接成类似facet_wrap的布局,并统一图例:
wrap_plots(plot_list, ncol = 2) + plot_layout(guides = "collect")
这样每个分面都会拥有适配自身数据的次坐标轴,解决了原代码的适配问题。
内容的提问来源于stack exchange,提问作者bic ton
相关产品推荐
相关产品推荐

