Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to invert the y-axis on a plot

Tags:

plot

r

I would like to know how to make a plot in R where the y-axis is inverted such that the plotted data appears in what would be the fourth quadrant (IV) of a cartesian plane, as opposed to the first (I) quadrant.

For reference, the plot I am trying to make looks very similar to the following (source):

a plot with inverted y-axis

I have found a number of questions online pertaining to reversing the numbering on the y-axis, but these all still plot the data in the first quadrant. Can anyone suggest how I might produce a plot similar to that shown above?

like image 955
Bryce Thomas Avatar asked Apr 28 '12 04:04

Bryce Thomas


People also ask

How do you invert the Y axis?

Flipping axis using the Format Axis dialog To do this, we have to right click the y axis that we want to reverse. Then, select the Format Axis from the context menu. The next thing to do is to check the Categories in reverse order. This is found in the Format Axis dialog, in the Axis Options.

How do you invert a graph in Python?

By using ylim() method ylim() method is also used to invert axes of a plot in Matplotlib. Generally, this method is used to set limits for the axes.

How do you reverse axis in Seaborn?

The value of Y-axis in a seaborn heatmap is reversed when home icon or H button is pushed.

Which function is used to specify the starting and ending points for Y axis in Python?

Use xticks and yticks method to specify the ticks on the axes with x and y ticks data points respectively.


2 Answers

Just to provide a worked out answer, following the comments of @timriffe and @joran...

Use the function for minor log ticks from this answer:

minor.ticks.axis <- function(ax,n,t.ratio=0.5,mn,mx,...){

  lims <- par("usr")
  if(ax %in%c(1,3)) lims <- lims[1:2] else lims[3:4]

  major.ticks <- pretty(lims,n=5)
  if(missing(mn)) mn <- min(major.ticks)
  if(missing(mx)) mx <- max(major.ticks)

  major.ticks <- major.ticks[major.ticks >= mn & major.ticks <= mx]

  labels <- sapply(major.ticks,function(i)
    as.expression(bquote(10^ .(i)))
                   )
  axis(ax,at=major.ticks,labels=labels,...)

  n <- n+2
  minors <- log10(pretty(10^major.ticks[1:2],n))-major.ticks[1]
  minors <- minors[-c(1,n)]

  minor.ticks = c(outer(minors,major.ticks,`+`))
  minor.ticks <- minor.ticks[minor.ticks > mn & minor.ticks < mx]


  axis(ax,at=minor.ticks,tcl=par("tcl")*t.ratio,labels=FALSE)

}

Make some reproducible example data:

x <- 1:8
y <- 10^(sort(runif(8, 1, 10), decreasing = TRUE))

Plot without axes:

plot(x, log10(y), # function to plot
xlab="",          # suppress x labels
type = 'l',       # specify line graph
xlim = c(min(x), (max(x)*1.3)),  # extend axis limits to give space for text annotation
ylim = c(0, max(log10(y))),      # ditto
axes = FALSE)    # suppress both axes

Add fancy log axis and turn tick labels right way up (thanks @joran!):

minor.ticks.axis(2, 9, mn=0, mx=10, las=1)

Add x-axis up the top:

axis(3)

Add x-axis label (thanks for the tip, @WojciechSobala)

mtext("x", side = 3, line = 2)

And add an annotation to the end of the line

text(max(x), min(log10(y)), "Example", pos = 1)

Here's the result:

enter image description here

like image 116
Ben Avatar answered Sep 25 '22 23:09

Ben


Answering the question in the title, the best/easiest way to invert the axis is to flip the limit variables around:

> plot(1:10, xlim=c(1,10));

standard plot

> plot(1:10, xlim=c(10,1));

plot with inverted X axis

> plot(1:10, ylim=c(10,1));

plot with inverted Y axis

Doing it this way means that you don't need to mess around with axes that are different from the image coordinates.

This can be combined with the 'xaxt="n"' parameter and an additional axis command to place an axis on another side:

> plot(1:10, ylim=c(10,1), xaxt="n"); axis(3);

Inverted graph with X axis on top

like image 29
gringer Avatar answered Sep 25 '22 23:09

gringer