I would like to add a common border for the combined pie charts. When I use panel_border() the left and bottom lines appear as more darker than upper and right lines. I couldn't figure out my mistake.1) How can I add a common border for combined plots?
2) How can I reduce the thickness of left and bottom lines?
df1 <- data.frame(
variable = c("china","korea","canada","UK","USA"),
value = c(1632,1320,4491,991,620)
)
df2 <- data.frame(
variable = c("china","korea","canada","UK","USA"),
value = c(7376,1770,5210,5005,3947)
)
library(ggplot2)
p1 <-ggplot(df1,aes(x="", y = value, fill = variable))+ geom_bar(stat="identity", width=1) + ggtitle("Rainfall - 2014")+ panel_border() +coord_polar(theta = "y")+xlab("")+ylab("")+theme(legend.position="right", legend.title=element_blank(), plot.title = element_text(lineheight=3, face="bold", color="black", size=14))
p2 <-ggplot(df2,aes(x="", y = value, fill = variable))+ geom_bar(stat="identity", width=1) + ggtitle("Rainfall - 2015")+panel_border() +coord_polar(theta = "y")+xlab("")+ylab("")+theme(legend.position="right", legend.title=element_blank(), plot.title = element_text(lineheight=3, face="bold", color="black", size=14))
library(cowplot)
plot_grid(p1, p2, labels=c("A", "B" ))
Sanu,
The first component of the problem is that you are not seeing a border your are seeing the axis.line, and axis.text theme attributes. You need to remove these from the theme by applying element_blank() to both...
library(ggplot2)
library(cowplot)
df1 <- data.frame(
variable = c("china","korea","canada","UK","USA"),
value = c(1632,1320,4491,991,620)
)
df2 <- data.frame(
variable = c("china","korea","canada","UK","USA"),
value = c(7376,1770,5210,5005,3947)
)
p1 <-ggplot(df1, aes(x="", y = value, fill = variable))
p1 <- p1 + geom_bar(stat="identity", width=1)
p1 <- p1 + ggtitle("Rainfall - 2014")
# p1 <- p1 + panel_border()
p1 <- p1 + coord_polar(theta = "y")
p1 <- p1 + xlab("")
p1 <- p1 + ylab("")
p1 <- p1 + theme(legend.position="right",
legend.title=element_blank(),
axis.line=element_blank(),
axis.ticks=element_blank(), # the axis ticks
plot.title = element_text(lineheight=3, face="bold", color="black", size=14))
p2 <-ggplot(df2,aes(x="", y = value, fill = variable))
p2 <- p2 + geom_bar(stat="identity", width=1)
p2 <- p2 + ggtitle("Rainfall - 2015")
# p2 <- p2 + panel_border()
p2 <- p2 + coord_polar(theta = "y")
p2 <- p2 + xlab("")
p2 <- p2 + ylab("")
p2 <- p2 + theme( legend.position="right",
legend.title = element_blank(),
axis.line=element_blank(),
axis.ticks=element_blank(), # the axis ticks
plot.title = element_text(lineheight=3, face="bold", color="black", size=14))
plot_grid(p1, p2, labels=c("A", "B" ))
result:
a better solution might be to clean up the plot as follows:
library(gridExtra)
get_legend<-function(myggplot){
tmp <- ggplot_gtable(ggplot_build(myggplot))
leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
legend <- tmp$grobs[[leg]]
return(legend)
}
legend <- get_legend(p1)
p1 <- p1 + theme(legend.position="none")
p2 <- p2 + theme(legend.position="none")
# Arrange ggplot2 graphs with a specific width
grid.arrange(p1, p2, legend, ncol=3, widths=c(2.3, 2.3, 0.8))
result:
and now we add the border by adding...
# next line adds border
grid.rect(.5,.5,width=unit(.99,"npc"), height=unit(0.99,"npc"),
gp=gpar(lwd=3, fill=NA, col="black"))
thus:
to remove the axis test we add axis.text.x=element_blank() to the theme definition... Thus:
library(ggplot2)
library(cowplot)
df1 <- data.frame(
variable = c("china","korea","canada","UK","USA"),
value = c(1632,1320,4491,991,620)
)
df2 <- data.frame(
variable = c("china","korea","canada","UK","USA"),
value = c(7376,1770,5210,5005,3947)
)
p1 <-ggplot(df1, aes(x="", y = value, fill = variable))
p1 <- p1 + geom_bar(stat="identity", width=1)
p1 <- p1 + ggtitle("Rainfall - 2014")
# p1 <- p1 + panel_border()
p1 <- p1 + coord_polar(theta = "y")
p1 <- p1 + xlab("")
p1 <- p1 + ylab("")
p1 <- p1 + theme(legend.position="right",
legend.title=element_blank(),
axis.line=element_blank(),
axis.ticks=element_blank(), # the axis ticks
axis.text.x=element_blank(),
plot.title = element_text(lineheight=3, face="bold", color="black", size=14))
p1
p2 <-ggplot(df2,aes(x="", y = value, fill = variable))
p2 <- p2 + geom_bar(stat="identity", width=1)
p2 <- p2 + ggtitle("Rainfall - 2015")
# p2 <- p2 + panel_border()
p2 <- p2 + coord_polar(theta = "y")
p2 <- p2 + xlab("")
p2 <- p2 + ylab("")
p2 <- p2 + theme( legend.position="right",
legend.title = element_blank(),
axis.line=element_blank(),
axis.ticks=element_blank(), # the axis ticks
axis.text.x=element_blank(),
plot.title = element_text(lineheight=3, face="bold", color="black", size=14))
plot_grid(p1, p2, labels=c("A", "B" ))
library(gridExtra)
get_legend<-function(myggplot){
tmp <- ggplot_gtable(ggplot_build(myggplot))
leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
legend <- tmp$grobs[[leg]]
return(legend)
}
legend <- get_legend(p1)
p1 <- p1 + theme(legend.position="none")
p2 <- p2 + theme(legend.position="none")
# 4. Arrange ggplot2 graphs with a specific width
grid.arrange(p1, p2, legend, ncol=3, widths=c(2.3, 2.3, 0.8))
# next line adds border
grid.rect(.5,.5,width=unit(.99,"npc"), height=unit(0.99,"npc"),
gp=gpar(lwd=3, fill=NA, col="black"))
result:
Related
I am trying to both add multi-plot axis labels and align plots axis in ggplot2.
Here is an example with mtcars data.
library(ggplot2)
library(gridExtra)
#make some plots
c1 <- ggplot(mtcars,aes(mpg,cyl)) + geom_point() + theme(axis.title.x = element_blank(),axis.title.y = element_blank())
c2 <- ggplot(mtcars,aes(mpg,cyl)) + geom_line() + theme(axis.title.x = element_blank(),axis.title.y = element_blank())
c3 <- ggplot(mtcars,aes(mpg,cyl)) + geom_path() + theme(axis.title.x = element_blank(),axis.title.y = element_blank())
c4 <- ggplot(mtcars,aes(mpg,cyl)) + geom_violin() + theme(axis.title.x = element_blank(),axis.title.y = element_blank())
#arrange and add axis
grid.arrange(
arrangeGrob(c1,c2,ncol = 1, left = "Left Axis",bottom = "Bottom Left"),
arrangeGrob(c3,c4,ncol = 1, left = "Middle Axis"),
ncol = 2
)
I want to keep the Bottom Left axis label and align the the axis as well. The 'bottom' label will be slightly below the plot area.
Edit
c1 <- ggplot(mtcars,aes(mpg,cyl)) + geom_point() + theme(axis.title.x = element_blank(),axis.title.y = element_blank())
c2 <- ggplot(mtcars,aes(mpg,cyl)) + geom_line() + theme(axis.title.x = element_blank(),axis.title.y = element_blank())
c3 <- ggplot(mtcars,aes(mpg,cyl)) + geom_path() + theme(axis.title.x = element_blank(),axis.title.y = element_blank())
c4 <- ggplot(mtcars,aes(mpg,cyl)) + geom_violin() + theme(axis.title.x = element_blank(),axis.title.y = element_blank())
#arrange and add axis
grid.arrange(
arrangeGrob(c1,c2,ncol = 1, left = "Left Axis",bottom = "Bottom Left"),
arrangeGrob(c3,c4,ncol = 1, left = "Middle Axis", bottom = " "),
ncol = 2
)
Or
library(ggplot2)
library(gridExtra)
c1 <- ggplot(mtcars,aes(mpg,cyl)) + geom_point() + theme(axis.title.x = element_blank(),axis.title.y = element_blank())
c2 <- ggplot(mtcars,aes(mpg,cyl)) + geom_line() + theme(axis.title.y = element_blank()) + labs(x = "Bottom")
c3 <- ggplot(mtcars,aes(mpg,cyl)) + geom_path() + theme(axis.title.x = element_blank(),axis.title.y = element_blank())
c4 <- ggplot(mtcars,aes(mpg,cyl)) + geom_violin() + theme(axis.title.y = element_blank()) + labs(x = " ")
library(ggpubr)
ggarrange(c1, c3, c2, c4)
Created on 2021-04-06 by the reprex package (v2.0.0)
I want to increase the size of the panel background in ggplot2 so that extends over the axis titles like in the following graphic:
I tried to play around with element_rect but did not succeed. Here is what I got until now.
dat <- data.frame(x=2001:2017, y=rnorm(17,100))
ggplot2::ggplot(data=dat, ggplot2::aes(x=x, y=y)) +
ggplot2::geom_line(size=1.5) +
ggplot2::theme(panel.background=ggplot2::element_rect(fill="darkgrey"),
plot.background=ggplot2::element_rect(fill="lightgrey", color=NA)) +
ggplot2::ggtitle("Title of the plot")
Any help would be appreciated!
Thanks
Daniel
You can try
# first plot
p <- ggplot(data=dat, aes(x=x, y=y)) +
geom_line(size=1.5) +
theme(panel.background=element_rect(fill="darkgrey"),
plot.background=element_rect(fill="darkgrey"))
# blank plot
p1 <- ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_blank() +
theme(plot.background=element_rect(fill="lightgrey"),
line = element_blank(),
axis.text = element_blank(),
axis.title = element_blank(),
plot.title = element_text(hjust = 0))
# plot with title
p2 <- p1 + ggtitle("Title of the plot", subtitle = "this is a sub")
# plot with figure text
p3 <- p1 + ggtitle("",subtitle = "this is a second sub")
# final plot
library(cowplot)
plot_grid(p2, p, p3, nrow = 3, rel_heights = c(10, 80, 10))
Ok, lets take some sample data.
A <- sample(1:100, 25)
B <- sample(1:25, 25)
df.1 <- data.frame(A,B)
C <- sample(1:80, 15)
D <- sample(1:15, 15)
df.2 <- data.frame(C,D)
Then we plot the data using ggplot
library(ggplot2)
(plot2 <- ggplot(NULL) +
geom_point(data=df.1, aes(x=A, y=B),
color='black', cex=1, pch=16 ) +
geom_smooth(data=df.1, aes(x=A, y=B), method="lm", size=1,
se=FALSE, colour="black", linetype=2)+
geom_point(data=df.2, aes(x=C, y=D),
color='black', cex=1, pch=15 ) +
geom_smooth(data=df.2, aes(x=C, y=D), method="lm", size=1,
se=FALSE, colour="black", linetype=1)+
scale_y_continuous("Y scale") +
ggtitle("Plot") +
theme_bw()+
theme(plot.title = element_text(face="bold", size=20),
axis.title.x = element_text(vjust=-0.25),
axis.title.y = element_text(vjust=1),
axis.title = element_text(face="bold", size=15)
)
)
So we have created and modified the title, axis, etc.
But I want to create a legend which shows the linetype's from the geom_smooth() function of df.1 and df.2. It should be in the top right of the graph.
(so for df.1 we want a solid line and df.2 a dashed line)
The example here walks you through an example, but the data comes from within the same data set
Here you go:
#combine and create x and y (as mappings follow
#same pattern)
df.1$group <- "df.1"
df.1$x <- df.1$A
df.1$y <- df.1$B
df.2$group <- "df.2"
df.2$x <- df.2$C
df.2$y <- df.2$D
library(plyr) #for rbind.fill
df.all <- rbind.fill(df.1,df.2)
plot3 <- ggplot(df.all, aes(x=x,y=y,group=group)) +
geom_point(color='black', cex=1, pch=16 ) +
geom_smooth(aes(linetype=group),method="lm", size=1,
se=FALSE, colour="black") +
scale_y_continuous("Y scale") +
ggtitle("Plot") +
theme_bw()+
theme(plot.title = element_text(face="bold", size=20),
axis.title.x = element_text(vjust=-0.25),
axis.title.y = element_text(vjust=1),
axis.title = element_text(face="bold", size=15)
) +
#add custom linetypes (not necessary now, as default mapping to 1 and 2)
plot3 + scale_linetype_manual(values=c("df.1"=1,"df.2"=2))
I want to plot a restricted cubic spline as main plot and add a box-and-whisker plot to show the variation of the X variable. However, the lower hinge (x=42), the median (x=51), and the upper hinge(x=61) did not fit perfectly with the corresponding grid line of the main plot.
library(Hmisc)
library(rms)
library(ggplot2)
library(gridExtra)
data(pbc)
d <- pbc
rm(pbc)
d$status <- ifelse(d$status != 0, 1, 0)
dd = datadist(d)
options(datadist='dd')
f <- cph(Surv(time, status) ~ rcs(age, 4), data=d)
p <- Predict(f, fun=exp)
df <- data.frame(age=p$age, yhat=p$yhat, lower=p$lower, upper=p$upper)
### 1st PLOT: main plot
(g <- ggplot(data=df, aes(x=age, y=yhat)) + geom_line(size=1))
# CI
(g <- g + geom_ribbon(data=df, aes(ymin=lower, ymax=upper), alpha=0.5, linetype=0, fill='#FFC000'))
# white background
(g <- g + theme_bw())
# X-axis
(breaks <- round(boxplot.stats(p[,"age"])$stats))
(g <- g + scale_x_continuous(breaks=breaks, limits=range(p[,"age"]), labels=round(breaks)))
(g <- g + xlab("Age"))
# Y-Achse
(g <- g + ylab("Hazard Ratio"))
# size and color of axis
(g <- g + theme(axis.line = element_line(color='black', size=1)))
(g <- g + theme(axis.ticks = element_line(color='black', size=1)))
(g <- g + theme( plot.background = element_blank() ))
#(g <- g + theme( panel.grid.major = element_blank() ))
(g <- g + theme( panel.grid.minor = element_blank() ))
(g <- g + theme( panel.border = element_blank() ))
### 2nd PLOT: box whisker plot
describe(df$age, digits=0)
round(range(df$age))
(gg <- ggplot(data=df, aes(x=1, y=age)) + geom_boxplot(outlier.shape=NA, size=1) + coord_flip())
(gg <- gg + theme( axis.line=element_blank() )) #
(gg <- gg + theme( axis.text.x=element_blank() ))
(gg <- gg + theme( axis.text.y=element_blank() ))
(gg <- gg + theme( axis.ticks=element_blank() ))
(gg <- gg + theme( axis.title.x=element_blank() ))
(gg <- gg + theme( axis.title.y=element_blank() ))
(gg <- gg + theme( panel.background=element_blank() ))
(gg <- gg + theme( panel.border=element_blank() )) #
(gg <- gg + theme( legend.position="none" )) #
(gg <- gg + theme( panel.grid.major=element_blank() )) #
(gg <- gg + theme( panel.grid.minor=element_blank() ))
(gg <- gg + theme( plot.background=element_blank() ))
(gg <- gg + theme( plot.margin = unit( c(0,0,0,0), "in" ) ))
(gg <- gg + scale_x_continuous(breaks=c(70,77,84), expand=c(0,0)) )
### FINAL PLOT: put box whisker plot in main plot
(final.gg <- g + annotation_custom(ggplotGrob(gg), ymin=2.4, ymax=2.6))
What do I have to change for the perfect fit?
Is there a better for a automatized alignment of the y-position of the
box-and-whisker?
UPDATE #1
Thanks for your answer! Below you can see my example with your code. However, as you can see, the lower hinge, the median, and the upper hinge still do not fit. What is going wrong?
library(Hmisc)
library(rms)
library(ggplot2)
library(gridExtra)
data(pbc)
d <- pbc
rm(pbc, pbcseq)
d$status <- ifelse(d$status != 0, 1, 0)
dd = datadist(d)
options(datadist='dd')
f <- cph(Surv(time, status) ~ rcs(age, 4), data=d)
p <- Predict(f, fun=exp)
df <- data.frame(age=p$age, yhat=p$yhat, lower=p$lower, upper=p$upper)
### 1st PLOT: main plot
(breaks <- boxplot.stats(p[,"age"])$stats)
g <- ggplot(data=df, aes(x=age, y=yhat)) + geom_line(size=1) +
geom_ribbon(data=df, aes(ymin=lower, ymax=upper), alpha=0.5, linetype=0, fill='#FFC000') +
theme_bw() +
scale_x_continuous(breaks=breaks) +
xlab("Age") +
ylab("Hazard Ratio") +
theme(axis.line = element_line(color='black', size=1),
axis.ticks = element_line(color='black', size=1),
plot.background = element_blank(),
# panel.border = element_blank(),
panel.grid.minor = element_blank())
### 2nd PLOT: box whisker plot
gg <- ggplot(data=df, aes(x=1, y=age)) +
geom_boxplot(outlier.shape=NA, size=1) +
scale_y_continuous(breaks=breaks) +
ylab(NULL) +
coord_flip() +
# theme_bw() +
theme(axis.line=element_blank(),
# axis.text.x=element_blank(),
axis.text.y=element_blank(),
axis.ticks.y=element_blank(),
axis.title=element_blank(),
# panel.background=element_blank(),
panel.border=element_blank(),
# panel.grid.major=element_blank(),
panel.grid.minor=element_blank(),
# plot.background=element_blank(),
plot.margin = unit( c(0,0,0,0), "in" ),
axis.ticks.margin = unit(0, "lines"),
axis.ticks.length = unit(0, "cm"))
### FINAL PLOT: put box whisker plot in main plot
(final.gg <- g + annotation_custom(ggplotGrob(gg), ymin=2.4, ymax=2.6))
Minor edit: Updating to ggplot2 2.0.0
axis.ticks.margin is deprecated
In the boxplot, even though you have set various elements to element_blank and margins to zero, default spaces remain resulting in the misalignment. These spaces belong to:
axis.ticks.length
xlab
In the code below, I've re-arranged your code somewhat (I hope that's okay), and commented out some lines of code so that it can be seen that the two plots do align. I've also set the breaks in the two plot to un-rounded breaks (min and max values, hinges, and the median).
# X-axis
(breaks <- boxplot.stats(p[,"age"])$stats)
### 1st PLOT: main plot
g <- ggplot(data=df, aes(x=age, y=yhat)) + geom_line(size=1) +
geom_ribbon(data=df, aes(ymin=lower, ymax=upper), alpha=0.5, linetype=0, fill='#FFC000') +
theme_bw() +
scale_x_continuous(breaks=breaks) +
xlab("Age") +
ylab("Hazard Ratio") +
theme(axis.line = element_line(color='black', size=1),
axis.ticks = element_line(color='black', size=1),
plot.background = element_blank(),
# panel.border = element_blank(),
panel.grid.minor = element_blank())
### 2nd PLOT: box whisker plot
gg <- ggplot(data=df, aes(x=1, y=age)) +
geom_boxplot(outlier.shape=NA, size=1) +
scale_y_continuous(breaks=breaks) +
xlab(NULL) +
coord_flip() +
# theme_bw() +
theme(axis.line=element_blank(),
# axis.text.x=element_blank(),
axis.text.y=element_blank(),
axis.ticks.y=element_blank(),
axis.title=element_blank(),
# panel.background=element_blank(),
panel.border=element_blank(),
# panel.grid.major=element_blank(),
panel.grid.minor=element_blank(),
# plot.background=element_blank(),
plot.margin = unit( c(0,0,0,0), "in" ),
# axis.ticks.margin = unit(0, "lines"),
axis.ticks.length = unit(0, "cm"))
### FINAL PLOT: put box whisker plot in main plot
(final.gg <- g + annotation_custom(ggplotGrob(gg), ymin=2.4, ymax=2.6))
You should note that ggplot's method for calculating the hinges differs slightly from the method used by boxplot.stats.
# ggplot's hinges
bp = ggplot(data=df, aes(x=1, y=age)) +
geom_boxplot(outlier.shape=NA, size=1)
bpData = ggplot_build(bp)
bpData$data[[1]][1:5]
Alternative answer using gtable functions to position the boxplot outside the main plot. The height of the box plot can be adjusted using the "h" parameter
library(rms)
# Data
data(pbc)
d <- pbc
rm(pbc)
d$status <- ifelse(d$status != 0, 1, 0)
dd = datadist(d)
options(datadist='dd')
f <- cph(Surv(time, status) ~ rcs(age, 4), data=d)
p <- Predict(f, fun=exp)
df <- data.frame(age=p$age, yhat=p$yhat, lower=p$lower, upper=p$upper)
# X-axis
breaks <- boxplot.stats(p[,"age"])$stats
# Main plot
MP <- ggplot(data=df, aes(x=age, y=yhat)) + geom_line(size=1) +
geom_ribbon(data=df, aes(ymin=lower, ymax=upper), alpha=0.5, linetype=0, fill='#FFC000') +
theme_bw() +
scale_x_continuous(breaks=breaks) +
xlab("Age") +
ylab("Hazard Ratio") +
theme(axis.line = element_line(color='black', size=1),
axis.ticks = element_line(color='black', size=1),
panel.grid.minor = element_blank())
# Boxplot
BP <- ggplot(data=df, aes(x=factor(1), y=age)) +
geom_boxplot(width = 1, outlier.shape=NA, size=1) +
geom_jitter(position = position_jitter(width = .3), size = 1) +
scale_y_continuous(breaks=breaks) +
coord_flip() +
theme_bw() +
theme(panel.border=element_blank(),
panel.grid=element_blank())
#### Set up the grobs and gtables here
library(gtable)
library(grid)
h = 1/15 # height of boxplot panel relative to main plot panel
# Get ggplot grobs
gMP = ggplotGrob(MP)
BPg = ggplotGrob(BP)
BPg = gtable_filter(BPg, "panel") # from the boxplot, extract the panel only
# In the main plot, get position of panel in the layout
pos = gMP$layout[gMP$layout$name == "panel", c('t', 'l')]
# In main plot, set height for boxplot
gMP$heights[pos$t-2] = unit(h, "null")
# Add boxplot to main plot
gMP = gtable_add_grob(gMP, BPg, t=pos$t-2, l=pos$l)
# Add small space
gMP$heights[pos$t-1] = unit(5, "pt")
# Draw it
grid.newpage()
grid.draw(gMP)
I wish to plot a number of tightly spaced graphs as illustrated by the following toy example:
library(ggplot2)
library(gridExtra)
set.seed(314159)
n <- 100
data <- data.frame(x = rnorm(n), y = rnorm(n), z = rep("dummy var", n))
p00 <- ggplot(data, aes(x)) + stat_density() + theme(plot.margin = unit(c(0,0,0,0), units = "lines" ), axis.text = element_blank(), axis.title = element_blank(), axis.ticks = element_blank()) + labs(x = NULL, y = NULL)
p01 <- ggplot(data, aes(x, y)) + geom_point() + theme(plot.margin = unit(c(0,0,0,0), units = "lines" ), axis.text = element_blank(), axis.title = element_blank(), axis.ticks = element_blank()) + labs(x = NULL, y = NULL)
p10 <- ggplot(data, aes(y, x)) + geom_point() + theme(plot.margin = unit(c(0,0,0,0), units = "lines" ), axis.text = element_blank(), axis.title = element_blank(), axis.ticks = element_blank()) + labs(x = NULL, y = NULL)
p11 <- ggplot(data, aes(y)) + stat_density() + theme(plot.margin = unit(c(0,0,0,0), units = "lines" ), axis.text = element_blank(), axis.title = element_blank(), axis.ticks = element_blank()) + labs(x = NULL, y = NULL)
grid.arrange(p00, p01, p10, p11, ncol = 2)
In spite of my best efforts, I have been unable to overcome a complication that arises when I attempt to do so after having removed the facet strips from my graphs. In the following example, I have added horizontal and vertical strips to each graph by faceting on a dummy variable:
p00 <- p00 + facet_grid(z ~ z)
p01 <- p01 + facet_grid(z ~ z)
p10 <- p10 + facet_grid(z ~ z)
p11 <- p11 + facet_grid(z ~ z)
grid.arrange(p00, p01, p10, p11, ncol = 2)
Next I remove the strips according to the procedure outlined in this post. However, the resulting graphs are rather widely spaced by comparison:
p00 <- p00 + theme(plot.margin = unit(c(0,0.5,0.5,0), units = "lines" ), strip.background = element_blank(), strip.text = element_blank())
p01 <- p01 + theme(plot.margin = unit(c(0,0.5,0.5,0), units = "lines" ), strip.background = element_blank(), strip.text = element_blank())
p10 <- p10 + theme(plot.margin = unit(c(0,0.5,0.5,0), units = "lines" ), strip.background = element_blank(), strip.text = element_blank())
p11 <- p11 + theme(plot.margin = unit(c(0,0.5,0.5,0), units = "lines" ), strip.background = element_blank(), strip.text = element_blank())
grid.arrange(p00, p01, p10, p11, ncol = 2)
Any suggestions on how to reduce the spacing between graphs would be much appreciated.
To remove all elements associated with the axes, in addition to the elements you have set to element_blank, the tick margins and tick lengths need to be set to zero. But space will remain for the facet strips. Setting the background and text to element_blank does not affect the height and width of the strips. To remove the strips, I use functions that manipulate the gtable layout. However, I think it is better to leave some white space between the plots. I have set a small plot margin to 0.2 lines.
library(ggplot2)
library(gridExtra)
set.seed(314159)
n <- 100
data <- data.frame(x = rnorm(n), y = rnorm(n), z1 = rep("dummy var", n), z2 = rep("dummy var", n))
theme = theme(plot.margin = unit(c(.2,.2,.2,.2), units = "lines"),
axis.text = element_blank(),
axis.title = element_blank(),
axis.ticks = element_blank(),
axis.ticks.length = unit(0, "lines"))
labs = labs(x = NULL, y = NULL)
p00 <- ggplot(data, aes(x)) + stat_density() + theme + labs + facet_grid(z1 ~ z2)
p01 <- ggplot(data, aes(x, y)) + geom_point() + theme + labs + facet_grid(z1 ~ z2)
p10 <- ggplot(data, aes(y, x)) + geom_point() + theme + labs + facet_grid(z1 ~ z2)
p11 <- ggplot(data, aes(y)) + stat_density() + theme + labs + facet_grid(z1 ~ z2)
This is where the gtable layout is manipulated.
# Get the four gtables (and the four plots) into a list
pList = list(p00, p01, p10, p11)
gList = lapply(pList, ggplotGrob)
# Remove the top strip from each plot
stripT <- subset(gList[[1]]$layout, grepl("strip-t", gList[[1]]$layout$name))
gList = lapply(gList, function(x) x[-stripT$t, ])
# Remove the right strip from each plot
stripR <- subset(gList[[1]]$layout, grepl("strip-r", gList[[1]]$layout$name))
gList = lapply(gList, function(x) x[, -stripR$r])
# Draw the revised plots
nCol <- floor(sqrt(length(pList)))
do.call(grid.arrange, c(gList, ncol = nCol))
Edit: Using revised data and plot.
library(grid)
data <- data.frame(x = rnorm(n), y = rnorm(n), z = rep("dummy var", n), u = seq(1, n) %% 2)
p01 <- ggplot(data, aes(x, y)) + geom_point() + theme + labs + facet_grid(z ~ u)
g = ggplotGrob(p01)
stripT = subset(g$layout, grepl("strip-t", g$layout$name))
g = g[-stripT$t, ]
stripR = subset(g$layout, grepl("strip-r", g$layout$name))
g = g[, -stripR$r]
grid.draw(g) # Still got the space between the facets
g$widths # where is the space? it's the 5.55 pt width
g$widths[[5]] = unit(0, "lines") # remove it completely
g$width
grid.draw(g)