【问题标题】:ggplot2: reorder bars from highest to lowest in each facet [duplicate]ggplot2:在每个方面从最高到最低重新排列条形[重复]
【发布时间】:2017-08-27 20:13:12
【问题描述】:

在下面的df 中,我想将条形从最高到最低重新排序在每个方面

我试过了

df <- df %>% tidyr::gather("var", "value", 2:4)
ggplot(df, aes (x = reorder(id, -value), y = value, fill = id))+
  geom_bar(stat="identity")+facet_wrap(~var, ncol =3)

它给了我

它没有将每个方面的条形从高到低排序。

我想出了另一种方法来获得我想要的东西。我必须一次绘制每个变量,然后使用 grid.arrange() 组合所有图

#I got this function from @eipi10's answer
#http://stackoverflow.com/questions/38637261/perfectly-align-several-plots/38640937#38640937  
#Function to extract legend
# https://github.com/hadley/ggplot2/wiki/Share-a-legend-between-two-ggplot2-graphs
g_legend<-function(a.gplot) {
  tmp <- ggplot_gtable(ggplot_build(a.gplot))
  leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
  legend <- tmp$grobs[[leg]]
  return(legend)
}

p1 <- ggplot(df[df$var== "A", ], aes (x = reorder(id, -value), y = value, fill = id))+
  geom_bar(stat="identity") + facet_wrap(~var, ncol =3)

fin_legend <- g_legend(p1)
p1 <- p1 + guides(fill= F)

p2 <- ggplot(df[df$var== "B", ], aes (x = reorder(id, -value), y = value, fill = id))+
  geom_bar(stat="identity") + facet_wrap(~var, ncol =3)+guides(fill=FALSE) 

p3 <- ggplot(df[df$var== "C", ], aes (x = reorder(id, -value), y = value, fill = id))+
  geom_bar(stat="identity") + facet_wrap(~var, ncol =3)+guides(fill=FALSE) 


grid.arrange(p1, p2, p3, fin_legend, ncol =4, widths = c(1.5, 1.5, 1.5, 0.5))

结果就是我想要的

我想知道是否有一种直接的方法可以帮助我在所有方面从最高到最低对条形进行排序,而不必分别绘制每个变量然后将它们组合起来。任何建议将不胜感激。

数据

df <-  read.table(text = c("
id  A   B   C
site1   10  15  20
site2   20  10  30
site3   30  20  25
site4   40  35  40
site5   50  30  35"), header = T)

【问题讨论】:

    标签: r ggplot2 geom-bar


    【解决方案1】:

    下面的方法使用一个专门为 x 轴准备的变量 facet_wrap(),但使用 labels 参数到 scale_x_discrete() 来显示正确的 x 轴标签:

    准备数据

    data.table我比较流利,所以这里用这个。随意使用您喜欢的任何软件包进行数据操作。

    编辑:删除第二个虚拟变量,只需要ord

    library(data.table)   
    # reshape from wide to long
    molten <- melt(setDT(df), id.vars = "id")
    # create dummy var which reflects order when sorted alphabetically
    molten[, ord := sprintf("%02i", frank(molten, variable, -value, ties.method = "first"))]
    
    molten
    #       id variable value ord
    # 1: site1        A    10  05
    # 2: site2        A    20  04
    # 3: site3        A    30  03
    # 4: site4        A    40  02
    # 5: site5        A    50  01
    # 6: site1        B    15  09
    # 7: site2        B    10  10
    # 8: site3        B    20  08
    # 9: site4        B    35  06
    #10: site5        B    30  07
    #11: site1        C    20  15
    #12: site2        C    30  13
    #13: site3        C    25  14
    #14: site4        C    40  11
    #15: site5        C    35  12
    

    创建情节

    library(ggplot2)
    # `ord` is plotted on x-axis instead of `id`
    ggplot(molten, aes(x = ord, y = value, fill = id)) +
      # geom_col() is replacement for geom_bar(stat = "identity")
      geom_col() +
      # independent x-axis scale in each facet, 
      # drop absent factor levels (not the case here)
      facet_wrap(~ variable, scales = "free_x", drop = TRUE) +
      # use named character vector to replace x-axis labels
      scale_x_discrete(labels = molten[, setNames(as.character(id), ord)]) + 
      # replace x-axis title
      xlab("id")
    

    数据

    df <- read.table(text = "
    id  A   B   C
    site1   10  15  20
    site2   20  10  30
    site3   30  20  25
    site4   40  35  40
    site5   50  30  35", header = T)
    

    【讨论】:

    • 非常感谢您对每一行代码的详细解释。非常感谢 Uwe。
    • 优秀的解决方案!!!希望这个逻辑被内置到 ggplot facet 函数中
    【解决方案2】:

    如果您愿意丢失 X 轴标签,您可以通过使用实际 y 值作为 x 美学来做到这一点,然后在每个方面删除未使用的因子级别:

    ggplot(df, aes (x = factor(-value), y = value, fill = id))+
        geom_bar(stat="identity", na.rm = TRUE)+
        facet_wrap(~var, ncol =3, scales = "free_x", drop = TRUE) +
        theme(
            axis.text.x = element_blank(),
            axis.ticks.x = element_blank()
        )
    

    结果:

    x 轴标签的丢失在这里可能并不算太糟糕,因为您仍然可以继续使用颜色(而且 x 轴无论如何都会令人困惑,因为它在各个方面不一致)。

    【讨论】:

    • 这真是个天才!非常感谢!
    猜你喜欢
    • 2017-01-03
    • 1970-01-01
    • 2014-04-14
    • 2017-02-20
    • 2019-12-05
    • 2019-04-24
    • 2014-06-30
    • 2016-07-03
    • 1970-01-01
    相关资源
    最近更新 更多