I have a compilation of 4 plots drawn together with par(mfrow=c(2,2))
. I would like to draw a common title for the 2 above plots and a common title for the 2
This should work, but you'll need to play around with the line
argument to get it just right:
par(mfrow = c(2, 2))
plot(iris$Petal.Length, iris$Petal.Width)
plot(iris$Sepal.Length, iris$Petal.Width)
plot(iris$Sepal.Width, iris$Petal.Width)
plot(iris$Sepal.Length, iris$Petal.Width)
mtext("My 'Title' in a strange place", side = 3, line = -21, outer = TRUE)
mtext
stands for "margin text". side = 3
says to place it in the "top" margin. line = -21
says to offset the placement by 21 lines. outer = TRUE
says it's OK to use the outer-margin area.
To add another "title" at the top, you can add it using, say, mtext("My 'Title' in a strange place", side = 3, line = -2, outer = TRUE)
The same but in bold can be done using title(...)
with the same arguments as above:
title("My 'Title' in a strange place", line = -21, outer = TRUE)
Here's another way to do it, using the line2user
function from this post.
par(mfrow = c(2, 2))
plot(runif(100))
plot(runif(100))
text(line2user(line=mean(par('mar')[c(2, 4)]), side=2),
line2user(line=2, side=3), 'First title', xpd=NA, cex=2, font=2)
plot(runif(100))
plot(runif(100))
text(line2user(line=mean(par('mar')[c(2, 4)]), side=2),
line2user(line=2, side=3), 'Second title', xpd=NA, cex=2, font=2)
Here, the title is positioned 2 lines higher than the upper edge of the plot, as indicated by line2user(2, 3)
. We centre it by offsetting it with respect to the 2nd and 4th plots, by half of the combined width of the left and right margins, i.e. mean(par('mar')[c(2, 4)])
.
line2user
expresses an offset (number of lines) from an axis in user coordinates, and is defined as:
line2user <- function(line, side) {
lh <- par('cin')[2] * par('cex') * par('lheight')
x_off <- diff(grconvertX(0:1, 'inches', 'user'))
y_off <- diff(grconvertY(0:1, 'inches', 'user'))
switch(side,
`1` = par('usr')[3] - line * y_off * lh,
`2` = par('usr')[1] - line * x_off * lh,
`3` = par('usr')[4] + line * y_off * lh,
`4` = par('usr')[2] + line * x_off * lh,
stop("side must be 1, 2, 3, or 4", call.=FALSE))
}
You can use the function layout()
and set two plotting regions which occurs in both columns (see the repeating numbers 1 and 3 in the matrix()
). Then I used plot.new()
and text()
to set titles. You can play with margins and heights to get better representation.
x<-1:10
par(mar=c(2.5,2.5,1,1))
layout(matrix(c(1,2,3,4,1,5,3,6),ncol=2),heights=c(1,3,1,3))
plot.new()
text(0.5,0.5,"First title",cex=2,font=2)
plot(x)
plot.new()
text(0.5,0.5,"Second title",cex=2,font=2)
hist(x)
boxplot(x)
barplot(x)