【问题标题】:How do you order the fill-colours within ggplot2 geom_bar您如何在 ggplot2 geom_bar 中订购填充颜色
【发布时间】:2013-03-06 15:47:56
【问题描述】:

我正在调用 ggplot 函数

ggplot(data,aes(x,y,fill=category)+geom_bar(stat="identity")

结果是一个条形图,条形由与类别对应的各种颜色填充。但是,颜色的顺序在条与条之间并不一致。假设有粉色、绿色和蓝色。有些条从下到上呈粉红色、绿色、蓝色,有些则呈绿色、粉红色、蓝色。我没有看到任何明显的模式。

这些顺序是如何选择的?我怎样才能改变它?至少,我怎样才能让 ggplot 选择一致的顺序?

(x,y and category)的类分别是(integer,numeric and factor)。如果我将类别设为有序因子,它不会改变这种行为。

有人知道如何解决这个问题吗?

可重现的例子:

dput(data)

structure(list(mon = c(9L, 10L, 11L, 10L, 8L, 7L, 7L, 11L, 9L, 
10L, 12L, 11L, 7L, 12L, 8L, 12L, 9L, 7L, 9L, 10L, 10L, 8L, 12L, 
7L, 11L, 10L, 8L, 7L, 11L, 12L, 12L, 9L, 9L, 7L, 7L, 12L, 12L, 
9L, 9L, 8L), gclass = structure(c(9L, 1L, 8L, 6L, 4L, 4L, 3L, 
6L, 2L, 4L, 1L, 1L, 5L, 7L, 1L, 6L, 8L, 6L, 4L, 7L, 8L, 7L, 9L, 
8L, 3L, 5L, 9L, 2L, 7L, 3L, 5L, 5L, 7L, 7L, 9L, 2L, 4L, 1L, 3L, 
8L), .Label = c("Down-Down", "Down-Stable", "Down-Up", "Stable-Down", 
"Stable-Stable", "Stable-Up", "Up-Down", "Up-Stable", "Up-Up"
), class = c("ordered", "factor")), NG = c(222614.67, 9998.17, 
351162.2, 37357.95, 4140.48, 1878.57, 553.86, 40012.25, 766.52, 
15733.36, 90676.2, 45000.29, 0, 375699.84, 2424.21, 93094.21, 
120547.69, 291.33, 1536.38, 167352.21, 160347.01, 26851.47, 725689.06, 
4500.55, 10644.54, 75132.98, 42676.41, 267.65, 392277.64, 33854.26, 
384754.67, 7195.93, 88974.2, 20665.79, 7185.69, 45059.64, 60576.96, 
3564.53, 1262.39, 9394.15)), .Names = c("mon", "gclass", "NG"
), row.names = c(NA, -40L), class = "data.frame") 

ggplot(data,aes(mon,NG,fill=gclass))+geom_bar(stat="identity")

【问题讨论】:

  • 请提供可重现的示例?
  • 顺便说一句:Brian 向我证实这实际上是一个(有些长期存在的)错误。
  • 读者当心 - 不幸的是,这种行为在 ggplot2 的近期历史中发生了多次变化,并且答案中的一些示例不再有效。

标签: r graphics ggplot2


【解决方案1】:

从 ggplot2_2.0.0 开始,order 美学不再可用。要获得按填充颜色排序的堆栈图,您只需按要排序的分组变量对数据集进行排序。

为此,我经常使用 dplyrarrange。在这里,我通过 ggplot 调用中的 fill 因子对数据集进行排序,而不是创建有序数据集,但两者都可以正常工作。

library(dplyr)

ggplot(arrange(data, gclass), aes(mon, NG, fill = gclass)) +
    geom_bar(stat = "identity")

这很容易在基础 R 中完成,当然,使用带有提取括号的经典 order

ggplot(data[order(data$gclass), ], aes(mon, NG, fill = gclass)) +
    geom_bar(stat = "identity")

现在两种情况下的结果图都按所需顺序:

ggplot2_2.2.0 更新

在 ggplot_2.2.0 中,填充顺序基于因子水平的顺序。默认顺序将在堆栈的顶部而不是底部绘制第一级。

如果您想要堆栈底部的第一个级别,您可以在position_stack 中使用reverse = TRUE。请注意,您也可以使用geom_col 作为geom_bar(stat = "identity") 的快捷方式。

ggplot(data, aes(mon, NG, fill = gclass)) +
    geom_col(position = position_stack(reverse = TRUE))

【讨论】:

  • 这似乎适用于 stat="identity",但使用 geom_bar(stat="summary", fun.y=median) 失败。在这种情况下,我必须汇总数据并使用 stat="identity" 来获得适当的排序。我相信这是自 2.0 以来的新功能
  • @EtienneLow-Décarie 可能stat_summary_bin 是合适的工具。您是否尝试过使用stat = "summary_bin" 而不是stat = "summary"
  • 呃,这很烦人。任何人都可以评论为什么 order 美学被删除了吗?供参考:github.com/hadley/ggplot2/issues/1593
  • 太棒了!非常感谢您的说明和解决方案!
  • 对于那些可能想要更改图例顺序以匹配堆叠的人,添加例如guides(fill = guide_legend(reverse = T)) 应该很好用。
【解决方案2】:

您还需要指定order 美学。

ggplot(data,aes(mon,NG,fill=gclass,order=gclass))+
    geom_bar(stat="identity")

这可能是也可能不是bug

【讨论】:

  • 截至 ggplot >= 2.0; Ignoring unknown aesthetics: order! (见下文)
【解决方案3】:

要下单,必须使用levels参数并通知下单。像这样:

data$gclass
(data$gclass2 <- factor(data$gclass,levels=sample(levels(data$gclass)))) # Look the difference in the factors order
ggplot(data,aes(mon,NG,fill=gclass2))+geom_bar(stat="identity")

【讨论】:

    【解决方案4】:

    您可以使用scale_fill_ 函数更改颜色。例如:

    ggplot(dd,aes(mon,NG,fill=gclass)) + 
      geom_bar(stat="identity") + 
      scale_fill_brewer(palette="blues")
    

    要在bars 中获得一致的排序,则需要对数据框进行排序:

    dd = dd[with(dd, order(gclass, -NG)), ]
    

    为了改变图例的顺序,改变gclass 因子。所以像:

    dd$gclass= factor(dd$gclass,levels=sort(levels(dd$gclass), TRUE))
    

    【讨论】:

    • 对您来说,这看起来像是一致的排序吗?我遇到了与他的数据相同的问题。这里发生了一些可疑的事情。
    • @joran Ahh,我现在看到了问题!
    • @Dave31415 我想我已经回答了这个问题,但是,我对为什么这项工作的理解有点复杂。
    • 好的,我同意,对 df 进行排序似乎可行。但这对我来说仍然很可疑。
    • @csgillespie。谢谢。这似乎有效,但似乎仍然有点奇怪。我想知道 stat="identity" 是否是问题所在。
    【解决方案5】:

    在@aosmith 的回答的基础上,另一种排序条的方法是:

    ggplot(data, aes(x=mon, y=reorder(NG,gclass), fill = gclass)) +
        geom_bar(stat = "identity")
    

    base stats 包中的 reorder 函数的美妙之处在于您可以在 reorder(based_on_dimension, y, function) 中应用它,其中 y 是基于 sum、mean 等函数排序的 based_on_dimension。

    【讨论】:

      【解决方案6】:

      由于此交换首先出现在“因子填充订单”中,因此我将再添加一个解决方案,我认为该解决方案更直接,并且不需要更改您的基础数据。

      ggplot(data,aes(x,y,fill=factor(category, levels = c("Down-Down", "Down-Stable", "Down-Up", "Stable-Down", "Stable-Stable", "Stable-Down", "Up-Down", "Up-Stable", "Up-Up"))) + 
      geom_col(position = position_stack(reverse = FALSE))
      

      或者按照我的喜好,我先创建一个变量向量,以便稍后简化编码并使其更易于编辑:

      v_factor_levels <- c("Down-Down", "Down-Stable", "Down-Up", "Stable-Down", "Stable-Stable", "Stable-Down", "Up-Down", "Up-Stable", "Up-Up")
      
      ggplot(data,aes(x,y,fill=factor(category, levels = v_factor_levels)) + 
      geom_col(position = position_stack(reverse = FALSE))
      

      你不需要 geom_col() 中的反向位置元素,我将这些作为提醒,以防我想反向,但你可以通过消除它来进一步简化。

      【讨论】:

        猜你喜欢
        • 2014-03-02
        • 1970-01-01
        • 2018-12-21
        • 1970-01-01
        • 1970-01-01
        • 2013-08-16
        • 2018-12-12
        • 2015-10-19
        相关资源
        最近更新 更多