# Draw Plot with Two Y-Axes in R (Example)

In this R programming tutorial you’ll learn how to create a plot with two y-axes in Base R.

Here’s how to do it:

## Creation of Example Data

First, we need to create some example data for the plot of this example:

```set.seed(25852)                             # Create example data
x <- rnorm(30)
y1 <- x + rnorm(30)
y2 <- x + rnorm(30, 5)```

Our example data consists of three numeric vectors: x, y1, and y2.

Now, let’s plot these data!

## Example: Create Plot with 2 Axes in R

If we want to draw a plot with two different y-axes, we can use the following R code:

```par(mar = c(5, 4, 4, 4) + 0.3)              # Additional space for second y-axis
plot(x, y1, pch = 16, col = 2)              # Create first plot
par(new = TRUE)                             # Add new plot
plot(x, y2, pch = 17, col = 3,              # Create second plot without axes
axes = FALSE, xlab = "", ylab = "")
axis(side = 4, at = pretty(range(y2)))      # Add second axis
mtext("y2", side = 4, line = 3)             # Add second axis label``` Figure 1: Plot with 2 Y-Axes in R.

Figure 1 is illustrating the output of the previous R syntax. As you can see, we created a scatterplot with two different colors and different y-axis values on the left and right side of the plot.

How did we do that? Let’s deconstruct the code:

1. par(mar = c(5, 4, 4, 4) + 0.3) – This code defines how much white space should be shown around the plot. It is important to leave enough space for the second y-axis.
2. plot(x, y1, pch = 16, col = 2) – This code creates the first plot (i.e. the red dots).
3. par(new = TRUE) – This code specifies that we want to overlay a second plot.
4. plot(x, y2, pch = 17, col = 3, axes = FALSE, xlab = “”, ylab = “”) – This code draws the second plot (i.e. the green triangles).
5. axis(side = 4, at = pretty(range(y2))) – This code adds the axis labels on the right side.
6. mtext(“y2”, side = 4, line = 3) – This code adds the name of the second y-axis (i.e. y2).

Note that this code is adapted from this thread on Stack Overflow. Have a look at this thread for more examples of the plotting of multiple axes.

Also note that we used a scatterplot for this example. However, you may add a secondary axis to many different types of graphics such as boxplots, line charts, histograms, density plots, and so on…

## Video, Further Resources & Summary

I have recently released a video on my YouTube channel, which explains the R programming code of this tutorial. You can find the video below:

Please accept YouTube cookies to play this video. By accepting you will be accessing content from YouTube, a service provided by an external third party. If you accept this notice, your choice will be saved and the page will refresh.

Furthermore, you might want to have a look at the related tutorials on my homepage:

In summary: This article explained how to add dual axes to a plot in the R programming language. Don’t hesitate to let me know in the comments, in case you have further comments or questions.

Subscribe to the Statistics Globe Newsletter

• Morgan
June 12, 2021 6:02 pm

Great code! Thank you! I am having trouble trying to add a legend to this plot since there are two separate plots layered on one another. Would you be able to show how to add a legend to this plot structure?

• June 14, 2021 6:40 am

Hey Morgan,

Thank you for the nice comment!

You would have to add the legend at the very end of the code. For example, try to add the following code at the end:

```legend("topleft",
legend = c("A", "B"),
col = 2:3,
pch = 16:17)```

Regards

Joachim

• Maria Alejandra Munoz torres
September 16, 2021 8:01 am

Hi, nice code, How I can add space to not superpose the dot. Thanks

• September 16, 2021 11:15 am

Hey Maria,

You may decrease the size of the points and triangles using the cex argument. For instance:

`plot(x, y1, pch = 16, col = 2, cex = 0.5)`

Regards

Joachim

• Maria Alejandra Munoz torres
September 16, 2021 5:37 pm

I couldnt solve adding cex = 0.5 because I am doing a boxplot graph, this is my code:

par(mar = c(5, 4, 4, 4) + 0.5)
boxplot (MOR~ sample1, my_data, pch = 16, col = 2, cex=0.5)
par(new = TRUE)
boxplot(density~sample1, my_data, axes= FALSE, xlab = “”, ylab = “”)
axis(side = 4, line=0, at = pretty(range(density))) # Add second axis
mtext(“density”, side = 4, line = 3)

• September 17, 2021 5:24 am

Ah, I see. In case of boxplots you would have to use the boxwex argument (e.g. boxwex = 0.5) instead of cex to change the width of the boxes.

Another (likely even better) alternative might be the at argument as explained in Example 8 of this tutorial: https://statisticsglobe.com/boxplot-in-r

Regards

Joachim

• Luis Aviles
October 29, 2021 2:50 am

Hello, I really like your posts!
Is this a way to do this with ggplot?
L.

• October 29, 2021 5:41 am

Hey Luis,

Thank you for the kind words!

