An alternative answer using gtable functions to place a rectangle outside the main chart. Window graph height can be adjusted using parameter "h"
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)

source share