在facet_grid ggplot上强制x轴标签:x轴标签每行不同

时间:2014-11-17 02:19:21

标签: r plot ggplot2 facet gtable

我很高兴在帖子中找到问题解决方案的大部分内容," Force X axis text on for all facets of a facet_grid plot"

我想创建一个看起来有点像OP Drew Steen的图表,除了我有两行以上的刻面,我想制作x轴标签每一行都不同。

我用@ baptiste的一个很棒的答案做了一个超级hacky的解决方案(主要是因为我不熟悉gtable包),我想知道:

  1. 如果有比我下面写的那些混乱更优雅的解决方案
  2. 如何为" Premium"添加标签。 (中)排。
  3. 以下是我改编自@Drew Steen和@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)
    

    see graph

1 个答案:

答案 0 :(得分:2)

替代版本(2015年4月24日添加)显示了元素的手动构建并包含更多评论。

## 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)

但你甚至不需要将面板绑定到轴上;只需从布局中选择适当的行:

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

然后绑定这三个新行。

原始版

只有在行绑定时才会出错。你已经将一个轴绑定到顶部&#34;非常好&#34;行。底部&#34;理想&#34; row已经有一个轴,因此不需要绑定。修复:中间&#34; Premium&#34;行需要一个轴。

我已分别构造每一行,将轴绑定到顶行和中行,然后绑定三行。

我已添加了另一个步骤,可以在行之间添加更多空间。

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)

enter image description here