首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在一个图像中生成图形

在一个图像中生成图形
EN

Stack Overflow用户
提问于 2019-06-04 11:55:09
回答 2查看 79关注 0票数 0

我在R中制作了大约18个图形,我想让它们在一个图像中渲染。我收到一条关于大小的错误消息。

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

因此,在我所做的工作中,我希望生成一个6乘以3的渲染。因此,它看起来像六行三列。我认为这应该很简单,通过使用par(mfrow = c(6,3))

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

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

我试着用3乘3而不是6乘3来解决这个问题,这会得到我想要的一半,但是我可以通过MSpaint将它们组合在一起。有点麻烦,但是生成最后的6乘以3就足够了。有没有一种更简单的方法,让它在R中完成?

EN

回答 2

Stack Overflow用户

发布于 2019-06-10 02:54:47

我很抱歉,如果讨论R中不同绘图机制的优点的旧线程是多余的,那么,我认为可能值得展示具有三种主要绘图机制的“简单”多面板绘图的解决方案。@thelatemail关于将latticeggplot2用于这些类型的绘图的建议是正确的,也许这个答案说明了为什么。

尽管基数R可能需要对par()进行最多的调整,并且需要熟悉library(help = "graphics")的功能,但我倾向于使用基数R来生成出版物质量数字。在这篇PDF中,我发现了一篇关于Sean Anderson使用base R进行多面板绘图的精彩讨论。

首先,在一个data.frame中生成一些可复制的数据(always a good idea),该数据由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)

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)

在不同的标绘机制中,语法和嵌入的美学原则是不同的。这在基本的ggplot2解决方案中是显而易见的。

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

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

  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  
票数 2
EN

Stack Overflow用户

发布于 2019-06-04 12:13:47

我推荐使用ggplot2。这是一个tutorial

您可能会想要使用grid.arrange()。我经常使用它,它工作得很好。我在上面提供的链接详细介绍了它的用法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56437142

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档