Force X axis text on for all facets of a facet_grid plot
Asked Answered
G

2

22

I have the same problem as this user: I'd like to make a facet_grid plot with a discrete x-axis, and I'd like to have the x-axis labels be written under each facet rather than only underneath the bottom row of facets. For instance:

# Drop some factor levels to make the plot smaller 
diamondSub <- subset(diamonds, (cut=="Ideal" | cut=="Premium") & 
                     (color=="E" | color=="I"))

# Note that scales="free_x" has no practical effect here
ggplot(diamondSub, aes(x=clarity, y=price)) + 
  geom_blank()+ 
  geom_boxplot() +
  facet_grid(cut~color, scales="free_x")

enter image description here

However, I'd prefer not to use the solution from that post, which was just to use facet_wrap instead of facet_grid, because I prefer the way facet_grid labels the strip text with one variable on top of the columns, and the other variable on the sides of the rows.

Is there a way to get x-axis labels under each facet, when all the x-axes are actually the same, using facet_grid?

Geomorphic answered 15/7, 2013 at 18:17 Comment(0)
S
19

You can insert a copy of the axes inside the gtable,

library(gtable)
g <- ggplotGrob(p)
# locate the panels
panels <- grep("panel", g$layout$name)
top <- unique(g$layout$t[panels])
# intersperse a copy of the bottom axes
all <- gtable:::rbind_gtable(gtable:::rbind_gtable(g[seq.int(min(top)), ], 
                                                   g[max(top)+1,], "first"), 
                             g[seq(min(top)+1, nrow(g)),], "first")
grid.newpage()
grid.draw(all)

enter image description here

Slicer answered 15/7, 2013 at 18:32 Comment(10)
I get error while running the line all <- gtable:::rbind_gtable(gtable:::rbind_gtable(g[1:4],g[7,]), g[5:9,]). The error I got is Error in UseMethod("grid.draw") : no applicable method for 'grid.draw' applied to an object of class "function". I believe p refers to ggplot object, is that true ?Bornstein
yes, p is your ggplot. What do you get with print(all)? It should be a TableGrob (10 x 8) "layout": 16 grobs etc.Slicer
The error I got now is as follows: > all <- gtable:::rbind_gtable(gtable:::rbind_gtable(g[1:4],g[7,]), g[5:7,]) Error in mmm < each : comparison of these types is not implementedBornstein
I see. That's because I grew tired of this and fixed it in my own version of gtable. Try the updated code.Slicer
It seems to work but the final figure doesn't look like the figure you posted. On my machine the y-axis get overlapped. The final figure looks like this: [1]: i.sstatic.net/2wzE8.pngBornstein
strange,; make sure you don't forget to issue grid.newpage() between new plots, otherwise they get drawn on top of each other.Slicer
+1 grid.newpage() seems to solve the problem. Thank you. May you you can add grid.newpage() on your code.Bornstein
Great way to add axes to every facet, however I seem to have lost the y-axis label. Any thought on how to recover that?Chibouk
Is this "workaround" still the best solution for this question? Why does not ggplot support the x-axis in all subplots? @ChiboukEndospore
worked, but only for 2 x 2, what about other arranges... 3x1 3x2 3x3 3x4 3x5Klara
J
1

Script can be much simpler by using cbind.gtable:

library(gtable)
g <- ggplotGrob(p)
# locate the panels
panels <- grep("panel", g$layout$name)
top <- unique(g$layout$t[panels])

# intersperse a copy of the bottom axes
all <- gtable:::cbind.gtable(
    g[seq.int(min(top)), ], 
    g[max(top)+1,],
    g[seq(min(top)+1, nrow(g)),], 
    size = "first")
grid.newpage()
grid.draw(all)
Jennajenne answered 3/10, 2018 at 0:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.