気ままにデータ分析

データサイエンティスト見習いの学習メモ

PythonによるCOVID-19患者数可視化

yupine.hatenablog.com
前回(上)の記事でやったのと同じことを今度はPythonでやってみます。

今回もグラフを作成した以外のことはやってません。悪しからず。


使用したデータ

github.com

前回に引き続き、ジョンズ・ホプキンズ大学が公開しているこのデータを用いました。

国別・地域別の感染者数、回復者数、死亡者数のデータがcsvで取得できます。

また時系列ごとのデータと日ごとのデータにも分かれています。
前回使用時のデータは数字が明らかにおかしいところがちょいちょいあったのですが、今回はいくつか修正されているようです。
(まだ何日分か正しくなさそうですが...。)

※今回使うデータの数字は厚生労働省や各社メディアによる発表の数とは異なっている場合があります。


準備

#必要なライブラリのインポート
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as dates
import seaborn as sns
from datetime import datetime

pd.set_option('max_columns', 50)
plt.style.use('seaborn')

#描画における日本語フォントの設定
from matplotlib import rcParams
rcParams['font.family'] = 'sans-serif'
rcParams['font.sans-serif'] = ['Hiragino Maru Gothic Pro', 'Yu Gothic', 'Meirio', 'Takao', 'IPAexGothic', 'IPAPGothic', 'Noto Sans CJK JP']

データ取得

#累計患者数
time_series_confirmed = pd.read_csv('~/time_series_covid19_confirmed_global.csv')
#累計回復者数
time_series_deaths = pd.read_csv('~/time_series_covid19_deaths_global.csv')
#累計死亡者数
time_series_recovered = pd.read_csv('~/time_series_covid19_recovered_global.csv')

データ前処理


取得したデータをみてみましょう。

time_series_confirmed.head()

f:id:Yupine:20200403000602p:plain


Country/RegionからJapanを指定します。

time_series_confirmed = (
    time_series_confirmed[time_series_confirmed['Country/Region']=='Japan']
    .drop(['Lat','Long','Province/State'], axis=1)
)
time_series_confirmed

f:id:Yupine:20200403000534p:plain


日付が列になっていて横長のデータになっています。
これを縦長のデータに変換します。まずは累計患者数に絞ってデータを整形していきます。

time_series_confirmed = (
    #Country/Regionを行に
    time_series_confermed.pivot(columns='Country/Region') 
    .T #転置
    .reset_index() #インデックスを解除
    .rename(columns={139:'累計患者数','level_0':'日付'}) #列名変更
)

#日付をTimestamp型に変換
time_series_confirmed['日付'] = pd.to_datetime(time_series_confirmed['日付'])
time_series_confirmed.tail() #末尾(直近5日)

f:id:Yupine:20200403002248p:plain
Country/Regionを行に変換して、転置することで日付を縦のデータにしました。
また日付をTimestamp型に変換し、3/30/20のように月/日/年となっていた表記をyyyy-MM-ddの表記にしました。


同様に、累計回復者数、累計死亡者数のdataframeも変換します。

#累計死亡者数のdataframe整形
time_series_deaths = (
    time_series_deaths[time_series_deaths['Country/Region']=='Japan']
    .drop(['Lat','Long','Province/State'], axis=1)
)

time_series_deaths = (
    time_series_deaths.pivot(columns='Country/Region')
    .T
    .reset_index()
    .rename(columns={139:'累計死亡者数','level_0':'日付'})
)
time_series_deaths['日付'] = pd.to_datetime(time_series_deaths['日付'])

#累計回復者数のdataframe整形
time_series_recovered = (
    time_series_recovered[time_series_recovered['Country/Region']=='Japan']
    .drop(['Lat','Long','Province/State'], axis=1)
)

time_series_recovered = (
    time_series_recovered.pivot(columns='Country/Region')
    .T
    .reset_index()
    .rename(columns={133:'累計回復者数','level_0':'日付'})
)
time_series_recovered['日付'] = pd.to_datetime(time_series_recovered['日付'])

データの結合

整形した累計患者数、累計回復者数、累計死亡者数の3つのdataframeを
日付をキーにjoinして、1つのdataframeにまとめます。

japan_covid = (
    time_series_confirmed
    .merge(time_series_recovered[['日付','累計回復者数']], 
           how='left',
           on='日付')
)

japan_covid = (
    japan_covid
    .merge(time_series_deaths[['日付','累計死亡者数']],
           how='left', 
           on='日付')
)

japan_covid = japan_covid.drop('Country/Region', axis=1)
japan_covid.set_index('日付', inplace=True)
japan_covid.tail()

f:id:Yupine:20200403002337p:plain
1つのデータフレームにまとまりました。

積み上げ棒グラフの描画

それでは描画してみます。
Rのggplotで描画する時とは違い、matplotlibで積み上げ棒グラフを描画する場合は
dataframeの列番号をずらしながら横方向に和を順番にとっていき、それぞれの棒グラフを表示させることで
積み上げを表現します。

fig = plt.figure(figsize=(15,8))
ax = fig.add_subplot(111)

x, cols = japan_covid.index, len(japan_covid.columns)

#列ごとに(横方向に)和をとる
for i, t in enumerate(japan_covid.columns):
    y = japan_covid.iloc[:,i:cols].sum(axis=1)
    ax.bar(x, y, label=t)

#7日ごとに日付を表示
ax.xaxis.set_major_locator(dates.DayLocator(bymonthday=None, interval=7, tz=None))
ax.xaxis.set_major_formatter(dates.DateFormatter("%m月%d日"))

#タイトル、軸ラベルの設定
ax.set_title('新型コロナウィルス患者数の推移(日本)', fontsize=18)
ax.set_xlabel('日付', fontsize=12)
ax.set_ylabel('人数', fontsize=12)
    
ax.legend(fontsize=12)
plt.show()

f:id:Yupine:20200403002714p:plain

約2週間前に描画した時は累計患者数が800名に満たないくらいでしたが、今は3000名に迫る勢いです...。
これ以上増加が加速しないことを祈るばかりです。