Reputation: 11772
I created a graph with ggplot
and later I used arrangeGrob
to combine those graphs. Is there a way to remove parts a graph from this combined plot? Or maybe extract?
Here is a minimal example:
library(ggplot2)
library(gridExtra)
df <- data.frame(x=rnorm(20), y=rnorm(20), y2=rnorm(20))
g1 <- ggplot(df, aes(x, y)) + geom_point()
g2 <- ggplot(df, aes(x, y2)) + geom_point()
g <- arrangeGrob(g1,g2, widths=c(3.5,7.5), ncol=2)
print(g)
I would like to remove one of the two plots.
Upvotes: 8
Views: 489
Reputation: 32859
If you don't have to use arrangeGrob
: It is possible to extract grobs from a gtable
layout. It takes longer to set up the layout, but the extracting of the required element is straightforward.
library(gtable)
library(grid)
gt = gtable(unit(c(3.5, 7.5), "null"), unit(1, "null"))
gt = gtable_add_grob(gt, ggplotGrob(g1), l = 1, t = 1)
gt = gtable_add_grob(gt, ggplotGrob(g2), l = 2, t = 1)
plot(gt)
plot(gt[, 1])
plot(gt[, 2])
If you want to keep the size and positioning of the extracted plot the same as its size and positioning in the combined plot:
EDIT: Using Baptiste's suggestion:
gt = gtable(unit(c(3.5, 7.5), "null"), unit(1, "null"))
gt = gtable_add_grob(gt, ggplotGrob(g1), name = "g1", l = 1, t = 1)
gt = gtable_add_grob(gt, ggplotGrob(g2), name = "g2", l = 2, t = 1)
grid.newpage()
grid.draw(gtable_filter(gt, "g2", trim = FALSE))
grid.newpage()
grid.draw(gtable_filter(gt, "g1", trim = FALSE))
Original:
# Keep g2
p2 = gt
p2$layout = gt$layout[-1, ]
p2$grobs = gt$grobs[-1]
grid.newpage()
grid.draw(p2)
# Keep g1
p1 = gt
p1$layout = gt$layout[-2, ]
p1$grobs = gt$grobs[-2]
grid.newpage()
grid.draw(p1)
Upvotes: 1
Reputation: 162451
First, use grid.ls()
to see a listing of the grobs that make up the plot. Here, you'll be looking for the names of the two gTree
objects that encode the individual plots. (Compared to lattice, ggplot2's naming of component grobs is relatively unhelpful, although in this case, it's not too hard to see which pieces you'll want to extract.)
grid.ls()
# GRID.arrange.90
# GRID.frame.84
# GRID.cellGrob.85
# GRID.frame.5
# GRID.cellGrob.44
# GRID.gTree.42
# GRID.clip.43
# layout
# GRID.cellGrob.83
# GRID.gTree.81
# GRID.clip.82
# layout
# GRID.cellGrob.86
# GRID.null.1
# GRID.cellGrob.87
# GRID.null.2
# GRID.cellGrob.88
# GRID.null.4
# GRID.cellGrob.89
# GRID.null.3
Then, you can extract and plot them like this:
gg1 <- getGrob(g, ("GRID.gTree.42"))
grid.draw(gg1)
gg2 <- getGrob(g, ("GRID.gTree.81"))
grid.draw(gg2)
Upvotes: 4
Reputation: 94277
grid graphics are complicated nested trees of things. A bit (okay, a lot) of trial and error managed to get your two plots out like this:
> plot(g$children[[1]]$children[[1]]$children[[1]]$children[[1]]$children[[1]]$children[[2]])
> plot(g$children[[1]]$children[[1]]$children[[1]]$children[[2]]$children[[1]]$children[[2]])
There's probably an easier way...
Upvotes: 1