在 ggplot2 中调整分组柱状图的列间距以消除空白区域

人工智能 2026-07-07

问题

我想为我的数据集显示一个分组柱状图,其中某些组有子组关联。下面是一个示例数据集:

main_group <- c("Fruit", "Fruit", "Fruit", "Fruit", "Vegetables", "Dairy")
sub_group <- c("Total", "Apple", "Mango", "Kiwi", NA, NA)
profit <- c(14, 7, 5, 2, 10, 5)
df <- data.frame(main_group, sub_group, profit)

在绘制数据时,我可以使用 position_dodge2(preserve = "total") 来“保留在一个位置处所有元素的总宽度”(也就是说,每个主组在图上占用相同的空间,无论它们有多少子组),或者我可以使用 position_dodge2(preserve = "single") 来保持单个元素的宽度(也就是说,所有列宽相等,但子组较少/没有的分组会用空白填充)。

ggplot(df, aes(x = main_group, y = profit, fill = factor(sub_group))) + geom_col(position = position_dodge2(preserve = "total")) + theme_classic()
ggplot(df, aes(x = main_group, y = profit, fill = factor(sub_group))) +
 geom_col(position = position_dodge2(preserve = "single")) +
 theme_classic()

preserve="single" 选项更接近我想要的效果,但我想知道是否有其他函数/包等,能够让我减少主组之间的空白空间?换句话说,如果某个主组没有相关的分组变量,那么它在图上占用的空间就会更小。

这正是我设想的样子:

示例柱状图,显示期望输出。

答案 1

我认为最简单的做法是使用分面:

df |>
  mutate(across(main_group:sub_group, 
                ~coalesce(.x, "") |> factor() |> fct_inorder())) |>
ggplot( aes(sub_group, profit)) +
  geom_col(position = position_dodge(preserve = "single")) +
  scale_y_continuous(expand = expansion(mult = c(0, 0.05))) +
  facet_grid(~main_group, scales = "free_x", space = "free_x", 
             switch = "x") +
  theme_classic() +
  theme(strip.placement = "outside",
        strip.background = element_blank(),
        panel.spacing.x = unit(0, "pt"))

在此处输入图片描述

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章