【问题标题】:multiple graphs in one canvas using ggplot2使用 ggplot2 在一个画布中绘制多个图形
【发布时间】:2011-07-10 18:05:24
【问题描述】:

我正在尝试根据此表将两个 ggplot2 图合并为一个:

   Type    RatingA  RatingB
1  One     3        36
2  Two     5        53
3  One     5        57
4  One     7        74
5  Three   4        38
6  Three   8        83

我想制作两个散点图,y 轴为评分的平均值,x 轴为输入。

这是我创建每个图表的方式:

p1 <- ggplot(test, aes(x=reorder(Type, RatingA, mean), y=RatingA)) +
        stat_summary(fun.y="mean", geom="point")

p2 <- ggplot(test, aes(x=reorder(Type, RatingB, mean), y=RatingB)) + 
        stat_summary(fun.y="mean", geom="point")

由于 p1 和 p2 具有相同的 x 轴,我希望它们垂直排列。我查看了 facet_align,但找不到可以完成这项工作的东西。

【问题讨论】:

标签: r ggplot2


【解决方案1】:

这是一个老问题,但我最近发现了multiplot 函数,可以很好地完成他的工作。

multiplot 函数来自Cookbook for R:

它自己的功能是:

# Multiple plot function
#
# ggplot objects can be passed in ..., or to plotlist (as a list of ggplot objects)
# - cols:   Number of columns in layout
# - layout: A matrix specifying the layout. If present, 'cols' is ignored.
#
# If the layout is something like matrix(c(1,2,3,3), nrow=2, byrow=TRUE),
# then plot 1 will go in the upper left, 2 will go in the upper right, and
# 3 will go all the way across the bottom.
#
multiplot <- function(..., plotlist=NULL, file, cols=1, layout=NULL) {
  require(grid)

  # Make a list from the ... arguments and plotlist
  plots <- c(list(...), plotlist)

  numPlots = length(plots)

  # If layout is NULL, then use 'cols' to determine layout
  if (is.null(layout)) {
    # Make the panel
    # ncol: Number of columns of plots
    # nrow: Number of rows needed, calculated from # of cols
    layout <- matrix(seq(1, cols * ceiling(numPlots/cols)),
                    ncol = cols, nrow = ceiling(numPlots/cols))
  }

 if (numPlots==1) {
    print(plots[[1]])

  } else {
    # Set up the page
    grid.newpage()
    pushViewport(viewport(layout = grid.layout(nrow(layout), ncol(layout))))

    # Make each plot, in the correct location
    for (i in 1:numPlots) {
      # Get the i,j matrix positions of the regions that contain this subplot
      matchidx <- as.data.frame(which(layout == i, arr.ind = TRUE))

      print(plots[[i]], vp = viewport(layout.pos.row = matchidx$row,
                                      layout.pos.col = matchidx$col))
    }
  }
}

您只需要将这个函数提供给您的脚本。

【讨论】:

  • 我在这里发表评论,因为我无法对您提供的链接页面发表评论...为什么会有“文件”参数?显然,这没有在函数中使用。
  • @Stingery,好问题。但我不知道答案。对不起。
【解决方案2】:

胡里奥,

您提到 p1 和 p2 具有相同的 x 轴,但是您基于均值进行的重新排序不会使它们相同。 p1 的轴为“一--> 二--> 三”,而p2 的轴为“二--> 一-> 三”。这是故意的吗?

无论如何,ggplot 提供了一些其他解决方案来将这些图合并为一个,即colourfaceting(您可能已经尝试过?)。其中任何一个的第一步是将melt您的data.frame 转换为长格式。我们将识别 id 变量“Type”,melt 假设其余列为melted

test.m <- melt(test, id.var = "Type")

快速检查新对象的结构表明几乎所有内容都符合要求,除了类型的级别有点不正常:

> str(test.m)
'data.frame':   12 obs. of  3 variables:
 $ Type    : Factor w/ 3 levels "One","Three",..: 1 3 1 1 2 2 1 3 1 1 ...
 $ variable: Factor w/ 2 levels "RatingA","RatingB": 1 1 1 1 1 1 2 2 2 2 ...
 $ value   : int  3 5 5 7 4 8 36 53 57 74 ...

让我们重新排列关卡:

test.m$Type <- factor(test.m$Type, c("One", "Three", "Two"), c("One", "Two", "Three"))

现在进行绘图。带颜色:

ggplot(test.m, aes(x = Type, y = value, group = variable, colour = variable)) + 
stat_summary(fun.y = "mean", geom = "point") 

或带有刻面:

ggplot(test.m, aes(x = Type, y = value, group = variable)) + 
stat_summary(fun.y = "mean", geom = "point") +
facet_grid(variable ~ ., scales = "free")

注意我在分面中使用了scales = "free" 参数,以便每个图都有自己的比例。如果这不是您想要的效果,只需删除该参数即可。

【讨论】:

  • 对于这个特定问题,这是一个更好的解决方案,但 Ista 的解决方案总体上更好(例如,当两个图属于不同类型时)。
【解决方案3】:

您可以像这样在 gridExtra 包中使用grid.arrange()

grid.arrange(p1, p2)

【讨论】:

  • 您能补充一些信息吗?哪里来的这个功能?如何导入?此外,该函数似乎没有绘制到同一个画布上,而是连接了两个图。
  • @Sören grid.arrange 在 gridExtra 包中,正如我已经说过的。您可以像导入任何其他包一样导入它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-19
  • 1970-01-01
相关资源
最近更新 更多