9.10 多图

9.10.1 问题

你想把多个图形放到同一个页面中。

9.10.2 方案

最简单的方法就是使用 multiplot() 函数。

multiplot() 函数可以将任意数量的图像对象作为参数,或者可以构建一个图像对象列表传递到该函数的 plotlist 参数中。

  1. # 多图功能 ggplot 对象可以直接放入 `…` 中,也可以传递到
  2. # `plotlist` 里(这里的 ggplot 对象以列表形式存在) -
  3. # cols: 图像的列数 - layout:
  4. # 用来指定布局的一组矩阵。当其存在时,可以忽略 `cols`
  5. # 参数。 假设 layout 参数是 matrix(c(1,2,3,3), nrow=2,
  6. # byrow = TRUE),
  7. # 那么第一幅图像会位于左上方,第二幅图会在右上方,而
  8. # 第三幅图会占据整个下方。
  9. multiplot <- function(..., plotlist = NULL, file, cols = 1,
  10. layout = NULL) {
  11. library(grid)
  12. # 从参数 `…`中建立一个列表然后 plotlist
  13. plots <- c(list(...), plotlist)
  14. numPlots = length(plots)
  15. # 假如 layout 是 NULL, 那么可以用 `cols` 来定义布局
  16. if (is.null(layout)) {
  17. # 创建面板 ncol: 图像的列数 nrow:
  18. # 根据上述给定的列数,计算所需要的行数
  19. layout <- matrix(seq(1, cols * ceiling(numPlots/cols)),
  20. ncol = cols, nrow = ceiling(numPlots/cols))
  21. }
  22. if (numPlots == 1) {
  23. print(plots[[1]])
  24. } else {
  25. # 创建页面
  26. grid.newpage()
  27. pushViewport(viewport(layout = grid.layout(nrow(layout),
  28. ncol(layout))))
  29. # 让每一幅图像排列在正确的位置
  30. for (i in 1:numPlots) {
  31. # 获取包含这一子图所在区域的坐标 matrix i,j
  32. matchidx <- as.data.frame(which(layout == i,
  33. arr.ind = TRUE))
  34. print(plots[[i]], vp = viewport(layout.pos.row = matchidx$row,
  35. layout.pos.col = matchidx$col))
  36. }
  37. }
  38. }

如果它不能满足你的需求,你可以将其复制下来然后作出适当的修改。

首先,构建并保存图像但不需要对它们进行渲染,这些图像的细节并不重要。你只需要将这些图像对象储存为变量。

  1. # 以下例子使用的是 ggplot2 包中自带的 Chickweight 数据集
  2. # 第一幅图像
  3. p1 <- ggplot(ChickWeight, aes(x = Time, y = weight, colour = Diet,
  4. group = Chick)) + geom_line() + ggtitle("Growth curve for individual chicks")
  5. # 第二幅图像
  6. p2 <- ggplot(ChickWeight, aes(x = Time, y = weight, colour = Diet)) +
  7. geom_point(alpha = 0.3) + geom_smooth(alpha = 0.2, size = 1) +
  8. ggtitle("Fitted growth curve per diet")
  9. # 第三幅图像
  10. p3 <- ggplot(subset(ChickWeight, Time == 21), aes(x = weight,
  11. colour = Diet)) + geom_density() + ggtitle("Final weight, by diet")
  12. # 第四幅图像
  13. p4 <- ggplot(subset(ChickWeight, Time == 21), aes(x = weight,
  14. fill = Diet)) + geom_histogram(colour = "black", binwidth = 50) +
  15. facet_grid(Diet ~ .) + ggtitle("Final weight, by diet") +
  16. theme(legend.position = "none") #为了避免冗余,这里不添加图例

这些图像都构建好了后,我们可以用 multiplot() 对它们进行渲染。下面将这些图形分成两列进行展示:

  1. multiplot(p1, p2, p3, p4, cols = 2)
  2. #> `geom_smooth()` using method = 'loess' and formula 'y ~ x'

9.10 多图 - 图1