使用 R 的 ggplot2 绘制淡化线条的意大利面条线图

2021 年 4 月 12 日

如果有人告诉我他们上个月的销售额是 1000 万美元,我该怎么理解?仅仅依靠这个数字,我无法得出任何结论。为了理解这个数字,我需要一些背景信息,例如时间跨度或与同类公司的比较。使用数据可视化可以帮助我将数字置于一个可以理解的背景中。

时间跨度是一种特别有用的背景信息。今天的数据与过去一段时间的数据相比如何?将数据绘制成时间线图可以帮助我了解这一点。

这里有一个比销售额更令人沮丧的例子,即马萨诸塞州每 10 万人因新冠肺炎死亡的人数。

这很有价值,因为我现在可以将今天的数据放在历史背景中,将最近的数据与过去两次高峰时期的数据进行比较。在 R 中绘制此图表也非常容易,只需要几行代码。

death_pp %>%
    filter(state == "MA") %>%
    ggplot(aes(date, death_pm_rm)) +
    labs(y = "deaths per 100,000") +
    geom_line(color = "blue")
显示加载 death_pp 的代码
# cdc covid data records New York City seperately from New York state
cdc_pops <- pops %>% 
  mutate(pop = if_else(state == "NY", pop - 8400000, pop)) %>%  
    add_row(name = "New York City", state = "NYC", pop = 8400000)

# http  -d "https://data.cdc.gov/api/views/9mfq-cb36/rows.csv" > cdc_cases.csv
cdc_cases <- read_csv("cdc_cases.csv") %>% 
    select(state, submission_date, new_death, tot_death) %>% 
    mutate(date = mdy(submission_date)) %>% 
    arrange(date) %>% 
    group_by(state) 

death_pp <- cdc_cases %>% 
  left_join(cdc_pops, by = "state") %>% 
  drop_na(pop) %>% 
  mutate(death_pm = new_death * 1000000 / pop) %>% 
  mutate(death_pm_rm = rollmean(death_pm, 7, fill=NA, align="right"))

但我可以展示比时间跨度更多的背景信息。为了更好地了解马萨诸塞州的疫情发展,我可以将其与其他州的情况进行比较。一个好方法是将其他所有美国州的线图作为淡化背景显示。

据我所知,这种类型的图表没有普遍接受的术语。在折线图中绘制多条线有时被称为意大利面条线图。因此,我将此称为淡化意大利面条图。

在 R 中,绘制此图非常容易,关键是将另一个 geom_line 与不同的数据源一起绘制,作为我们要查看的主要线。

death_pp %>%
    filter(state == "MA") %>%
    ggplot(aes(date, death_pm_rm)) +
    labs(y = "deaths per 100,000") +
    geom_line(data = death_pp, aes(group = state), color = "grey", size = 1, alpha = 0.5) +
    geom_line(aes(y = death_pm_rm), color = "blue")

请注意,我在绘制前景线之前绘制背景,以确保前景线清晰地显示在顶部。

使用网格(分面)实现

用一个州展示这一点很好,但通常需要能够以这种方式查看多个州。ggplot2 提供了非常方便的 facet_wrap 命令,可以为集合中的每个值绘制一个折线图,但需要一些技巧才能使其与这种淡化意大利面条背景一起使用。

技巧在于我需要指定意大利面条的分组方式。

death_pp %>%
  filter(state %in% c("MA", "VT", "CT", "RI", "NH")) %>% 
  ggplot(aes(date, death_pm_rm)) +
  labs(y = "deaths per 100,000") +
  geom_line(data = death_pp %>% rename(s = state),
              aes(group = s), color = "grey", size = 1, alpha = 0.5) +
  geom_line(color = "blue") +
  facet_wrap(~state, ncol = 3)

通过重命名分组列,ggplot 仅对主要线进行分面,并在每个分面上绘制意大利面条。 [1]


脚注

1: 我花了很长时间进行实验和网络搜索,才找到如何在分面上实现这一点。最终,我在 from data to viz 上找到了答案