How to reverse order of x-axis breaks in ggplot?

I’m trying to make a plot wherein large values on the x-axis are actually small, and vice versa. Because of how ggplot reads the data, it’s automatically ordering the data such that the x-axis is ordered smallest to largest, and I’m trying to figure out how to reverse that.

I ended up reversing the actual order of the data by using rev(), but that won’t change where the breaks in the x-axis are.

For example:

library(tidyverse)

# Making fake data
Freq <- rep(c(1, 2, 3, 5, 10, 15, 20), 10)
SD <- c(rep(1, 7), rep(2, 7), rep(3, 7), rep(4, 7), rep(5, 7), rep(6, 7), rep(7, 7), rep(8, 7), rep(9, 7), rep(10, 7))
Intro_0 <- sample(80:120,135,TRUE)
Intro_0 <- c(seq(80, 74, -1), seq(78, 72, -1), seq(76, 70, -1), seq(74, 68, -1), seq(72, 66, -1), seq(70, 64, -1), seq(68, 62, -1), seq(66, 60, -1), seq(64, 58, -1), seq(62, 56, -1))
test2 <- data.frame(cbind(Freq, SD, Intro_0))

# Plotting
# Here's where I reverse the order of the data: "rev(Freq)"
ggplot(test2, aes(rev(Freq), SD, z = Intro_0)) +
  geom_contour_filled(bins = 9)+
  scale_fill_brewer(palette = "BuPu")+
  labs(x="Frequency", 
       y="Magnitude",
       title="Test Plot")+
  # Here's where I *think* the issue is...
  scale_x_continuous(breaks = c(1, 2, 3, 5, 10, 15, 20), # I've tried rev() here
                     labels = c("Freq = 1/20", " ", " ", " ", " ", " ", "Freq = 1/1"))+
  # Aesthetic to clear up panel; can ignore
  theme_bw()+
  theme(panel.border = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), axis.line = element_line(colour = "white"))+
  theme(axis.text.x = element_text(angle = 45, hjust=1), plot.caption.position = "plot", plot.caption = element_text(hjust = 0))+
  labs(fill="Legend")

enter image description here

If you run the lines above, you’ll find that the rev(Freq) reorders the data how I want it, but that the breaks in the x-axis still aren’t ordered properly (the first three ticks are closer together, indicating the "1, 2, 3, … , 20" (though the break labels are as I want them). I’ve tried reversing the breaks argument and a few other obvious fixes, but nothing’s worked.

Let me know if you have any ideas! Thanks so much for any advice 🙂

>Solution :

This is exactly what scale_x_reverse is for:

ggplot(test2, aes(Freq, SD, z = Intro_0)) +
  geom_contour_filled(bins = 9)+
  scale_fill_brewer(palette = "BuPu")+
  labs(x = "Frequency", y = "Magnitude", title = "Test Plot", fill = "Legend") +
  scale_x_reverse(breaks = c(1, 2, 3, 5, 10, 15, 20), 
                  labels = c("Freq = 1/1", "", "", "", "", "", "Freq = 1/20")) +
  theme_bw()+
  theme(panel.border = element_blank(), 
        panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank(), 
        axis.line = element_line(colour = "white"),
        axis.text.x = element_text(angle = 45, hjust=1), 
        plot.caption.position = "plot", 
        plot.caption = element_text(hjust = 0)) 

enter image description here

Leave a Reply