I'd approach this by making 2 plots, one of the plot area and one of the axis labels, then stick them together with a package like cowplot
. You can use some theme settings to disguise the fact that the axis labels are actually made by a geom_text
.
The first plot is fairly straightforward. For the second which becomes the axis labels, use dummy data with the same variables and adjust spacing how you want via text size and scale expansion. You'll probably also want to mess with the rel_heights
argument in plot_grid
to change the ratio of the two charts' heights.
library(ggplot2)library(cowplot)p1 <- ggplot(diamonds, aes(x = cut_label, y = carat)) + facet_grid(cols = vars(cut), scales = "free_x") + theme(axis.text.x = element_blank()) + labs(x = NULL)axis <- ggplot(dplyr::distinct(diamonds, cut_label, cut), aes(x = cut_label, y = 1)) + geom_text(aes(label = cut_label), angle = 90, hjust = 0, size = 3.5) + facet_grid(cols = vars(cut), scales = "free_x") + scale_x_discrete(breaks = NULL) + scale_y_continuous(expand = expansion(add = c(0.1, 1)), breaks = NULL) + labs(y = NULL) + theme(strip.text = element_blank(), axis.text.x = element_blank(), axis.ticks = element_blank(), panel.background = element_blank())plot_grid(p1, axis, ncol = 1, axis = "lr", align = "v")