用分组变量注释小平面图

Annotate facet plot with grouped variables

我想将观察的数量放在一个侧面箱线图之上。这是一个例子:

exmp = mtcars %>% as_tibble() %>%
  mutate(cartype = as.factor(row.names(mtcars))) %>% 
  group_by(cyl, am, gear) %>% 
  mutate(N = n())

ggplot(exmp, aes(x = am, fill = gear, y = wt)) +
  facet_grid(.~cyl) +
  geom_boxplot() +
  geom_text(aes(y = 6, label = N))

因此,我已经创建了列 N 来获取箱线图中每个框的标签(cylamgear 的组合)。 如何绘制这些标签,使它们位于相应的方框上方?请注意,am 的每个级别的齿轮级别数量不同故意.

我真的看了很多 ggplot 教程,有很多关于在分面图中进行注释的问题。但是 none 解决了这个相当普遍的问题...

您需要在 geom_text 中给出 position_dodge() 以匹配框的位置,还定义 data 参数以获得 distinct 观察值:

ggplot(exmp, aes(x = as.factor(am), fill = as.factor(gear), y = wt)) +
  geom_boxplot() +
  facet_grid(.~cyl) + 
  geom_text(data = dplyr::distinct(exmp, N), 
            aes(y = 6, label = N), position = position_dodge(0.9))

也许在您的 geom_text() 中使用 position_dodge() 会得到您想要的东西?

mtcars %>% as_tibble() %>%
  mutate(cartype = as.factor(row.names(mtcars))) %>% 
  group_by(cyl, am, gear) %>% 
  mutate(N = n()) %>% 
  ggplot(aes(x = as.factor(am), fill = as.factor(gear), y = wt)) +
  geom_boxplot() +
  geom_text(aes(y = 6, label = N), position = position_dodge(width = 0.7)) +
  facet_grid(.~cyl)

这里的一个小问题是您为每个数据点打印一次 N 值,而不是为每个 cyl/am/gear 组合打印一次。因此,您可能想要添加一个过滤步骤以避免过度绘制该文本,这在屏幕上看起来很乱,减少了对 alpha 的控制,并在数据较大的情况下减慢了绘制速度。

library(tidyverse)
exmp = mtcars %>% as_tibble() %>%
  mutate(cartype = as.factor(row.names(mtcars))) %>% 
  group_by(cyl, am, gear) %>% 
  mutate(N = n()) %>%
  ungroup() %>%
  mutate(am = as.factor(am),
         gear = as.factor(gear))

(上面的数据准备对于我让情节看起来像你的例子是必要的。我使用的是 tidyverse 1.2.1 和 ggplot2 3.2.1)

ggplot(exmp, aes(x = am, fill = gear, y = wt, 
                 group = interaction(gear, am))) +
  facet_grid(.~cyl) +
  geom_boxplot() +
  geom_text(data = exmp %>% distinct(cyl, gear, am, N),
            aes(y = 6, label = N),
            position = position_dodge(width = 0.8))

这是同一张图表,但有过度绘制: