LoginSignup
6
2

More than 3 years have passed since last update.

【matplotlib入門】COVID-19データから終息時期を読む♬

Last updated at Posted at 2020-03-20

前回の新型コロナのシミュレーションでわかったことがいくつかあるが、よく見るとコロナの感染状況のグラフから、感染のピークを予測可能かもしれないと思わせてくれる。
それは、以下のようなシミュレーションであった。
pNo1000_R30sec_IP30%.gif
すなわち、赤い棒グラフが感染数、そして緑の棒グラフが治癒数を表しているが、感染数はどこまで増えるか予測は難しいが、治癒数は感染数に上限値を制限されているために、少なくとも感染数を超えることは無い。しかも、治癒率で表すと終息時にはほぼ100%になるものである。しかも、治癒率は感染ピークに比べて必ず遅れてピークとなる。一見、先にピークが来る感染数のほうが終息を見極めやすそうであるが、このピークは必ずしも上限であるかどうかがわからない。
一方、治癒数は50%辺りが感染のピークになり、だんだんその値に近づいて行くと思われる。
すなわち、この値を追いかければ終息時期がだいたい見えそうである。
という信念で上記のグラフを見ると、治癒が始まるころから感染も飽和に向かっている。
今回は、まず実データが同じような振る舞いをしているかを見てみることとする。
【参考】
コロナウイルスの感染者数をmatplotlibで可視化してみる

やったこと

・コード解説
・各国の感染者数を可視化

・コード解説

コードは以下に置いた。
collective_particles/draw_covid19.py

今回は、複数データの可視化方法である。
感染データの可視化のためには、以下のサイトから少なくとも3つのデータを取得する。簡単のためにzipファイルを以下の参考サイトからダウンロードして展開した。
(以下のリンクはファイルのリンクページです。下の参考から一括ダウンロードをおすすめ)
time_series_19-covid-Confirmed.csv
time_series_19-covid-Deaths.csv
time_series_19-covid-Recovered.csv
【参考】
CSSEGISandData/COVID-19
これらのデータを適当に処理して、上記と同じようなグラフを描画することとします。
以下グラフ描画までを説明します。
まず、以下のLibを利用する。
ここで、今回も環境はJetson-nanoを利用しているが、pandasを新たにインストールした。
参考のとおりであるが、単純なものだとエラーが出たので、最終的に以下のコマンドで入れた。

sudo apt-get install python-pandas
sudo apt-get install python3-pandas

なお、以下のコードはpythonで動いたが、python3だとimport pandasが動かなかった。
※以下のとおり一見動くんだけど??

$ python3
Python 3.6.9 (default, Nov  7 2019, 10:44:02) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pandas as pd
>>> 

【参考】
pipを使わない方法@3分でできるPandasのインストール方法

# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

次に3つのcsvファイルを以下のとおり読込ます。

#pandasでCSVデータ読む。
data = pd.read_csv('COVID-19/csse_covid_19_data/csse_covid_19_time_series/time_series_19-covid-Confirmed.csv')
data_r = pd.read_csv('COVID-19/csse_covid_19_data/csse_covid_19_time_series/time_series_19-covid-Recovered.csv')
data_d = pd.read_csv('COVID-19/csse_covid_19_data/csse_covid_19_time_series/time_series_19-covid-Deaths.csv')

変数を定義します。
読み込むデータは以下のような構造なので、最初の4つを除いています。

Province/State Country/Region Lat Long 1/22/20 1/23/20 1/24/20 1/25/20
Thailand 15 101 2 3 5 7
Japan 36 138 2 1 2 2
New South Wales Australia -33.8688 151.2093 0 0 0 0

日付は、日数に変更していますね。。。上記参考記事より

confirmed = [0] * (len(data.columns) - 4)
confirmed_r = [0] * (len(data_r.columns) - 4)
confirmed_d = [0] * (len(data_d.columns) - 4)
recovered_rate = [0] * (len(data_r.columns) - 4)
deaths_rate = [0] * (len(data_d.columns) - 4)
days_from_22_Jan_20 = np.arange(0, len(data.columns) - 4, 1)

