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

Retrieve facet labels from a ggplot or a gtable/gTree/grob/gDesc object

我有正在使用 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))

给出:

显然标签很长而且在图中看起来很乱所以我想知道是否有办法在 ggplot 对象 (p) 或 gtable/gTree/grob/gDesc 对象 (ggplotGrob(p)).

我知道获得更好标签的一种方法是在创建 ggplot 对象时使用 labeller function,但在我的例子中,我专门寻找一种编辑方面的方法ggplot 对象创建后的标签。

正如我在评论中提到的,方面名称嵌套在 ggplotGrob() 给你的 gtable 中。然而,这仍然是可能的,因为 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)

请注意,这会使用 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

例如,要访问第 4 个标签,您需要做的就是将 num_to_acces 更改为 4。希望这对您有所帮助!