Getting the number of rows and columns for the device
The n2mfrow()
was designed for this purpose, although it tends to vary rows faster than columns so is opposite of what you want. For example:
> n2mfrow(2)
[1] 2 1
indicates 2 rows by 1 column. Of course, rev()
makes it easy to get the output you want:
> rev(n2mfrow(3))
[1] 1 3
Here is output from n2mfrow()
for 2 to 16 total plots with columns varying faster:
t(sapply(2:16, function(x) rev(n2mfrow(x))))
> t(sapply(2:16, function(x) rev(n2mfrow(x))))
[,1] [,2]
[1,] 1 2
[2,] 1 3
[3,] 2 2
[4,] 2 3
[5,] 2 3
[6,] 3 3
[7,] 3 3
[8,] 3 3
[9,] 3 4
[10,] 3 4
[11,] 3 4
[12,] 4 4
[13,] 4 4
[14,] 4 4
[15,] 4 4
Making this interactive
For the "click after 16" bit. If doing your plotting in a for(i in numplots)
loop, when i
> 16 call devAskNewPage(ask = TRUE)
and that will prompt for user to active next plot.
For example:
np <- 18 ## number of plots
rc <- ifelse(np > 16, 16, np)
op <- par(mfrow = rev(n2mfrow(rc)))
for(i in seq_len(np)) {
if(i == 2) {
devAskNewPage(ask = TRUE)
}
plot(1:10)
}
par(op)
devAskNewPage(ask = FALSE)
A similar thing could be done using locator(1)
to force a click to move on post 16 plots, but it needs a bit more work:
np <- 18 ## number of plots
rc <- ifelse(np > 16, 16, np)
op <- par(mfrow = rev(n2mfrow(rc)))
for(i in seq_len(np)) {
if((i %% 16) + 1 == 2 && i > 1) {
message("Page filled. Click on device to continue...")
locator(1)
}
plot(1:10)
}
par(op)