调整ggplot条形图X轴标签:将均值线下方标签移至上方
问题描述
我使用如下R代码绘制了ggplot条形图,希望将均值线下方的条形对应的Genotype标签移至均值线上方。绘图代码及数据集如下:
hiz <- mean(data$SPAD) quux <- data %>% select(Genotype,Species, SPAD) %>% arrange(desc(SPAD)) %>% mutate(Genotype = factor(Genotype, levels = Genotype)) ggplot(quux, aes(Genotype, fill=Species)) + geom_rect(aes(xmin=as.numeric(Genotype)-0.4, xmax=as.numeric(Genotype) + 0.4, ymin=pmax(horiz, SPAD), ymax=pmin(horiz, SPAD)), colour="black")+ scale_fill_manual(values=c('#e9002d', '#ffaa00', '#00b000','blue'))+ geom_errorbar(aes(ymin = SPAD, ymax = ifelse(SPAD > horiz, SPAD+3.3306, pmin(horiz, SPAD-3.3306))), width = 0.4, position = position_dodge(0.9)) + theme_bw()+ scale_x_discrete() + scale_y_continuous(breaks = seq(6.8, 13.50, 0.75),labels = number_format(accuracy = 0.01))+ geom_hline(yintercept = horiz, linetype = "dashed", color = "black")+ geom_text(aes(label = Genotype, y = horiz), angle=90, hjust = 1.1) + labs(title="a.",y="", x="")+ theme_light()+ theme(panel.background = element_rect(colour = "black"), axis.text.x = element_blank(), axis.ticks.x = element_blank(), axis.text.y =element_text(colour="black", size = "10", face = "bold"), plot.title = element_text(hjust=0.02,vjust = 1, size = "11", face = "bold"), legend.position=c(0.93, 0.9), legend.text = element_text(size=10,face= "italic"))
数据集
| Genotype | Species | SPAD |
|---|---|---|
| BGB003 | sp1 | 35.5642 |
| BGB008 | sp1 | 34.8968 |
| BGB009 | sp1 | 32.8186 |
| BGB027 | sp1 | 40.6409 |
| BGB045 | sp1 | 32.9753 |
| BGB083 | sp2 | 34.1282 |
| BGB086 | sp2 | 33.824 |
| BGB088 | sp3 | 36.9244 |
| BGB089 | sp3 | 37.7132 |
| BGB091 | sp3 | 43.968 |
| BGB093 | sp3 | 39.1745 |
| BGB096 | sp2 | 32.1512 |
| BGB098 | sp2 | 36.8385 |
| BGB101 | sp2 | 42.7797 |
| BGB102 | sp2 | 33.7136 |
| BGB103 | sp2 | 40.8532 |
| BGB107 | sp2 | 39.5082 |
| BGB109 | sp2 | 49.1457 |
| BGB113 | sp2 | 43.1033 |
| BGB313 | sp4 | 44.675 |
| BGB444 | sp2 | 33.3934 |
| BGB451 | sp2 | 33.4456 |
| BGB467 | sp2 | 37.6576 |
| BGB472 | sp2 | 35.7361 |
解决方案
核心是根据每个条形的SPAD值与均值的大小关系,动态设置标签的位置和对齐方式:
- 若SPAD小于均值,将标签移至均值线上方,并调整对齐方向朝向条形
- 若SPAD大于等于均值,保持标签在均值线下方的原有位置
修改后的完整代码如下:
library(tidyverse) library(scales) # 统一变量名,避免原代码中hiz/horiz不一致的问题 horiz <- mean(data$SPAD) quux <- data %>% select(Genotype, Species, SPAD) %>% arrange(desc(SPAD)) %>% mutate(Genotype = factor(Genotype, levels = Genotype)) ggplot(quux, aes(Genotype, fill = Species)) + geom_rect(aes(xmin = as.numeric(Genotype)-0.4, xmax = as.numeric(Genotype)+0.4, ymin = pmax(horiz, SPAD), ymax = pmin(horiz, SPAD)), colour = "black")+ scale_fill_manual(values = c('#e9002d', '#ffaa00', '#00b000','blue'))+ geom_errorbar(aes(ymin = SPAD, ymax = ifelse(SPAD > horiz, SPAD+3.3306, SPAD-3.3306)), width = 0.4)+ scale_x_discrete() + # 修正y轴范围,适配实际SPAD数据(原范围6.8-13.5与数据不符) scale_y_continuous(breaks = seq(30, 50, 2), labels = number_format(accuracy = 0.01))+ geom_hline(yintercept = horiz, linetype = "dashed", color = "black")+ # 动态设置标签位置与对齐 geom_text(aes(label = Genotype, y = ifelse(SPAD < horiz, horiz + 0.8, horiz), hjust = ifelse(SPAD < horiz, -0.1, 1.1)), angle = 90) + labs(title = "a.", y = "", x = "")+ theme_light()+ theme(panel.background = element_rect(colour = "black"), axis.text.x = element_blank(), axis.ticks.x = element_blank(), axis.text.y = element_text(colour = "black", size = 10, face = "bold"), plot.title = element_text(hjust = 0.02, vjust = 1, size = 11, face = "bold"), legend.position = c(0.93, 0.9), legend.text = element_text(size = 10, face = "italic"))
关键修改说明
- 统一变量名:将原代码中
hiz改为horiz,消除变量名不一致的潜在错误 - 动态标签位置:通过
ifelse(SPAD < horiz, horiz + 0.8, horiz)设置y坐标,让均值线下的标签上移(+0.8可根据绘图效果自行调整) - 标签对齐调整:用
ifelse(SPAD < horiz, -0.1, 1.1)设置hjust,确保标签始终朝向对应条形 - 修正y轴范围:原代码y轴范围与实际SPAD数据不匹配,调整为30-50以完整展示所有条形
内容的提问来源于stack exchange,提问作者Ikram Bashir
相关产品推荐
相关产品推荐

