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

如何用ggplot实现样本量可变的多行分面条形图并保持条形宽度一致?

解决方案:实现多行分面且保持条形宽度一致

要解决多行分面同时维持条形宽度一致的问题,直接用ggplot2的facet_wrap()替代facet_grid()即可,核心是设置scales = "free_x"和space = "free_x"参数,同时指定行数/列数。

修改后的完整代码

library(ggplot2)
library(tidyr)
library(dplyr)

set.seed(123)

selected_pops <- data.frame(
  id = numeric(),
  pop = numeric(),
  val_high = numeric(),
  val_medium = numeric(),
  val_low = numeric()
)

pops = c("A", "B", "C", "D", "E", "F", "G", "H", "I")
for (i in 1:length(pops)) {
  num_iterations <- floor(rnorm(1, mean = 9, sd = 3))
  print(paste("num iterations for ", i, "is: ", num_iterations))
  
  pop_values <- rep(pops[i], num_iterations)
  id_values <- 0:(num_iterations - 1)
  val_high_values <- rnorm(num_iterations, mean = 3, sd = 1)
  val_medium_values <- rnorm(num_iterations, mean = 7, sd = 2)
  val_low_values <- rnorm(num_iterations, mean = 9, sd = 3)
  
  selected_pops <- rbind(selected_pops, data.frame(
    id = id_values,
    pop = pop_values,
    val_high = val_high_values,
    val_medium = val_medium_values,
    val_low = val_low_values
  ))
}

selected_pops <- selected_pops %>%
  arrange(desc(rowSums(select(., starts_with("val.")))))

# Reshape data to long format
selected_long <- gather(selected_pops, key = "level", value = "value", -id, -pop)
selected_long$level <- factor(selected_long$level)

# Define the order in which you want the facets
populations_to_include <- pops
desired_facet_order <- populations_to_include

# Reorder the 'pop' variable
selected_long$pop <- factor(selected_long$pop, levels = desired_facet_order)

# Plot colors
custom_colors <- c("val_high" = "darkred", "val_medium" = "red", "val_low" = "orange")
legend_labels <- c("val_high" = "High",
                   "val_medium" = "Medium",
                   "val_low" = "Low"
)

#do actual plotting
big_bar <- ggplot(selected_long, aes(x = as.factor(id), y = value, fill = factor(level))) +
  geom_bar(stat = "identity", position = "stack", width = 1) +
  labs(
    title = "Summed values by group",
    fill = "Sub values",  # Change legend title
    x = "Individual ID",     # Change x-axis label
    y = "Summed Values"
  ) +
  scale_fill_manual(values = custom_colors, labels = legend_labels) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1, size = 8)) +
  # 关键改动:用facet_wrap替代facet_grid,指定行数,开启x轴尺度和空间自由调整
  facet_wrap(~ pop, scales = "free_x", space = "free_x", nrow = 3)

big_bar

关键改动说明

  • 替换facet_grid(. ~ pop, scales = "free", space = "free")为facet_wrap(~ pop, scales = "free_x", space = "free_x", nrow = 3)
  • scales = "free_x":让每个分面的x轴刻度根据样本量自动调整
  • space = "free_x":让每个分面的宽度根据样本量自动适配,保证条形宽度一致
  • nrow = 3:指定分面排成3行,可根据需求调整为其他数值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 04:07:11