如何使用position_dodge2()保持ggplot条形图的条形宽度?
关于ggplot中position_dodge2(preserve="single")的异常行为解析
核心差异:position_dodge vs position_dodge2
position_dodge:仅在x类别下存在多个分组时分配闪避空间,单个分组的x类别会占满该位置的全部宽度,导致不同x类别的条形宽度不均。position_dodge2:先为每个x类别分配固定总宽度,再在内部给分组划分空间。默认preserve="total"保证x类别总宽度一致,但单个分组宽度随分组数量变化;设置preserve="single"则强制所有分组的单个条形宽度完全一致。
问题原因
当设置preserve="single"时,position_dodge2会给每个x类别预留对应所有分组数量的空间。如果你的RACE 5只有一个SEX类别,而其他RACE有两个,ggplot会为RACE 5的位置预留两个分组的空间,但其中一个分组没有数据,y值被默认设为0,因此出现大量高度为0的“多余条形”,同时现有条形的高度因为空间分配逻辑变化,看起来只有最高的条形匹配原图形(实际是其他分组高度为0被掩盖)。
解决方法
补全缺失分组数据
用tidyr::complete补全每个RACE下所有SEX的组合,缺失值设为0,这样每个x类别下都有完整分组,position_dodge2就能正常分配空间:library(tidyr) healthdata_complete <- complete(healthdata, RACE, SEX, fill = list(HealthcareCosts = 0)) ggplot(healthdata_complete) + geom_col(aes(x = RACE, y = HealthcareCosts, fill=SEX), position = position_dodge2(preserve = "single"))用position_dodge手动控制宽度
如果不想补全数据,直接用position_dodge并手动设置条形宽度和闪避宽度,保证单个条形宽度一致:ggplot(healthdata) + geom_col(aes(x = RACE, y = HealthcareCosts, fill=SEX), position = position_dodge(width = 0.8), width = 0.8)
内容的提问来源于stack exchange,提问作者Arjun Mohan
相关产品推荐
相关产品推荐

