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

