从ggplot或gtable/gTree/grob/gDesc对象中检索facet标签

3

我需要使用 ggplotfacet_grid 绘制数据:

我的数据如下:

species <- c("spcies1","species2")
conditions <- c("cond1","cond2","cond3")
batches <- 1:6

df <- expand.grid(species=species,condition=conditions,batch=batches)

set.seed(1)
df$y <- rnorm(nrow(df))
df$replicate <- 1
df$col.fill <- paste(df$species,df$condition,df$batch,sep=".")

我的情节:

integerBreaks <- function(n = 5, ...)
{
  library(scales)
  breaker <- pretty_breaks(n, ...)
  function(x){
    breaks <- breaker(x)
    breaks[breaks == floor(breaks)]
  }
}

library(ggplot2)
p <- ggplot(df,aes(x=replicate,y=y,color=col.fill))+
  geom_point(size=3)+facet_grid(~col.fill,scales="free_x")+
  scale_x_continuous(breaks=integerBreaks())+
  theme_minimal()+theme(legend.position="none",axis.title=element_text(size=8))

这将会产生以下内容: enter image description here

显然,标签太长,在图表中显得非常混乱,因此我想知道是否有一种方法可以在ggplot对象(p)或者gtable/gTree/grob/gDesc对象(ggplotGrob(p))中编辑这些标签。

我知道在创建ggplot对象时使用labeller函数可以获得更好的标签,但在我的情况下,我特别寻找一种在创建ggplot对象之后编辑分面标签的方法。


你想让他们改成什么?这些标签在ggplotGrob(p)生成的gtable中嵌套得相当深。 - Mike H.
我想让它们变成:gsub("cond","c",df$condition) - dan
啊,我明白了,这大概就是为什么你不只是在分面中使用那个变量的原因吧?因为你希望它们仍然是自己的分面? - Mike H.
是的,这更或多或少是情况。它是长代码的一部分,在生成ggplot后测试是否可以根据某些条件编辑facet标签,在这个例子中恰好满足这些条件。再次说明,我知道SO有一些帖子介绍如何在生成ggplot对象时创建标签,但在我的情况下,如果可以在ggplot或ggplotGrob(p)对象中编辑标签,那么事情会变得更容易。 - dan
1个回答

4

正如我在评论中提到的那样,这些方面的名称在gtable中嵌套得非常深,而ggplotGrob()给出的。然而,这仍然是可能的,并且由于OP明确希望在绘制后对它们进行编辑,您可以通过以下方式实现:

library(grid)
gg <- ggplotGrob(p)

edited_grobs <- mapply(FUN = function(x, y) {
                                  x[["grobs"]][[1]][["children"]][[2]][["children"]][[1]][["label"]] <- y
                                  return(x)
                              },
                        gg$grobs[which(grepl("strip-t",gg$layout$name))],
                        unique(gsub("cond","c", df$condition)),
                        SIMPLIFY = FALSE)

gg$grobs[which(grepl("strip-t",gg$layout$name))] <- edited_grobs
grid.draw(gg)

enter image description here

请注意,这里使用gg$grobs[which(grepl("strip-t",gg$layout$name))]提取所有条带,并将它们传递给mapply,以使用OP在评论中指定的gsub(...)进行重置。
一般来说,如果您只想访问一个文本标签,则有一个非常类似的结构,我在我的mapply中使用了它。
num_to_access <- 1
gg$grobs[which(grepl("strip-t",gg$layout$name))][[num_to_access]][["grobs"]][[1]][["children"]][[2]][["children"]][[1]]$label

所以,要访问第四个标签,例如,您只需要更改`num_to_access`为4。希望这可以帮助您!

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