thomasp85 / patchwork

The Composer of ggplots
https://patchwork.data-imaginist.com
Other
2.42k stars 157 forks source link

last ggplot added to a patchwork is not accessible (subscript out of bound), although it can be displayed #320

Closed BorisVSchmid closed 11 months ago

BorisVSchmid commented 1 year ago

There is some indexing bug in patchwork 1.1.2. I cannot access the last plot in a patchwork through $patches$plots[[number]].

If I look at the patchwork object it indeed only contains 2 plots in $patches, but the patchwork displays 3 plots just fine (I am sure you would have noticed if it didn't display three plots :-))

> library(ggplot2)
> library(patchwork)
> g1 <- ggplot()
> g2 <- ggplot()
> g3 <- ggplot()
> p1 <- g1 + g2 + g3
> p1$patches$plots[[1]]
> p1$patches$plots[[2]]
> p1$patches$plots[[3]]
Error in p1$patches$plots[[3]] : subscript out of bounds
> 
> p1  ;; displays fine
> 
BorisVSchmid commented 1 year ago

Found that the data for the last plot is stored in p1$data, so you can manually add it to the patches list and call wrap_plots. You can style it in the same way as the other plots by grabbing one of the patchwork plots from $patches$plots, and use the %+% operator to replace the data in the plot.

More in detail: here is an example of how create a new patchwork from an existing patchwork, for a patchwork named global.p, a dataframe occ.df and a list of plot names xnames. The reason I was interested in recreating a patchwork from an existing patchwork was to add an additional ggplot element to each of the plots in the patchwork (namely the geom_rug).

glist <- global.p$patches$plots
glist[[length(glist) + 1]] <- global.p$patches$plots[[1]] %+% global.p$data + ggtitle(tail(xnames,1))
for (i in 1:length(glist)) {
  glist[[i]] <- glist[[i]] + geom_rug(data=occ.df,aes(x=.data[[xnames[i]]]),alpha = 0.1,inherit.aes = FALSE)
}
global.p <- wrap_plots(glist)
thomasp85 commented 11 months ago

you generally shouldn't peak into internals like this. The top level object lets you index into the sub plots directly, e.g.

p <- p1 + p2

# retrieve p2
p[[2]]