I'm trying to tile plots, specifically in a 2x3 matrix, for example:
x <- seq(1, 10, by=.01)
y <- 1/x
prms<-
list(xlab=rep(c("", "x"), each=3),
ylab=rep(c("y", "", ""), 2),
xaxt=rep(c("n", "s"), each=3),
yaxt=rep(c("s", "n", "n"), 2),
mar=list(c(0 , 4.1, 4.1, 0),
c(0 , 0, 4.1, 0),
c(0 , 0, 4.1, 1.1),
c(5.1, 4.1, 0, 0),
c(5.1, 0, 0, 0),
c(5.1, 0, 0, 1.1)))
par(mfrow=c(2, 3))
for (ii in 1:6){
par(mar=prms$mar[[ii]])
plot(x, y, type="l", lwd=2,
xlab=prms$xlab[ii], ylab=prms$lab[ii],
xaxt=prms$xaxt[ii], yaxt=prms$yaxt[ii])
}
Which produces:
I've suppressed the "inner" margins and axes because all x
(resp., y
) units are the same, so such axes would be redundant. However, as you can see, by squeezing the margins on the left- and rightmost plots, I've accidentally given the middle plots too much space (it's not as apparent, but the same trouble plagues the top vis-a-vis the bottom row).
Therein lies the conundrum. mfrow
assigns equal space to each subplot (i.e., axes, margins, etc), not to each plot area. How can I change my approach so that each plotting area is of equal size, ceteris paribus (i.e., axes, etc. unchanged)? I thought of using layout
, but couldn't think of a nice programmatic way to go about making sure everything has equal representation.
You may set mar
to 0, and use oma
to give the size of the outer margins. Axes are added to relevant plots in a loop. Common x and y axis labels are added with mtext
and outer = TRUE
par(mfrow = c(2, 3),
mar = c(0, 0, 0, 0),
oma = c(4, 4, 0.5, 0.5))
for (i in 1:6) {
plot(x, y, type = "l", axes = FALSE)
if (i %in% c(4, 5, 6))
axis(side = 1)
if (i %in% c(1, 4))
axis(side = 2)
box()
}
mtext("x values", side = 1, outer = TRUE, line = 2.5)
mtext("y values", side = 2, outer = TRUE, line = 2.5)
See also How to create multiple plots, each with same plot area size, when only one plot has axis labels?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With