如何在ggplot分面面板中保持条形宽度一致?
问题描述
使用ggplot2绘制带facet_wrap的条形图时,因不同面板的x轴类别数量不同,导致条形宽度不一致,需要修改代码使所有面板的条形宽度保持统一。
原始数据及绘图代码如下:
set.seed(123) # For reproducibility df_long <- data.frame( trait = rep(c("Trait1", "Trait2", "Trait3", "Trait4", "Trait5"), each = 4), type = rep(c("eur_ita", "eur_ita_2", "eur_ita_3", "eur_ita_4"), times = 5), value = c(runif(5, 5, 15), runif(5, 8, 20), runif(5, 1, 12), runif(5, 4, 18)), macro_cat3 = rep(c("Category1", "Category2", "Category3"), each = 10) # Dividing into two macro categories )
ggplot(df_long, aes(x = trait, y = value, fill = type, alpha = type)) + geom_col(position = position_dodge(width = 0.6), color = "black", width = 0.6) + # Adjust dodge and bar width facet_wrap(~ macro_cat3, scales = "free_x", ncol = 4) + # Keep free_x scales labs(x = "Trait", y = "Percentage of r2", fill = " Type") + scale_fill_manual( values = c( "eur_ita" = "red", "eur_ita_2" = "black", "eur_ita_3" = "green", "eur_ita_4" = "gray" ), name = NULL # Removes the legend title ) + scale_alpha_manual( values = c( "eur_ita" = 1, "eur_ita_2" = 0.9, "eur_ita_3" = 0.9, "eur_ita_4" = 1 ), guide = "none" )
解决方案
方法1:用ggh4x包固定面板宽度
ggh4x扩展包的facet_wrap2函数支持fixed_width参数,可强制所有面板使用相同宽度,从而保证条形宽度一致。
修改后的代码:
# 首次使用需安装包 # install.packages("ggh4x") library(ggh4x) ggplot(df_long, aes(x = trait, y = value, fill = type, alpha = type)) + geom_col(position = position_dodge(width = 0.6), color = "black", width = 0.6) + # 替换facet_wrap为facet_wrap2,设置固定宽度 facet_wrap2(~ macro_cat3, scales = "free_x", ncol = 4, fixed_width = unit(2, "cm")) + labs(x = "Trait", y = "Percentage of r2", fill = " Type") + scale_fill_manual( values = c( "eur_ita" = "red", "eur_ita_2" = "black", "eur_ita_3" = "green", "eur_ita_4" = "gray" ), name = NULL ) + scale_alpha_manual( values = c( "eur_ita" = 1, "eur_ita_2" = 0.9, "eur_ita_3" = 0.9, "eur_ita_4" = 1 ), guide = "none" )
方法2:统一x轴因子水平
将trait转换为包含所有可能水平的因子,并设置drop=FALSE,让每个面板的x轴保留所有trait的位置(无数据的trait留空),以此保证x轴长度一致,条形宽度统一。
修改后的代码:
# 统一trait的因子水平 df_long$trait <- factor(df_long$trait, levels = c("Trait1", "Trait2", "Trait3", "Trait4", "Trait5")) ggplot(df_long, aes(x = trait, y = value, fill = type, alpha = type)) + geom_col(position = position_dodge(width = 0.6), color = "black", width = 0.6) + facet_wrap(~ macro_cat3, scales = "free_x", ncol = 4) + labs(x = "Trait", y = "Percentage of r2", fill = " Type") + scale_x_discrete(drop = FALSE) + # 保留所有因子水平,避免空trait被删除 scale_fill_manual( values = c( "eur_ita" = "red", "eur_ita_2" = "black", "eur_ita_3" = "green", "eur_ita_4" = "gray" ), name = NULL ) + scale_alpha_manual( values = c( "eur_ita" = 1, "eur_ita_2" = 0.9, "eur_ita_3" = 0.9, "eur_ita_4" = 1 ), guide = "none" )
注:方法2会在无对应trait数据的面板显示空白标签位,若需隐藏空白标签,可额外调整主题的x轴标签样式。
内容的提问来源于stack exchange,提问作者Khaleesi95
相关产品推荐
相关产品推荐

