为何ggplot中geom_col与geom_bar填充色不一致?如何设置等效固定填充?
问题:geom_bar与geom_col填充颜色不匹配的原因
以下代码本应生成除轴标签外完全一致的两个柱状图,数据框dat是颜色响应类数据,用对应颜色填充合理:
colOrder = c('green', 'blue', 'red', 'orange', 'purple') dat <- data.frame(q = rep(c('red', 'orange', 'green', 'blue', 'purple'), c(1:5))) # using geom_bar ggplot(dat, aes(x = factor(q, levels = colOrder) )) + geom_bar(fill = colOrder) #using geom_col dc <- as.data.frame(table(dat$q)) names(dc) <- c('q', 'n') ggplot(dc, aes(x = factor(q, levels = colOrder), y = n )) + geom_col(fill = colOrder)
但实际两个图表并不相同:geom_col的填充颜色是按dc$q的顺序分配,而geom_bar则正确遵循了指定的colOrder。这是文档遗漏的内容?还是bug?
解答
这不是bug,核心原因是两个函数接收fill向量时的匹配逻辑不同:
- 对于
geom_bar:它处理的是原始长数据,x轴的每个类别按factor(q, levels=colOrder)的顺序排列,直接赋值fill=colOrder时,颜色会按x轴的类别顺序一一对应匹配,结果正确。 - 对于
geom_col:它处理的是汇总后的dc数据,而table()函数生成的结果默认按字母顺序排序(查看dc的行:blue, green, orange, purple, red)。赋值fill=colOrder时,颜色是按dc的行顺序依次分配,而非x轴的levels顺序,因此出现颜色错位。
修正方法(任选其一):
- 方法1:提前按colOrder排序dc数据框
dc <- dc[match(colOrder, dc$q), ] ggplot(dc, aes(x = factor(q, levels = colOrder), y = n )) + geom_col(fill = colOrder)
- 方法2:将fill映射为因子,用scale指定颜色
ggplot(dc, aes(x = factor(q, levels = colOrder), y = n, fill = q )) + geom_col() + scale_fill_manual(values = setNames(colOrder, colOrder)) + guides(fill = "none") # 不需要图例可隐藏
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

