在R语言ggplot2中如何分别调整多个图例的位置?
单独设置ggplot2中不同图例的位置
要实现分别控制fill和shape两个图例的位置,你需要先将每个图例单独提取出来,再通过自定义注释的方式添加到图中指定位置,具体步骤如下:
1. 准备环境与数据
先加载所需包并创建数据集:
library(ggplot2) library(cowplot) # 用于提取单独图例 library(grid) # 用于相对坐标设置 # 创建数据集 Nitrogen= c(0, 50, 100, 0, 50, 100) Season= c("2020yr", "2021yr", "2022yr", "2020yr", "2021yr", "2022yr") Yield= c(20, 30, 55, 24, 29, 22) df=data.frame(Nitrogen, Season, Yield)
2. 绘制基础图形(隐藏默认合并图例)
先绘制原始散点图,并隐藏默认的合并图例:
p <- ggplot(df, aes(x=Nitrogen, y=Yield, fill=as.factor(Nitrogen), shape=Season)) + geom_point(size=5) + scale_shape_manual(values=c(22, 22, 23), guide=guide_legend(override.aes=list(colour=1))) + scale_fill_manual(values=c("darkred", "darkblue", "darkgreen"), guide=guide_legend(override.aes= list(shape=21))) + scale_x_continuous(breaks=seq(0,120,40),limits=c(0,120)) + scale_y_continuous(breaks=seq(0,120,40),limits=c(0,120)) + theme_classic(base_size=18, base_family="serif") + theme( legend.position = "none", # 隐藏默认合并图例 axis.line = element_line(linewidth = 0.5, colour="black") )
3. 单独提取每个图例
分别生成fill和shape对应的图例对象,并设置图例样式:
# 提取fill图例(对应氮水平) fill_legend <- get_legend( ggplot(df, aes(fill=as.factor(Nitrogen))) + geom_point(size=5, shape=21) + scale_fill_manual(values=c("darkred", "darkblue", "darkgreen")) + theme( legend.title=element_blank(), legend.key=element_rect(color="white", fill="white"), legend.text=element_text(family="serif", face="plain", size=12, color="black"), legend.background= element_rect(fill="white") ) ) # 提取shape图例(对应年份) shape_legend <- get_legend( ggplot(df, aes(shape=Season)) + geom_point(size=5, colour=1) + scale_shape_manual(values=c(22, 22, 23)) + theme( legend.title=element_blank(), legend.key=element_rect(color="white", fill="white"), legend.text=element_text(family="serif", face="plain", size=12, color="black"), legend.background= element_rect(fill="white") ) )
4. 将图例添加到指定位置
使用annotation_custom()将两个图例分别放到图中任意位置,支持两种坐标方式:
方式一:使用坐标轴数值定位
直接对应x/y轴的数值范围来设置位置:
p + # fill图例放在左上角(x:0-30,y:80-120) annotation_custom(grob = fill_legend, xmin = 0, xmax = 30, ymin = 80, ymax = 120) + # shape图例放在右下角(x:80-120,y:20-60) annotation_custom(grob = shape_legend, xmin = 80, xmax = 120, ymin = 20, ymax = 60)
方式二:使用相对坐标定位
用unit()设置相对整个绘图区域的位置(0-1,0为左/下,1为右/上),和你之前用legend.position的逻辑一致:
p + # fill图例放在左上方(相对x:0.1-0.3,y:0.7-0.9) annotation_custom(grob = fill_legend, xmin = unit(0.1, "npc"), xmax = unit(0.3, "npc"), ymin = unit(0.7, "npc"), ymax = unit(0.9, "npc")) + # shape图例放在右下方(相对x:0.7-0.9,y:0.1-0.3) annotation_custom(grob = shape_legend, xmin = unit(0.7, "npc"), xmax = unit(0.9, "npc"), ymin = unit(0.1, "npc"), ymax = unit(0.3, "npc"))
原理说明
ggplot2默认会将所有图例合并到同一个容器中,因此theme(legend.position)只能整体移动这个容器。通过单独提取图例并添加为自定义注释,就能完全独立控制每个图例的位置。
内容的提问来源于stack exchange,提问作者J.K Kim
相关产品推荐
相关产品推荐

