I am attempting to display 4 separate plots in the same figure. I am using the following code:
library(lattice)
library(gridExtra)
p1 = dotplot(mpg ~ cyl, data = mtcars)
grid.arrange(p1,p1,p1,p1)
but this gives me a plot that is sort of smushed. How can I make this more visually pleasing? I want to make the graphs bigger so they can actually be read. I tried adding the heights argument to grid.arrange but this did not help
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 love the JMP variability plot. (link) It is a powerful tool.
The example the plot has 2 x-axis labels, one for part-number and one for operator.
Here the JMP variability plot displays more than 2 levels of variables. The following splits by oil amount, batch size, and popcorn type. It can take some work to find the right sequence to show strongest separation, but this is an excellent tool for communication of information.
How does one do this, the multiple-level x-labels, with R using the ggplot2 library?
The best that I can find is this (link, link), which separates based on cylinder count, but does not make the x-axis labels.
My example code is this:
#reproducible
set.seed(2372064)
#data (I'm used to reading my own, not using built-in)
data(mtcars)
attach(mtcars)
#impose factors as factors
fact_idx <- c(2,8:11)
for(i in fact_idx){
mtcars[,i] <- as.factor(mtcars[,i])
}
#boxplot
p <- ggplot(mtcars, aes(gear, mpg, fill=cyl)) +
geom_boxplot(notch = TRUE)
p
The plot this gives is:
How do I make the x-axis lables indicate both gears and cylinders?
In jmp I get this:
You could use R-package VCA which comes with function varPlot implementing variability charts similar to JMP. There are multiple examples provided in the help. Your example would look like this:
library(VCA)
dat <- mtcars[order(mtcars$cyl, mtcars$gear),]
# default
varPlot(mpg~cyl/gear, dat)
# nicely formatted
varPlot(mpg~cyl/gear, dat,
BG=list(var="gear", col=paste0("gray", c(90,80,70)),
col.table=T),
VLine=list(var="cyl"), Mean=NULL,
MeanLine=list(var=c("cyl", "gear"), col=c("blue", "orange"),
lwd=c(2,2)),
Points=list(pch=16, cex=1))
I have two ggplot2 plots and I want to draw a series (10-100) slightly different curves between them. That is, I will have a two-panel layout and want to draw connecting lines from the left plot to the right plot. So far I have tried doing this by converting things to grob's and using the gtable package to add curves.
To illustrate, I have something like:
library(ggplot2)
library(gtable)
library(grid)
library(gridExtra)
p1 = ggplot(data.frame(x=1:10,y=1:10),aes(x=x,y=y))+geom_point()
p2 = ggplot(data.frame(x=1:10,y=1:10),aes(x=x,y=y))+geom_point()
g1 = ggplotGrob(p1)
g2 = ggplotGrob(p2)
gt = gtable:::cbind.gtable(g1,g2,size='first')
gt$heights = unit.pmax(g1$heights,g2$heights)
for(i in 1:10) {
gt = gtable_add_grob(gt,curveGrob(0,0.5,1,0.5,ncp=5,square=FALSE,curvature=i/10),l=5,r=8,b=3,t=3)
}
grid.newpage()
grid.draw(gt)
producing a plot like this:
which is almost right, except only the last of the curveGrob objects is shown. I've tried playing around with the z-index for the added grobs and the last one plotted always overwrites the others. I want my plot to look the same, except it should show all 10 curves between the two plot areas, instead of just the one that is showing with my existing code.
So how can I either modify my existing code to show all 10 curves or achieve the same effect by using a different method? I am stuck using ggplot2 for the main plots, as they are considerably more complex than the toy example shown.
gtable wants unique names for grobs that are in the same position
gt = gtable_add_grob(gt,curveGrob(0,0.5,1,0.5,ncp=5,square=FALSE,curvature=i/10),
l=5,r=8,b=3,t=3, name=paste(i))
I'm trying to inset a plot using ggplot2 and annotation_custom (the plot is actually a map that I'm using to replace the legend). However, I'm also using facet_wrap to generate multiple panels, but when used with annotation_custom, this reproduces the plot in each facet. Is there an easy way to insert the plot only once, preferably outside the plotting area?
Here is a brief example:
#Generate fake data
set.seed(9)
df=data.frame(x=rnorm(100),y=rnorm(100),facets=rep(letters[1:2]),
colors=rep(c("red","blue"),each=50))
#Create base plot
p=ggplot(df,aes(x,y,col=colors))+geom_point()+facet_wrap(~facets)
#Create plot to replace legend
legend.plot=ggplotGrob(
ggplot(data=data.frame(colors=c("red","blue"),x=c(1,1),y=c(1,2)),
aes(x,y,shape=colors,col=colors))+geom_point(size=16)+
theme(legend.position="none") )
#Insert plot using annotation_custom
p+annotation_custom(legend.plot)+theme(legend.position="none")
#this puts plot on each facet!
This produces the following plot:
When I would like something more along the lines of:
Any help is appreciated. Thanks!
In the help of annotation_custom() it is said that annotations "are the same in every panel", so it is expected result to have your legend.plot in each facet (panel).
One solution is to add theme(legend.position="none") to your base plot and then use grid.arrange() (library gridExtra) to plot both plots.
library(gridExtra)
p=ggplot(df,aes(x,y,col=colors))+geom_point()+facet_wrap(~facets)+
theme(legend.position="none")
grid.arrange(p,legend.plot,ncol=2,widths=c(3/4,1/4))
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.