【问题标题】:How can I annotate facets that do not have data using ggplot2 facet_grid?如何使用 ggplot2 facet_grid 注释没有数据的构面?
【发布时间】:2020-02-03 17:22:24
【问题描述】:

我有多元纵向样本,我在一个大的 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")

【问题讨论】:

    标签: r ggplot2 facet-grid


    【解决方案1】:

    您可以使用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)
    

    对于“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))
    

    或者我们可以使用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))
    

    只需调用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))
    

    【讨论】:

    • 我非常感谢您花时间提供多种方法来执行此操作。起初我对您为什么选择“模型”变量进行过滤感到有些困惑,但在我自己的测试中,我意识到任何相关变量都可以用于过滤目的。我将尝试更多地解决这个问题,以弄清楚我如何可以为不同的情况提供不同颜色的 X。再次感谢您的精彩回答!
    • 如果原始数据中始终存在数据,则任何列(构面列除外)都可用于过滤。我使用了model,因为它是一个可以快速输入的简短单词。如果原始数据框的所有列中都可能缺少数据,那么您只需向原始数据框添加一个标记列并过滤以仅保留该列缺少数据的行。
    猜你喜欢
    • 2020-10-13
    • 1970-01-01
    • 1970-01-01
    • 2018-11-03
    • 2019-12-13
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 2023-03-27
    相关资源
    最近更新 更多