sachem87
sachem87

Reputation: 59

Flip ggplot y-axis for bar graph?

I am trying to create a bar graph that plots rank, where lower values are better. I want larger bars to correspond to smaller values, so the "best" groups in the data receive more visual weight.

Reprex:

dat = data.frame("Group" = c(rep("Best",50),
                             rep("Middle",50),
                             rep("Worst",50)
                             ),
                 "Rank" = c(rnorm(n = 50, mean = 1.5, sd = 0.5),
                            rnorm(n = 50, mean = 2.5, sd = 0.5),
                            rnorm(n = 50, mean = 3.5, sd = 0.5)
                            )
                 )

    tibdat = as_tibble(dat) %>%
      group_by(Group) %>%
      summarise(Mean_Rank = mean(Rank,na.rm=T))

# creates simple rightside up bar graph
  
    ggplot(data = tibdat, mapping = aes(Group, Mean_Rank, fill = Group)) +
      geom_col() +
      scale_y_continuous(breaks = c(1:4), limits = c(1,4),  oob = scales::squish)

# my attempt below, simply reversing the breaks and limits
    
    ggplot(data = tibdat, mapping = aes(Group, Mean_Rank, fill = Group)) +
      geom_col() +
      scale_y_continuous(breaks = c(4:1), limits = c(4,1),  oob = scales::squish)

The graphing code at the end does succeed in flipping the axis, but the data disappears (the bars are not plotted).

Note that I do not want the graphs to originate from the top, which scale_y_reverse can achieve. I want the bars to originate from the bottom, at the y = 4 line (or below).

How is this achieved?

Edit: Added image below to show the original bar graph that works but is wrong.

Graph that works but is not ideal

Upvotes: 1

Views: 389

Answers (1)

Guillaume Mulier
Guillaume Mulier

Reputation: 503

I just transformed the labels. I don't know if that's what you searched.

ggplot(data = tibdat, mapping = aes(Group, Mean_Rank, fill = Group)) +
  geom_col() +
  scale_y_continuous(breaks = c(1:4), limits = c(1,4), oob = scales::squish, labels = function(x) 5 - x)

With another trick in the aes argument I think you can arrive to the wanted result. Maybe someone better than me knows a clean way to do it.

ggplot(data = tibdat, mapping = aes(Group, 5 - Mean_Rank, fill = Group)) +
geom_col() +
scale_y_continuous(breaks = c(1:4), limits = c(1,4),  oob = scales::squish, labels = function(x) 5 - x)

And here is the result : plot_from_4

Upvotes: 1

Related Questions