As far as I know, the ggplot2 package restricts the usage of two y-axes. One way to draw two y-axes in a ggplot2 plot is shown here: https://statisticsglobe.com/draw-ggplot2-plot-with-two-y-axes-in-r The resulting plot is not the same as the plot shown in this tutorial though.

Regards,
Joachim

• Edwin
November 1, 2021 4:12 pm

Hi Joachim,

I am wondering whether is it possible to fit a linear regression with predicted output (yi) and real output (yhati) into this code?

• Ben
December 8, 2021 12:29 am

Hi I was wondering if it is possible to put factors on the x-axis? So instead of -1.5, -1.0 etc, what function would you use to put for example “Day 1, Day 2” etc.

• Meg
May 24, 2022 7:21 pm

Hello! I am wondering if it is possible to change the ticks on the second y-axis? For example, I would like a range of 1690 to 1700 with ticks spaced apart 1 digit. (1690, 1691, 1692, etc)

• May 25, 2022 5:50 am

Hi Meg,

You can do that by specifying the at argument within the axis function accordingly. In this example, I have used the pretty function to specify the axis values. However, you can assign basically any value you want to the at argument.

You may also have a look here for more details on the axis function.

Regards,
Joachim

• Trine Bak
June 17, 2022 8:12 am

Hey
I’m having some problems with adding the right axis. I can add the text “BALF” but the values at the axis dosen’t show.
This is my code:

par(mar=c(4,4,4,4))
boxplot(BALFogELF\$ELF~BALFogELF\$Study,pch=16,col=2)
par(new=TRUE)
boxplot(BALFogELF\$ï..BALF~BALFogELF\$Study,pch=17,col=3,axes=TRUE,xlab=””,ylab=””)
axis(side=4,at=pretty(range(BALFogELF\$ï..BALF)))
mtext(“BALF”,side=4,line=3)

I hope you can help 🙂

• June 20, 2022 7:31 am

Hey Trine,

Could you illustrate the structure of the column BALFogELF\$ï..BALF? What is returned when you print this column to the console?

Regards,
Joachim

• Fausto
September 13, 2022 8:50 pm

Thanks for the cool code! Is there any chance to change number facing to the graph? I mean a 180o rotation both numbers and axys name

• September 19, 2022 11:14 am

Hi Fausto,

Thank you for the kind words, glad you like the code!

I just returned from holidays, so unfortunately, I couldn’t respond to your question earlier. Are you still looking for help?

Regards,
Joachim

• Emily Deanna Palmer
January 9, 2023 11:22 am

Hi, thank you for the code. Would you be able to tell me how I would be able to add lines of best fit to the data sets?

• January 9, 2023 1:59 pm

Hello Emily,

You can check out our tutorial: Scatterplot in R .

Regards,
Cansu

• Thirza
January 26, 2023 2:36 pm

Thanks for this code. However, I would like to make a graph with temperature on one y-axis and yield on the other. How could I do this?

• January 26, 2023 3:00 pm

Hello Thirza,

Where do you have difficulties in adapting the code in the tutorial?

Regards,
Cansu

• Lucie
February 20, 2023 6:51 pm

Hi, really helpful video, thankyou! After plotting the second ‘graph’ with the second y-axis, how do you add a lowess line to this second graph?

• February 21, 2023 10:30 am

Hello Lucie,

You can check the page on the RGraph Gallery for the respective plotting.

Regards,
Cansu

• Lucie
February 21, 2023 11:16 am

Hi, I’m not sure this is helpful because it is using a different package. It doesn’t show how to add a lowess line to the second graph as is in this tutorial

• February 21, 2023 11:28 am

Hey,

Have you checked the third and fourth sections on the page? I thought you wanted to do that, but maybe I got you wrong. What do you want different than the given examples? I think using ggplot2 is even more preferable when it comes to a wide range of graphical applications. I recommend it.

Regards,
Cansu

• Jaya
June 14, 2023 4:47 am

Sir,
With this data, could we make a regression line for each y1 and y2?

Regards,
Jaya

• June 14, 2023 6:24 am

Hello Jaya,

Check out the following code.

```# Create some sample data
set.seed(123)
x <- 1:100
y1 <- rnorm(100, 5*x, sd=3)
y2 <- rnorm(100, -1*x, sd=5)

# Fit the regression models
fit1 <- lm(y1 ~ x)
fit2 <- lm(y2 ~ x )

# Create the two y-axis plot
par(mar = c(5, 4, 4, 4) + 0.3)  # Leave space for the second y-axis

# Plot the first set of data and add the regression line
plot(x, y1, type = "p", pch = 20, col = "blue", ylab = "y1 values", xlab = "x values")
abline(fit1, col = "blue")

par(new = TRUE)
plot(x, y2, type = "p", pch = 20, col = "red", axes = FALSE, ylab = "", xlab = "")
axis(side = 4)  # Add the second y-axis
mtext("y2 values", side = 4, line = 3)  # Label the second y-axis

# Add the regression line for the second set of data
abline(fit2, col = "red") 