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

ggplot2中geom_col如何用Total_In_Class变量设置柱宽?

问题描述

我是首次发帖,若有问题欢迎提出建设性意见。我使用ggmosaic包的titanic数据绘制了柱状图,希望让柱宽匹配Total_In_Class变量,但尝试geom_col的width参数及在aes中设置width=Total_In_Class均无效,请问是否有实现方法或需更换可视化方式?

原代码如下:

library(tidyverse)
library(ggmosaic)

titanic %>%
  group_by(Class, Sex, Age, Survived) %>%
  tally() %>%
  spread(key = Survived, value = n, fill = 0) %>%
  mutate(Classification = paste("Class: ", Class, " Sex: ", Sex, " Age: ", Age)) %>%
  mutate(Total_In_Class = Yes + No) %>%
  mutate(Percent_Survived = Yes / Total_In_Class) %>%
  ggplot() +
  geom_col(aes(x = Classification, y = Percent_Survived)) + 
  geom_text(aes(x = Classification, y = Percent_Survived, label = Total_In_Class), vjust = -.3) +
  theme(axis.text.x = element_text(angle = -90, vjust = -.05))

附原图:
柱状图

解决方案

geom_col不支持直接按变量设置柱宽,因为它的x轴是离散分类,每个分类的位置固定,width参数无法实现按变量调整宽度。你可以用两种方式解决:

方式一:用geom_rect手动绘制可控宽度的柱子

通过计算每个分类的x轴起始、结束位置和宽度比例,手动绘制柱子:

library(tidyverse)
library(ggmosaic)

titanic_processed <- titanic %>%
  group_by(Class, Sex, Age, Survived) %>%
  tally() %>%
  spread(key = Survived, value = n, fill = 0) %>%
  mutate(Classification = paste("Class: ", Class, " Sex: ", Sex, " Age: ", Age)) %>%
  mutate(Total_In_Class = Yes + No) %>%
  mutate(Percent_Survived = Yes / Total_In_Class) %>%
  # 计算宽度占比和x轴位置
  mutate(width_prop = Total_In_Class / sum(Total_In_Class)) %>%
  arrange(Classification) %>%
  mutate(x_start = cumsum(width_prop) - width_prop,
         x_end = cumsum(width_prop),
         x_mid = (x_start + x_end)/2)

ggplot(titanic_processed) +
  geom_rect(aes(xmin = x_start, xmax = x_end, ymin = 0, ymax = Percent_Survived, fill = Classification)) +
  geom_text(aes(x = x_mid, y = Percent_Survived, label = Total_In_Class), vjust = -.3) +
  scale_x_continuous(breaks = titanic_processed$x_mid, labels = titanic_processed$Classification) +
  theme(axis.text.x = element_text(angle = -90, vjust = -.05)) +
  labs(x = "Classification")

方式二:直接使用ggmosaic的马赛克图

马赛克图天生会按组内样本量比例展示宽度,完美匹配你的需求,无需手动计算:

library(tidyverse)
library(ggmosaic)

ggplot(titanic) +
  geom_mosaic(aes(x = product(Class, Sex, Age), fill = Survived, weight = n)) +
  labs(x = "Classification", fill = "Survived")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 05:32:20