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

ggplot2轴自定义(间距/分段):分组分隔与栏宽调整实现

问题描述

现有一个ggplot生成的横向条形图,需要将变量划分为两个子集:

  • 「6个月组」:包含变量x1、x2
  • 「基线组」:对应变量baseline

需要实现两个定制需求:

  1. 在两个子集之间添加分隔间距
  2. 让两个子集的条形宽度不同

当前使用的代码及生成的图形如下:

library(ggplot2)
library(ggnewscale)

x1 = rep(1:3, times = 2)
x2 = rep(c("Y", "N"), each = 3)
baseline = rep(0:1, times = 3)
y <- data.frame(x1,x2,baseline)

Dat <- y |>
  mutate(across(everything(), as.character)) |>
  pivot_longer(everything(), names_to = "var")

ggplot(Dat, aes(y = var)) +
  coord_flip() +
  geom_bar(data = ~subset(.x, var %in% c("x1")), aes(fill = value), position = "fill") +
  scale_fill_viridis_d(option = "B", guide = guide_legend(order = 3))+
  new_scale_fill() +
  geom_bar(data = ~subset(.x, var %in% c("x2")), aes(fill = value), position = "fill") +
  scale_fill_brewer(palette = "Dark2", guide = guide_legend(order = 2)) +
  new_scale_fill() +
  geom_bar(data = ~subset(.x, var %in% c("baseline")), aes(fill = value), position = "fill") +
  scale_fill_brewer(palette = "Paired", guide = guide_legend(order = 1))

原图形

实现思路与代码

核心思路

  1. 子集分隔与间距:给变量添加分组标签,将y轴映射为指定顺序的因子,通过position_nudge调整不同子集条形的位置,配合scale_y_discrete的expand参数强化子集间的分隔间距。
  2. 不同条形宽度:针对两个子集分别调用geom_bar,设置不同的width参数,实现宽度差异。

所需包

仅需原代码中的ggplot2和ggnewscale,无需额外安装新包。

完整实现代码

library(ggplot2)
library(ggnewscale)
library(dplyr) # 用于数据处理

# 构造数据
x1 = rep(1:3, times = 2)
x2 = rep(c("Y", "N"), each = 3)
baseline = rep(0:1, times = 3)
y <- data.frame(x1,x2,baseline)

# 整理数据并添加分组标签
Dat <- y |>
  mutate(across(everything(), as.character)) |>
  pivot_longer(everything(), names_to = "var") |>
  # 标记每个变量所属的子集
  mutate(group = case_when(
    var %in% c("x1", "x2") ~ "6-months",
    var == "baseline" ~ "baseline"
  )) |>
  # 指定变量顺序:先6个月组,再基线组,确保子集排列正确
  mutate(var = factor(var, levels = c("x1", "x2", "baseline")))

ggplot(Dat, aes(y = var)) +
  coord_flip() +
  # 绘制6个月组条形:宽度0.8,位置左移实现间距
  geom_bar(data = ~subset(.x, group == "6-months"), 
           aes(fill = value), position = "fill", width = 0.8,
           position = position_nudge(y = -0.1)) +
  scale_fill_viridis_d(option = "B", guide = guide_legend(order = 3))+
  new_scale_fill() +
  # 绘制基线组条形:宽度0.6,位置右移实现间距
  geom_bar(data = ~subset(.x, group == "baseline"), 
           aes(fill = value), position = "fill", width = 0.6,
           position = position_nudge(y = 0.2)) +
  scale_fill_brewer(palette = "Paired", guide = guide_legend(order = 1)) +
  # 调整y轴刻度的扩展间距,进一步拉开子集距离
  scale_y_discrete(expand = expansion(add = c(0.5, 0.5))) +
  labs(y = "")

效果说明

  • 两个子集通过位置偏移和轴刻度扩展实现了清晰的分隔间距
  • 6个月组条形宽度为0.8,基线组为0.6,满足宽度差异化需求
  • 保留了原有的多组独立填充色设置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 18:05:17