I would like to remove the redundancy of strip labels when using facet_wrap()
and faceting with two variables and both scales free.
For example, this facet_wrap
version of the following graph
library(ggplot2)
dt <- txhousing[txhousing$year %in% 2000:2002 & txhousing$month %in% 1:3,]
ggplot(dt, aes(median, sales)) +
geom_point() +
facet_wrap(c("year", "month"),
labeller = "label_both",
scales = "free")
should have the looks of this facet_grid
version of it, where the strip labels are at the top and right edge of the graph (could be bottom and left edge as well).
ggplot(dt, aes(median, sales)) +
geom_point() +
facet_grid(c("year", "month"),
labeller = "label_both",
scales = "free")
Unfortunately, using facet_grid
is not an option because, as far as I understand, it doesn't allow scales to be "completely free" - see here or here
One attempt that I thought about would be to produce separate plots and then combine them:
library(cowplot)
theme_set(theme_gray())
p1 <- ggplot(dt[dt$year == 2000,], aes(median, sales)) +
geom_point() +
facet_wrap("month", scales = "free") +
labs(y = "2000") +
theme(axis.title.x = element_blank())
p2 <- ggplot(dt[dt$year == 2001,], aes(median, sales)) +
geom_point() +
facet_wrap("month", scales = "free") +
labs(y = "2001") +
theme(strip.background = element_blank(),
strip.text.x = element_blank(),
axis.title.x = element_blank())
p3 <- ggplot(dt[dt$year == 2002,], aes(median, sales)) +
geom_point() +
facet_wrap("month", scales = "free") +
labs(y = "2002") +
theme(strip.background = element_blank(),
strip.text.x = element_blank())
plot_grid(p1, p2, p3, nrow = 3)
I am ok with the above hackish attempt, but I wonder if there is something in facet_wrap
that could allow the desired output. I feel that I miss something obvious about it and maybe my search for an answer didn't include the proper key words (I have the feeling that this question was addressed before).
The facet_grid() function will produce a grid of plots for each combination of variables that you specify, even if some plots are empty. The facet_wrap() function will only produce plots for the combinations of variables that have values, which means it won't produce any empty plots.
facet_grid() forms a matrix of panels defined by row and column faceting variables. It is most useful when you have two discrete variables, and all combinations of the variables exist in the data.
Facet labelsSetting strip. text to element_blank() will remove all facet labels. You can also remove the labels across rows only with strip.
facet_wrap() makes a long ribbon of panels (generated by any number of variables) and wraps it into 2d. This is useful if you have a single variable with many levels and want to arrange the plots in a more space efficient manner.
This does not seem easy, but one way is to use grid graphics to insert panel strips from a facet_grid plot into one created as a facet_wrap. Something like this:
First lets create two plots using facet_grid and facet_wrap.
dt <- txhousing[txhousing$year %in% 2000:2002 & txhousing$month %in% 1:3,]
g1 = ggplot(dt, aes(median, sales)) +
geom_point() +
facet_wrap(c("year", "month"), scales = "free") +
theme(strip.background = element_blank(),
strip.text = element_blank())
g2 = ggplot(dt, aes(median, sales)) +
geom_point() +
facet_grid(c("year", "month"), scales = "free")
Now we can fairly easily replace the top facet strips of g1
with those from g2
library(grid)
library(gtable)
gt1 = ggplot_gtable(ggplot_build(g1))
gt2 = ggplot_gtable(ggplot_build(g2))
gt1$grobs[grep('strip-t.+1$', gt1$layout$name)] = gt2$grobs[grep('strip-t', gt2$layout$name)]
grid.draw(gt1)
Adding the right hand panel strips need us to first add a new column in the grid layout, then paste the relevant strip grobs into it:
gt.side1 = gtable_filter(gt2, 'strip-r-1')
gt.side2 = gtable_filter(gt2, 'strip-r-2')
gt.side3 = gtable_filter(gt2, 'strip-r-3')
gt1 = gtable_add_cols(gt1, widths=gt.side1$widths[1], pos = -1)
gt1 = gtable_add_grob(gt1, zeroGrob(), t = 1, l = ncol(gt1), b=nrow(gt1))
panel_id <- gt1$layout[grep('panel-.+1$', gt1$layout$name),]
gt1 = gtable_add_grob(gt1, gt.side1, t = panel_id$t[1], l = ncol(gt1))
gt1 = gtable_add_grob(gt1, gt.side2, t = panel_id$t[2], l = ncol(gt1))
gt1 = gtable_add_grob(gt1, gt.side3, t = panel_id$t[3], l = ncol(gt1))
grid.newpage()
grid.draw(gt1)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With