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

如何用ggplot2复现R基础绘图的BMI多边形分布图?

问题原因与解决方案:用ggplot2绘制BMI体重等级多边形分布图

问题根源

  • geom_area的堆叠特性:geom_area()本质是为堆叠面积图设计的,默认会将不同分组的Y值累加,导致最终Y轴显示的是各等级数值的总和,而非单个等级的原始数值,这是Y轴数值不符的核心原因。
  • geom_polygon的点集要求:geom_polygon()需要输入按顺序排列的闭合多边形点集——也就是要包含多边形的所有边界点(包括底部Y=0的点),且点的顺序要能形成闭合图形。如果你的长格式数据只包含每个等级的峰值点,缺少边界点或点顺序错误,就会出现图形扭曲。

正确实现方法

步骤1:构造闭合的多边形点集

首先需要为每个BMI等级生成完整的多边形点,每个等级的点集应包含:左边界(0) → 右边界(0) → 右边界(峰值) → 左边界(峰值) → 左边界(0),确保图形闭合。

示例代码:

library(ggplot2)
library(dplyr)

# 定义BMI等级的区间和对应数值(替换为你的真实数据)
grade_details <- tibble(
  grade = c("偏瘦", "正常", "超重", "肥胖"),
  x_start = c(10, 18.5, 24, 28),  # 每个等级的左边界
  x_end = c(18.5, 24, 28, 35),    # 每个等级的右边界
  y_value = c(50, 120, 80, 30)    # 每个等级的峰值数值
)

# 生成每个等级的闭合多边形点集
polygon_data <- grade_details %>%
  group_by(grade) %>%
  group_map(function(.x, .y) {
    tibble(
      x = c(.x$x_start, .x$x_end, .x$x_end, .x$x_start, .x$x_start),
      y = c(0, 0, .x$y_value, .x$y_value, 0),
      grade = .x$grade
    )
  }) %>%
  bind_rows()

步骤2:用geom_polygon绘图

使用生成的闭合点集绘图,即可得到和基础绘图一致的结果:

ggplot(polygon_data, aes(x = x, y = y, fill = grade)) +
  geom_polygon(color = "black", linewidth = 0.5) +  # 添加边框区分等级
  labs(x = "BMI指数", y = "人数/比例") +
  scale_fill_manual(values = c("#8dd3c7", "#ffffb3", "#bebada", "#fb8072")) +  # 自定义颜色
  theme_minimal()

补充:基于反转数据的解决方案

如果你的原始长格式数据已经包含各等级的关键节点,可以通过添加反转的底部边界点来构造闭合图形:

# 假设你已有长格式数据(仅包含各等级的峰值点)
original_long_data <- tibble(
  grade = rep(c("偏瘦", "正常", "超重", "肥胖"), each = 2),
  x = c(18.5, 18.5, 24, 24, 28, 28, 35, 35),
  y = c(0, 50, 0, 120, 0, 80, 0, 30)
)

# 为每个等级添加左边界点,并生成反转的底部点
final_data <- original_long_data %>%
  group_by(grade) %>%
  group_map(function(.x, .y) {
    # 确定当前等级的左右边界
    x_left <- if (.y$grade == "偏瘦") 10 else .x$x[1]
    x_right <- .x$x[2]
    y_top <- .x$y[2]
    
    # 构造完整点集
    tibble(
      x = c(x_left, x_right, x_right, x_left, x_left),
      y = c(0, 0, y_top, y_top, 0),
      grade = .y$grade
    )
  }) %>%
  bind_rows()

# 绘图
ggplot(final_data, aes(x = x, y = y, fill = grade)) +
  geom_polygon(color = "black") +
  labs(x = "BMI指数", y = "人数/比例")

关键注意事项

  • 不要用geom_area()直接绘制此类图形,除非你明确需要堆叠效果;如果一定要用,需设置position = "identity",但仍需确保点集正确。
  • 多边形点的顺序非常重要,必须按顺时针或逆时针方向排列,否则ggplot2会绘制出交叉的异常图形。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 21:16:10