Как я могу аннотировать фасеты, у которых нет данных, используя ggplot2 facet_grid? - PullRequest
1 голос
/ 03 февраля 2020

У меня есть многовариантные продольные выборки, которые я строю в большом facet_grid, в частности, используя facet_grid, так что, когда у меня нет определенного момента времени для определенного образца, он все еще сохраняет все в хорошо упорядоченной сетке. Я пытаюсь добавить какой-то индикатор к пустым фасетам, чтобы показать, что у них нет данных (вместо того, чтобы просто не показывать точки), потому что иногда пустой фасет является результатом того, что этот образец еще не собран. То, что мне удалось получить, - это метка, которая отображается в каждом фасете, который имеет данные, но я не могу понять, как получить метку, которая появляется в каждом фасете, который НЕ имеет данных. Было бы даже лучше, если бы я мог добавить красный крестик X через выделенные фасеты или какое-либо другое указание «Нет данных» вместо текстовой метки, если у вас также есть предложения по этому поводу.

ggplot(mpg, aes(displ, cty)) + geom_point() + 
facet_grid(vars(drv), vars(cyl)) + geom_text(x = 5, y = 20, label = "Blah")

Example plot

1 Ответ

8 голосов
/ 03 февраля 2020

Вы можете добавить строки для отсутствующих комбинаций с помощью full_join. Эти новые строки не будут иметь данных, поэтому ничего не будет отображаться, но вы можете добавить дополнительный столбец с сообщением, которое будет использовать geom_text:

library(tidyverse)
theme_set(theme_bw())

mpg %>% 
  full_join(crossing(drv=unique(mpg$drv), cyl=unique(mpg$cyl))) %>% 
  mutate(empty=ifelse(is.na(model), "No data available", NA_character_),
         x=mean(range(displ, na.rm=TRUE)), 
         y=mean(range(cty, na.rm=TRUE))) %>% 
  ggplot(aes(displ, cty)) + 
    geom_point() + 
    facet_grid(vars(drv), vars(cyl)) + 
    geom_text(aes(x, y, label=empty), colour="red", size=3)

enter image description here

Для "X" измените текст empty на "X" и нанесите его с большим размером. Например:

mpg %>% 
  full_join(crossing(drv=unique(mpg$drv), cyl=unique(mpg$cyl))) %>% 
  mutate(empty=ifelse(is.na(model), "X", NA_character_),
         x=mean(range(displ, na.rm=TRUE)), 
         y=mean(range(cty, na.rm=TRUE))) %>% 
  ggplot(aes(displ, cty)) + 
    geom_point() + 
    geom_text(aes(x, y, label=empty), colour="red", size=20) +
    facet_grid(vars(drv), vars(cyl))

enter image description here

Или мы можем использовать geom_segment:

mpg %>% 
  full_join(crossing(drv=unique(mpg$drv), cyl=unique(mpg$cyl))) %>% 
  ggplot(aes(displ, cty)) + 
    geom_point() + 
    geom_segment(data=. %>% filter(is.na(model)),
                 x=min(mpg$displ), xend=max(mpg$displ),
                 y=min(mpg$cty), yend=max(mpg$cty),
                 colour="red") +
    geom_segment(data=. %>% filter(is.na(model)),
                 x=min(mpg$displ), xend=max(mpg$displ),
                 y=max(mpg$cty), yend=min(mpg$cty),
                 colour="red") +
    facet_grid(vars(drv), vars(cyl))

enter image description here

Вышесказанное можно сделать одним вызовом geom_segment, но это требует (AFAICT) более сложной подготовки данных:

mpg %>% 
  full_join(crossing(drv=unique(mpg$drv), cyl=unique(mpg$cyl))) %>% 
  ggplot(aes(displ, cty)) + 
    geom_point() + 
    geom_segment(data=. %>% 
                   filter(is.na(model)) %>% 
                   select(-displ, -cty) %>% 
                   crossing(
                     displ=range(mpg$displ),
                     cty=range(mpg$cty)
                   ),
                 aes(xend=rev(displ), yend=rev(cty)), colour="red") +
    facet_grid(vars(drv), vars(cyl))
...