ggplot2:使用gtable将条带标签移动到facet_grid面板的顶部

10

我正在使用facet_grid创建图形,以在y轴上分割分类变量。我决定不使用facet_wrap,因为我需要space = 'free'labeller = label_parsed。我的标签很长,并且我在右侧有一个图例,所以我想将标签从面板的右侧移动到面板的顶部。

下面是一个示例,展示了我卡住的地方。

library(ggplot2)
library(gtable)

mt <- ggplot(mpg, aes(x = cty, y = model)) + geom_point() +
  facet_grid(manufacturer ~ ., scales = 'free', space = 'free') +
  theme_minimal() +
  theme(panel.margin = unit(0.5, 'lines'), strip.text.y = element_text(angle = 0))

mt.png

我希望将每个图表右侧的文本移到每个图表的顶部。我可以存储条形图标签的 grobs 并将其从图表中移除:

grob <- ggplotGrob(mt)
strips.y <- gtable_filter(grob, 'strip-right')
grob2 <- grob[,-5]

但是,当涉及将这些图形对象(grobs)使用rbind组合在一起时,我现在遇到了困难,因为标签无法放置在面板的顶部。

另一个可能的解决方案是使用facet_wrap,然后重新调整面板大小(在另一个问题中讨论),但在这种情况下,我必须手动更改分面上的标签,因为对于facet_wrap没有labeller=label_parsed

我很感谢对任何一种方法的建议!

感谢阅读,

汤姆

2个回答

8

这是您的第一种方法。它在每个面板上方插入一行,获取条形图(右侧)并将其插入新行中。

library(ggplot2)
library(gtable)
library(grid)

mt <- ggplot(mpg, aes(x = cty, y = model)) + geom_point() +
  facet_grid(manufacturer ~ ., scales = 'free', space = 'free') +
  theme(panel.spacing = unit(0.5, 'lines'), 
         strip.text.y = element_text(angle = 0))

# Get the gtable
gt <- ggplotGrob(mt)

# Get the position of the panels in the layout
panels <-c(subset(gt$layout, grepl("panel", gt$layout$name), se=t:r))

# Add a row above each panel
for(i in rev(panels$t-1)) gt = gtable_add_rows(gt, unit(.5, "lines"), i)

# Get the positions of the panels and the strips in the revised layout
panels <-c(subset(gt$layout, grepl("panel", gt$layout$name), se=t:r))
strips <- c(subset(gt$layout, grepl("strip-r", gt$layout$name), se=t:r))

# Get the strip grobs
stripText = gtable_filter(gt, "strip-r")

# Insert the strip grobs into the new rows
for(i in 1:length(strips$t)) gt = gtable_add_grob(gt, stripText$grobs[[i]]$grobs[[1]],  t=panels$t[i]-1, l=4)

# Remove the old strips
gt = gt[,-5]

# For this plot - adjust the heights of the strips and the empty row above the strips
for(i in panels$t) {
   gt$heights[i-1] = unit(0.8, "lines")
   gt$heights[i-2] = unit(0.2, "lines")
   }

# Draw it
grid.newpage()
grid.draw(gt)

enter image description here

或者,您可以使用facet_wrap_labeller函数(从这里获取)来实现第二种方法。

library(ggplot2)
library(gtable)

mt <- ggplot(mpg, aes(x = cty, y = model)) + geom_point() +
   facet_wrap(~ manufacturer, scales = "free_y", ncol = 1) +
   theme(panel.margin = unit(0.2, 'lines'))


facet_wrap_labeller <- function(gg.plot, labels=NULL) {
  require(gridExtra)

  g <- ggplotGrob(gg.plot)
  gg <- g$grobs      
  strips <- grep("strip_t", names(gg))

  for(ii in seq_along(labels))  {
    modgrob <- getGrob(gg[[strips[ii]]], "strip.text", 
                       grep=TRUE, global=TRUE)
    gg[[strips[ii]]]$children[[modgrob$name]] <- editGrob(modgrob,label=labels[ii])
  }

  g$grobs <- gg
  class(g) = c("arrange", "ggplot",class(g)) 
  return(g)
}

## Number of y breaks in each panel
g <- ggplot_build(mt) 
N <- sapply(lapply(g$panel$ranges, "[[", "y.major"), length)

# Some arbitrary strip texts
StripTexts = expression(gamma[1], sqrt(gamma[2]), C, `A really incredibly very very very long label`, gamma[5], alpha[1], alpha[2], `Land Rover`, alpha[1], beta[2], gamma^2, delta^2, epsilon[2], zeta[3], eta[4] )

 # Apply the facet_wrap_labeller function
gt = facet_wrap_labeller(mt, StripTexts)

# Get the position of the panels in the layout
panels <- gt$layout$t[grepl("panel", gt$layout$name)]

# Replace the default panel heights with relative heights
gt$heights[panels] <- lapply(N, unit, "null")

# Draw it
gt

enter image description here


3
非常好,谢谢。我对你的第一种方法进行了一些小改动,以便我可以将其转换为函数:for(i in 1:length(strips$t)) gt = gtable_add_grob(gt, stripText$grobs[[i]], t=panels$t[i]-1, l=4, r=4) -> for(i in 1:length(strips$t)) gt = gtable_add_grob(gt, stripText$grobs[[i]], t=panels$t[i]-1, l=min(panels$l), r=max(panels$r)) 来插入新的条带grobs和 gt = gt[,-5] -> gt <- gt[,-c(min(strips$l), max(strips$r))] 去除旧的条带。 - Tom Harrop
有没有更新版本适用于当前的ggplot2?条带的标签不同等等。我无法使其工作。 - Jan Stanstrup
@JanStanstrup 第一个版本已经编辑完毕,目前正常运行。请耐心等待 - 第二个版本即将推出。 - Sandy Muspratt

1

我曾遇到一个类似的问题,但是将标签放在底部。我使用了这个答案的代码适应。最近发现

ggplot2 ver.2.2.1.0(http://docs.ggplot2.org/current/facet_grid.html

~facet_grid(.~variable,switch='x')

这个选项对我非常有效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接