COVID-19ダッシュボードから学ぶ echarts4rでコロプレス地図の描画

近頃covid-19の流行に伴い行政や民間の開発者がそれぞれの可視化ダッシュボードを公開している動きが多く見られます。それぞれに良い点や改善すべき点などが散見されますが、RユーザーとしてSPAを開発する際にはshiny dashboardフレームワークを活用した事例を紹介し、そのサイトでどのような可視化ライブラーが用いられているかを確認してみたいと思います。

記事のモチベーション

使い易さや、開発コミュニティの大きさからggplot2が可視化の文脈ではもっとも多く用いられているが

  • 他のライブラリーにはどのようなものがあるのかを把握する
  • 可視化のレパートリーを多くもつことでレポートスタイルにあったライブラリーを選択できるようにする

これらの動機で記事を公開します。

参考にするダッシュボードページ

新型コロナウイルス感染速報

github.com

用いられているライブラリー

global.Rファイルからライブラリーのインポート部分を下記に抜粋しました。

library(shiny)
# library(NipponMap)
library(shinydashboard)
library(data.table)
library(DT)
library(ggplot2)
library(shinycssloaders)
library(shinydashboardPlus)
library(shinyWidgets)
library(leaflet)
library(rjson)
library(htmltools)
library(leaflet.minicharts)
library(echarts4r)
library(echarts4r.maps)

当記事で紹介するのは、下の二つのライブラリーecharts4recharts4r.mapsです。

github.com

github.com

covid-2019.liveでは上記の二つの可視化ライブラリーでほとんどのグラフを描画しています。いくつかある中で今回はソースファイルで記述されているコロプレスマップの可視化事例を取り上げます。

.
├── Components
│   ├── ComfiredMap.R     # 確認されている感染者を表す日本地図グラフ

Snapshot 1: マップ

Screen Recording 2020-03-16 at 11.39 AM.gif

気に入っている点

  • インタラクティブ、直感的で分かりやすい
  • マウスをホバーした際にいい感じに県名が表示されている

Rユーザーとして可視化の文脈ではggplot2が頻繁に利用されているし、自分も静的なグラフを描画したい際(レポートや論文、ブログ記事等)には全くもって問題がないと思います。しかし、SPAのダッシュボード内で可視化を行う際には時としてインタラクティブなグラフが役立つことが多い気がしています。この点を補うにはggplot2でもできなくはないですが他のインタラクティブな可視化に特化したライブラリーを把握しておく必要があると感じました。またこの記事で取り上げるecharts4rライブラリーはダッシュボードとの親和性が非常に高いと感じました。

コロプレスマップの実装

前述したように基本的にソースコードは全て公開されているため、今回はデータを3/16、22:00時点で公開されているものをダウンロードして使います。また、ソースファイルのスクリプトは参考としましたが全てを再現するわけではなく、キーとなるエッセンスの部分のみを用います。

# ------------------------ Package Loading & Data Prep -----------------------------------
pacman::p_load(echarts4r, echarts4r.maps, tidyverse, data.table)
byDate <- fread('data/byDate.csv', header = T) # https://github.com/swsoyee/2019-ncov-japan/blob/5fc98d771d/Data/byDate.csv
provinceCode <- fread('data/prefectures.csv') # https://github.com/swsoyee/2019-ncov-japan/blob/5fc98d771d/Data/prefectures.csv

# ------------------------ Data Preprocessing -----------------------------------
byDate[is.na(byDate)] <- 0     #欠損地を0で代入                               
byDate$date <- lapply(byDate[, 1], function(x){as.Date(as.character(x), format = '%Y%m%d')})                    # 日付カラムのフォーマットを整える

dt <- data.frame(date = byDate$date)
for (i in 2:ncol(byDate)) {
  dt[, i] = cumsum(byDate[, i, with = F])  #データを観測値から累積数へと変換
}
dt <- reshape2::melt(dt, id.vars = 'date')
mapDt <- data.table(dt)

mapDt <- mapDt[!(variable %in% c('クルーズ船', 'チャーター便', '検疫職員'))]       #都道府県以外のデータを便宜上、除外
mapDt <- merge(x = mapDt, y = provinceCode, by.x = 'variable', by.y = 'name-ja', all = T)
mapDt <- mapDt[, .(date, variable, `name-en`, value)]
colnames(mapDt) <- c('date', 'ja', 'en', 'count')
nameMap <- as.list(mapDt$ja)
names(nameMap) <- mapDt$en
# ------------------------ Data Visualization -----------------------------------
mapDt %>%
  group_by(date) %>% 
  e_charts(ja, timeline = T) %>%
  em_map("Japan") %>%
  e_map(count, map = "Japan",
        name = '感染確認数', roam = T,
        nameMap = nameMap,
        layoutSize = '50%',
        center = c(137.1374062, 36.8951298),
        zoom = 1.5,
        scaleLimit = list(min = 1, max = 4)) %>%
  e_visual_map(
    count,
    top = '30%',
    left = '0%',
    inRange = list(color = c('#EEEEEE', "#DD4B39", "#B03C2D")), # カラーの設定
    type = 'piecewise',
    splitList = list(
      list(min = 50),
      list(min = 30, max = 50),
      list(min = 10, max = 30),                                 # 判例の設定
      list(min = 5, max = 10),
      list(min = 1, max = 5),
      list(value = 0)
    )
  ) %>% 
  e_color(background = '#FFFFFF') %>%                # 背景色の設定
  e_tooltip()                                                   # マウスホバーした際のの設定(デフォルト)

Screen Recording 2020-03-16 at 10.45 PM.gif

以上のコーディングだけで最低限の質の描画ができます。処理の部分はコメントアウトされた部分に適宜、注意を書いておきました。