# How to Add an Extra Vertical Axis to R Plots

##### Posted on December 28th, 2012

Especially when analyzing time series, we often need plots with two vertical axes. Researchers often expect the two series to "move together," but with different locations and scales. To show that the series move together, you should give each series its own scale. One vertical scale should appear on the left side of the plot and the other on the right. In this post, I'll show you how to add the extra vertical axis on the right side of the plot.

## Generating Sample Data

Let's start by quickly generating two fake time series. This can be done with the code below.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
set.seed(3571) n <- 100 a1 <- rnorm(n) a2 <- rnorm(n) x <- NULL y <- NULL x[1] <- a1[1] y[1] <- a2[1] for (t in 2:n) { x[t] <- -.2*x[t-1] + .5*y[t-1] + a1[t] y[t] <- y[t-1] + a2[t] } |

The Problem

Now let's plot the data in the "standard way": plot one series using the high-level plot() function and then add the other series using the low-level lines() function.

1 2 |
plot(ts(x)) lines(ts(y), col = "red") |

This code gives the plot below.

You can see one big problem--the second series goes off the scale! (We could fix this particular problem by plotting the series in the opposite order, but that does not work in general.)

A second problem is that the scales of the series are different. Both series are heading to infinity, but the x series is going there more slowly. The x series also has less variability than the y series. Both of these differences suggest we plot the series on different vertical scales. Indeed, our hypothesis usually suggests that the series should "move together," not that particular values of x should correspond to the same values of y.

## The Solution

You can easily add a separate vertical scale using the par(new=TRUE) command between two calls to the high-level plot() function. The code below does just this.

1 2 3 |
plot(ts(x)) par(new = T) plot(ts(y), col = "red") |

This code produces the figure below.

We can see from this plot that the two series indeed move together. Also notice two details of this plot. First, the vertical axes (one is plotted over the other on the left side) have different scales. Second, the horizontal axes are on the same scale (you can tell because R is plotting the exact same axis twice, making the axis fuzzy).

Now we just need to clean up the plot a little, moving one axis to the right side of the figure, plotting the horizontal axis only once, and cleaning up the labeling a little. Note that R defaults for axes and axis notation are not the best, but I deal with that in a separate post. For this exercise, I use the R defaults when they make sense, even if they are not the most aesthetically pleasing.

I make the following changes.

- Adjust the mar option in the graphical parameters to give me a little more room for constructing the vertical axis on the right side.
- Add the xlab="x" argument to the first plot() function call. This improves the label of the vertical axis on the left.
- Add the axes = F, xlab = NA, and ylab = NA arguments to the second plot() function call. This removes all the axes and axis notation from this call.
- Add the vertical axis on the right with a simple call to the axis() function and setting side = 4.
- Add a label to the vertical axis on the right with the mtext() command. Use the options side = 4 and line = 3 to position the text "y" correctly.

The new code is given below.

1 2 3 4 5 6 |
par(mar = c(5,5,2,5)) plot(ts(x), ylab = "x") par(new = T) plot(ts(y), col = "red", axes = F, xlab = NA, ylab = NA) axis(side = 4) mtext(side = 4, line = 3, "y") |

This code produces the following plot, which could be cleaned up a lot, but has the basic feature we're looking for: a separate vertical axis for each series.

## Summary

In this post, I've shown how to add a separate vertical axis for each series in a plot. This can be accomplished by setting the parameter new="TRUE" after plotting the first series. I've focused on solving the main problem at the expense of nicer axes and axis notation. I've written more about how to improve on R's axis defaults here and here.