How to plot the restults of ctree in grid?

181 Views Asked by At

The results of the plot can be normally arranged in grids. I currently have an issue by plotting the results of the ctree function from the party package in a grid. This question is a duplicate of a question from 6 years and 8 months ago (Plot of BinaryTree (ctree, party) ignores plot option of par()). It was opted that gridExtra could provide a solution. However, till now no solution for this issue has been given. Consider the example below.

library(party)
library(gridExtra)

#Create random dataframe
dfA <- data.frame(x=c(rnorm(50, 5), rnorm(50, 2)), 
                  y=c(rbinom(50, 1, .9), rbinom(50, 1, .1)))

#Duplicate dataframe
dfB <- dfA

#Plot in base R wit par (does not work)
par(mfrow = c(1, 2))
plot(party::ctree(y~x, data=dfA))
plot(party::ctree(y~x, data=dfB))

#Try to organize in a grid wit gridExtra (does not work)
treeA <- party::ctree(y~x, data=dfA)
treeB <- party::ctree(y~x, data=dfB)

grobA <- arrangeGrob(plot(treeA))
grobB <- arrangeGrob(plot(treeB))

grid.arrange(grobA, grobB, ncol=2)

Error in gList(list(wrapvp = list(x = 0.5, y = 0.5, width = 1, height = 1,  : 
                                    only 'grobs' allowed in "gList" 

The arrangeGrob(plot(treeA)) and arrangeGrob(plot(treeB)) also return an error stating Error in vapply(x$grobs, as.character, character(1)) : values must be length 1, but FUN(X[[1]]) result is length 0

Does someone known how plot the results of the ctree function in a grid?

Thank you in advance.

2

There are 2 best solutions below

0
On BEST ANSWER
## grab the scene as a grid object
library(gridExtra)
library(gridGraphics)
library(grid)

list.to.pass <- list('plot(ctree(y~x, data=dfA))',
                     'plot(ctree(y~x, data=dfB))')
out<-list()
for (i in c(1,2)){
  print(i)
  
  formula(list.to.pass[[i]])
  
  out[[i]] <- grid.grab()
  
  print(out[[i]])
  dev.off()
}
grid.arrange(out[[1]], out[[2]], nrow = 1,ncol=2)

You will get:

enter image description here

0
On

The plots in party and its successor package partykit are implemented in grid and hence the base graphics options from par() such as mfrow do not work. You can use grid.layout() to achieve similar results. Doing so in plain grid is a bit technical but the code should not be too hard to follow:

grid.newpage()
pushViewport(viewport(layout = grid.layout(1, 2)))

pushViewport(viewport(layout.pos.row = 1, layout.pos.col = 1))
plot(treeA, newpage = FALSE)
popViewport()

pushViewport(viewport(layout.pos.row = 1, layout.pos.col = 2))
plot(treeB, newpage = FALSE)
popViewport()

party grid

The reason for the newpage = FALSE argument is that by default the plot is drawn on a new page, rather than adding to a potentially existing plot.