Jeevan Rai

My thoughts, opinions and experiences

Two y-axes in R


Recently, I had to plot two axes in a single graph. Like always, I googled. Countless solutions but most of them were not what I was looking for. These worked. But I didn’t want a complicated solution. Finally, two sources worked for me. One was to plot two y-axes and another to add custom tick marks. However, I had to modify these codes to meet my needs. So, to spare you the search, I got the solutions here.

I got the datasets and codes to calculate the errors beforehand. So I am using those. Since I cannot share the dataset, I will try my best to simulate it as closely as I can.

library(Rmisc) # load package for summarySE function

######################### Simulating dataset first ########################### DF <- data.frame(nrow= 100, ncol = 3) # data frame to put our simulated data set.seed(c(1,2)) # to have same randomized datasets # Now we will simulate two datasets, for length and girth measurements of snakes DF[1:100,2] <- cbind(as.integer(c(rnorm(50, 150, 50),rnorm(50, 75, 25)))) # first 50 length come from snakes in undisturbed habitat and next 50 from disturbed DF[1:100,3] <- cbind(abs(as.integer(c(rnorm(50, 40, 25),rnorm(50, 25, 15 ))))) # first 50 come from snakes in undisturbed habitat and next 50 from disturbed # Naming the data.frame DF[1:50,1] <- "Undisturbed" # first 50 come from undisturbed habitats DF[51:100,1] <- "Disturbed"  # next 50 from disturbed habitats colnames(DF) <- c("Habitat",  "Length", "Girth") # Finding errors length <- summarySE(DF, measurevar="Length", groupvars=c("Habitat")) # Length categorized by habitat characteristics girth <- summarySE(DF, measurevar="Girth", groupvars = c("Habitat")) # Girth categorized by habitat characteristics

Now, we can begin the plotting process

Since I had factors in the x-axis, I was getting a line instead of points. To get around it, I merge all the variables in a data frame and created another column with numbers. Then I used this number to get point plots. I later found that I could have used plot.default too for this. I haven’t tried it yet though.

# Merge them all in a data.frame for ease

Master <- data.frame(ID= length[,1], length = length[,3], lt.se = length[,5], girth = girth[,3], girth.se = girth[,5], no = c(1,2))

We will plot the girth measurements of snakes first.

############## Here, we create a plot with two different y-axes ##############

# Set the margins for plot par(mar = c(5,5,2,5))                                                              # Plot the GIRTH with(Master, plot(Master$no, Master$girth, type = "p", col = 'black', xaxt ='n', xlim = c(0,3),pch = 19, cex = 1, ylim = c(0,60), ylab = "Girth (cm)", xlab = "Habitat of snake")) # Add error bars arrows(Master$no, Master$girth+Master$girth.se, Master$no, Master$girth-Master$girth.se, code = 3, angle = 90, length = 0.1)

Now we need to plot the second graph with length measurements later. However, we will not put x-axis or second y-axis yet.

# Next, we plot the second graph on top but with any axis labels
par(new = T)
# Plot the lengths
with(Master, plot(Master$no, Master$length, col = 'red', 
        pch = 19, cex = 1,ylim = c(0,200), axes=F, 
        xlab=NA, ylab=NA, xlim = c(0,3)))

# Add error bars                             
arrows(Master$no, Master$length+Master$lt.se,Master$no,
        Master$length-Master$lt.se, code = 3, angle = 90,      
        length = 0.1, col = "red")

This is when we put the second y-axis.

# Add second y-axis

axis(side = 4, col ="red", col.ticks = "red", col.axis = "red") mtext(side = 4, line = 3, 'Length (cm)', col= "red") Add a legend now. # Add legend legend("topleft", legend=c("Girth", "Length"), bty ="n",         pch=c(16, 16), col=c("black", "red"))

And finally labels for x-axis.

# Finally, to get labels in x-axis

xtick <- seq(1:2) axis(side=1, at=xtick, labels = FALSE) text(x=xtick,  par("usr")[3], labels = Master$ID, srt = 0, pos = 1, xpd = TRUE)

Codes in github can be found in this link

https://github.com/Ljeevan9211/Data-Management-and-Analysis/blob/master/Two%20y-axes%20in%20R


Leave a Reply

Your email address will not be published. Required fields are marked *