You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 08:30:00