こいつ、動くぞ! ~Web会議で映えるアニメーションPlotのつくり方~


この記事は、NTTテクノクロス Advent Calendar 2020 10日目です。

こんにちは。NTTテクノクロス IoTイノベーション事業部の山田です。
社内では、様々なデータ解析やデータサイエンティスト養成をやっています。

データサイエンティスト養成… と言いながら、私は今も昔も心は統計屋さんでデータサイエンティストって求められる技術多すぎない?と感じてます。

今年は、そんな統計屋さんが昔から、そしてデータサイエンティストさんが根源的に抱えるデータ見える化についてお話していきます。

見える化って何なの?

見える化については、"Transformation of the symbolic into the geometric"(象徴から具体へ)という有名な言葉があります。1

さらに見える化についてはデータドリブンマーケティングで紹介されている、データドリブンで意思決定することを妨げる点の代表が、心に刺さるので紹介します。2

  1. 何から手を付けていいかわからない。
  2. 因果関係が不明。
  3. データ不足
  4. 経営資源やツールが不足
  5. 組織や人の問題

このうち、1,2に対しての最も有効な手立ては まずはやってみる、スモールウィン、スモール仮説検証の実験が大切と同著ではあります。

この際に大きな武器となのは、複雑な手法や、優れたアルゴリズムではなく、記述統計つまり目で見てできる事から始まります。

統計屋さん的には、グラフとか書く前に、しっかりとした検討を経ていきたいところですが、正直まず図で見せていくスタイルもスピードを上げるうえでは重要です。
悩むなら見せる。これが大切。

リモート会議主体だから…

スライドと資料が混ざったものを「スライデュメント」(Slide + Document)と呼びます。

2017年くらいに人気になった、プレゼンテーションZEN などでは、避けるべきもの、忌むべき存在として有名です。3

一方、Storytelling with data などでは、ライブプレゼンテーションでも、ドキュメントの中間としての定義で、ライブプレゼンテーションほど、相手の受け取る情報をコントロールできるわけではないが、プレゼンテーションよりも必要な詳細情報はずっと多い。ドキュメントほど情報ないが、ドキュメントよりは受け取る情報をコントロールできる。

として 定義されていたりします。4

さて、この辺は往々にして、「どっちつかずになるから」止めておけ。
という話で色々な本では、やっぱりやめておこうになる部分もあります。

ただし今はだいぶ状況が変わりました。ここ最近の皆さんが在宅勤務を多く仕出し、会議と言えばもっぱらWeb会議という状況では、まさに、プレゼンテーションするほど近くはないが、ドキュメントで送るほど遠くもない という 状況ではないでしょうか。

この状況において、せっかくなので、これまでの資料ではあまり実現しにくかった表現方法。
そう、アイにメーションを用いた、データ見える化にチャレンジしたいと思います。

データセットはせっかくだからCovid-19

今回、可視化するデータはCovid19です。
最近では多く可視化サイトがあふれていますが、改めて今何が起きているかを自分で確かめるために、見てみましょう。

東洋経済オンライン「新型コロナウイルス 国内感染の状況」でも公開されているデータのうち
都道府県別の感染の状況のデータを利用していきます。データソース

データセットをダウンロードしたら Rで読み込みます。

ちなみにPython ,R論争はここでは行いません。がアニメーションを作る場合、個人的にはRが優れている印象です。

ここでは 各都道府県の陽性者や入院患者がどのように遷移していったかを見える化したいと思います

gganimateによる アニメーションプロット

まずはさっそくデータを読み込んでいきます。


library(data.table)
library(dplyr)
library(gganimate)
library(ggrepel)

prefecture <- fread("prefectures.csv")

prefecture <- prefecture %>%
  filter(month > 5 ) %>%
  mutate_all(~ifelse(is.na(.),0,.))%>%
  as.data.table()

prefecture[,YMD := as.POSIXct(paste(year,month,date,sep="-"))] 

ここではお決まりの dplyr で読み込みNAのゼロパディング、年月日の形式統一を行います。

ここから本題の アニメーション作成です。

まず、比較的何も考えずに図を書いてみましょう。

