带有自定义 x 轴标签的 ggplot2 Facet_wrap 图?

Jor*_* E. 1 r ggplot2 facet-wrap axis-labels

我有一个 ggplot2 对象,使用 facet_wrap 在一张图像中制作 26 个单独的直方图,但我想为每个图形分配单独的 x 标签(每个轴上的数字按原样就好,我只想在下面放置一些自定义文本每个情节)。我在 google 和 stackoverflow 上上下搜索,试图找到答案,但没有成功。

che*_*123 6

有几种方法可以做到这一点......但没有一种方法像您可能期望的那样非常直接。我假设您想要用新标题替换默认的 x 轴标题,所以我们将从那里开始。这是数据集中的一个示例iris

library(ggplot2)

p <- ggplot(iris, aes(Sepal.Length, Sepal.Width)) +
  geom_point() +
  facet_wrap(~Species)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

使用条带文本放置

为每个轴创建特定的轴标题的一种方法是使用条带文本(也称为构面标签)。这个想法是将条带文本放置在构面的底部(通常默认情况下位于顶部)并弄乱格式。

ggplot(iris, aes(Sepal.Length, Sepal.Width)) +
  geom_point() +
  labs(x=NULL) +    # remove axis title
  facet_wrap(
    ~Species,
    strip.position = "bottom") +  # move strip position
  theme(
    strip.placement = "outside",   # format to look like title
    strip.background = element_blank()
  )
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

这里我们做几件事:

  1. 删除轴标题
  2. 将条形文本位置移动到底部,然后
  3. 通过删除周围的矩形并确保将其放置在轴刻度下方的绘图区域“外部”,将条带文本格式化为看起来像轴标题

使用 Facet 标签制作您自己的标签

做我们上面做的事情怎么样……但是制作自己的标签?您可以通过设置命名向量来调整条带文本标签(小平面标签)as.labeller()。否则,与上面的更改相同。这是一个例子:

my_strip_labels <- as_labeller(c(
  "setosa" = "My Setosa",
  "versicolor" = "Your versicolor",
  "virginica" = "Some other stuff"
))

ggplot(iris, aes(Sepal.Length, Sepal.Width)) +
  geom_point() +
  labs(x=NULL) +
  facet_wrap(
    ~Species, labeller = my_strip_labels,  # add labels
    strip.position = "bottom") +
  theme(
    strip.placement = "outside",
    strip.background = element_blank()
  )
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

保留刻面标签

如果您想保留构面标签,而只在每个构面下方添加轴标题,该怎么办?好吧,也许你可以通过annotation_custom()制作一些 grobs 来做到这一点,但我认为将它们作为文本几何对象放置可能更容易。为此,我们的想法是在绘图区域之外添加文本几何图形,并将标签文本本身映射到面。您需要使用单独的数据框来执行此操作(以避免过度标记),并且数据框需要包含两列:一列的标签与分面列的标签相同,另一列用于存储我们首选的轴标题文本。

这是有效的:

axis_titles <- data.frame(
  Species = c("setosa", "versicolor", "virginica"),
  axis_title = c("Setosa's Axis", "Versi's Axis", "Virgin's Axis")
)

p + labs(x=NULL) +
  geom_text(
    data=axis_titles,
    aes(label=axis_title), hjust=0.5,
    x=min(iris$Sepal.Length) + diff(range(iris$Sepal.Length))/2,
    y=1.7, color='red', fontface='bold'
  ) +
  coord_cartesian(clip="off") +
  theme(
    plot.margin= margin(b=30)
  )
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

这里我们要做几件事:

  1. 创建数据框来存储我们的轴标题
  2. 删除默认轴标题
  3. 添加geom_text()链接到新数据框并修改位置。请注意,我在数学上将位置固定在 x 轴的“中间”。我手动放置了 y 值,但如果需要,您也可以在那里使用方程。
  4. 转动clip="off"。这很重要,因为clip="on"如果几何图形位于面板区域之外,它将阻止显示它们。
  5. 将绘图边距向下延伸一点,以便我们能够真正看到文本。