使用gridExtra排列GGally图形?

4
我想用arrangeGrob来排列我的ggpairs图形:
library(GGally)
library(gridExtra)

df <- structure(list(var1 = 1:5, var2 = 4:8, var3 = 6:10), .Names = c("var1", "var2", "var3"), row.names = c(NA, -5L), class = "data.frame")

p1 <- ggpairs(df, 1:3) 
p2 <- ggpairs(df, 1:2)

p <- arrangeGrob(p1, p2, ncol=2)

这会导致以下错误:
Error in arrangeGrob(p1, p2, ncol = 2) : input must be grobs!

有没有解决这个问题的办法?

p1p2属于ggpairs类,这显然不是arrangeGrob的有效类。 - David Arenburg
是的,我也想到了;) 但我想知道是否有一种方法仍然可以使用gridExtra(或其他方法)来排列GGally图。 - erc
这是我能想到的唯一方法... p1 <- ggplot(df, aes(var1, var2)) + geom_point(); p2 <- ggplot(df, aes(var2, var3)) + geom_point(); p3 <- ggplot(df, aes(var1, var3)) + geom_point(); p <- arrangeGrob(p1, p2, p3, ncol=3) - David Arenburg
可能是由'ggpair'和'ggplot'生成的图并排的重复问题。 - user20650
@user20650 我的问题怎么可能是一个1.5年后才被提出的问题的重复?! - erc
嗨beetroot- 看起来引导读者到更近期的问题更为合适,那里有两个回答展示了现在如何实现。 - user20650
3个回答

3
library(GGally)
library(gridExtra)
library(grid)

# reproducing initial data
df <- structure(list(var1 = 1:5, var2 = 4:8, var3 = 6:10), 
                .Names = c("var1", "var2", "var3"), 
                row.names = c(NA, -5L), class = "data.frame")
p1 <- ggpairs(df, 1:3) 
p2 <- ggpairs(df, 1:2)

# declaring new method for drawing ggmatrix objects using grid.draw
grid.draw.ggmatrix <- function(x, recording = T) print(x, gridNewPage = F)
# then making them look like grob objects
attributes(p1)$class <- c(attributes(p1)$class, "grob")
attributes(p2)$class <- c(attributes(p2)$class, "grob")

p <- arrangeGrob(p1, p2, ncol=2)
grid.newpage()
grid.draw(p)

Arranged ggpairs plots


1
尝试使用此方法时,我收到以下错误信息:“Error in UseMethod("depth") : no applicable method for 'depth' applied to an object of class "NULL"”。 - agstudy

3

我找到了一个使用cowplot解决此问题的答案(在https://github.com/ggobi/ggally/issues/256中找到)

解决方案:

 library(GGally)
 library(gridExtra)
 library(cowplot)

 df <- structure(list(var1 = 1:5,var2 = 4:8, var3 = 6:10), 
                      .Names = c("var1",  "var2", "var3"),
                      row.names = c(NA, -5L), class = "data.frame")

 p1 <- ggpairs(df, 1:3) 
 p2 <- ggpairs(df, 1:2)



 plot_grid(
   ggmatrix_gtable(p1),
   ggmatrix_gtable(p2),
   nrow = 2)


3
很遗憾,我无法看出这是可能的。
首先,这不会与gridExtra一起工作,因为arrangeGrob操作TableGrob对象:
> ggplotGrob(qplot(1:100))
stat_bin: binwidth defaulted to range/30. Use 'binwidth = x' to adjust this.
TableGrob (6 x 5) "layout": 8 grobs
  z     cells       name                                 grob
1 0 (1-6,1-5) background      rect[plot.background.rect.3349]
2 3 (3-3,3-3)     axis-l absoluteGrob[GRID.absoluteGrob.3341]
3 1 (4-4,3-3)     spacer                       zeroGrob[NULL]
4 2 (3-3,4-4)      panel               gTree[GRID.gTree.3329]
5 4 (4-4,4-4)     axis-b absoluteGrob[GRID.absoluteGrob.3335]
6 5 (5-5,4-4)       xlab         text[axis.title.x.text.3343]
7 6 (3-3,2-2)       ylab         text[axis.title.y.text.3345]
8 7 (2-2,4-4)      title           text[plot.title.text.3347]
< p > ggpairs 对象的内部表示仅包含要调用的方法,而不是实际的 grobs:

> str(p1$plots)
List of 9
 $ : chr "ggally_diagAxis(ggally_data, ggplot2::aes(x = var1))"
 $ : chr "ggally_cor(ggally_data, ggplot2::aes(x = var2, y = var1))"
 $ : chr "ggally_cor(ggally_data, ggplot2::aes(x = var3, y = var1))"
 $ : chr "ggally_points(ggally_data, ggplot2::aes(x = var1, y = var2))"
 $ : chr "ggally_diagAxis(ggally_data, ggplot2::aes(x = var2))"
 $ : chr "ggally_cor(ggally_data, ggplot2::aes(x = var3, y = var2))"
 $ : chr "ggally_points(ggally_data, ggplot2::aes(x = var1, y = var3))"
 $ : chr "ggally_points(ggally_data, ggplot2::aes(x = var2, y = var3))"
 $ : chr "ggally_diagAxis(ggally_data, ggplot2::aes(x = var3))"

整个构建实际 grobs 的工作由 GGally:::print.ggpairs 完成。查看源代码,你会看到 grid.newpage() 以及多个 popViewportpushViewport。这意味着即使是低级的 grid 方法(例如在 这里 描述的方法)也不适用,因为你的 grid 构造将被 GGally:::print.ggpairs 覆盖。
当然总有办法。修改源代码始终是一种选择,虽然我认为这对你的任务来说是一条漫长而困难的道路。如果有人能想出一个简单的解决方法,我很乐意被证明是错误的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接