如何将空图添加到多图?

时间:2019-04-17 08:14:02

标签: r ggplot2

假设您要创建一个如下图所示的图形。

enter image description here

我想基于ggplot2使用multiplot函数。如何添加空图以获得带有多图的三角形输出?

以下MWE:

library(ggplot2)

# Multiplot function from http://www.cookbook-r.com/Graphs/Multiple_graphs_on_one_page_(ggplot2)/
multiplot <- function(..., plotlist=NULL, file, cols=1, layout=NULL) {
  library(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))
    }
  }
}

# Example plot
p <- ggplot(data = mtcars, aes(x=wt, y=mpg)) + geom_point()

multiplot(p,p,p,p,p,p,p,p,p,cols=3)  

这产生

enter image description here

3 个答案:

答案 0 :(得分:3)

只需将""添加到多图,即可创建一个空元素:

multiplot(p,"","",p,p,"",p,p,p,cols=3) 

或者,创建一个空图并将其添加到列表中:

p1 <- ggplot() + theme_void()
multiplot(p,p1,p1,p,p,p1,p,p,p,cols=3) 

无论哪种方式,您都会得到

enter image description here

答案 1 :(得分:3)

或者,grid.arrange()可以使用布局,

m = matrix(NA, 3, 3)
m[upper.tri(m, TRUE)] = 1:6
lp = replicate(6, ggplot(), FALSE)
gridExtra::grid.arrange(grobs = lp, layout_matrix = m)

答案 2 :(得分:2)

multiplot函数被组合以来,已经出现了一些软件包,它们可以完成诸如此类的任务并具有更多功能,其中包括cowplotegg和{{3} }。我认为patchwork最适合此任务,因为它构建网格的方式以及plot_spacer函数可创建用于填充的空ggplot对象。

patchwork有一组用于将图放在一起的算法,但是+是最简单的算法。您已经拥有的代码将变为:

library(ggplot2)
library(patchwork)

p <- ggplot(data = mtcars, aes(x=wt, y=mpg)) + geom_point()
s <- plot_spacer()

p + p + p +
s + p + p +
s + s + p +
  plot_layout(ncol = 3, nrow = 3)

但是,您最初发布的示例更加复杂,因为它有多个相互显示的变量。您可以在patchwork中构建此代码,理想情况下可以使用一些tidyeval来简化多个ggplot调用,或者可以使用散点图矩阵函数,例如GGally中的那个。

我制作了一个更复杂的数据集,更接近于您的最佳示例中使用的数据集。

library(dplyr)
library(purrr)
library(tidyr)
library(GGally)

df <- tibble(
  id = rep(1:100, times = 4),
  key = rep(letters[1:4], each = 100),
  value = map(1:4, ~rnorm(100, mean = .)) %>% reduce(c)
) %>%
  spread(key, value)

head(df)
#> # A tibble: 6 x 5
#>      id     a     b     c     d
#>   <int> <dbl> <dbl> <dbl> <dbl>
#> 1     1 1.89  0.912  2.96  4.92
#> 2     2 2.58  1.12   3.38  3.85
#> 3     3 0.730 2.92   2.64  5.16
#> 4     4 2.04  4.30   2.63  5.85
#> 5     5 1.28  1.41   3.82  3.35
#> 6     6 1.77  1.60   2.79  5.54

对于对角线标签,我使用GGally的辅助函数和一些tidyeval(quo_name)构建了一个自定义几何图形。这将在矩阵的对角线上给您一个标签,而不是默认的密度图。

diag_label <- function(data, mapping) {
  var_name <- quo_name(mapping[[1]])
  ggplot(data, mapping) +
    ggally_text(var_name, color = "black")
}

ggpairs(df, columns = 2:ncol(df),
        upper = list(continuous = "points"),
        lower = list(continuous = "blank"),
        diag = list(continuous = diag_label),
        progress = FALSE) +
  theme_bw()

您还可以进行更多调整,以使轴和标签看起来像第一个示例一样。