You need to enable JavaScript to run this app. ggplot2中如何单独拉大最后一组柱形与其他组的间距
优惠活动
大模型
产品
解决方案
定价
更多

ggplot2中如何单独拉大最后一组柱形与其他组的间距

解决方案

方法1:插入隐藏空白因子水平(最简便)

通过在第四组和第五组的因子水平之间插入一个不显示的空水平,即可快速拉大两组间距,无需修改其余绘图逻辑。

library(data.table)
library(ggplot2)
library(dplyr)
library(tidyverse)
library(ggsignif)

graph <- structure(list(Constraint = structure(c(4L, 2L, 3L, 1L, 5L, 4L, 
2L, 3L, 1L, 5L), .Label = c("Major Constraint", "Minor Constraint", 
"Moderate Constraint", "No Constraint", "Total"), class = "factor"), 
    `Observation for Crime = 0` = c(3124, 2484, 3511, 4646, 13765, 
    3124, 2484, 3511, 4646, 13765), `Observation for Crime = 1` = c(762, 
    629, 1118, 1677, 4186, 762, 629, 1118, 1677, 4186), `Total Observations` = c(3886, 
    3113, 4629, 6323, 17951, 3886, 3113, 4629, 6323, 17951), 
    variable = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
    2L), .Label = c("Crime = 0", "Crime = 1"), class = "factor"), 
    value = c(80.3911477097272, 79.79441053646, 75.847915316483, 
    73.4777795350308, 76.6809648487549, 19.6088522902728, 20.20558946354, 
    24.152084683517, 26.5222204649692, 23.3190351512451)), row.names = c(NA, 
-10L), class = "data.frame")
setnames(graph, "variable", "Crime Incidence (Yes=1)")


graph %>% 
  # 调整因子水平,在第四组和第五组之间插入空水平
  mutate(`Constraint` = fct_relevel(`Constraint`, "No Constraint", "Minor Constraint", "Moderate Constraint", "Major Constraint") %>%
           fct_expand(" ") %>% # 新增空白水平
           fct_relevel(" ", .after = "Major Constraint")) %>% # 将空白水平放在第四组之后
  ggplot(aes(x = `Constraint`, y = value)) + 
  geom_col(position = position_dodge(width=0.9), aes(fill = `Crime Incidence (Yes=1)`)) + 
  geom_text(position = position_dodge(width = .9),
            aes(label=sprintf("%.02f %%", round(value, digits = 1)), group = `Crime Incidence (Yes=1)`),
            vjust = -2.5,
            size = 4) +        
  geom_text(position = position_dodge(width = .9),
            aes(label= paste0("(", ifelse(`Crime Incidence (Yes=1)` == "Crime = 0", `Observation for Crime = 0`, `Observation for Crime = 1`), ")"), group = `Crime Incidence (Yes=1)`),
            vjust = -0.6,
            size = 4) +     
  scale_fill_grey(start = 0.8, end = 0.5) +
  ylab("% within constraint level (Observations in parentheses)") + 
  xlab("Perception of Taxes as a Constraint") + 
  # 隐藏空白水平的刻度,保留空白位置
  scale_x_discrete(breaks = c("No Constraint", "Minor Constraint", "Moderate Constraint", "Major Constraint", "Total"), drop = FALSE) +
  scale_y_continuous(expand = expansion(mult = c(0, .1))) +
  theme_bw(base_size = 15)

如果觉得间距过大或过小,可以调整空白水平的数量,或者配合scale_x_discrete(expand = c(0,0))调整整体边距。

方法2:手动指定X轴坐标

如果需要更精准控制间距,可以将X轴映射为数值,手动设置第五组的位置:

graph %>% 
  mutate(
    `Constraint` = fct_relevel(`Constraint`, "No Constraint", "Minor Constraint", "Moderate Constraint", "Major Constraint", "Total"),
    # 手动给每组分配X坐标,前四组间距为1,第五组比第四组大1.5(按需调整数值即可改间距)
    x_pos = case_when(
      Constraint == "No Constraint" ~ 1,
      Constraint == "Minor Constraint" ~ 2,
      Constraint == "Moderate Constraint" ~3,
      Constraint == "Major Constraint" ~4,
      Constraint == "Total" ~5.5 # 这里的5.5就是拉大的间距,改成5就是原间距,越大间距越大
    )
  ) %>%
  ggplot(aes(x = x_pos, y = value)) + 
  geom_col(position = position_dodge(width=0.9), aes(fill = `Crime Incidence (Yes=1)`)) + 
  geom_text(position = position_dodge(width = .9),
            aes(label=sprintf("%.02f %%", round(value, digits = 1)), group = `Crime Incidence (Yes=1)`),
            vjust = -2.5,
            size = 4) +        
  geom_text(position = position_dodge(width = .9),
            aes(label= paste0("(", ifelse(`Crime Incidence (Yes=1)` == "Crime = 0", `Observation for Crime = 0`, `Observation for Crime = 1`), ")"), group = `Crime Incidence (Yes=1)`),
            vjust = -0.6,
            size = 4) +     
  scale_fill_grey(start = 0.8, end = 0.5) +
  ylab("% within constraint level (Observations in parentheses)") + 
  xlab("Perception of Taxes as a Constraint") + 
  # 自定义X轴刻度标签
  scale_x_continuous(breaks = c(1,2,3,4,5.5), labels = levels(graph$Constraint)) +
  scale_y_continuous(expand = expansion(mult = c(0, .1))) +
  theme_bw(base_size = 15)

调整x_pos中Total对应的数值即可精准控制和前一组的间距大小。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 14:21:00