在一张图像中生成图形

时间:2019-06-04 03:55:09

标签: r plot graph

我正在R中制作大约18个图形,我希望它们在一张图像中呈现。我收到有关大小的错误消息。

过去,我曾使用par(mfrow = c(2,2))和这些简单的东西在一个渲染中生成多个图形。

因此,在执行操作时,我想生成六倍于三倍的渲染。因此,它看起来像六行三列。我认为使用par(mfrow = c(6,3))应该很简单。

在R中,当我尝试par(mfrow = c(6,3))时得到

  

“ plot.new()中的错误:图形边距太大”。

我试图通过使用3乘3而不是6乘3来解决此问题。这将得到我想要的一半,但是我可以通过MSpaint将它们组合在一起。有点麻烦,但是它可以完成最后6次3的工作。是否有更简单的方法可以在R中完成?

2 个答案:

答案 0 :(得分:2)

对于在较旧的线程中讨论R中不同绘图机制的优点的做法,如果这样做是多余的,我深表歉意。但是,我认为值得为使用三种主要绘图机制的“简单”多面板绘图显示解决方案。 @thelatemail推荐使用latticeggplot2进行这些类型的绘图是正确的,也许这个答案说明了原因。

尽管,尽管基本R可能需要对par()进行最多的调整,并且需要熟悉library(help = "graphics")所提供的功能,但我还是倾向于使用基本R来生成出版物质量数据。在此Sean Anderson中,我找到了关于以PDF为底的R为基础的多面板绘图的精彩讨论。

首先,在单个data.frame中生成由18组20个x-y对组成的可重现数据(始终是个好主意),并带有适当的组标签和索引uid。这些图将显示x-y数据并添加一条平滑线。

  set.seed(1234)
  x <- seq(0, 9, length.out = 20)
  y <- replicate(6, (x-5) + rnorm(x))
  y <- c(y, replicate(6, 5*sin(x) + rnorm(x)))
  y <- c(y, replicate(6, 5*atanh((9-x)/10) + rnorm(x)))

  a <- gl(3, 120, labels = c("A","B","C")) # these factors are handy
  b <- gl(6, 20, length = 360)
  uid <- as.numeric(b:a)

  df <- data.frame(x, y, a, b, uid)
  rm(x, y, a, b, uid) # prevent use of variables outside of the data.frame

以我的经验,R Studio对绘图的要求更高(控制)。我不确定这段代码在R Studio下运行的如何。出现该警告后,将创建适当大小的绘图设备以启动。

  dev.new(width = 6.5, height = 6.5)

首先,使用par(mfrow = c(6, 3)和外部页边距参数(oma)的基本R解决方案。这也使非典型地使用legend()函数为每个面板添加标题。

  par(mfrow = c(6, 3), mar = c(0,0,0,0), oma = c(6, 6, 2, 2))
  ylim <- range(df$y) # to ensure uniformly sized plots
  ncol <- 3 # number of columns to the plot
  for(u in 1:18) {
    sel <- df$uid == u
    plot(y ~ x, df, subset = sel, ann = FALSE, axes = FALSE, ylim = ylim)
    box() # adds a "frame" or "box" around each plot
    xy <- loess.smooth(df$x[sel], df$y[sel], span = 1/3)
    lines(xy)
    if ((u - 1)%%ncol == 0) axis(2, las = 1)
    if ((u - 1)%/%ncol == 5) axis(1)
    leg.text <- paste(unique(df$a[sel]), unique(df$b[sel]), sep = ":")
    legend("top", leg.text, bty = "n")
  }
  mtext("x", side = 1, outer = TRUE, line = 3)
  mtext("y", side = 2, outer = TRUE, line = 3)

base multipanel plot
ggplot2lattice都将返回可以进一步优化的对象。此处显示的是lattice精神的解决方案。

  library(lattice)
  o <- xyplot(y ~ x | b:a, df, as.table = TRUE, layout = c(3, 6))
  o <- update(o, type = c("p", "smooth"), span = 1/3)
  plot(o)

lattice multipanel plot
在绘制机制之间,语法和嵌入的美学原理也有所不同。这在基本的ggplot2解决方案中是显而易见的。

  library(ggplot2)
  g <- ggplot(df, aes(x, y)) + geom_point() + facet_wrap(b:a ~ ., ncol = 3)
  g <- g + geom_smooth()
  plot(g)

ggplot2 multipanel plot
使用哪种机制的选择是个人的。我提到我经常喜欢使用基本图形进行精细控制。为了准备将要显示在监视器上的图,ggplot2给出了一些对屏幕友好的图像,几乎不需要大惊小怪。对于反复地探索多维数据,我发现lattice是最有用的。这可以通过执行绘图代码(不加载库)所需的时间来说明。 system.time()的输出已捕获并显示在此处(从Windows i7机器)。

  rbind(base = time1, lattice = time2, ggplot = time3)[, 1:3]
>         user.self sys.self elapsed  
> base         0.05     0.03    0.10  
> lattice      0.23     0.03    0.28  
> ggplot       1.27     0.05    1.38  

答案 1 :(得分:0)

我建议使用ggplot2。这是tutorial

您可能需要使用grid.arrange()。我经常使用它,并且效果很好。我上面提供的链接详细介绍了其用法。