In multi-panel/faceted plots, I like when it\'s feasible to squash the panels together with no space between them, e.g. using theme(panel.spacing=grid::unit(0,\"lines\"))<
EDIT Updated to ggplot2 ver 3.0.0
One possibility might be to modify the build data. It is possible to take the limits of the original plot, and apply a multiplicative expansion factor. The relative positions of the major and minor breaks also need adjustment. Note that the function allows selection of the panels to which the expansion is to apply.
What's the difference between this and using expand
within scale_y_continuous
(apart from being able to select the panels)? This function leaves the breaks (and the tick marks and grid lines) as they were in the original. It's just that they take up less space. expand
, however, will compress the scale but ggplot will add new labels, grid lines and tick marks if it can.
It would not take much to break the function - ggplot has been known to change the names of the elements of the build data in recent versions.
dd <- data.frame(x=rep(1:3,3),
y=c(0.1,0.2,0.3,
0.1,0.4,0.6,
1,2,3),
f=factor(rep(letters[1:3],each=3)))
library(ggplot2)
p = ggplot(dd,aes(x,y))+
facet_grid(f~.,scale="free")+
geom_point()+
theme_bw(base_size=24)+
theme(panel.spacing=grid::unit(0,"lines"))
expand = function(plot, mult = 0.1, applyTo) {
# Get the build data
gd = ggplot_build(plot)
# Get the original limits,
# and calculate the new limits,
# expanded according to the multiplicative factor
limits <- sapply(gd$layout$panel_params, "[[", "y.range") # Original limits
fac = mult*(limits[2,] - limits[1, ])
newlimits = rbind(limits[1, ] - fac, limits[2, ] + fac)
# The range for the new limits
range = newlimits[2, ] - newlimits[1, ]
# Calculate the new y.major and y.minor relative positions
# and put them along with the new limits back into the build data
N = dim(gd$layout$panel_params)[1] # Number of panels
for(i in applyTo) {
y.major = (gd$layout$panel_params[[i]]$y.major_source - newlimits[1, i]) / range[i]
y.minor = (gd$layout$panel_params[[i]]$y.minor_source - newlimits[1, i]) / range[i]
gd$layout$panel_params[[i]]$y.range = newlimits[, i]
gd$layout$panel_params[[i]]$y.major = y.major
gd$layout$panel_params[[i]]$y.minor = y.minor
}
# Get the gtable
ggplot_gtable(gd)
}
# Plot it
grid::grid.draw(expand(p, mult = 0.1, applyTo = 1:2))
Original
Modified