如何用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
相关产品推荐
相关产品推荐

