A quick trick to get one of "topleft"
, "topright"
, "bottomleft"
and "bottomright"
:
auto.legend.pos <- function(x,y,xlim=range(x),ylim=range(y)) {
countIt <- function(a,zero.only=TRUE) {
tl <- sum(x <= xlim[1]*(1-a)+xlim[2]*a & y >= ylim[1]*a+ylim[2]*(1-a))
tr <- sum(x >= xlim[1]*a+xlim[2]*(1-a) & y >= ylim[1]*a+ylim[2]*(1-a))
bl <- sum(x <= xlim[1]*(1-a)+xlim[2]*a & y <= ylim[1]*(1-a)+ylim[2]*a)
br <- sum(x >= xlim[1]*a+xlim[2]*(1-a) & y <= ylim[1]*(1-a)+ylim[2]*a)
c(topleft=tl,topright=tr,bottomleft=bl,bottomright=br)
}
for (k in seq(0.5,0.1,by=-0.05)) {
a <- countIt(k)
if (sum(a==0)>0) break
}
names(a)[which(a==0)][1]
}
Test:
plot(Sepal.Length~Petal.Length, data=iris)
auto.legend.pos(iris$Petal.Length, iris$Sepal.Length)
# [1] "topleft"
EDIT
par("usr")
after plot
returns the extremes of the user coordinates of the plotting regions: see ?par
. So we can change the function to:
auto.legend.pos <- function(x,y,xlim=NULL,ylim=NULL) {
if (dev.cur() > 1) {
p <- par('usr')
if (is.null(xlim)) xlim <- p[1:2]
if (is.null(ylim)) ylim <- p[3:4]
} else {
if (is.null(xlim)) xlim <- range(x, na.rm = TRUE)
if (is.null(ylim)) ylim <- range(y, na.rm = TRUE)
}
countIt <- function(a) {
tl <- sum(x <= xlim[1]*(1-a)+xlim[2]*a & y >= ylim[1]*a+ylim[2]*(1-a))
tr <- sum(x >= xlim[1]*a+xlim[2]*(1-a) & y >= ylim[1]*a+ylim[2]*(1-a))
bl <- sum(x <= xlim[1]*(1-a)+xlim[2]*a & y <= ylim[1]*(1-a)+ylim[2]*a)
br <- sum(x >= xlim[1]*a+xlim[2]*(1-a) & y <= ylim[1]*(1-a)+ylim[2]*a)
c(topleft=tl,topright=tr,bottomleft=bl,bottomright=br)
}
for (k in seq(0.5,0.1,by=-0.05)) {
a <- countIt(k)
if (sum(a==0)>0) break
}
names(a)[which(a==0)][1] # may delete "[1]"
}
plot(Sepal.Length~Petal.Length, data=iris, xlim=c(1,5), ylim=c(3.5,6))
auto.legend.pos(iris$Petal.Length, iris$Sepal.Length)
# [1] "bottomright"