我有 4 个用par(mfrow=c(2,2))
. 我想为上面的 2 个图绘制一个通用标题,并为位于左右 2 个图之间的 2 个下面的面板绘制一个通用标题。
这可能吗?
这应该可行,但是您需要使用该line
参数才能使其正确:
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
代表“边距文本”。side = 3
说把它放在“顶部”边缘。line = -21
表示将位置偏移 21 行。outer = TRUE
表示可以使用外边距区域。
要在顶部添加另一个“标题”,您可以使用,例如,mtext("My 'Title' in a strange place", side = 3, line = -2, outer = TRUE)
您可以使用该函数layout()
并设置出现在两列中的两个绘图区域(请参阅 中的重复数字 1 和 3 matrix()
)。然后我用plot.new()
andtext()
来设置标题。您可以使用边距和高度来获得更好的表示。
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)
title(...)
可以使用与上述相同的参数来完成相同但粗体的操作:
title("My 'Title' in a strange place", line = -21, outer = TRUE)
这是另一种方法,使用这篇文章line2user
中的函数。
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)
在这里,标题的位置比绘图的上边缘高 2 行,如 所示line2user(2, 3)
。我们通过将它相对于第 2 和第 4 个图偏移,以左右边距的组合宽度的一半,即mean(par('mar')[c(2, 4)])
.
line2user
表示从用户坐标轴的偏移量(行数),定义为:
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))
}
感谢@DidzisElferts 的回答,我刚刚在这里找到了一个很棒的文档
只需尝试以下代码。我帮助我了解了发生了什么:
def.par <- par(no.readonly = TRUE) # save default, for resetting...
## divide the device into two rows and two columns
## allocate figure 1 all of row 1
## allocate figure 2 the intersection of column 2 and row 2
layout(matrix(c(1,1,0,2), 2, 2, byrow = TRUE))
## show the regions that have been allocated to each plot
layout.show(2)
## divide device into two rows and two columns
## allocate figure 1 and figure 2 as above
## respect relations between widths and heights
nf <- layout(matrix(c(1,1,0,2), 2, 2, byrow = TRUE), respect = TRUE)
layout.show(nf)
## create single figure which is 5cm square
nf <- layout(matrix(1), widths = lcm(5), heights = lcm(5))
layout.show(nf)
##-- Create a scatterplot with marginal histograms -----
x <- pmin(3, pmax(-3, stats::rnorm(50)))
y <- pmin(3, pmax(-3, stats::rnorm(50)))
xhist <- hist(x, breaks = seq(-3,3,0.5), plot = FALSE)
yhist <- hist(y, breaks = seq(-3,3,0.5), plot = FALSE)
top <- max(c(xhist$counts, yhist$counts))
xrange <- c(-3, 3)
yrange <- c(-3, 3)
nf <- layout(matrix(c(2,0,1,3),2,2,byrow = TRUE), c(3,1), c(1,3), TRUE)
layout.show(nf)
par(mar = c(3,3,1,1))
plot(x, y, xlim = xrange, ylim = yrange, xlab = "", ylab = "")
par(mar = c(0,3,1,1))
barplot(xhist$counts, axes = FALSE, ylim = c(0, top), space = 0)
par(mar = c(3,0,1,1))
barplot(yhist$counts, axes = FALSE, xlim = c(0, top), space = 0, horiz = TRUE)
par(def.par) #- reset to default