我有一个与 par(mfrow=c(2,2))一起绘制的4个情节汇编。我想绘制一个共同的标题为上面的2个情节和一个共同的标题为下面的2个面板中心的2左和右情节。
par(mfrow=c(2,2))
这可能吗?
这个 应该可以工作,但是你需要调整一下 line的参数来得到正确的结果:
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
side = 3
line = -21
outer = TRUE
要在顶部添加另一个“ title”,可以使用(比如说) mtext("My 'Title' in a strange place", side = 3, line = -2, outer = TRUE)添加它
mtext("My 'Title' in a strange place", side = 3, line = -2, outer = TRUE)
可以使用函数 layout()并设置两个绘图区域,这两个区域出现在两列中(请参见 matrix()中的重复数字1和3)。然后我使用 plot.new()和 text()来设置标题。你可以利用边距和高度来获得更好的表示。
layout()
matrix()
plot.new()
text()
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(...)
title("My 'Title' in a strange place", line = -21, outer = TRUE)
下面是另一种方法,使用来自 这篇文章的 line2user函数。
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(2, 3)
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