今回は武漢のデータを見てみます。

city = "Hubei"

以下の最初の変数は、タイトル表示用に総件数、総治癒数、総死亡数を格納するために用意します。
上記のデータを見るとわかるように、州、国と並んでいるので武漢のデータを持ってくるには、if (data.iloc[i][0] == city):とします。国はコメントアウトしたのを使います。
confirmed,confirmed_r,そしてconfirmed_dにそれぞれの日別の数値を格納します。
件数データは累計値になっているので、その日の治癒件数データを引いて当日感染数に変更しています。
なお、+=の計算は国が同一で異なる地方の合算値を得るのに利用しています。

#データを加工する
t_cases = 0
t_recover = 0
t_deaths = 0
for i in range(0, len(data), 1):
    #if (data.iloc[i][1] == city): #for country/region
    if (data.iloc[i][0] == city):  #for province:/state  
        print(str(data.iloc[i][0]) + " of " + data.iloc[i][1])
        for day in range(4, len(data.columns), 1):
            confirmed[day - 4] += data.iloc[i][day] -  data_r.iloc[i][day]
            confirmed_r[day - 4] += data_r.iloc[i][day]
            confirmed_d[day - 4] += data_d.iloc[i][day]
        t_recover += data_r.iloc[i][day]        
        t_deaths += data_d.iloc[i][day]

今回は、上記の終息を見たいので、治癒率を計算しています。また、気になる死亡率も計算しています。

tl_confirmed = 0        
for i in range(0, len(confirmed), 1):
    tl_confirmed = confirmed[i] + confirmed_r[i] + confirmed_d[i]
    if tl_confirmed > 0:
        recovered_rate[i]=float(confirmed_r[i]*100)/float(tl_confirmed)
        deaths_rate[i]=float(confirmed_d[i]*100)/float(tl_confirmed)
    else:
        continue
t_cases = tl_confirmed       

以下でグラフにしています。今回は複数のグラフをまとめて表示できるようにしています。
※この記事の方が汎用性高くていいねもらえそうです
参考上げておきますが、以下のコードでわかりやすいと思います。
【参考】
Secondary axis with twinx(): how to add to legend?

#matplotlib描画
fig, (ax1,ax2) = plt.subplots(2,1,figsize=(1.6180 * 4, 4*2))
ax3 = ax1.twinx()
ax4 = ax2.twinx()

lns1=ax1.plot(days_from_22_Jan_20, confirmed, "o-", color="red",label = "cases")
lns2=ax1.plot(days_from_22_Jan_20, confirmed_r, "*-", color="green",label = "recovered")
lns3=ax3.plot(days_from_22_Jan_20, confirmed_d, "D-", color="black", label = "deaths")
lns4=ax2.plot(days_from_22_Jan_20, recovered_rate, "*-", color="green",label = "recovered")
lns5=ax4.plot(days_from_22_Jan_20, deaths_rate, "D-", color="black", label = "deaths")

lns_ax1 = lns1+lns2+lns3
labs_ax1 = [l.get_label() for l in lns_ax1]
ax1.legend(lns_ax1, labs_ax1, loc=0)

lns_ax2 = lns4+lns5
labs_ax2 = [l.get_label() for l in lns_ax2]
ax2.legend(lns_ax2, labs_ax2, loc=0)

ax1.set_title(city +" ; {} cases, {} recovered, {} deaths".format(t_cases,t_recover,t_deaths))
ax1.set_xlabel("days from 22, Jan, 2020")
ax1.set_ylabel("casas, recovered ")
ax2.set_ylabel("recovered_rate %")
ax2.set_ylim(0,100)

ax3.set_ylabel("deaths ")
ax4.set_ylabel("deaths_rate %")
ax4.set_ylim(0,10)
ax1.grid()
ax2.grid()

plt.pause(1)
plt.savefig('./fig/fig_{}_.png'.format(city)) 
plt.close()

fig_Hubei_.png

