Reverse order of categorical y axis (in ggridges/ggplot2)

Hi all,

I am using the ggridges packages to plot a geom_density_ridges. I am looking to reverse the order of the y-axis, even though it is categorical. I tried scale_y_continuous(trans = "reverse") (from https://stackoverflow.com/questions/28391850/r-reverse-order-of-discrete-y-axis-in-ggplot2 ), but that answer did not work for me since the axis labels cannot be coerced to numeric..

As I was typing up this question, I figured out a way to solve it - by adding in a line

mutate(y = fct_rev(as_factor(y))) 

before the ggplot call, but that seems a bit indirect to me. Is there another way (fully within ggplot2 to do the same thing)?

@AJF, you should be able to do y = fct_rev(as_factor(y)) within the ggplot call, so ggplot will convert y without having to mutate it beforehand.

I have to do this all the time in bayesplot. The solution I came up with, short of writing a full-on scale function, is:

ggplot(iris) + 
  aes(x = Sepal.Length, y = Species) + 
  geom_point() + 
  scale_y_discrete(limits = unique(rev(iris$Species)))

Edit: I always have the column sorted in my code, so to generalize the solution, it should be:

ggplot(iris) + 
  aes(x = Sepal.Length, y = Species) + 
  geom_point() + 
  scale_y_discrete(limits = rev(unique(sort(iris$Species))))

Just wondering, wouldn't this be more straightforward?

library(forcats)
ggplot(iris) + 
  aes(x = Sepal.Length, y = fct_rev(Species)) + 
  geom_point()

1 Like

Sure, it would, although it needs an extra line to clean up the y-axis label :wink:. I didn't want a forcats dependency in the package, so I didn't go that route.

Fair enough. Your scale_y_discrete(limits = rev(unique(sort(iris$Species)))) brought back some nightmares from my early fumblings with ggplot some years ago where seemingly simple stuff like this was difficult to get right. :sweat:

Thanks @martin.R!

For anyone who finds this later and wants to use it -- I actually found (based on Martin's suggestion) that just doing y = fct_rev(y) works -- I guess fct_rev automatically coerces to factor, so I didn't need an explicit as_factor. (It would have worked like that in the mutate too).

Thanks for the suggestion @tjmahr . I was actually using it to display posterior distributions of parameters from RStan ... I should probably just check out bayesplot instead of trying to reinvent the wheel :stuck_out_tongue:

2 Likes