如何让ggplot中两张图的主次Y轴范围保持一致?
解决ggplot2拆分数据后主次Y轴范围不一致问题
要让拆分后的两张图主次Y轴范围完全一致(主Y轴0-1200,次Y轴0-90),核心是手动指定Y轴的固定范围,避免ggplot自动根据子集数据调整范围。具体修改如下:
修改后完整代码
library(forcats) library(tidyr) library(ggplot2) # 原始数据 mydata<-data.frame(id=c(1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12), mean=c(80,80,53,53,46,46,42,42,37,37,33,33, 28,28,22,22,20,20,17,17,10,10,8,8), type=rep(c("dead","survived"),12), value=c(46,130,220,980,20,840,13,452,8,350,5,69, 4,536,16,141,0,55,38,168,12,95,42,170)) # 拆分数据 mydata1<-mydata[which(mydata$id %in% c(1:6)),] mydata2<-mydata[which(mydata$id %in% c(7:12)),] # 绘制第一张图(ID1-6) mydata1%>% ggplot(aes(x=factor(id), y=value, fill=factor(type,levels=c("dead","survived"))))+ geom_bar(position=position_stack(),stat="identity") + geom_text(data=subset(mydata1,value != 0), aes(label = value),position=position_stack(vjust=0.5),size=4) + # 调整mean缩放比例,匹配主Y轴0-1200与次Y轴0-90的对应关系 geom_line(color='grey30', linewidth=0.5, aes(x = id, y = mean*(1200/90), group=1)) + geom_point(aes(x=id,y=mean*(1200/90))) + geom_text(aes(label = mean,y=mean*(1200/90)+30),size=3.5) + theme(legend.position = c(0.90,0.85)) + labs(x="Site ID",y="",fill="Num of pts") + scale_y_continuous( breaks = seq(0, 1200, 60), name="num of pts", # 强制主Y轴范围固定为0-1200 limits = c(0, 1200), # 转换函数确保主Y轴1200对应次Y轴90 sec.axis = sec_axis(~.*(90/1200), name="mean events",breaks = seq(0, 90, 10)) ) # 绘制第二张图(ID7-12) mydata2%>% ggplot(aes(x=factor(id), y=value, fill=factor(type,levels=c("dead","survived"))))+ geom_bar(position=position_stack(),stat="identity") + geom_text(data=subset(mydata2,value != 0), aes(label = value),position=position_stack(vjust=0.5),size=4) + geom_line(color='grey30', linewidth=0.5, aes(x = id, y = mean*(1200/90), group=1)) + geom_point(aes(x=id,y=mean*(1200/90))) + geom_text(aes(label = mean,y=mean*(1200/90)+30),size=3.5) + theme(legend.position = c(0.90,0.85)) + labs(x="Site ID",y="",fill="Num of pts") + scale_y_continuous( breaks = seq(0, 1200, 60), name="num of pts", limits = c(0, 1200), sec.axis = sec_axis(~.*(90/1200), name="mean events",breaks = seq(0, 90, 10)) )
关键修改点
- 在
scale_y_continuous中添加limits = c(0, 1200),强制主Y轴范围固定,避免ggplot根据子集数据自动缩小范围。 - 调整次Y轴转换函数为
~.*(90/1200),确保主Y轴最大值1200对应次Y轴的90,实现次Y轴范围0-90。 - 同步调整
mean的缩放比例为mean*(1200/90),保证mean数值能正确映射到主Y轴,同时在次Y轴显示对应数值。 - 微调
geom_text的Y偏移量,避免标签超出固定的Y轴范围。
内容的提问来源于stack exchange,提问作者Robin
相关产品推荐
相关产品推荐

