How do plot multiple lattice plots onto a single lattice plot where the plots are generated using an lapply function?
The following is a demonstration of what I have tried so far using the built in mtcars dataset.
require(lattice)
response <- c("cyl","disp","hp","drat")
par(mfrow=c(2,2))
lapply(response, function(variable) {
print(xyplot(mtcars$mpg ~ mtcars[variable]))
})
This produces the plots desired. However it seems to be ignoring the par(mfrow=c(2,2)) instruction and plotting each plot separately.
If you really don't want to use the built-in facetting or viewport options of lattice, you can replicate the behavior of par(mfrow) with the following,
require(lattice)
response <- c("cyl","disp","hp","drat")
# save all plots in a list
pl <- lapply(response, function(variable) {
xyplot(mtcars$mpg ~ mtcars[variable])
})
library(gridExtra)
# arrange them in a 2x2 grid
do.call(grid.arrange, c(pl, nrow=2))
Your example is not how lattice is intended to be used (grid would be more appropriate).
Here is a lattice solution:
xyplot(mpg ~ cyl+disp+hp+drat,
data=mtcars,
groups=cyl+disp+hp+drat,
scales=list(relation="free"),
col="blue"
)
The multiplot function on this page is something I have used many times to get multiple plot objects on one page.
Related
I'm trying to figure out how I can arrange diagnostic plots differently using the plot() function. Here is my code:
mtcars_linear_model <- lm(mpg ~ wt, mtcars)
plot(mtcars_linear_model)
It will print these four plots in my console.
Is there a way to arrange them using ggarrange? I can't seem to print one of them at a time. I thought maybe I could call the index with the plot() function to get the plots one at a time but it doesn't work:
plot(mtcars_linear_model)[1]
I want to use each plot separately in ggarrange like this:
ggarrange(residuals_vs_fitted, normal_qq, scale_location, residuals_vs_leverage)
So that I could get one image with a 2x2 grid of these four diagnostic plots.
Using R base
x11()
par(mfrow=c(2,2))
plot(mtcars_linear_model)
This will produce:
You can reset plot params by par(mfrow=c(1,1))
I am trying to create a tiled plot using plot.kmeans functions from the package "useful". This can be done very easily for base plot function using par() or layout(), or in ggplot using facests. I want to visualize results of various runs of kmeans with different number of clusters using plot or plot.kmeans function from the package "useful". I have tried par() and layout(), but I only get one plot not multiple plots.
Consider the following code segment:
results1 <- kmeans(x=dataset1,centers=5,nstart = 25)
results2 <- kmeans(x=dataset2,centers=5,nstart = 25)
par(mfrow=c(2,1))
plot.kmeans(results1,dataset1)
plot.kmeans(results2,dataset2)
I have two datasets and apply kmeans on them separately. I want to draw results of both datasets side by side. plot.kmeans is good function to see results of clustering. But somehow i feel that we cannot two or more plots side by side like we do in case of base plotting facility. If instead of plot.kmeans, I use base plot functions it will work. So thats my problem in brief.
Thanks.
The function plot.kmeans from the package "useful" (not to be confused with general qualifier 'a useful package) returns a ggplot2 object. These do not work with par() or layout().
Look instead at grid.arrange from the "gridExtra" package:
results1 <- kmeans(x=dataset1,centers=5,nstart = 25)
results2 <- kmeans(x=dataset2,centers=5,nstart = 25)
library(gridExtra)
p1 <- plot.kmeans(results1,dataset1)
p2 <- plot.kmeans(results2,dataset2)
grid.arrange(p1, p2, ncol=2)
I've been trying to edit some plots created by ggplot2 using the functions provided by the packages grid and gridExtra. I realize that ggplot2 alone can make some really nice multifaceted plots. However, in some instances I like to create individual plots and then combine then together later on. While trying to do just that, I came across some unexpected behavior using cbind() with grid.draw() or grid.arrange() when using a ggplot2 graph that had been edited. Below is the code for an MWE:
#Load libraries
library(ggplot2); library(gridExtra)
#Load data
data(mtcars)
#Ggplot
p = qplot(wt,mpg,data=mtcars,color=cyl)
grob = ggplotGrob(p)
#Bold xlabel
grobEdited = editGrob(grid.force(grob),gPath("xlab","GRID.text"),grep=TRUE,gp=gpar(fontface="bold"))
#Visualize
grid.newpage()
grid.draw(grobEdited)
It worked as expected. Now to illustrate the issue, lets cbind() two of the same edited ggplot2 graphs:
#Cbind example with edited graphs
grid.newpage()
grid.draw(cbind(grobEdited,grobEdited))
It didn't work as expected! Now test cbind() on the unedited graphs:
#Cbind example with grob
grid.newpage()
grid.draw(cbind(grob,grob))
Works as expected. I'm new to gridded figures, so is there something I'm doing wrong?
I'm posting an answer following the comment from #user20650. The easiest workaround is to cbind() the ggplot2 graphs before editing them using the editing functions provided by grid or gridExtra:
#Edit after cbind()
grobEdited = editGrob(grid.force(cbind(grob,grob)),gPath("xlab","GRID.text"),global=TRUE,grep=TRUE,gp=gpar(fontface="bold"))
#Visualize
grid.newpage()
grid.draw(grobEdited)
I know most of the programers would refer me to 'LATTICE' or 'ggplot2' packages of R as a solution to this question, but there must be a way to do it with the base package. I want to plot multiple graphs with corresponding regression lines and correlation coefficients with simple loops. An easy example data may look like-
a=list(cbind(c(1,2,3), c(4,8,12)), cbind(c(5,15,25), c(10,30,50)))
par(mfrow=c(1,2))
lapply(1:length(a), function(i)
plot(a[[i]][,1], a[[i]][,2]))
lapply(1:length(a), function(i)
abline(lm(a[[i]][,2]~a[[i]][,1])))
require(plotrix)
lapply(1:length(a), function(i)
boxed.labels(a[[i]][,1][1], a[[i]][,2][3],
labels=paste(round(cor(a[[i]][,2], a[[i]][,1], use = "pairwise.complete.obs"),2)),
border=FALSE, adj=0.5, cex=0.8))
If you run the above script you'd notice that all linear lines and r-values will plot on the top of the last graph. Is there any way to write in the call for regression along with the plot command? Or any other clever way to deal with loops to plot regressions on corresponding figures?? It works fine for a single plot (shown below), but I'm working with a considerably large list!
plot(a[[1]][,1], a[[1]][,2])
abline(lm(a[[1]][,2]~a[[1]][,1]))
boxed.labels(a[[1]][,1][1], a[[1]][,2][3],
labels=paste(round(cor(a[[1]][,2], a[[1]][,1], use = "pairwise.complete.obs"),2)),
border=FALSE, adj=0.5, cex=0.8)
Once you call plot(), you start drawing in a new "cell". So if you want to add more to the plot before moving on to the next one, make sure you do all of your drawing before calling the next plot()
For example
a=list(cbind(c(1,2,3), c(4,8,12)), cbind(c(5,15,25), c(10,30,50)))
par(mfrow=c(1,2))
lapply(a, function(d) {
d <- setNames(data.frame(d), c("x","y"))
plot( y~x, d )
abline( lm( y ~ x, d ) )
boxed.labels(min(d$x), max(d$y),
labels=paste(round(cor(d$y, d$x, use = "pairwise.complete.obs"),2)),
border=FALSE, adj=0.5, cex=0.8)
})
Note how we do all the drawing inside a single lapply() so that abline and boxed.labels are called in between the multiple plot calls rather than after they are all done.
I have been trying to plot simple density plots using R as:
plot(density(Data$X1),col="red")
plot(density(Data$X2),col="green")
Since I want to compare, I'd like to plot both in one figure. But 'matplot' doesn't work!! I also tried with ggplot2 as:
library(ggplot2)
qplot(Data$X1, geom="density")
qplot(Data$X2, add = TRUE, geom="density")
Also in this case, plots appear separately (though I wrote add=TRUE)!! Can anyone come up with an easy solution to the problem, please?
In ggplot2 or lattice you need to reshape the data to seupose them.
For example :
dat <- data.frame(X1= rnorm(100),X2=rbeta(100,1,1))
library(reshape2)
dat.m <- melt(dat)
Using ``lattice`
densityplot(~value , groups = variable, data=dat.m,auto.key = T)
Using ``ggplot2`
ggplot(data=dat.m)+geom_density(aes(x=value, color=variable))
EDIT add X1+X2
Using lattice and the extended formua interface, it is extremely easy to do this:
densityplot(~X1+X2+I(X1+X2) , data=dat) ## no need to reshape data!!
You can try:
plot(density(Data$X1),col="red")
points(density(Data$X2),col="green")
I must add that the xlim and ylim values should ideally be set to include ranges of both X1 and X2, which could be done as follows:
foo <- density(Data$X1)
bar <- density(Data$X2)
plot(foo,col="red", xlim=c(min(foo$x,bar$x),max(foo$x,bar$x)) ylim=c(min(foo$y,bar$y),max(foo$y,bar$y))
points(bar,col="green")
In base graphics you can overlay density plots if you keep the ranges identical and use par(new=TRUE) between them. I think add=TRUE is a base graphics strategy that some functions but not all will honor.
If you specify n, from, and to in the calls to density and make sure that they match between the 2 calls then you should be able to use matplot to plot both in one step (you will need to bind the 2 sets of y values into a single matrix).