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
相关产品推荐
相关产品推荐

