ggplot2:循环绘制柱状图时添加折线、双Y轴并设置对应ID标题
解决ggplot2按ID绘制双Y轴组合图表问题
数据准备
ID <- c('1P', '1P', '1P', '2P', '2P', '2P', '3P', '3P', '3P') Visit <- c('V1','V2','V3','V1','V2','V3','V1','V2','V3') var1 <- c(100, 150, 125, 75, 90, 100, 50, 60, 110) var2<-c(1.1, 0.8,0.7, 1, 0.5, 0.2, 1.8, 0.8, 0.3) df<- data.frame(ID, Visit, var1, var2)
需求说明
- 按
ID拆分数据,每个ID对应独立图表 - 图表X轴为
Visit,同时展示:var1的柱状图(左侧Y轴)var2的折线图(右侧Y轴)
- 每张图表标题为对应的
ID
错误代码问题分析
你之前的代码存在三个核心问题:
- 用
ggplot(NULL)初始化画布,未绑定子数据框,导致图层无法读取对应ID的专属数据 - 未处理
var1和var2的数值范围差异,直接绘制会让折线被压缩到几乎不可见 - 未传递
ID信息,无法设置对应标题
正确实现代码
library(ggplot2) # 按ID拆分数据 df_split <- split(df, df$ID) # 遍历每个ID生成对应图表 plots <- lapply(names(df_split), function(id) { # 获取当前ID的子数据框 sub_df <- df_split[[id]] # 计算转换系数,将var2映射到var1的数值范围 coeff <- max(sub_df$var1) / max(sub_df$var2) ggplot(sub_df, aes(x = Visit)) + # 绘制var1柱状图 geom_col(aes(y = var1), fill = "#619CFF") + # 绘制var2折线图(先乘系数匹配左轴范围) geom_line(aes(y = var2 * coeff), color = "#F8766D", size = 1.2, group = 1) + geom_point(aes(y = var2 * coeff), color = "#F8766D", size = 2) + # 设置双Y轴,右轴还原var2原始数值 scale_y_continuous( name = "var1", sec.axis = sec_axis(~ . / coeff, name = "var2") ) + # 设置图表标题为当前ID ggtitle(paste("ID:", id)) + # 美化主题 theme_minimal() + theme( plot.title = element_text(hjust = 0.5, size = 14, face = "bold"), axis.title.y.right = element_text(color = "#F8766D"), axis.text.y.right = element_text(color = "#F8766D"), axis.title.y.left = element_text(color = "#619CFF"), axis.text.y.left = element_text(color = "#619CFF") ) }) # 查看生成的所有图表 plots
关键要点说明
- 遍历
names(df_split)直接获取ID名称,方便设置图表标题 - 通过转换系数解决双Y轴数值范围差异问题,确保折线和柱状图都清晰可见
- 所有图层绑定当前ID的子数据框,保证每个图表只展示对应ID的数据
- 通过颜色区分左右轴和对应图层,提升图表可读性
内容的提问来源于stack exchange,提问作者endimm
相关产品推荐
相关产品推荐

