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

在ggplot2中根据类别占比调整堆叠条形图宽度

实现按类别频率调整堆叠条形图宽度的方法

要在ggplot中创建宽度随cut类别频率变化的堆叠条形图,直接用geom_bar的width参数没法实现动态调整(它只能设置统一宽度),我们需要通过预处理数据计算每个条形的位置和范围,再用geom_rect来绘制自定义宽度的堆叠块。下面是完整的实现步骤:

步骤1:预处理数据

首先我们需要计算:

  • 每个cut类别的占比(你已经完成了这一步)
  • 每个cut在x轴的起始/结束位置(用来控制条形宽度)
  • 每个cut内堆叠分组(比如color)的起始/结束高度(实现堆叠效果)
library(tidyverse)

# 计算cut的全局占比,同时生成x轴位置信息
cut_prop <- diamonds %>% 
  group_by(cut) %>% 
  summarise(cut_prop = n()/nrow(diamonds)) %>% 
  ungroup() %>% 
  # 计算每个cut的x轴起始和结束位置(从0开始累积)
  mutate(x_start = cumsum(lag(cut_prop, default = 0)),
         x_end = x_start + cut_prop)

# 合并位置信息到原数据,再计算每个cut内color的堆叠高度(以计数为例)
diamonds_stack <- diamonds %>% 
  left_join(cut_prop) %>% 
  group_by(cut, color) %>% 
  summarise(count = n(),
            x_start = first(x_start),
            x_end = first(x_end)) %>% 
  ungroup() %>% 
  # 按color排序,计算每个堆叠块的上下边界
  group_by(cut) %>% 
  arrange(color) %>% 
  mutate(y_start = cumsum(lag(count, default = 0)),
         y_end = y_start + count) %>% 
  ungroup()

步骤2:绘制自定义宽度的堆叠条形图

用geom_rect来绘制每个堆叠的矩形块,同时添加x轴标签让图表更易读:

ggplot(diamonds_stack) +
  # 绘制堆叠的矩形,fill映射到color
  geom_rect(aes(xmin = x_start, xmax = x_end,
                ymin = y_start, ymax = y_end,
                fill = color)) +
  # 在每个条形下方添加cut标签
  geom_text(data = cut_prop,
            aes(x = x_start + cut_prop/2, y = 0, label = cut),
            vjust = 1.5, size = 4) +
  # 调整x轴刻度,对齐条形中心
  scale_x_continuous(breaks = cut_prop$x_start + cut_prop$cut_prop/2,
                     labels = cut_prop$cut) +
  # 添加标题和标签
  labs(x = "Cut (Width proportional to total frequency)",
       y = "Number of Diamonds",
       fill = "Diamond Color") +
  theme_minimal()

可选:用比例替代计数作为y轴

如果希望y轴显示全局占比而非计数,只需要修改数据预处理部分的计算逻辑:

# 计算每个cut-color组合的全局占比
diamonds_stack_prop <- diamonds %>% 
  left_join(cut_prop) %>% 
  group_by(cut, color) %>% 
  summarise(prop = n()/nrow(diamonds),
            x_start = first(x_start),
            x_end = first(x_end)) %>% 
  ungroup() %>% 
  group_by(cut) %>% 
  arrange(color) %>% 
  mutate(y_start = cumsum(lag(prop, default = 0)),
         y_end = y_start + prop) %>% 
  ungroup()

# 绘制比例版本的图表
ggplot(diamonds_stack_prop) +
  geom_rect(aes(xmin = x_start, xmax = x_end,
                ymin = y_start, ymax = y_end,
                fill = color)) +
  geom_text(data = cut_prop,
            aes(x = x_start + cut_prop/2, y = 0, label = cut),
            vjust = 1.5, size = 4) +
  scale_x_continuous(breaks = cut_prop$x_start + cut_prop$cut_prop/2,
                     labels = cut_prop$cut) +
  labs(x = "Cut (Width proportional to total frequency)",
       y = "Proportion of Total Diamonds",
       fill = "Diamond Color") +
  theme_minimal()

原理说明

  • 我们通过x_start和x_end控制每个cut条形的宽度(等于该类别的全局占比cut_prop)
  • 通过y_start和y_end控制每个堆叠块的高度,实现类似geom_bar(stat="identity")的堆叠效果
  • geom_rect相比geom_bar更灵活,能完全自定义每个图形元素的位置和大小

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:12:07