Frederik Vanrenterghem wrote on 12/13/2011 01:55:03 PM: > Hi, > > Being a novice to R, I would like to create a graph in R with 2 axes. > One of the 2 only has positive values, the other one also has negative > values. The part I'm struggling with is how to align the 2. > > Rather than starting to plot the data from the x axis, I would like to > start plotting the positive values on the right axis only as of the 0 > value on the left axis. > > Using a simple example found online, I understand how to get 2 axis on > a single drawing, but I'm unsure how to accomplish the alignment > objective. In the example, the 0 value of the right axis should align > with the 0 of the left axis, and the red line should start in the > middle of the graph only, rather than at the bottom of it. > > (This is an arbitrary example - the right axis could also start as of > value 1000, in which case I'd like 1000 to align with 0 of the left > axis.) > > Code: > > # set up some fake test data > time <- seq(0,72,12) > betagal.abs <- c(0.05,-0.18,0.25,0.31,0.32,0.34,0.35) > cell.density <- c(0,1000,2000,3000,4000,5000,6000) > > #add extra space to right margin of plot within frame > par(mar=c(5, 4, 4, 4) + 0.1) > > # Plot first set of data and draw its axis > plot(time, betagal.abs, pch=16, axes=F, ylim=c(-1,1), xlab="", > ylab="", type="b",col="black", main="Mike's test data") > axis(2, ylim=c(-1,1),col="black") > mtext("Beta Gal Absorbance",side=2,line=2.5) > box() > > # Allow a second plot on the same graph > par(new=T) > > # Plot the second plot and put axis scale on right > plot(time, cell.density, pch=15, xlab="", ylab="", ylim=c(0,7000), > axes=F, type="b", col="red") > mtext("Cell Density",side=4,col="red",line=2.5) > axis(4, ylim=c(0,7000), col="red",col.axis="red") > > # Draw the time axis > axis(1,pretty(range(time),10)) > mtext("Time (Hours)",side=1,col="black",line=2.5) > > # Add Legend > legend(5,7000,legend=c("Beta Gal","Cell > Density"),text.col=c("black","red"),pch=c(16,15),col=c("black","red")) > > Thanks in advance for any help you can provide! > > Best regards, > Frederik Vanrenterghem
Use a function to convert units between the two y axes, then, rather than adding a second plot to the graph, just add another line using the same coordinates that you set up originally. For example: # this function converts units between the two y axes # the inputs are two points on the y1 axis (y1a and y1b) # which should line up with two points on the y2 axis (y2a and y2b) # use to=1 to convert from y2 to y1 units, # use to=2 to convert from y1 to y2 units convert.y <- function(y1a, y1b, y2a, y2b, y, to=1) { slope <- (y1b - y1a) / (y2b - y2a) intercept <- y1a - slope * y2a if(to==1) intercept + slope * y else (y - intercept) / slope } # set up some fake test data time <- seq(0, 72, 12) betagal.abs <- c(0.05, -0.18, 0.25, 0.31, 0.32, 0.34, 0.35) cell.density <- (0:6)*1000 # plot the first line par(mar=c(5, 4, 4, 4) + 0.1) plot(time, betagal.abs, pch=16, axes=F, ylim=c(-1,1), type="b" xlab="Time (Hours)", ylab="Beta Gal Absorbance", main="Mike's test data") mtext("Cell Density", side=4, col="red", line=2.5) # add the second line dens.conv <- convert.y(y1a=0, y1b=1, y2a=min(cell.density), y2b=max(cell.density), cell.density, 1) points(time, dens.conv, pch=15, type="b", col="red") # add axes axis(1) axis(2) box() tick.labels <- pretty(cell.density) tick.locations <- convert.y(y1a=0, y1b=1, y2a=min(cell.density), y2b=max(cell.density), tick.labels, 1) axis(4, at=tick.locations, labels=tick.labels, col="red", col.axis="red") # add legend legend("topleft", legend=c("Beta Gal", "Cell Density"), text.col=c("black","red"), pch=c(16,15), col=c("black", "red")) Jean [[alternative HTML version deleted]] ______________________________________________ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.