grid.arrange with John Fox's effects plots - r

I'd like to combine multiple effect plots in one window with the effects package, but don't know if there is an easy way to do so.
Here's an example that doesn't work:
d1 <-data.frame(x1=rnorm(100,0:10),y1=rnorm(100,0:10),x2=rnorm(100,0:10),y2=rnorm(100,0:10))
require(effects)
require(gridExtra)
plot1 <- plot(allEffects(mod=lm(y1~x1,d1)))
plot2 <- plot(allEffects(mod=lm(y2~x2,d1)))
grid.arrange(plot1,plot2,ncol=2)

I think you need to collect the values of allEffects components and then plot them as an 'efflist'. It looked to me that the plotting was base-graphics, but it is in fact 'lattice' if you follow the class-function trail (or if you read: ?plot.efflist )
Try this:
ef1 <-allEffects(mod=lm(y1~x1,d1))[[1]]
ef2 <- allEffects(mod=lm(y2~x2,d1))[[1]]
elist <- list( ef1, ef2 )
class(elist) <- "efflist"
plot(elist, col=2)

Interestingly, the result from plotting an efflist (which is the result from allEffects) is not a lattice graphic; it instead builds up a multipanel graphic of lattice graphics using the print.lattice methods. However, if you plot the individual effects, either by taking the elements from allEffects or by using effect, then you do get lattice graphics.
Either like this
p1 <- plot(allEffects(m1)[[1]])
p2 <- plot(allEffects(m2)[[1]])
or like this.
p1 <- plot(effect("x1", m1))
p2 <- plot(effect("x2", m2))
These can be combined with grid.arrange; the catch is that their class is c("plot.eff", "trellis") which grid.arrange doesn't recognize, so they have to be made into simple trellis objects first.
class(p1) <- class(p2) <- "trellis"
grid.arrange(p1, p2, ncol=2)

Related

arrange R plots: how can I arrange plots of the VIM package?

I would like to generate multiple plots using marginplot() (VIM package) and then arrange them into one big figure. I tried to use grid.arrange (grid/gridExtra package) and it did not work. The error was, that a grob was expected as input. So I tried to first convert the marginplot into a ggplot (as.ggplot) or grob (as.grob) but this did not work. Has anyone an idea how to arrange the plots?
library(VIM)
library(ggplotify)
library(grid)
library(gridExtra)
x <- cars[, c("speed", "dist")]
marginplot(x)
y <- cars[, c("speed", "dist")]
marginplot(y)
p <- qplot(1,1)
#p2 <- as.ggplot(marginplot(x))
r <- rectGrob(gp=gpar(fill="grey90"))
grid.arrange( r, p,p, r, ncol=2)
I created a small code with cars, where I managed to arrange grey squares and qplots. put I cannot add the marginplot.
With base plots this error occurs. Learned here: grid.arrange from gridExtras exiting with "only 'grobs' allowed in 'gList'" after update
grid.arrange is intended to be used with "grid graphical objects" (grobs), such as ggplot2.
One could find an equivalent grid-plot or use a base-graphics approach to stacking plots.
Try this:
library(VIM)
x <- cars[, c("speed", "dist")]
y <- cars[, c("speed", "dist")]
par(mfrow = c(2,2))
marginplot(x)
marginplot(y)
plot(rnorm(100))
hist(rnorm(100))
par(mfrow = c(1, 1)) #reset this parameter

How to combine multiple fviz_dist plots into one plot

I have unsuccessfully tried to combine multiple fviz_dist (factoextra package) plots into one plot using par(mfrow=c(2,2)) and by naming the plots and adding them e.g., PlotA + PlotB (as I have seen with histograms).
looking forward to hearing your tips and tricks
#Generates 4 individual plots
par(mfrow=c(2,2))
fviz_dist(dist.euclraw)
fviz_dist(dist.euclscaled)
fviz_dist(dist.corraw)
fviz_dist(dist.corscaled)
There are 2 ways you can do it like
library(factoextra)
library(ggpubr)
library(gridExtra)
data(USArrests)
dist.pearson <- get_dist(USArrests, stand = TRUE, method = "pearson")
dist.euclraw <- get_dist(USArrests, stand = TRUE, method = "euclidean")
p1 <- fviz_dist(dist.pearson)
p2 <- fviz_dist(dist.euclraw)
ggpubr::ggarrange(p1,p2)
gridExtra::grid.arrange(p1,p2)

Using a pheatmap in arrangeGrob