このデータかなりシミュレーションと比較するにはいいデータになっています。惜しむらくはカウントの仕方を変更した部分が大きく見えてしまっています。
このデータから、シミュレーションでこれを再現できれば、今回の武漢での感染伝播をシミュレート出来ることになります。
そして、治癒率を見てみると50%のところがこの感染伝播のピークであって、その後同程度日数で終息するだろうと予測出来ることがわかります。すなわち感染開始から40日程度でピークとなり、そこから20日程度たった今、あと20日程度で終息しそうです。
また、死亡率はじわじわ上がってきており、約4.5%程度のようです。
これは、新規感染者は増えないけど、単純には死者は最終晩まで発生が続くので致し方ないことだと思います。
※医療手順が整備されだんだん死ななくなるといいと思います

・各国の感染者数を可視化

それでは、気になる国の状況を出力して見てみましょう
以下、いろいろコメントを記載しましたが、あくまで素人ウワンがグラフを見ての感想ですのであしからず。

・韓国

fig_Korea, South_.png
死亡率は低くていいです。しかし、終息していると聞いていたのですが、感染数はピークに達したようですが、まだまだ治癒率が20%以下であり、予断は許さないかなという印象です。単純に50%までは30日程度かかり、その後50日程度無いと終息までは行かないような感じです。
※ここをもう少し定量的に評価できるアプリを作る予定です

・イタリア

fig_Italy_.png
医療崩壊かと噂があって心配していましたが、データはしっかりしていて安心しました。
つまり、国として統制が取れていると感じます。しかし、特徴は死亡率がどんどん上がっていて直近約8%と高いです。また、治癒率は約10%程度であり、感染数は約4万人ですが、今まさしく増加の真っ只中であり、終息の目処は立ちません。

・イラン

fig_Iran_.png
イタリアと並んで心配な国です。やはり、死亡率が異常値でしたが、ここに来てまたまた急激に増加し6%を超えてしまいました。ただし、治癒率が約30%程度まで来たのでもうすぐ感染数のピークが来るのかもしれません。治癒率の増加は遅いですが、そこから治癒数ピークが予測できれば封じ込めまで行ける目処が立ってきます。
データもしっかりしてきたので医療崩壊ということも大丈夫なようです。

・フランス/ドイツ/アメリカ

fig_France_.png
fig_Germany_.png
まとめて示しました。この両国も心配な国です。なぜならば、どちらも件数が上がっていますが、治癒がほとんど0です。急激な感染が予測され、これだと当面終息はしないのではないかと想像できます。
死亡率はフランスは2%と低めですが、ドイツは30名以下で、ほとんど0です。これは感染してから20日もたっていないので、闘病中の方が多いという想像はできますが、推移を見たいと思います。
アメリカも急減に感染数が増えている国です。
fig_US_.png
アメリカも上記の国と同様に治癒数は0で、死亡率は2%以下で低めに抑えられていますが、これも感染数の立ち上がりから20日程度なので、推移を見たいと思います。

・スペイン

スペインも心配な国の一つです。以下のとおりになっています。
fig_Spain_.png
データはしっかりしていて、コントロールされているように感じます。しかし、ここも死亡率が上がってきており、直近は4%を超えてきました。そして治癒率を見ると10%以下であり、感染数はそろそろ1.5万人ですが、まだまだ初期の段階であるとわかります。今後の推移を注視したいと思います。

・日本

fig_Japan_.png
日本は一番ゆるやかに感染が拡大している国だと思います。
ある意味、中国と両極な印象を受けます。
また、死亡率も低めに抑えられていましたが、徐々に4%に近づいているように見えます。また、治癒率は今18%位に増加してきましたが、すごくゆっくりにしか増加していないので、まだまだ感染ピークも治癒率ピークも見えるところには無いと思います。あと30日位このまま増加すれば見えてくるように思います。ただし、感染数の増加は下に凸の曲線であり、急激な増加につながる可能性もあるので予断は許さないと思います。

まとめ

・COVID-19データをプロットしてみた
・複数のグラフを関連付けて出力できた
・シミュレーションから見えることを実データで評価した

・シミュレーションを拡張して終息予測が出来るように拡張する
・各国の状況をカテゴライズするアプリを作ろうと思う

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2