R ggplot 多面图中的多级 x 轴标签

D. *_*mpo 1 r ggplot2 facet-wrap multi-level x-axis

我尝试使用两次调用 annotate() 的技巧来获取 2 级嵌套刻度标签(此处),但我想与 facet_wrap() 结合使用

df <- tribble(
  ~action, ~gend, ~status, ~cellMean,
  "P",     "M",   "A",     1,
  "P",     "M",   "B",     2,
  "P",     "F",   "A",     1.4,
  "P",     "F",   "B",     2.6,
  "V",     "M",   "A",     2,
  "V",     "M",   "B",     3,
  "V",     "F",   "A",     2.2,
  "V",     "F",   "B",     3.8
) %>%
  mutate(action=factor(action,levels=c("P","V")),
         gend  =factor(gend,  levels=c("F","M")),
         status=factor(status,levels=c("A","B")))

df

# action obscured/overlaid
df %>%
  ggplot(data=., mapping=aes(x=interaction(status,gend), y=cellMean,
                             color=status, shape=gend)) +
  geom_point(size=3.5) +
  theme_light()
Run Code Online (Sandbox Code Playgroud)

单面板叠加

# action used as facet
df %>%
  ggplot(data=., mapping=aes(x=interaction(status,gend), y=cellMean,
                             color=status, shape=gend)) +
  geom_point(size=3.5) +
  theme_light() +
  facet_wrap(~action)
Run Code Online (Sandbox Code Playgroud)

使用facet_wrap()

# annotate hack on unfaceted
df %>%
  ggplot(data=., mapping=aes(x=interaction(status,gend), y=cellMean,
                             color=status, shape=gend)) +
  geom_point(size=3.5) +
  annotate(geom = "text", x = 1:4, y = .7, label = rep(c("A","B"), times=2) ) +
  annotate(geom = "text", x = c(1.5,3.5), y = .6, label = c("Females","Males")) +
  coord_cartesian(ylim = c(.8, 4), xlim=c(.5,4.5), expand = FALSE, clip = "off") +
  theme_light() +
  theme(plot.margin = unit(c(1, 1, 4, 1), "lines"),
        axis.title.x = element_blank(),
        axis.text.x = element_blank() )
Run Code Online (Sandbox Code Playgroud)

在unfaceted上应用注释

# annotate hack on FACETED fails saying it wants 8 labels
df %>%
  ggplot(data=., mapping=aes(x=interaction(status,gend), y=cellMean,
                             color=status, shape=gend)) +
  geom_point(size=3.5) +
  annotate(geom = "text", x = 1:4, y = .7, label = rep(c("A","B"), times=2) ) +
  annotate(geom = "text", x = c(1.5,3.5), y = .6, label = c("Females","Males")) +
  coord_cartesian(ylim = c(.8, 4), xlim=c(.5,4.5), expand = FALSE, clip = "off") +
  theme_light() +
  theme(plot.margin = unit(c(1, 1, 4, 1), "lines"),
        axis.title.x = element_blank(),
        axis.text.x = element_blank() ) +
  facet_wrap(~action)
Run Code Online (Sandbox Code Playgroud)

产生:“错误:美学必须是长度 1 或与数据 (8): 标签相同”,这似乎需要跨两个面的 8 个标签,每个面有 4 个标签。

但是,尝试供应 8 个然后才需求 16 个。

# annotate hack on FACETED with length 8 vectors fails saying 16
df %>%
  ggplot(data=., mapping=aes(x=interaction(status,gend), y=cellMean,
                             color=status, shape=gend)) +
  geom_point(size=3.5) +
  annotate(geom = "text", x = rep(1:4, times=2), y = .7, label = rep(c("A","B"), times=4) ) +
  annotate(geom = "text", x = c(1.5,3.5), y = .6, label = c("Females","Males")) +
  coord_cartesian(ylim = c(.8, 4), xlim=c(.5,4.5), expand = FALSE, clip = "off") +
  theme_light() +
  theme(plot.margin = unit(c(1, 1, 4, 1), "lines"),
        axis.title.x = element_blank(),
        axis.text.x = element_blank() ) +
  facet_wrap(~action)
Run Code Online (Sandbox Code Playgroud)

产生:“错误:美学必须是长度 1 或与数据 ( 16 )相同:标签

有没有办法将 annotate() 技巧与facet_wrap() 一起使用?

我想知道是否需要制作 2 个图并将它们并排放置以模拟面。

teu*_*and 6

我也常常很难annotate()很好地处理方面。我无法让它工作,但你可以使用geom_text()它。需要在剪辑、x 标签格式和主题设置方面进行一些改进才能使其正常工作。我vjust = 3, y = -Inf没有对 y 位置进行硬编码,这样人们就可以更轻松地将其推广到他们的绘图中。

df %>%
  ggplot(data=., mapping=aes(x=interaction(status,gend), y=cellMean,
                             color=status, shape=gend)) +
  geom_point(size=3.5) +
  geom_text(data = data.frame(z = logical(2)),
            aes(x = rep(c(1.5, 3.5), 2), y = -Inf,
                label = rep(c("Females", "Males"), 2)),
            inherit.aes = FALSE, vjust = 3) +
  theme_light() +
  coord_cartesian(clip = "off") +
  facet_wrap(~action) +
  scale_x_discrete(labels = ~ substr(.x, 1, nchar(.x) - 2)) +
  theme(axis.title.x.bottom = element_text(margin = margin(t = 20)))
Run Code Online (Sandbox Code Playgroud)

另一种选择是用于ggh4x::guide_axis_nested()显示interaction()ed 因子。您需要重新编码您的 M/F 级别以读取男性/女性以获得与上面类似的结果。

df %>%
  ggplot(data=., mapping=aes(x=interaction(status,gend), y=cellMean,
                             color=status, shape=gend)) +
  geom_point(size=3.5) +
  theme_light() +
  facet_wrap(~action) +
  guides(x = ggh4x::guide_axis_nested(delim = ".", extend = -1))
Run Code Online (Sandbox Code Playgroud)

由reprex 包于 2022 年 3 月 30 日创建(v2.0.1)

免责声明:我写了 ggh4x。