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" )
关键修改说明
- 图例显示线条而非点:将
geom_hline的col参数移到aes()内部,绑定到对应的图例名称,让ggplot为水平线生成线条图例,替代原来的点图例。 - 修复图例颜色:通过
scale_colour_manual直接映射预设的颜色向量,确保"P-value upper Limit"显示黑色,"Contam. score upper limit"显示红色。 - 仅展示次轴相关图例:将
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
相关产品推荐
相关产品推荐

