The updateusr method from Greg Snow's TeachingDemos package is a great solution for this problem. The idea behind updateusr is define new plot region according to the ratio of one unit in each axis.
The code:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
updateusr <- function(x1, y1=NULL, x2, y2=NULL) { | |
xy1 <- xy.coords(x1,y1) | |
xy2 <- if( missing(x2) && missing(y2) ) { | |
xy.coords(y1) | |
} else { | |
xy.coords(x2,y2) | |
} | |
cur.usr <- par('usr') | |
xslope <- diff(xy2$x)/diff(xy1$x) | |
yslope <- diff(xy2$y)/diff(xy1$y) | |
new.usr.x <- xslope * ( cur.usr[1:2] - xy1$x ) + xy2$x | |
new.usr.y <- yslope * ( cur.usr[3:4] - xy1$y ) + xy2$y | |
invisible(par(usr=c(new.usr.x, new.usr.y))) | |
} |
Example code:(add space 8/20)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
yy <- c(4,6,13,24,15,13,14,8,2,1) | |
n <- length(yy) | |
bar <- data.frame(Group=LETTERS[1:n], value=yy*1000, yield=yy+rnorm(n,50,10)) | |
ylim <- c(0,max(bar$value)) | |
space <- 0.3 | |
xlim <- c(0, floor((1+space)*n)+1) | |
plot(0, xaxs = "i", xlim = xlim, ylim = ylim, main = "Barplot with Line use par(new=TRUE)", xlab = "", ylab = "", type = "n", axes = FALSE) | |
r <- barplot(bar$value, axes=F, axisnames = FALSE, space = space, add = T) | |
axis(1, at = r, labels = LETTERS[1:n]) | |
axis(2, at = seq(0,ylim[2], 1000), las = 2) | |
#use par new | |
par(new = TRUE) | |
plot(x = r, y = bar$yield, axes = FALSE, xlim = xlim, ylim = c(0,110) ,xlab = "", ylab = "",type = "o") | |
abline(v=r, lty = 2, col = "red") | |
axis(4, at = seq(0, 110, 10)) | |
box() | |
plot(0, xaxs = "i", xlim = xlim, ylim = ylim, main = "Barplot with Line use updateusr", xlab = "", ylab = "", type = "n", axes = FALSE) | |
r <- barplot(bar$value, axes=F, axisnames = FALSE, space = space, add = T) | |
axis(1, at = r, labels = LETTERS[1:n]) | |
axis(2, at = seq(0,ylim[2], 1000), las = 2) | |
#By using updateusr | |
updateusr(r[1:2], ylim/100, r[1:2], 0:1) | |
lines(x = r, y = bar$yield, type = "o") | |
abline(v=r, lty = 2, col = "red") | |
axis(4, at = seq(0, 110, 10)) | |
box() |
Result: