在R的ggplot2中组合柱状图与折线图时双轴失效问题求助
双轴组合图(柱状+折线)失效问题解决
数据集
我使用的R数据集如下:
Sample_ID = c("LSL Guideline", "USL Guideline", "P1014B", "P1014F", "P1036A", "P1036B", "P1036C","P1036D" ,"P1036E", "P1036F") CONTAMINATION_SCORE_NA = c(0, 3106, 2677, 1021, 870, 6831, 1324, 4175, 1370, 875) CONTAMINATION_P_VALUE_NA = c(0.000, 0.049, 0.101, 1.000, 1.000, 0.000, 1.000, 0.036, 1.000, 1.000) df <- data.frame(Sample_ID, CONTAMINATION_SCORE_NA, CONTAMINATION_P_VALUE_NA)
输出的数据集内容:
Sample_ID CONTAMINATION_SCORE_NA CONTAMINATION_P_VALUE_NA 1 LSL Guideline 0 0.000 2 USL Guideline 3106 0.049 3 P1014B 2677 0.101 4 P1014F 1021 1.000 5 P1036A 870 1.000 6 P1036B 6831 0.000 7 P1036C 1324 1.000 8 P1036D 4175 0.036 9 P1036E 1370 1.000 10 P1036F 875 1.000
问题描述
我需要绘制除前2行外的数据:用柱状图展示CONTAMINATION_SCORE_NA,折线图展示CONTAMINATION_P_VALUE_NA在右侧副轴。参考教程写了如下代码:
ggplot(df[-c(1,2),]) + geom_bar(aes(x=Sample_ID, y=`CONTAMINATION_SCORE (NA)`),stat="identity", fill=rainbow(n=length(df$Sample_ID[-c(1:2)])))+ geom_line(aes(x=Sample_ID, y=`CONTAMINATION_P_VALUE (NA)`),stat="identity",color="red")+ labs(title= " QC", x="Sample ID",y=" Score") + scale_y_continuous(sec.axis=sec_axis(~.*0.01,name="Percentage"))
但右侧副轴未正常工作,折线因数值太小几乎被压缩到横轴,无法正常展示P值数据。
问题原因
- 数值范围不匹配:污染得分范围是870-6831,而P值范围是0-1,直接绘制会导致折线被压在底部。
- 副轴转换逻辑错误:代码中
sec_axis(~.*0.01)是把左轴数值缩小100倍,但P值本身已经是0-1,应该先把P值放大到左轴量级,再在副轴做反向转换。 - 折线图分组缺失:离散x轴下,
geom_line需要group=1来识别所有点属于同一组,否则无法连成线。
修正后的代码
library(ggplot2) # 筛选需要绘制的数据 df_plot <- df[-c(1, 2), ] # 计算缩放比例:用污染得分的最大值匹配P值的最大值(1) scale_ratio <- max(df_plot$CONTAMINATION_SCORE_NA) ggplot(df_plot) + # 绘制污染得分柱状图 geom_bar( aes(x = Sample_ID, y = CONTAMINATION_SCORE_NA), stat = "identity", fill = rainbow(nrow(df_plot)) ) + # 绘制P值折线图:先将P值乘以缩放比例匹配左轴范围,设置group=1保证连线 geom_line( aes(x = Sample_ID, y = CONTAMINATION_P_VALUE_NA * scale_ratio, group = 1), color = "red", size = 1, stat = "identity" ) + # 设置双轴:副轴将缩放后的数值转换回原始P值 scale_y_continuous( name = "污染得分", sec.axis = sec_axis(~ . / scale_ratio, name = "P值") ) + # 优化图表标签和样式 labs( title = "QC污染检测结果", x = "样本ID" ) + theme( axis.text.x = element_text(angle = 45, hjust = 1), plot.title = element_text(hjust = 0.5) )
修正说明
- 新增
scale_ratio实现数值范围匹配,将P值放大到与污染得分同量级,确保折线能在图上正常显示。 - 副轴使用
~ . / scale_ratio反向转换,将放大后的数值还原为原始P值,实现双轴对应。 - 给
geom_line添加group=1,解决离散x轴无法连线的问题。 - 优化了坐标轴标签和主题样式,提升图表可读性。
内容的提问来源于stack exchange,提问作者user483292
相关产品推荐
相关产品推荐

