ggplot双Y轴图表线条图例添加问题求助
双Y轴ggplot图表图例问题解决建议
问题说明
使用ggplot绘制双Y轴图表时,次Y轴(Z/E ratio)对应的线条无法显示图例。
数据
> dput(figure4) structure(list(Days = c(1.3, 3, 4, 6, 7.7, 1, 4, 7.7, 1, 4, 6, 7.7), type = c("Indirect", "Indirect", "Indirect", "Indirect", "Indirect", "Direct_control", "Direct_control", "Direct_control", "Temp_control", "Temp_control", "Temp_control", "Temp_control" ), fraction = c(100, 75.9, 63.8, 39.2, 32.4, 100, 96.35, 98.1, 100, 107.05, 102.45, 96.26), ratio2 = c(2.87, 2.86, 2.94, 3.55, 3.8, 3.99, 3.638, 4.189, 1.088, 1.112, 1.07, 1.12), se2 = c(15, 11.38, 9.57, 5.88, 4.86, 15, 14.88, 14.7, 15, 16.0571, 15.368, 14.439)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -12L))
当前图表

当前代码
ylim.prim <- c(0, 120) # 百分比 ylim.sec <- c(0, 5) # 比值 b <- diff(ylim.prim)/diff(ylim.sec) a <- ylim.prim[1] - b*ylim.sec[1] ggplot(figure4, aes(x=Days, y=fraction, shape = type, colour = type)) + geom_point(size=4) + geom_errorbar(aes(ymax = fraction + se2, ymin = fraction - se2, group= type), width = 0.25)+ geom_line(aes(x=Days, y=a + ratio2*b,colour = type, linetype = Ratio), size= 1)+ scale_y_continuous("Fraction remainig(%)", sec.axis = sec_axis(~ (. - a)/b, name = "Z/E ratio"))+ theme(text = element_text(size = 15))+ theme(axis.text.x = element_text(angle = 0, vjust = 1, hjust= 1,size =12 ))+ theme(axis.text.y = element_text(size =12 ))+ theme(text = element_text(size = 15)) + theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.background = element_blank(), axis.line = element_line(colour = "black"))
解决建议
问题根源
代码中geom_line的linetype = Ratio是无效映射——你的数据里没有名为Ratio的列,ggplot无法识别这个变量,自然不会生成对应的图例。另外,要让次Y轴的线条图例和主Y轴的点图例协同显示,需要调整映射逻辑。
修正后的代码方案
这里提供两种常见的处理方式:
方式1:给线条指定固定线型,合并图例
如果希望线条和点共用type的图例,只需移除无效的linetype = Ratio,确保线条的colour映射到type,这样ggplot会自动合并点和线条的图例:
ylim.prim <- c(0, 120) # 百分比 ylim.sec <- c(0, 5) # 比值 b <- diff(ylim.prim)/diff(ylim.sec) a <- ylim.prim[1] - b*ylim.sec[1] ggplot(figure4, aes(x=Days, colour = type)) + # 主Y轴的点和误差棒 geom_point(aes(y=fraction, shape = type), size=4) + geom_errorbar(aes(y=fraction, ymax = fraction + se2, ymin = fraction - se2, group= type), width = 0.25)+ # 次Y轴的线条 geom_line(aes(y=a + ratio2*b), size= 1)+ scale_y_continuous("Fraction remaining(%)", sec.axis = sec_axis(~ (. - a)/b, name = "Z/E ratio"))+ # 统一主题设置(合并重复的theme) theme(text = element_text(size = 15), axis.text.x = element_text(angle = 0, vjust = 1, hjust= 1,size =12 ), axis.text.y = element_text(size =12 ), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.background = element_blank(), axis.line = element_line(colour = "black"))
方式2:单独为线条创建图例(区分点和线)
如果希望单独显示线条对应的图例(标注为Z/E ratio),可以手动设置linetype的固定值并添加对应的scale:
ylim.prim <- c(0, 120) # 百分比 ylim.sec <- c(0, 5) # 比值 b <- diff(ylim.prim)/diff(ylim.sec) a <- ylim.prim[1] - b*ylim.sec[1] ggplot(figure4, aes(x=Days)) + # 主Y轴的点和误差棒 geom_point(aes(y=fraction, shape = type, colour = type), size=4) + geom_errorbar(aes(y=fraction, ymax = fraction + se2, ymin = fraction - se2, group= type, colour = type), width = 0.25)+ # 次Y轴的线条,指定linetype为1(实线),并映射到固定字符串 geom_line(aes(y=a + ratio2*b, colour = type, linetype = "Z/E ratio"), size= 1)+ scale_y_continuous("Fraction remaining(%)", sec.axis = sec_axis(~ (. - a)/b, name = "Z/E ratio"))+ # 设置线型图例 scale_linetype_manual(values = 1, name = "")+ # 主题设置 theme(text = element_text(size = 15), axis.text.x = element_text(angle = 0, vjust = 1, hjust= 1,size =12 ), axis.text.y = element_text(size =12 ), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.background = element_blank(), axis.line = element_line(colour = "black"))
额外优化点
- 代码里的
Fraction remainig拼写错误,修正为Fraction remaining - 合并重复的
theme(text = element_text(size = 15))设置,让代码更简洁
内容的提问来源于stack exchange,提问作者Tetyana Gilevska
相关产品推荐
相关产品推荐

