Search code examples
rggplot2fill

How to sort bars by value of Y instead of value of 'fill' in ggplot


I need to sort 'within' each goup in the x axis, but ggplot defaults to sorting by fill (so alphabetic order by default). I need to create a graph where all bars within each group in the x axis are sorted by the value of the Y axis.

ggplot(mpg, aes(class, hwy, fill=trans))+geom_col(position='dodge')

So in this example, I would like the three first bars within 2seater appeared in the following order: manual(m6), auto(s6), auto(i4).

I have my data arranged by groups, but still produces the ggplot using the alphabetical order of the fill value, I don't really know how to bypass this.

Thanks very much!


Solution

  • You need a separate variable that is the interaction between class and trans, ordered by hwy that you use to map the group aesthetic:

    mpg %>%
      group_by(class, trans) %>%
      summarise(hwy = mean(hwy)) %>%
      mutate(order = fct_reorder2(interaction(class, trans), 
                                  class, hwy)) %>%
      ggplot(aes(class, hwy, fill = trans, group = order)) +
      geom_col(position = 'dodge')
    

    enter image description here

    It might be better to then order your x axis according to the highest value in each class

    mpg %>%
      group_by(class, trans) %>%
      summarise(hwy = mean(hwy)) %>%
      mutate(order = fct_reorder2(interaction(class, trans), 
                                  class, hwy)) %>%
      ungroup() %>%
      mutate(class = fct_reorder2(class, trans, hwy, function(x, y) max(y))) %>%
      ggplot(aes(class, hwy, fill = trans, group = order)) +
      geom_col(width = 0.8, position = position_dodge())
    

    enter image description here