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

如何在ggplot2分组绘图中添加全体数据的统计图形?

解决方案

这里提供两种无需手动修改x轴参数的自动化实现方案,可快速生成分组分布图+全体分布图的组合可视化,匹配你提到的questionr中Ensemble列的效果:

方法1:数据整合+Facet垂直布局

通过将全体数据作为额外分组并入原数据,利用facet_grid实现垂直排列,全体图自动置于下方:

library(ggplot2)
library(dplyr)

# 示例数据(替换为你的数据框d即可)
set.seed(123)
d <- tibble(
  sex = sample(c("男", "女"), 200, replace = TRUE),
  score = rnorm(200, mean = ifelse(sex == "男", 70, 75), sd = 8)
)

# 整合数据:新增"全体"分组
d_combined <- bind_rows(
  d,
  d %>% mutate(sex = "全体")
)

# 指定分组顺序,确保"全体"位于最后
d_combined$sex <- factor(d_combined$sex, levels = c("男", "女", "全体"))

# 绘制组合图
ggplot(d_combined, aes(x = sex, y = score)) +
  geom_violin(fill = "lightblue", alpha = 0.7) +
  geom_boxplot(width = 0.2, fill = "white") +
  facet_grid(sex ~ ., scales = "free_y") + # 垂直排列分组,y轴自适应范围
  theme_minimal() +
  theme(strip.text.y = element_blank()) # 移除侧边重复标签

方法2:Patchwork拼图(布局更灵活)

使用patchwork包分别绘制分组图和全体图,再按上下布局拼接,可独立调整两个图的样式、高度比例:

library(ggplot2)
library(patchwork)

# 绘制分组分布图
p_group <- ggplot(d, aes(x = sex, y = score)) +
  geom_violin(fill = "lightblue", alpha = 0.7) +
  geom_boxplot(width = 0.2, fill = "white") +
  theme_minimal() +
  labs(title = "按性别分组的分数分布")

# 绘制全体数据分布图
p_total <- ggplot(d, aes(x = "全体", y = score)) +
  geom_violin(fill = "lightblue", alpha = 0.7) +
  geom_boxplot(width = 0.2, fill = "white") +
  theme_minimal() +
  labs(title = "全体数据的分数分布", x = "")

# 上下拼接图形,自定义高度比例(分组图占2份,全体图占1份)
p_group / p_total + plot_layout(heights = c(2, 1))

自动化封装函数

如果需要重复使用,可封装成通用函数,只需传入数据框、分组列和数值列即可自动生成图形:

plot_dist_with_total <- function(data, group_col, value_col, group_levels = NULL) {
  library(ggplot2)
  library(dplyr)
  library(patchwork)
  
  # 可选:指定分组显示顺序
  if (!is.null(group_levels)) {
    data[[group_col]] <- factor(data[[group_col]], levels = group_levels)
  }
  
  p_group <- ggplot(data, aes(x = .data[[group_col]], y = .data[[value_col]])) +
    geom_violin(fill = "lightblue", alpha = 0.7) +
    geom_boxplot(width = 0.2, fill = "white") +
    theme_minimal() +
    labs(title = paste("按", group_col, "分组的", value_col, "分布"))
  
  p_total <- ggplot(data, aes(x = "全体", y = .data[[value_col]])) +
    geom_violin(fill = "lightblue", alpha = 0.7) +
    geom_boxplot(width = 0.2, fill = "white") +
    theme_minimal() +
    labs(title = paste("全体数据的", value_col, "分布"), x = "")
  
  return(p_group / p_total + plot_layout(heights = c(2, 1)))
}

# 调用示例
plot_dist_with_total(d, "sex", "score", group_levels = c("男", "女"))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 22:15:27