ggplot中如何将标准差适配至第二Y轴?
适配第二Y轴的标准差柱状图解决方案
问题描述
我正在制作多组带有标准差的柱状图,已成功添加第二Y轴,但希望标准差数据能够适配该第二Y轴,而非仅对Y轴刻度进行调整。目前我仅将主Y轴数值除以100,得到的效果如图所示,期望实现类似Excel示例中的效果。
原始代码
df_bar <- as.data.frame( rbind( c('g1', 0.945131015, 1.083188828, 1.040164338, 1.115716593, 0.947886795), c('g2', 1.393211286, 1.264193745, 1.463434395, 1.298126006, 1.112718796), c('g3', 1.509976099, 1.450923745, 1.455102201, 1.280102338, 1.462689245), c('g4', 1.591697668, 1.326292649, 1.767207296, 1.623619341, 2.528108183), c('g5', 2.625114848, 2.164050167, 2.092843287, 2.301950359, 2.352736806) ) ) colnames(df_bar)<-c('interval', 'lvl3.Mellem.Høj', 'lvl1.Lav', 'TOM', ',lvl4.Høj', 'lvl2.Lav.Mellem') df_bar <- melt(df_bar, id.vars = "interval", variable.name = "name", value.name = "value") df_line <- as.data.frame( rbind( c('g1', 0.0212972, 0.0164494, 0.0188898, 0.01888982, 0.03035883), c('g2', 0.0195600, 0.0163811, 0.0188747, 0.01887467, 0.03548092), c('g3', 0.0192249, 0.0161914, 0.02215852, 0.02267605, 0.03426538), c('g4', 0.0187961, 0.0180842, 0.01962371, 0.02103450, 0.03902890), c('g5', 0.0209987, 0.0164596, 0.01838280, 0.02282300, 0.03516818) ) ) colnames(df_line)<-c('interval', 'lvl3.Mellem.Høj', 'lvl1.Lav', 'TOM', ',lvl4.Høj', 'lvl2.Lav.Mellem') df_line <- melt(df_line, id.vars = "interval", variable.name = "name", value.name = "sd") df <- inner_join(df_bar,df_line, by=c("interval", "name")) df %>% mutate(value = as.numeric(value)) %>% mutate(sd = as.numeric(sd)) %>% mutate(interval = as.factor(interval)) %>% mutate(name = as.factor(name)) %>% ggplot() + geom_bar(aes(x = interval, y = value, fill = interval), stat = "identity") + geom_line(aes(x = interval, y = sd, group = 1), color = "black", size = .75) + scale_y_continuous("Value", sec.axis = sec_axis(~ . /100, name = "sd")) + facet_grid(~name, scales = "free") + theme_bw() + theme(legend.position = "none") + xlab("Interval") + ylab("Value") + labs(caption = "Black line indicates standard deviation.")
解决方案
核心问题是你仅调整了第二Y轴的刻度显示,但标准差数据的实际数值未映射到第二Y轴尺度。正确做法是将标准差数据按比例放大以匹配主Y轴范围,同时让第二Y轴刻度对应实际标准差。
修改后的代码:
df_bar <- as.data.frame( rbind( c('g1', 0.945131015, 1.083188828, 1.040164338, 1.115716593, 0.947886795), c('g2', 1.393211286, 1.264193745, 1.463434395, 1.298126006, 1.112718796), c('g3', 1.509976099, 1.450923745, 1.455102201, 1.280102338, 1.462689245), c('g4', 1.591697668, 1.326292649, 1.767207296, 1.623619341, 2.528108183), c('g5', 2.625114848, 2.164050167, 2.092843287, 2.301950359, 2.352736806) ) ) colnames(df_bar)<-c('interval', 'lvl3.Mellem.Høj', 'lvl1.Lav', 'TOM', ',lvl4.Høj', 'lvl2.Lav.Mellem') df_bar <- melt(df_bar, id.vars = "interval", variable.name = "name", value.name = "value") df_line <- as.data.frame( rbind( c('g1', 0.0212972, 0.0164494, 0.0188898, 0.01888982, 0.03035883), c('g2', 0.0195600, 0.0163811, 0.0188747, 0.01887467, 0.03548092), c('g3', 0.0192249, 0.0161914, 0.02215852, 0.02267605, 0.03426538), c('g4', 0.0187961, 0.0180842, 0.01962371, 0.02103450, 0.03902890), c('g5', 0.0209987, 0.0164596, 0.01838280, 0.02282300, 0.03516818) ) ) colnames(df_line)<-c('interval', 'lvl3.Mellem.Høj', 'lvl1.Lav', 'TOM', ',lvl4.Høj', 'lvl2.Lav.Mellem') df_line <- melt(df_line, id.vars = "interval", variable.name = "name", value.name = "sd") df <- inner_join(df_bar,df_line, by=c("interval", "name")) df %>% mutate(value = as.numeric(value)) %>% mutate(sd = as.numeric(sd)) %>% mutate(interval = as.factor(interval)) %>% mutate(name = as.factor(name)) %>% ggplot() + geom_bar(aes(x = interval, y = value, fill = interval), stat = "identity") + # 将sd乘以100,匹配主Y轴尺度 geom_line(aes(x = interval, y = sd * 100, group = 1), color = "black", size = .75) + # 第二Y轴将主Y轴数值除以100,对应实际标准差 scale_y_continuous("Value", sec.axis = sec_axis(~ . / 100, name = "Standard Deviation")) + facet_grid(~name, scales = "free") + theme_bw() + theme(legend.position = "none") + xlab("Interval") + ylab("Value") + labs(caption = "Black line indicates standard deviation.")
说明
- 将
geom_line中的y = sd改为y = sd * 100,让标准差数据放大后适配主Y轴的高度范围。 sec_axis(~ . / 100)确保第二Y轴的刻度显示的是实际的标准差数值,和放大后的线条对应。- 这样修改后,标准差线条的高度会准确对应第二Y轴的刻度,实现类似Excel的双Y轴适配效果。
内容的提问来源于stack exchange,提问作者Mathias Nissen
相关产品推荐
相关产品推荐

