You need to enable JavaScript to run this app. 如何用ggplot绘制含两个x列、两个y列的分组箱线图
优惠活动
大模型
产品
解决方案
定价
更多

如何用ggplot绘制含两个x列、两个y列的分组箱线图

问题核心拆解

你现在没法用现成的gather代码出图的根本原因,是表结构和常规gather适配的场景不匹配:
常规gather方法适合的场景是「同一个X分组列下,并排多个Y变量」(比如单独一个Ocean.region列,对应MetaT、MetaG两个Y列);但你现在的原始表,是两套独立的X-Y观测序列横向拼接出来的:

  • 第一组观测:X变量是Ocean.regionT,对应Y值是MetaT
  • 第二组观测:X变量是Ocean.regionG,对应Y值是MetaG
    而且你提到Ocean.regionG/MetaG的有效长度短于另外两列,说明横向对齐的时候存在空值错位,直接硬拉平整表,不仅会打乱本来的配对关系,还会把长度不齐带来的空值错配带进后续绘图。
具体实现逻辑

核心思路是不要硬拉平整表,而是先把两套独立的X-Y配对序列拆出来,各自整理成统一格式的长表,再合并:

  • 分别把两组配对的列单独拆出,统一列名后新增分组标识,单独删掉每组内部的空值(这一步就自动解决了你提到的两列长度不齐的问题,因为短列对应的空值会在本组内过滤,不会把另一组长列的有效观测删掉)
  • 把两个整理好的长表按统一列名上下拼接,得到适合ggplot绘图的tidy格式
  • 直接按常规分组箱线图的语法绘图
library(tidyverse)
# 拆分第一组配对序列:Ocean.regionT + MetaT
df_T <- BB %>% 
  select(Ocean_region = Ocean.regionT, KO_Values = MetaT) %>% 
  mutate(Data_Type = "MetaT") %>% 
  drop_na() # 仅过滤本组内的空值,不影响另一组的有效数据

# 拆分第二组配对序列:Ocean.regionG + MetaG
df_G <- BB %>% 
  select(Ocean_region = Ocean.regionG, KO_Values = MetaG) %>% 
  mutate(Data_Type = "MetaG") %>% 
  drop_na() # 自动过滤长度不齐带来的空值行

# 上下合并为统一的长表,转换分类变量为因子
BB_tidy <- bind_rows(df_T, df_G) %>% 
  mutate(
    Ocean_region = as.factor(Ocean_region),
    Data_Type = as.factor(Data_Type)
  )

# 绘制分组箱线图
ggplot(BB_tidy, aes(x = Ocean_region, y = KO_Values, fill = Data_Type)) +
  geom_boxplot(outlier.size = 0.5) +
  scale_fill_brewer(palette = "Set1") +
  scale_y_log10() +
  theme_bw()
容易踩的坑
  • 不要直接对四列全表做gather拉平:比如直接把Ocean.regionT/Ocean.regionG作为key列、MetaT/MetaG作为value列拉成两列,会完全打乱“T的X配T的Y、G的X配G的Y”的对应关系,画出来的箱线图分组和数值是错配的
  • 空值过滤要放在每组拆分后单独做,不要在原表上一次性过滤:如果某一行里Ocean.regionG是空,但Ocean.regionT是有有效观测的,在原表上整行删空值,会把本来有效的MetaT观测直接丢掉
  • 示例数据里存在同个区域命名不一致的情况(比如Ocean.regionT的Madagascar对应Ocean.regionG的MS),绘图前可以统一一下命名规则,避免x轴上出现只有单个数据组的空分组

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.29 12:45:02