在多面条形图中添加标题标签

adding title labels inside faceted barplots

我正在创建一个多面条形图显示(每个图 = 不同的元素,条形图 = 区域),而不是在上面的条带中为每个图设置标题,我想将它们插入实际的图中。每个图都有一个截然不同的 y-axis 所以我正在为如何为标题标签定义一致的 y 位置而苦苦挣扎。 到目前为止我的代码:我正在考虑使用 geom_text 添加标签?


    p1 <- ggplot(data = data, aes(region, concentration, fill = region)) + 
      geom_bar(stat="summary", fun = mean) +
      facet_wrap(~element,scales="free_y")+
      ylab("Element Concentration") +
      theme(strip.background = element_rect(fill=NA, color=NA),
            panel.background = element_rect(fill=NA, color="gray60"),
            panel.grid.major = element_blank(),
            panel.grid.minor = element_blank(),
            panel.spacing.x=unit(0, "lines"),
            panel.spacing.y=unit(.3, "lines"),
            strip.text = element_blank(),
            axis.title.x=element_blank(),
            axis.text.x=element_blank(),
            axis.ticks.x=element_blank()) +
      scale_x_discrete(expand = c(0, 0)) + 
      scale_y_continuous(expand = expansion(mult = c(0, 0.3)))

what I have

what I want

另外:如果有人熟悉如何为 y 轴标签执行以下操作,那就太好了: 我的 y 实验室需要说:“Element Concentration μg element/g Ca” 真的很难添加轴标题的微克部分。

一个选项是 gggrid 包,它类似于 ggplot2::annotation_custom 允许使用相对坐标将 grobs 放在 ggplot 上(因此适用于不同的数据范围)但不同于 ggplot2::annotation_custom 允许在每个面上放置不同的 grobs。为此

  1. 编写一个自定义函数,它接受两个参数(datacoords)并创建 textGrobs

  2. 使用 gggrid::grid_panel 将 grob 添加到我们映射 element 的每个方面或面板,例如label 美学。

使用一些虚假的随机数据:

library(ggplot2)
library(gggrid)
#> Loading required package: grid
library(grid)

title_label <- function(data, coords) {
  textGrob(unique(data$label),
    x = unit(.5, "npc"),
    y = unit(1, "npc") - unit(2, "mm"),
    vjust = 1,
    gp = gpar(fontsize = 10)
  )
}

ggplot(data = data, aes(region, concentration, fill = region)) +
  geom_bar(stat = "summary", fun = mean) +
  grid_panel(title_label, aes(label = element)) +
  facet_wrap(~element, scales = "free_y") +
  ylab("Element Concentration") +
  theme(
    strip.background = element_rect(fill = NA, color = NA),
    panel.background = element_rect(fill = NA, color = "gray60"),
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(),
    panel.spacing.x = unit(0, "lines"),
    panel.spacing.y = unit(.3, "lines"),
    strip.text = element_blank(),
    axis.title.x = element_blank(),
    axis.text.x = element_blank(),
    axis.ticks.x = element_blank()
  ) +
  scale_x_discrete(expand = c(0, 0)) +
  scale_y_continuous(expand = expansion(mult = c(0, 0.3)))

数据

set.seed(123)

data <- data.frame(
  region = sample(LETTERS[1:5], 100, replace = TRUE),
  concentration = unlist(lapply(1:5, function(x) runif(20, 0, 2 * x))),
  element = paste("element", 1:5)
)