如何在分组条形图中保持Device列的填充颜色顺序?
问题
我希望用「Device」列为两张图表(Fig1和Fig2)填充相同顺序的颜色。但Fig2按Type分组后,Device列的因子顺序未被保留,与Fig1相反;不使用group参数时顺序则正常。我尝试过设置因子水平、提前整理数据,但添加group参数后顺序仍无法维持,期望Fig2中每个Type分组内的Device填充顺序与Fig1一致。
示例数据
data1:
System Device C mFP uFP CC A 6.70 9.11 455.70 CC B 0.02 308.73 1.03 CC C 6.65 2142.00 452.53
data2:
System Device Type Value CC A mFP 9.11 CC A uFP 455.70 CC B mFP 308.73 CC B uFP 1.03 CC C mFP 2142.00 CC C uFP 452.53
注:每个数据文件中Device均为带水平的因子,cbPalette为十六进制颜色向量。
示例代码
Fig1:
Fig1 <- ggplot(data1, aes(x=System, y=C,fill=Device)) + geom_bar(width=0.5, stat='identity', colour= 'black') + scale_fill_manual(values = cbPalette)
Fig2:
Fig2 <- ggplot(data2, aes(x=System, y=Value, fill=Device)) + geom_bar_pattern(aes(group=Type, pattern=Type), stat="identity",width=0.5, pattern_fill = "black",colour= 'black', pattern_density = 0.1,pattern_spacing = 0.025, pattern_key_scale_factor = 0.6)+ scale_pattern_manual("type", limits=c("uFP", "mFP"), scale_fill_manual(values = cbPalette)
解决方案
问题根源在于仅设置group=Type时,ggplot会默认按数据行顺序或分组内的默认规则排序,导致Device的因子顺序被打乱。要维持与Fig1一致的Device颜色顺序,需从以下两点调整:
- 指定包含Device顺序的分组规则:将group参数设置为
interaction(Device, Type),让分组逻辑先遵循Device的因子顺序,再按Type区分,确保每个Type分组内的Device排列顺序与Fig1匹配。 - 强制颜色映射匹配因子水平:在
scale_fill_manual中显式添加limits = levels(data2$Device),强制颜色映射严格对应Device的因子水平顺序,避免分组操作覆盖原有顺序。
修正后的Fig2代码:
Fig2 <- ggplot(data2, aes(x=System, y=Value, fill=Device)) + geom_bar_pattern( aes(group = interaction(Device, Type), pattern = Type), stat = "identity", width = 0.5, pattern_fill = "black", colour = 'black', pattern_density = 0.1, pattern_spacing = 0.025, pattern_key_scale_factor = 0.6 ) + scale_pattern_manual("type", limits = c("uFP", "mFP")) + scale_fill_manual(values = cbPalette, limits = levels(data2$Device))
若需要进一步确保数据顺序的稳定性,可提前对data2按Device的因子顺序排序,再结合上述设置:
# 按Device因子顺序排序数据 data2_sorted <- data2[order(data2$Device), ] Fig2 <- ggplot(data2_sorted, aes(x=System, y=Value, fill=Device)) + geom_bar_pattern( aes(group = interaction(Device, Type), pattern = Type), stat = "identity", width = 0.5, pattern_fill = "black", colour = 'black', pattern_density = 0.1, pattern_spacing = 0.025, pattern_key_scale_factor = 0.6 ) + scale_pattern_manual("type", limits = c("uFP", "mFP")) + scale_fill_manual(values = cbPalette, limits = levels(data2_sorted$Device))
内容的提问来源于stack exchange,提问作者plaroka
相关产品推荐
相关产品推荐

