Courtney
Courtney

Reputation: 147

Reverse the scale of the x axis in a plot

I have created a plot in R and my own custom x and y axes. I would like the x axis to be displayed in a reverse order (1-0 by -.02). I have read numerous posts and threads that suggest using xlim and reverse range but I just can't seem to make it work. Once plotted I am also converting the axes labels to percentages by multiplying by 100 (as you will see in the code). Here is what I have so far;

plot(roc.val, xlab = "Specificity (%)", ylab = "Sensitivity (%)", axes = FALSE)
axis(2, at = seq(0,1,by=.2), labels = paste(100*seq(0,1, by=.2)), tick = TRUE)
axis(1, at = seq(0,1,by=.2), labels = paste(100*seq(0,1, by=.2)), tick = TRUE)

How can I reverse the x axis scale so that the values begin at 100 and end at 0 with increments of 20?

Upvotes: 15

Views: 41538

Answers (4)

Daniel
Daniel

Reputation: 82

First, check out the ggplot2 library for making beautiful and extendable graphics. It is part of the Tidyverse approach to R and a gamechanger if you have not been exposed to it.

For example, to solve your issue using ggplot, you simply add the term scale_x_reverse() to your graphic.

See: http://ggplot.yhathq.com/docs/scale_x_reverse.html

Upvotes: 0

Eduardo Alvim
Eduardo Alvim

Reputation: 341

Adapting Mark Miller's answer to solve a similar problem (I found this topic by looking for the solution) and I found a variation of his solution in https://tolstoy.newcastle.edu.au/R/help/05/03/0342.html.
Basically if you want to reverse the X-axis values in the plot, instead of using ylim=rev(range(y)), you can use xlim=rev(c(-4,4)).

x <- seq(-4, 4, length = 10)
y <- exp(x) / (1 + exp(x))
par(mfrow=c(1,2))
plot(x, y, ylim=range(y), xlim=c(-4, 4))
plot(x, y, ylim=range(y), xlim=rev(c(-4, 4)))

plot1

And if you want to keep the x-axis values in the true order, you can use this:

par(mfrow=c(1,1))
plot(x, y, ylim=range(y), xlim=c(-4, 4), axes=FALSE)
par(new=TRUE)
plot(-100, -100, ylim=range(y), xlim=c(-4, 4), axes=FALSE, xlab="", ylab="", main="")
axis(1, at = seq(-4,4,by=1), labels = seq(-4,4,by=1), tick = TRUE)
axis(2, at = seq(0,1,by=.2), labels = paste(100*seq(0,1, by=.2)), tick = TRUE)

plot2

I'm posting this solution because I needed something very straightforward to solve my problem. And the solution for it needed the plot with the X-axis value in the correct order (and not reversed).

Upvotes: 3

Adam Quek
Adam Quek

Reputation: 7163

df <- data.frame(x=seq(0,1, length.out=50), y=seq(0, 1, length.out=50))
plot(df)

enter image description here

df$x1 <- (max(df$x) - df$x)/ (max(df$x) - min(df$x))
plot(df$x1, df$y, axes=F, xlab = "Specificity (%)", ylab = "Sensitivity (%)")
axis(2, at = seq(0,1,by=.2), labels = paste(100*seq(0,1, by=.2)), tick = TRUE)
axis(1, at = seq(0,1,by=.2), labels = paste(100*seq(1,0, by=-.2)), tick = TRUE)

enter image description here

Upvotes: 3

Mark Miller
Mark Miller

Reputation: 13123

I think this creates a plot in which the y-axis is in reverse order:

x <- seq(-4, 4, length = 10)
y <- exp(x) / (1 + exp(x))
plot(x,y, ylim = rev(range(y)))

This removes the axis values:

x <- seq(-4, 4, length = 10)
y <- exp(x) / (1 + exp(x))
plot(x,y, ylim = rev(range(y)), labels = FALSE)

I guess you can assign the axis values you want then with a variation of your lines:

axis(2, at = seq(0,1,by=.2), labels = paste(100*seq(0,1, by=.2)), tick = TRUE)
axis(1, at = seq(0,1,by=.2), labels = paste(100*seq(0,1, by=.2)), tick = TRUE)

Upvotes: 15

Related Questions