prefecture[YMD=="2020-12-01"] %>%
  mutate(label_text = case_when( log(hospitalized) >= max(log(hospitalized))/2 & \\
                                 log(testedPositive) >= max(log(testedPositive))/2\\
                                  ~ prefectureNameJ, TRUE ~ "")) %>%
  ggplot(aes(x = log(testedPositive),
             y = log(hospitalized),
             color = prefectureNameJ,
             label=label_text)) +
  geom_point(alpha=0.4)+
  geom_text_repel(point.padding = NA)+
  xlab("log(検査陽性者数)")+
  ylab("log(入院治療等を要する者)")

YMD に 年月日の形式で格納されていますので
ここでは、2020年12月1日のデータを用いたプロットになります。

ここまではシンプルなggplot の使い方講座なので、個々は割愛してしまいます。
唯一 以下の箇所だけ説明すると、表示するラベル(ここでは都道府県)が多すぎると 醜いので上位陣だけ表示されるようにしています。

 mutate(label_text = case_when( log(hospitalized) >= max(log(hospitalized))/2 & \\
                                 log(testedPositive) >= max(log(testedPositive))/2\\
                                  ~ prefectureNameJ, TRUE ~ "")) 

さて、ここから、アニメーションにしていきます。
手作業で行う場合、 YMDを1日単位で指定していき 一コマ一コマ 保存して、あとでGIFアニメーションにすることですが、そこはggplot。 gganimate というパッケージで非常にお手軽にアニメーションが作れます。

まず先ほどのように、アニメーションの核となる絵をかきます。

cell <-prefecture %>%
  mutate(label_text = case_when( log(hospitalized) >= max(log(hospitalized))/2 & log(testedPositive) >= max(log(testedPositive))/2 ~ prefectureNameJ, TRUE ~ "")) %>%
  ggplot(aes(x = log(testedPositive),
             y = log(hospitalized),
             color = prefectureNameJ,
             label=label_text)) +
  geom_point(alpha=0.4)+
  #geom_text_repel(point.padding = NA)+
  geom_text()+
  xlab("log(検査陽性者数)")+
  ylab("log(入院治療等を要する者)")

この段階では以下の図のようになります。

全ての 年月日が 1つの図にかかれているので、荘厳ですね。
ここからこのアニメーションを

ani <- cell +
    transition_time(YMD)+
    labs(title = "{frame_time}")

これだけです。
今回は YMDを時系列として扱っているので、 transition_time()を使いましたが
このほかにもtransition_states() などがあります。

さてこの結果を見ていきたいと思います。
上の時点でも表示できるのですが、ちょっと大きさやアニメーションの長さなどを変えたいので以下のようにすると…

animate(ani,
        duration=15,
        fps = 10,
        width = 1200,
        height = 400,
        end_pause = 10) 

アニメーションになりました!

とても簡単でびっくりしますよね。
このほかより滑らかさを求めたり、などを行いたくなるのですが、元の目的がリモート会議での資料表示で、スライドよりも動きものという点を思い出してください。
頑張って滑らかにしても、必ずしも、適切に表示されるとは限らないのです。

それよりもFPSを落として、リモート会議でガタつかない程度を目指すのが吉だと思います。
この場合は 先のコードにある fps = 10 を fps = 3 とかにしてあげると Web会議しぐさとしては適切かもしれません

動くことで何が見えるか

動くことで平素なグラフが見事に!ということだけではないです。

例えば北海道や沖縄、愛知に着目してみましょう。
変化の速さが解るはずです。

これを静止したグラフのみで行う場合、変化率や差分などを新たな軸に、グラフを書き直す必要が出るはずです。

これが、アニメーションだと自然に伝わる形になるわけです。
グラフ祭りになってしまう皆さん。ぜひアニメーションも活用ください

おわりに

いかがでしたか、働き方が変わると、会議形態も変わり、必要な資料の見せ方も変わっていく。そんな内容でした。

少しでもお役に立てれば幸いです。

明日は中田@nak-TXさんの クラウドの安全性に関わるお話です。楽しみですね。


  1. Visualizationの著名な資料にも登場する至言です。 

  2. Mark Jeffery 著 佐藤 他訳:データ・ドリブン・マーケティング―――最低限知っておくべき15の指標 より 

  3. Garr Reynolds 著, 熊谷 訳 :プレゼンテーションZEN 第2版 より 

  4. Cole Nussbaumer Knaflic 著 : Storytelling with Data: A Data Visualization Guide for Business Professionals より