You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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值数据。

问题原因

  1. 数值范围不匹配:污染得分范围是870-6831,而P值范围是0-1,直接绘制会导致折线被压在底部。
  2. 副轴转换逻辑错误:代码中sec_axis(~.*0.01)是把左轴数值缩小100倍,但P值本身已经是0-1,应该先把P值放大到左轴量级,再在副轴做反向转换。
  3. 折线图分组缺失:离散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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 10:30:55