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

在ggplot2中使用facet_wrap实现两类独立图例的技术问询

在ggplot2的facet_wrap中拆分图例并对应变量组

要实现将图例拆分为"Yes/No"和"Sometimes/Never"两组并分别靠近对应分面,有两种实用方案,具体如下:

方案1:使用ggnewscale添加多尺度图例

这种方法能在同一个facet_wrap布局中保留整体结构,同时生成两个独立图例:

步骤1:数据预处理

先把原响应变量拆分为两个子变量,分别对应两组类别:

library(tidyverse)
library(ggnewscale)

# 构造示例数据(替换为你的真实数据)
set.seed(123)
df <- tibble(
  group = rep(c("YN_Group", "SN_Group"), each = 200), # 对应两组分面
  response = sample(c("Yes", "No", "Sometimes", "Never"), 400, replace = TRUE),
  value = rnorm(400)
)

# 拆分响应变量:分别保留对应类别,其余设为NA
df <- df %>%
  mutate(
    yn_response = ifelse(response %in% c("Yes", "No"), response, NA),
    sn_response = ifelse(response %in% c("Sometimes", "Never"), response, NA)
  )

步骤2:绘图并添加双尺度图例

ggplot(df, aes(x = value)) +
  # 第一个图层:对应Yes/No类别
  geom_density(aes(fill = yn_response), alpha = 0.6) +
  scale_fill_manual(values = c("Yes" = "#1f77b4", "No" = "#ff7f0e"), name = "Yes/No") +
  # 开启新的填充尺度,用于第二个图例
  new_scale_fill() +
  # 第二个图层:对应Sometimes/Never类别
  geom_density(aes(fill = sn_response), alpha = 0.6) +
  scale_fill_manual(values = c("Sometimes" = "#2ca02c", "Never" = "#d62728"), name = "Sometimes/Never") +
  # 分面设置
  facet_wrap(~group) +
  # 调整图例位置,让两组图例水平排列在底部
  theme(
    legend.position = "bottom",
    legend.box = "horizontal",
    legend.spacing.x = unit(1, "cm")
  ) +
  # 指定图例顺序
  guides(
    fill = guide_legend(order = 1),
    fill.1 = guide_legend(order = 2)
  )

方案2:使用patchwork拆分分面并独立设置图例

如果需要让图例完全贴合对应分面,可将两个分面单独绘图后拼接:

library(patchwork)

# 绘制第一组分面(仅显示Yes/No)
p_yn <- ggplot(filter(df, group == "YN_Group"), aes(x = value, fill = response)) +
  geom_density(alpha = 0.6) +
  scale_fill_manual(values = c("Yes" = "#1f77b4", "No" = "#ff7f0e"), name = "Yes/No") +
  facet_wrap(~group) +
  theme(legend.position = "bottom")

# 绘制第二组分面(仅显示Sometimes/Never)
p_sn <- ggplot(filter(df, group == "SN_Group"), aes(x = value, fill = response)) +
  geom_density(alpha = 0.6) +
  scale_fill_manual(values = c("Sometimes" = "#2ca02c", "Never" = "#d62728"), name = "Sometimes/Never") +
  facet_wrap(~group) +
  theme(legend.position = "bottom")

# 水平拼接两个图
p_yn + p_sn + plot_layout(nrow = 1)

关键说明

  • 方案1适合需要保持单一facet_wrap整体布局的场景,图例可通过theme调整位置;
  • 方案2更灵活,每个分面的图例完全独立,精准对应各自的变量组;
  • 替换示例中的数据、颜色、图层类型(如柱状图替换密度图)即可适配你的真实可视化需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 02:30:59