I'm attempting to plate two plots in the same .jpg using arrangeGrob().
I've only just started learning about grids and grobs and I think I know what the problem is: pheatmap is a grid object and containing grob objects, not allowing me to put it in arrangeGrob. Is this true?
Would I somehow need to put the qplot in a grid and the pheatmap in a grid and then put those grids in a new grid?
library(grid)
library(gridExtra)
library(pheatmap)
library(ggplot2)
hmdat=rbind(c(1,2,3),
c(3,4,5),
c(5,6,7))
hm=pheatmap(hmdat)
qp=qplot(1,1)
lm=rbind(c(1,2,2),
c(1,2,2))
jpeg("plots.jpg")
arrangeGrob(qp,hm, layout_matrix=lm)
dev.off()
The above code snippet runs just fine when using
arrangeGrob(qp,qp, layout_matrix=lm)
I'm not sure if you wanted to have 6 figures or you wanted to have two figures one with twice as wide as the other one (I tried to do minimum code change):
library("grid")
library("gridExtra")
library("pheatmap")
library("ggplot2")
hmdat=rbind(c(1,2,3),
c(3,4,5),
c(5,6,7))
hm <- pheatmap::pheatmap(hmdat)
qp <- qplot(1,1)
lm <- rbind(c(1,2,2),
c(1,2,2))
grid.arrange(grobs = list(qp,hm[[4]]), layout_matrix = lm)
which will give you:
The same way you can have multiple pheatmaps side-by-side:
library("grid")
library("gridExtra")
library("pheatmap")
hmdat <- rbind(c(1,2,3),
c(3,4,5),
c(5,6,7))
hm <- pheatmap::pheatmap(hmdat)
lm <- rbind(c(1,2),
c(3,3))
grid.arrange(grobs = list(hm[[4]],
hm[[4]],
hm[[4]]),
layout_matrix = lm)
As #hrbrmstr mentioned in the comment, you should use the 4th item in the pheatmap object. Also remember to provide grobs as list to the grid.arrange

Multiple graphs within plot with loop

How to get graph for each column of data.frame within one plot with loop? Must be easy just can't figure it out.
Sample data:
rdata <- data.frame(y=rnorm(1000,2,2),v1=rnorm(1000,1,1),v2=rnorm(1000,3,3),
v3=rnorm(1000,4,4),v4=rnorm(1000,5,5))
What I have tried?
library(lattice)
p <- par(mfrow=c(2,2))
for(i in 2:5){
w <- xyplot(y~rdata[,i],rdata)
print(w)
}
par(p)
If you don't have to use lattice you can just use base plot instead and it should work as you want.
p <- par(mfrow=c(2,2))
for(i in 2:5){
plot(y~rdata[,i],rdata)
}
par(p)
If you want to use lattice look this answer. Lattice ignores par, so you have to do some more work to achieve what you want.
Inorder to easily arrange a bunch of lattice plots, I like to use the helper function print.plotlist. It has a layout= parameter that acts like the layout() function for base graphics. For example, you could call
rdata <- data.frame(y=rnorm(1000,2,2),v1=rnorm(1000,1,1),v2=rnorm(1000,3,3),
v3=rnorm(1000,4,4),v4=rnorm(1000,5,5))
library(lattice)
plots<-lapply(2:5, function(i) {xyplot(y~rdata[,i],rdata)})
print.plotlist(plots, layout=matrix(1:4, ncol=2))
to get
Otherwise you normally use a split= parameter to the print statement to place a plot in a subsection of the device. For example, you could also do
print(plots[[1]], split=c(1,1,2,2), more=T)
print(plots[[2]], split=c(1,2,2,2), more=T)
print(plots[[3]], split=c(2,1,2,2), more=T)
print(plots[[4]], split=c(2,2,2,2))

Multiple lattice plots with gridExtra

There is very convenient way of plotting multiple graphs and that's with gridExtra - grid.arrange:
grid.arrange(plot1,plot2,plot3,plot4,plot5,plot6,plot7,plot8,plot9, ncol=3)
The above command draws 3x3 graphs in one window.
Now, I'm using my own lattice setup to draw unique lines etc. via
trellis.par.set(my.setup)
However using the grid.arrange command for plotting multiple plots won't pass on the setup as the output plots are in default colours.
So the question is how to pass on the my.setup onto grid.arrange or alternatively how to plot easily multiple graphs in one go for lattice.
EDIT: Reproducible example:
Data <- data.frame(Col1=rnorm(10,0,1),Col2=rexp(10,2),Col3=rnorm(10,2,2),Col4=runif(10,0,2),
Time=seq(1,10,1))
trellis.par.set(col.whitebg())
newSet <- col.whitebg()
newSet$superpose.symbol$col <- c("blue3","orange2","gray1","tomato3")
newSet$superpose.symbol$pch <- 1
newSet$superpose.symbol$cex <- 1
newSet$superpose.line$col <- c("blue3","orange2","gray1","tomato3")
trellis.par.set(newSet)
Plot1 <- xyplot(Col1+Col2~Time, Data, type="spline")
Plot2 <- xyplot(Col2+Col3~Time, Data, type="spline")
Plot3 <- xyplot(Col1+Col3~Time, Data, type="spline")
Plot4 <- xyplot(Col3+Col4~Time, Data, type="spline")
grid.arrange(Plot1,Plot2,Plot3,Plot4, ncol=2)
I guess it's got something to do with the plot.trellis method not finding the global theme settings when it's wrapped in gridExtra::drawDetails.lattice. I don't understand these lattice options, but as far as I recall you can specify them explicitly at the plot level too,
pl = list(Plot1, Plot2, Plot3, Plot4)
# do.call(grid.arrange, c(pl, nrow=1))
do.call(grid.arrange, c(lapply(pl, update, par.settings=newSet), list(nrow=1)))

Resources