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

R绘图不同数据集图例项顺序不一致,如何自定义图例顺序?

控制ggplot图例顺序:固定参考线与站点项的位置

我是R和Stack Overflow新手,编写了R代码绘制按季节和站点分组的叶绿素数据箱线图,同时添加了水质标准(WQ Criteria)和报告限的参考线。代码功能正常,但切换不同数据集时,图例里的参考线项位置不稳定——有时在站点列表下方,有时在上方。试过用guide_legend和override.aes没解决问题,求固定图例顺序的方法。

原始代码

# Load libraries
library(readxl)
library(ggplot2)
library(dplyr)
library(tidyverse)
library(lubridate)
library(cowplot)
library(patchwork)
library(ggtext)
library(NADA)

Site <- c("Site 1","Site 8","Site 10","Site 3")
Season <- c("Win", "Spr", "Sum", "Fall")
Chla <- c(5, 10, 15, 20)

Sample_data <- data.frame(Site, Season, Chla)
newsam <- Sample_data
newsam$Site <- factor(newsam$Site, levels = c("Site 1", "Site 3", "Site 8", "Site 10"))
newsam %>% arrange(desc(Site))

#WQ line under site list
ggplot(Sample_data, aes(x=factor(Season), y=Chla, fill=factor(Site))) + 
  geom_hline(aes(yintercept = 10, linetype = "WQ Criteria"), color = "gray", 
             size =1) +
  geom_hline(aes(yintercept = 0.5, linetype = "Reporting Limit"), color = "red", size = 1) +
  geom_boxplot() +
  stat_summary(fun.y=mean, geom="point", shape=4, size=3, color="black",  
               position = position_dodge2(width = 0.75, preserve = "single")) +
  labs(x = "Season", y = "Chlorophyll α (mg/m&lt;sup&gt;3&lt;/sup&gt;)", linetype="", fill="") +
  theme_classic() +
  theme(
    axis.title.x = element_markdown(),
    axis.title.y = element_markdown() 
  ) +
  scale_x_discrete(limits = c("Win", "Spr", "Sum", "Fall")) +
  scale_fill_brewer(palette = "Paired") +
  ggtitle("Keystone Lake Chlorophyll, 2013-2022") +
  theme(plot.title = element_text(hjust = 0.5))

#WQ line over site list
ggplot(newsam, aes(x=factor(Season), y=Chla, fill=factor(Site))) + 
  geom_hline(aes(yintercept = 10, linetype = "WQ Criteria"), color = "gray", 
             size =1) +
  geom_hline(aes(yintercept = 0.5, linetype = "Reporting Limit"), color = "red", size = 1) +
  geom_boxplot() +
  stat_summary(fun.y=mean, geom="point", shape=4, size=3, color="black",  
               position = position_dodge2(width = 0.75, preserve = "single")) +
  labs(x = "Season", y = "Chlorophyll α (mg/m&lt;sup&gt;3&lt;/sup&gt;)", linetype="", fill="") +
  theme_classic() +
  theme(
    axis.title.x = element_markdown(),
    axis.title.y = element_markdown() 
  ) +
  scale_x_discrete(limits = c("Win", "Spr", "Sum", "Fall")) +
  scale_fill_brewer(palette = "Paired") +
  ggtitle("Keystone Lake Chlorophyll, 2013-2022") +
  theme(plot.title = element_text(hjust = 0.5))

问题原因

ggplot会自动合并fill(站点)和linetype(参考线)的图例,合并顺序受图层绘制顺序、数据的因子类型(字符/有序因子)影响,导致不同数据集下图例项位置波动。

解决方案:固定图例顺序

通过scale_linetype_manual指定参考线的顺序,再用guides()控制不同美学属性的图例显示优先级,就能彻底固定顺序。

修改后的代码(参考线在站点下方)

# 加载库
library(readxl)
library(ggplot2)
library(dplyr)
library(tidyverse)
library(lubridate)
library(cowplot)
library(patchwork)
library(ggtext)
library(NADA)

# 构造数据
Site <- c("Site 1","Site 8","Site 10","Site 3")
Season <- c("Win", "Spr", "Sum", "Fall")
Chla <- c(5, 10, 15, 20)

Sample_data <- data.frame(Site, Season, Chla)
newsam <- Sample_data
newsam$Site <- factor(newsam$Site, levels = c("Site 1", "Site 3", "Site 8", "Site 10"))

# 固定图例顺序的绘图代码
ggplot(newsam, aes(x=factor(Season), y=Chla, fill=factor(Site))) + 
  # 调整图层顺序,让箱线图在参考线之上
  geom_boxplot() +
  geom_hline(aes(yintercept = 10, linetype = "WQ Criteria"), color = "gray", size =1) +
  geom_hline(aes(yintercept = 0.5, linetype = "Reporting Limit"), color = "red", size = 1) +
  stat_summary(fun.y=mean, geom="point", shape=4, size=3, color="black",  
               position = position_dodge2(width = 0.75, preserve = "single")) +
  labs(x = "Season", y = "Chlorophyll α (mg/m<sup>3</sup>)", linetype="", fill="") +
  theme_classic() +
  theme(
    axis.title.x = element_markdown(),
    axis.title.y = element_markdown(),
    plot.title = element_text(hjust = 0.5)
  ) +
  scale_x_discrete(limits = c("Win", "Spr", "Sum", "Fall")) +
  scale_fill_brewer(palette = "Paired") +
  # 显式指定参考线的linetype和图例顺序
  scale_linetype_manual(
    values = c("WQ Criteria" = "solid", "Reporting Limit" = "solid"),
    breaks = c("WQ Criteria", "Reporting Limit") # 固定参考线的图例项顺序
  ) +
  # 控制图例整体顺序:站点(fill)在前,参考线(linetype)在后
  guides(
    fill = guide_legend(order = 1),
    linetype = guide_legend(order = 2)
  ) +
  ggtitle("Keystone Lake Chlorophyll, 2013-2022")

关键调整说明

  1. scale_linetype_manual:显式定义参考线的线型和图例项顺序,避免ggplot自动排序。
  2. guides():通过order参数设置不同美学属性的图例优先级——数值越小,图例越靠前。如果想让参考线在站点上方,把fill的order设为2,linetype的order设为1即可。
  3. 图层顺序调整:把geom_boxplot移到geom_hline前面,让箱线图在参考线之上显示,更符合可视化逻辑。

内容的提问来源于stack exchange,提问作者MrFury37

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 14:26:00