This is actually fairly difficult/hackish, because scatterplot()
internally uses layout
, which makes it hard to control the subplot currently being used by the graphics driver. (Update: it's harder than I thought -- setting par("mfg")
must have been working more or less by accident.)
Make up data (update: using data with mean x and y not equal zero and not equal to each other, as it illustrate the difficulties of naively using abline()
more clearly)
set.seed(1)
d <- data.frame(x=rnorm(10,mean=10),y=rnorm(10,mean=12))
library(car)
Try my old strategy (which doesn't actually work, or works only unpredictably):
scatterplot(y~x,data=d,reset.par=FALSE)
k <- 1
for (i in 1:2) {
for (j in 1:2) {
par(mfg=c(i,j,2,2))
abline(0,1,lwd=3,col=k)
k <- k+1
}
}
Depending on how I do this, I either get warnings and errors or bogus answers. It seems to matter whether I do the scatterplot()
call inside a function ... ??
Second try, more conservatively: reconstruct layout from scratch.
scatterplot(y~x,data=d)
uu <- par("usr")
## mimic layout frolm car:::scatterplot.default. Would be different if we were drawing only one
## of x-boxes or y-boxes
layout(matrix(c(1, 0, 3, 2), 2, 2), widths = c(5, 95),
heights = c(95, 5))
oldmar <- par(mar=rep(0,4)) ## zero out margins so we can plot in sub-boxes without errors
## now skip through the first two sub-plots
par(new=TRUE); plot.new(); par(new=TRUE); plot.new()
par(oldmar) ## reset margins
## blank plot with user limits set and 'interior' axis calculations
plot(0:1,0:1,xlab="",ylab="",xlim=uu[1:2],ylim=uu[3:4],xaxs="i",yaxs="i")
## add annotation
abline(a=0,b=1,col=4,lwd=3)
Given the amount of effort and fragility of this solution, it might actually be best to hack scatterplot
to optionally allow abline()
to be specified additionally, or to ask the maintainer for that capability ...