厚缊

诹图——螺旋的疫情图

厚缊 / 2020-03-14


人民日报带了头,Y叔用R重现,紧接着就是新一轮的模仿秀,我来赶个晚场,但也得玩出点花样,这不就把螺旋整上了。

依赖包

archncov数据来源于Y叔的nCov2019包,绘图函数主要依赖于ggvwline,没有安装的需要先安装。

## install.packages("devtools")
if(!require(ggvwline)) {
  devtools::install_github("houyunhuang/ggvwline")
}
if(!require(nCov2019)) {
  devtools::install_github("GuangchuangYu/nCov2019")
}
devtools::install_github("houyunhuang/archncov")

主要函数

archncov包可能需要用上的就两个函数:

但是目前还有几个小问题,第一个是当区域特别多,类似于全球130多个国家的数据,会导致标签重叠;第二个是颜色的处理,目前是按照name字段做离散型颜色映射,过几天可能会调整为按确诊病例数映射。目前没调是因为换成连续性颜色映射vwline包就报错,还需要分析下原因。

tidy_arch_ncov()函数

这个函数是把nCov2019包的数据转化成螺旋图需要的样式,并且同时根据螺旋线形状计算了标签旋转角度、字号、颜色等,这些可能都不是太gg的模式,等连续性颜色映射的bug整完了在一起整合到plot()函数里面去。

library(nCov2019)
library(archncov)

# 国内数据获取
get_nCov2019()[] %>% 
  tidy_arch_ncov()
## # A tibble: 3,780 x 15
##        x       y name  confirm width angle label label.filter    id label.x
##  * <dbl>   <dbl> <fct>   <dbl> <dbl> <dbl> <chr> <lgl>        <int>   <dbl>
##  1 0.2   0.      Tibet      14  1    0     "Tib… TRUE             1   0.202
##  2 0.200 5.37e-4 Tibet      14  1.02 0.154 "Tib… FALSE            2   0.202
##  3 0.201 1.08e-3 Tibet      14  1.03 0.308 "Tib… FALSE            3   0.202
##  4 0.201 1.62e-3 Tibet      14  1.05 0.461 "Tib… FALSE            4   0.202
##  5 0.201 2.16e-3 Tibet      14  1.06 0.615 "Tib… FALSE            5   0.202
##  6 0.201 2.70e-3 Tibet      14  1.08 0.769 "Tib… FALSE            6   0.202
##  7 0.202 3.25e-3 Tibet      14  1.09 0.923 "Tib… FALSE            7   0.202
##  8 0.202 3.79e-3 Tibet      14  1.11 1.08  "Tib… FALSE            8   0.202
##  9 0.202 4.34e-3 Tibet      14  1.13 1.23  "Tib… FALSE            9   0.202
## 10 0.202 4.89e-3 Tibet      14  1.14 1.38  "Tib… FALSE           10   0.202
## # … with 3,770 more rows, and 5 more variables: label.y <dbl>,
## #   label.angle <dbl>, vertical <lgl>, size <dbl>, colour <chr>
# 省区数据获取
get_nCov2019()["Hubei", ] %>% 
  tidy_arch_ncov(trans.log = FALSE)
## # A tibble: 67,814 x 15
##        x       y name  confirm width   angle label label.filter    id
##  * <dbl>   <dbl> <fct>   <int> <dbl>   <dbl> <chr> <lgl>        <int>
##  1 0.2   0.      Shen…      11  1    0       "She… TRUE             1
##  2 0.200 2.97e-5 Shen…      11  1.00 0.00850 "She… FALSE            2
##  3 0.200 5.93e-5 Shen…      11  1.00 0.0170  "She… FALSE            3
##  4 0.200 8.90e-5 Shen…      11  1.00 0.0255  "She… FALSE            4
##  5 0.200 1.19e-4 Shen…      11  1.00 0.0340  "She… FALSE            5
##  6 0.200 1.48e-4 Shen…      11  1.00 0.0425  "She… FALSE            6
##  7 0.200 1.78e-4 Shen…      11  1.01 0.0510  "She… FALSE            7
##  8 0.200 2.08e-4 Shen…      11  1.01 0.0595  "She… FALSE            8
##  9 0.200 2.37e-4 Shen…      11  1.01 0.0680  "She… FALSE            9
## 10 0.200 2.67e-4 Shen…      11  1.01 0.0765  "She… FALSE           10
## # … with 67,804 more rows, and 6 more variables: label.x <dbl>,
## #   label.y <dbl>, label.angle <dbl>, vertical <lgl>, size <dbl>,
## #   colour <chr>

plot()函数

ggplot2ggvwline的一些函数做的一点封装, 这个函数可以比较完美的配合tidy_arch_ncov()函数来进行可视化。

get_nCov2019()[] %>% 
  tidy_arch_ncov() %>% 
  plot()

默认情况下,螺旋外侧最大宽度是60mm,默认字号最大是10pt,我们都可以在tidy_arch_ncov()函数中自定义。

get_nCov2019()[] %>% 
  tidy_arch_ncov(max.width = 50, max.size = 7) %>% 
  plot()

plot()函数有个colours参数,可以改变填充色的调色板。这个地方设计的有点丑,和字体、宽度在tidy_arch_ncov()中设置显得格格不入,姑且先将就着用。

## clockwise可以控制旋转方向
get_nCov2019()["Guangdong", ] %>% 
  tidy_arch_ncov(max.width = 50, max.size = 7, clockwise = TRUE) %>% 
  plot(colours = c("white", "red", "darkred"),
       xlim = c(-1.2, 1.3), ylim = c(-1.8, 1.2))

最后看一下全球的螺旋图,这里由于数据太多,我过滤掉了一部分比较少的国家。我一直觉得标签从内到外很舒服,然后看了这个图的都说要要从左往右,就加了个参数来处理。

get_nCov2019()["global", ] %>%
  dplyr::filter(confirm > 50) %>% 
  tidy_arch_ncov(max.width = 50, max.size = 4, min.size = 0.1) %>% 
    plot(xlim = c(-1.5, 1.0), ylim = c(-1.1, 1.2),
         label.direction = "left_right")

自定义

也可以不依赖plot()函数来自己搞,甚至可以结合ggvwline玩出更多花样。最简单的就是直接使用geom_arch()geom_arch_label(),这个函数主要是为了快速出图,对geom_vwline()geom_text()做了一点封装,当然你完全可以直接用原函数来整。

library(ggplot2)
get_nCov2019()["global", ] %>%
  dplyr::filter(confirm > 300) %>% 
  tidy_arch_ncov(max.width = 50, max.size = 6, min.size = 0.1) %>% 
    ggplot() +
    geom_arch() +
    geom_arch_label(aes(label = name)) +
    scale_colour_identity(guide = "none") +
    scale_size_identity(guide = "none") +
    coord_fixed(xlim = c(-1.5, 1.0), ylim = c(-1.1, 1.2)) +
    theme_void() +
    theme(legend.position = "none")

小结

螺旋图只是提供了一个思路,完全可以把其它更好玩的曲线整合进来。当然,匆匆忙忙的写的东西,打成包就是为了使用更方便,会存在一些问题。