I suggest the axis_canvas
function from the cowplot package. (Disclaimer: I'm the package author.) It requires a little more work, but it allows you to draw any marginals you want. And you can specify the size exactly, in output units (e.g. inch).
require(cowplot)
pmain <- ggplot(data = mpg, aes(x = cty, y = hwy)) +
geom_point() +
xlab("City driving (miles/gallon)") +
ylab("Highway driving (miles/gallon)")
xbox <- axis_canvas(pmain, axis = "x", coord_flip = TRUE) +
geom_boxplot(data = mpg, aes(y = cty, x = 1)) + coord_flip()
ybox <- axis_canvas(pmain, axis = "y") +
geom_boxplot(data = mpg, aes(y = hwy, x = 1))
p1 <- insert_xaxis_grob(pmain, xbox, grid::unit(1, "in"), position = "top")
p2 <- insert_yaxis_grob(p1, ybox, grid::unit(1, "in"), position = "right")
ggdraw(p2)
See how the boxplots retain their width/height in the following two images with different aspect ratios. (Unfortunately Stackoverflow rescales the images, so the effect is somewhat obscured, but you can see that the height of the top boxplot is always equal to the width of the side one.)


The second advantage is that because you can use full-blown ggplot2 for your marginal plots, you can draw anything you want, e.g. grouped box plots.
require(cowplot)
pmain <- ggplot(data = mpg, aes(x = cty, y = hwy, color = factor(cyl))) +
geom_point() +
xlab("City driving (miles/gallon)") +
ylab("Highway driving (miles/gallon)") +
theme_minimal()
xbox <- axis_canvas(pmain, axis = "x", coord_flip = TRUE) +
geom_boxplot(data = mpg, aes(y = cty, x = factor(cyl), color = factor(cyl))) +
scale_x_discrete() + coord_flip()
ybox <- axis_canvas(pmain, axis = "y") +
geom_boxplot(data = mpg, aes(y = hwy, x = factor(cyl), color = factor(cyl))) +
scale_x_discrete()
p1 <- insert_xaxis_grob(pmain, xbox, grid::unit(1, "in"), position = "top")
p2 <- insert_yaxis_grob(p1, ybox, grid::unit(1, "in"), position = "right")
ggdraw(p2)
