R 在一页上放置多个对齐的绘图时,避免浪费空间

R 在一页上放置多个对齐的绘图时,避免浪费空间,r,plot,R,Plot,我想在一页上画四幅图。轴标签应仅在边缘打印,即仅底部图表的x轴标签和左侧图表的y轴标签。这既适用于轴的整体名称,也适用于单个记号标记。我可以使用以下代码生成这些内容: pdf(file = "ExampleOutput.pdf", width = 6.61, height = 6.61, pointsize = 10 ) set.seed(42) catA <- factor(c("m100", "m500", "m1000", "m2000", "m300

我想在一页上画四幅图。轴标签应仅在边缘打印,即仅底部图表的x轴标签和左侧图表的y轴标签。这既适用于轴的整体名称,也适用于单个记号标记。我可以使用以下代码生成这些内容:

pdf(file = "ExampleOutput.pdf",
    width = 6.61,
    height = 6.61,
    pointsize = 10
    )
set.seed(42)
catA <- factor(c("m100", "m500", "m1000", "m2000", "m3000", "m5000"))
catB <- factor(20:28)
samples <- 100
rsample <- function(v) v[ceiling(runif(samples, max=length(v)))]
Tab <- data.frame(catA = rsample(catA),
                  catB = rsample(catB),
                  valA = rnorm(samples, 150, 8),
                  valB = pmin(1,pmax(0,rnorm(samples, 0.5, 0.3))))
par(mfrow = c(2,2))
for (i in 0:3) {
  x <- Tab[[1 + i %% 2]]
  plot(x, Tab[[3 + i %/% 2]],
       xlab = if (i %/% 2 == 1) "Some Categories" else NULL,
       ylab = if (i %% 2 == 0) "Some Values" else NULL,
       axes = FALSE
       )
  axis(side = 1,
       at=1:nlevels(x),
       labels = if (i %/% 2 == 1) levels(x) else FALSE)
  axis(side = 2, labels = (i %% 2 == 0))
  box(which = "plot", bty = "l")
}
par(mfrow = c(1,1))
dev.off()
pdf(file=“ExampleOutput.pdf”,
宽度=6.61,
高度=6.61,
点大小=10
)
种子(42)

catA只需在
par
中操作您的参数即可。参数
mar
控制单个绘图的边距大小。将您的
par
更改为:

par(mfrow = c(2,2), mar=c(1, 4, 1, 1) + 0.1)#it goes c(bottom, left, top, right) 

您需要一个有条件的评估,为适合定位的
par('mar')
值赋值;下面是一个检查“x布局位置”的代码示例(在循环中):

pdf(file=“ExampleOutput2.pdf”,
宽度=6.61,
高度=6.61,
点大小=10
)
种子(42)

catA假设y轴和x轴标签适用于所有绘图,此处对您显示的常规绘图进行了轻微修改。它使用一个外部边距来包含轴标签,我们使用参数
outer=TRUE
将其添加到
title()
。这种效果有点像ggplot2晶格图中的标签

这里的关键是:

op <- par(mfrow = c(2,2),
          oma = c(5,4,0,0) + 0.1,
          mar = c(0,0,1,1) + 0.1)
整个脚本是:

set.seed(42)
catA <- factor(c("m100", "m500", "m1000", "m2000", "m3000", "m5000"))
catB <- factor(20:28)
samples <- 100
rsample <- function(v) v[ceiling(runif(samples, max=length(v)))]
Tab <- data.frame(catA = rsample(catA),
                  catB = rsample(catB),
                  valA = rnorm(samples, 150, 8),
                  valB = pmin(1,pmax(0,rnorm(samples, 0.5, 0.3))))
op <- par(mfrow = c(2,2),
          oma = c(5,4,0,0) + 0.1,
          mar = c(0,0,1,1) + 0.1)
for (i in 0:3) {
  x <- Tab[[1 + i %% 2]]
  plot(x, Tab[[3 + i %/% 2]], axes = FALSE)
  axis(side = 1,
       at=1:nlevels(x),
       labels = if (i %/% 2 == 1) levels(x) else FALSE)
  axis(side = 2, labels = (i %% 2 == 0))
  box(which = "plot", bty = "l")
}
title(xlab = "Some Categories",
      ylab = "Some Values",
      outer = TRUE, line = 3)
par(op)
set.seed(42)
catA我现在使用以下解决方案:

par(mfrow = c(2, 2),     # 2x2 layout
    oma = c(2, 2, 0, 0), # two rows of text at the outer left and bottom margin
    mar = c(1, 1, 0, 0), # space for one row of text at ticks and to separate plots
    mgp = c(2, 1, 0),    # axis label at 2 rows distance, tick labels at 1 row
    xpd = NA)            # allow content to protrude into outer margin (and beyond)
结果如下所示:


如您所见,这足以允许打印所有记号标签。如果不是,则根据,将小于1的值添加到参数列表中,将有助于减小字体大小。

这是非常好的,尽管它不能解决OP在左下方绘图的x轴上的标签问题。轴标签上较小的点大小可能会使这些点挤进去,但可能会留下非常小的标签。好吧,我的示例选得不好:两部分的轴标签需要不同。尽管如此,我们还是很高兴知道这种方法确实存在,并且这个例子确实为答案增加了价值。而
oma
mar
似乎在任何情况下都表明了一个有价值的方向。在这个答案的帮助下,我用
par(mfrow=c(2,2),oma=c(2,2,0,0),mar=c(1,1,0,0),mgp=c(2,1,0),xpd=NA)得到了它。在你的答案中也可以包含这一点,非常感谢@格伦布我错过了答案中的那一点;明智地使用
cex.axis
可以解决这个问题,使用
las
旋转标签并在底部外缘留出更多的空间。我尝试了这个方法,结果没有任何不同。是否每个绘图设置不适用于单个页面上多个绘图的定位?或者是否有其他原因可能会抑制这种影响?你真的能在我的代码中工作吗?它在你的代码中工作。但加文的答案看起来更好。很奇怪,这对你有效,但对我无效。如果我有更多的时间,我可能想进一步研究这一点,特别是因为您的解决方案对于其他布局可能更灵活(例如,3x3带有一些标记的内轴)。但我今天不会追查这个。仅供参考:我在R2.15.2上试过,并使用了代码中所示的pdf输出驱动程序。好的,我将发布在Mac 10.6.8上使用R2.15.2的完整代码
set.seed(42)
catA <- factor(c("m100", "m500", "m1000", "m2000", "m3000", "m5000"))
catB <- factor(20:28)
samples <- 100
rsample <- function(v) v[ceiling(runif(samples, max=length(v)))]
Tab <- data.frame(catA = rsample(catA),
                  catB = rsample(catB),
                  valA = rnorm(samples, 150, 8),
                  valB = pmin(1,pmax(0,rnorm(samples, 0.5, 0.3))))
op <- par(mfrow = c(2,2),
          oma = c(5,4,0,0) + 0.1,
          mar = c(0,0,1,1) + 0.1)
for (i in 0:3) {
  x <- Tab[[1 + i %% 2]]
  plot(x, Tab[[3 + i %/% 2]], axes = FALSE)
  axis(side = 1,
       at=1:nlevels(x),
       labels = if (i %/% 2 == 1) levels(x) else FALSE)
  axis(side = 2, labels = (i %% 2 == 0))
  box(which = "plot", bty = "l")
}
title(xlab = "Some Categories",
      ylab = "Some Values",
      outer = TRUE, line = 3)
par(op)
par(mfrow = c(2, 2),     # 2x2 layout
    oma = c(2, 2, 0, 0), # two rows of text at the outer left and bottom margin
    mar = c(1, 1, 0, 0), # space for one row of text at ticks and to separate plots
    mgp = c(2, 1, 0),    # axis label at 2 rows distance, tick labels at 1 row
    xpd = NA)            # allow content to protrude into outer margin (and beyond)