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

R语言ggplot双轴图表:次轴图例文本添加及样式修正求助

问题解决:ggplot2 图表图例与次轴优化

数据代码

Sample_ID <- c("P1014B", "P1014F", "P1036A", "P1036B", "P1036C", "P1036D", "P1036E", "P1036F")
`CONTAMINATION_SCORE (NA)` <- c(2677, 1021, 870, 6831, 1324, 4175, 1370, 875)
`CONTAMINATION_P_VALUE (NA)` <- c(0.101, 1.000, 1.000, 0.000, 1.000, 0.036, 1.000, 1.000)
contam_reads <- data.frame(Sample_ID, `CONTAMINATION_SCORE (NA)`, `CONTAMINATION_P_VALUE (NA)`, check.names = FALSE)

原绘图代码

cols = c("P-value upper Limit" = "black","Contam. score upper limit" = "red")

ggplot(contam_reads[-c(1,2),], aes(x=Sample_ID, y=`CONTAMINATION_SCORE (NA)`))  + 
  geom_bar(stat="identity", fill="cyan4") +
  geom_hline(aes(yintercept=contam_reads$`CONTAMINATION_SCORE (NA)`[1]), col = cols[2], size = 1.5, linetype=2) +
  geom_hline(aes(yintercept=contam_reads$`CONTAMINATION_P_VALUE (NA)`[1]*10000), col = cols[1], size = 1, linetype=2) +
  geom_point(aes(x=Sample_ID, y=`CONTAMINATION_P_VALUE (NA)`* 10000),stat="identity",color="red", size = 1.5, show.legend = T) +
  labs(title= "DNA Library QC Metrics for Contamination",
       x="Sample ID",y="Contamination Score") +
  scale_y_continuous(sec.axis=sec_axis(~./10000,name="P-value", breaks = seq(0,1,0.1))) +
  theme(
    axis.title.y = element_text(color = "cyan4",size=15),
    axis.text.y = element_text(color = "cyan4"),
    axis.title.y.right = element_text(color = "red"),
    axis.text.y.right = element_text(color = "red")
  ) +    
  scale_colour_manual(values=cols)

存在的问题

  • 图例显示为点而非线条
  • 图例中的第一个点无法设置为黑色
  • 需要仅为次轴添加文本或图例

解决方案

核心思路是把水平线的颜色映射放到aes()内部,让ggplot识别为图例项;同时分离点和线条的图例,最后通过guides()控制仅展示次轴相关的图例。

修改后的代码:

cols = c("P-value upper Limit" = "black","Contam. score upper limit" = "red")

ggplot(contam_reads[-c(1,2),], aes(x=Sample_ID, y=`CONTAMINATION_SCORE (NA)`))  + 
  geom_bar(stat="identity", fill="cyan4") +
  # 把color映射放到aes里,让线条生成图例
  geom_hline(aes(yintercept=contam_reads$`CONTAMINATION_SCORE (NA)`[1], color="Contam. score upper limit"), size = 1.5, linetype=2) +
  geom_hline(aes(yintercept=contam_reads$`CONTAMINATION_P_VALUE (NA)`[1]*10000, color="P-value upper Limit"), size = 1, linetype=2) +
  # 隐藏点的图例,只保留线条图例
  geom_point(aes(x=Sample_ID, y=`CONTAMINATION_P_VALUE (NA)`* 10000), color="red", size = 1.5, show.legend = FALSE) +
  labs(title= "DNA Library QC Metrics for Contamination",
       x="Sample ID",y="Contamination Score",
       color = "Thresholds") +  # 设置图例标题
  scale_y_continuous(sec.axis=sec_axis(~./10000,name="P-value", breaks = seq(0,1,0.1))) +
  scale_colour_manual(values=cols) +
  theme(
    axis.title.y = element_text(color = "cyan4",size=15),
    axis.text.y = element_text(color = "cyan4"),
    axis.title.y.right = element_text(color = "red"),
    axis.text.y.right = element_text(color = "red"),
    legend.position = "right"
  )

关键修改说明

  1. 图例显示线条而非点:将geom_hline的col参数移到aes()内部,绑定到对应的图例名称,让ggplot为水平线生成线条图例,替代原来的点图例。
  2. 修复图例颜色:通过scale_colour_manual直接映射预设的颜色向量,确保"P-value upper Limit"显示黑色,"Contam. score upper limit"显示红色。
  3. 仅展示次轴相关图例:将geom_point的show.legend设为FALSE,隐藏点的图例,只保留水平线的阈值图例,同时通过labs(color)设置图例标题,让图例与次轴对应。

如果需要单独为次轴添加文本标注,可以加入以下代码:

# 为次轴阈值添加文本标注
annotate("text", x = 1, y = contam_reads$`CONTAMINATION_P_VALUE (NA)`[1]*10000 + 500, 
         label = "P-value Threshold", color = "black", hjust = 0)

内容的提问来源于stack exchange,提问作者user483292

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 17:30:57