Force x-axis labels on facet_grid ggplot: x-axis labels differ per row

匿名 (未验证) 提交于 2019-12-03 08:54:24

问题:

I was so happy to find the greater part of a solution to my question in the post, "Force X axis text on for all facets of a facet_grid plot".

I'd like to create a graph to look somewhat like the OP Drew Steen's, except I have more than two rows of facets, and I'd like to make the x-axes labels different for each row.

I made a super-hacky solution out of @baptiste's awesome answer (mostly because I am unfamiliar with the gtable package), and I'd like to know:

  1. If there is a more elegant solution than the mess I wrote below
  2. How to insert labels for the "Premium" (middle) row.

Here is the code I adapted from @Drew Steen and @baptiste,

library(ggplot2)  diamondSub <-subset(diamonds, (cut=="Ideal" | cut=="Premium" | cut == "Very Good") & (color=="E" | color=="I"))  p<- ggplot(diamondSub, aes(x=carat, y=price)) +    geom_blank()+    geom_point() +   scale_x_discrete(breaks=c(1, 2, 3, 4), labels=c("a", "b", "c", "d")) +   facet_grid(cut~color, scales="free_x") p  p2<- ggplot(diamondSub, aes(x=carat, y=price)) +    geom_blank()+    geom_point() +   scale_x_discrete(breaks=c(1, 2, 3, 4), labels=c("f", "g", "h", "i")) +   facet_grid(cut~color, scales="free_x") p2  library(gtable)  g <- ggplotGrob(p) g2 <- ggplotGrob(p2)  # locate the panels panels <- grep("panel", g$layout$name) panels2 <- grep("panel", g2$layout$name)  top <- unique(g$layout$t[panels]) top2 <- unique(g2$layout$t[panels2]) # intersperse a copy of the bottom axes all <- gtable:::rbind_gtable(gtable:::rbind_gtable(g[seq.int(min(top)), ],                                                     g[max(top)+1,], "first"),                               g2[seq(min(top2)+1, nrow(g2)),], "first") grid.newpage() grid.draw(all)

回答1:

Alternative Version (added 24 April 2015) showing manual construction of the elements and containing more commenting.

## Alternative version library(gtable) library(grid)  # Get the ggplot grobs g <- ggplotGrob(p) g2 <- ggplotGrob(p2)  # Show the layout. # Note the rows and columns # In this case, the g2 layout is the same as the g layout gtable_show_layout(g)  # The large panels are the plot panels. # We will need rows 4, 6 and 8.  # For the top "Very Good" row, we will also need rows 1, 2, and 3.  # The axis is located in row 9  # Therefore rbind the grob in rows 1, 2, 3, and 4, with the grob in row 9. top.row <- rbind(g[1:4, ], g[9, ], size = "first")  # The second "Premium" row # We need the panels in row 6 plus the small gap row above, # and rbind that to the axis middle.row = rbind(g2[5:6, ], g2[9,], size = "first")  # The bottom "Ideal" row # We need the panel in row 8 plus the small gap in the row above # plus the axis in the row below # plus rows below that (axis label and margin) bottom.row = g2[7:11, ]   # rbind the three rows  all <- rbind(rbind(top.row, middle.row, size = "first"), bottom.row, size = "first")  # Draw it grid.newpage() grid.draw(all)  # Maybe add a little more space between the rows gtable_show_layout(all) all$heights[c(6,9)] = unit(1, "lines")  # Draw it grid.newpage() grid.draw(all)

But you don't even need to do the binding of the panel to the axis; just select the appropriate rows from the layout:

top.row <- g[c(1:4, 9), ] middle.row = g2[c(5:6, 9), ] bottom.row = g2[7:11, ]

then bind these three new rows.

Original Version

It is only in the binding of the rows that you have made a mistake. You have bound an axis to the top "Very Good" row. The bottom "Ideal" row already has an axis, so no binding is required. To Fix: The middle "Premium" row needs an axis.

I have constructed each row separately, binding an axis to the top and middle rows, then binding the three rows.

I've added another step to add a little more space between the rows.

g <- ggplotGrob(p) g2 <- ggplotGrob(p2)  # locate the panels panels <- grep("panel", g$layout$name) panels2 <- grep("panel", g2$layout$name)  top <- unique(g$layout$t[panels]) top2 <- unique(g2$layout$t[panels2])  # Construct each row separately top.row <- gtable:::rbind_gtable(g[seq.int(min(top)), ], g[max(top)+1,], "first") middle.row <- gtable:::rbind_gtable(g2[c(top[2]-1,top[2]), ], g2[max(top)+1,], "first") bottom.row <- g2[(max(top2)-1):nrow(g2), ]  all <- gtable:::rbind_gtable(gtable:::rbind_gtable(top.row, middle.row, "first"), bottom.row, "first")  # Draw it grid.newpage() grid.draw(all)  # Maybe add a little more space between the rows all$heights[c(6,9)] = unit(1, "lines")  grid.newpage() grid.draw(all)



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!