COVID-19

[ご注意] ブラウザによっては更新(再読み込み)しても古い画像が表示されることがあるようです。いわゆる「スーパーリロード」([Shift] + [更新] または [Control] + [更新])をお試しください。

番外編1番外編2も参考になるかもしれません。もう変化のないクルーズ船ダイヤモンド・プリンセス号は別ページにしました。

はじめに

日本では「新型コロナウイルス感染症」と呼ばれている COVID-19(コービッド・ナインティーン)についての最新のデータを収集し,Python でグラフにする。COVID-19 は病名で,ウイルス名は当初 2019-nCoV と呼ばれたが現在は SARS-CoV-2(サーズ・シーオーブイ・ツー)が公式名である。

Python コードの繰返し現れる部分は省略してあるところがある。完全なコードデータも置いてある(頭に COVID が付いているファイル)。GitHub にも同じものを置いている。例えばデータは これ

WHOの日報

WHO の Coronavirus disease (COVID-2019) situation reports に基づいて集計したデータ COVID-19.csv を Python でグラフにする。

import matplotlib.pyplot as plt
import pandas as pd

df = pd.read_csv("https://oku.edu.mie-u.ac.jp/~okumura/python/data/COVID-19.csv",
                 index_col='Date', parse_dates=['Date'])

これで df.plot() とすれば全部のコラムがプロットできるが,見にくいので,もうちょっとがんばってみる:

import matplotlib.dates as mdates

locator = mdates.AutoDateLocator()
formatter = mdates.ConciseDateFormatter(locator)
fig, ax = plt.subplots()
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(formatter)

cmap = plt.get_cmap("tab20")
ax.bar(df.index, df['Global Confirmed'], color=cmap(3))
ax.bar(df.index, df['China Confirmed'], color=cmap(2))
ax.bar(df.index, df['Global Deaths'], color=cmap(6))
ax.legend(['Global Confirmed', 'China Confirmed', 'Global Deaths'])

fig.savefig('COVID-19.svg', bbox_inches="tight")

2020-02-17から湖北省については laboratory-confirmed だけでなく clinically diagnosed も含めたので急増している。

COVID-19

対数グラフにするには ax.bar() の部分を次のように変える:

ax.plot(df.index, df['Global Confirmed'], "s-", color=cmap(3))
ax.plot(df.index, df['China Confirmed'], "o-", color=cmap(2))
ax.plot(df.index, df['Global Deaths'], "s-", color=cmap(7))
ax.plot(df.index, df['China Deaths'], "o-", color=cmap(6))
ax.set_yscale('log')

日本のデータもグラフに含めてみた。

COVID-19

以上は累計値である。差分(1日あたりの値)は次の通り。Confirmed の定義が変わった 2020-02-17 の差分は表示していない。この前後での比較は要注意。

import numpy as np

dt = (df.index.to_series().diff() / pd.Timedelta(days=1))
c = df['Global Confirmed'].diff()
c[df.index == '2020-02-17'] = np.nan
ax.bar(df.index, c / dt, width=-dt, align='edge', color=cmap(3), edgecolor="white")
ax.bar(df.index, df['Global Deaths'].diff() / dt, width=-dt,
       align='edge', color=cmap(6), edgecolor="white")
ax.legend(['Confirmed', 'Deaths'])
COVID-19

中国でのピークは2月上旬で過ぎていることがわかる。なお,こういう図をエピカーブ(epidemic curve, epi curve)という。エピカーブの横軸は発病日が一般的だが,ここでは報告日である。

日本については,上記 WHO の日報から拾ったものを COVID-jp.csv として置いておく。なお,2022-02-05 の数は 33 となっていたがこれは明らかに 23 の誤記だと思われるので訂正しておいた。

累積

COVID-19 (Japan)

差分(2020-03-18からWHOはその日の00:00 CET(08:00 JST)時点での各国からの報告に基づくようになったので,日本・中国・韓国などは2020-03-17と2020-03-18との差分はゼロになっている)。

COVID-19 (Japan)

同じ WHO の最新の日報から,番外編1で解説した方法で,国ごとの確定数,死亡数(2人以上)をプロットしたものも挙げておく。灰色の対角線は中国と同じ死亡数/確定数のラインである。オレンジと緑の線は中国と日本の履歴である。中国の履歴が突然右に飛んでいるのは 2020-02-17 に Confirmed の基準が変わったためである(上述)。

COVID-19

CSSEのデータ

Johns Hopkins 大学の Center for Systems Science and Engineering (CSSE) は Coronavirus COVID-19 Global Cases by Johns Hopkins CSSE という COVID-19 可視化サイトを早くから立ち上げている。データについては GitHub の 2019 Novel Coronavirus COVID-19 (2019-nCoV) Data Repository by Johns Hopkins CSSE で公開している。そのデータのプロット例を番外編1の後半で示した。最新の図をこちらにも載せておく。まずは確定数。黒丸マーカーを付けたものが日本である。

COVID-19

差分(つまり1日ごとの増分):

COVID-19

死亡数:

COVID-19

差分(つまり1日ごとの増分):

COVID-19

厚労省の(ほぼ)日報

厚労省報道発表一覧(新型コロナウイルス)からリンクされている日報(ただし毎日ではない)の最近のものには,やや見やすい表がある。これから拾ったデータ COVID-mhlw.csv によるその時点までのPCR検査結果(累計)は以下の通り(より古いデータ COVID-mhlw-old.csv はチャーター機帰国者を含まない)。データには時刻(これまでのところ 12:00 つまり正午)が入っているが,x軸目盛は日の 0:00 に付いていることに注意。3月4日に検査人数が急増しているが,「「令和2年3月4日版」以後は、陽性となった者の濃厚接触者に対する検査も含めた検査実施人数を都道府県に照会し、回答を得たものを公表している」とのこと。陽性数が当日12時のものであるのに対し,検査人数は前日18時のもの。2020-03-19に累積の検査人数が減っているが,「千葉県が人数でなく件数でカウントしていたことが判明したため、千葉県の件数を引いたことによる」。2020-03-25にも909人減っているが理由は不明。Japan's COVID-19 Reports - 140KBs of Unadulterated Incompetence という指摘を受けたためか,2020-03-28から表の形式などが少し変わった。

COVID-19 (Japan)

データの差分をとって,高さを1日あたりの数に直したものも描いてみる。最近は負になったりしてデータの信頼性がまったくない。

dt = (df.index.to_series().diff() / pd.Timedelta(days=1))
ax.bar(df.index, df['Examined'].diff() / dt, width=-dt+0.1, align='edge')
ax.bar(df.index, df['Confirmed'].diff() / dt, width=-dt+0.1, align='edge')
COVID-19 (Japan)

陰性の数が増えて(しかも報告が安定せず)見にくくなってきたので,検査人数を省いたグラフにした。データが正午締めで,数え方も番外編2のものと若干異なる。'Hospitalized' は,2020-02-10から2020-03-27までは有症状で入院治療を要する者,発表のフォーマットが変わった2020-03-28以降は入院治療を要する者(無症状を含む)である:

COVID-19 (Japan)

陽性の割合(累計)と95%信頼区間のグラフ:

from statsmodels.stats.proportion import proportion_confint

p = [x['Confirmed'] / x['Examined'] for i, x in df.iterrows()]
ci0, ci1 = np.array([proportion_confint(x['Confirmed'], x['Examined'], method='beta')
                     for i, x in df.iterrows()]).T
ax.errorbar(df.index, p, [p - ci0, ci1 - p], fmt="o", capsize=5, color="C1")
ax.grid(axis='y')
COVID-19 proportion of positives (Japan)

こちらも差分なら次のようになる:

p = df['Confirmed'].diff() / df['Examined'].diff()
ci0, ci1 = np.array([proportion_confint(x['Confirmed'], x['Examined'], method='beta')
                     for i, x in df.diff().iterrows()]).T
ax.errorbar(df.index, p, [p - ci0, ci1 - p], fmt="o", capsize=5, color="C1")
ax.grid(axis='y')
COVID-19 (Japan)

各地の状況

都道府県ごとにPCR検査件数(または検査人数)・陽性数が報告されているが,おのおの報告の基準が違うため,比較するのは困難である。推移を見るだけに留めたい。

けんもねずみ (kenmo_economics) さんのこちらのサイトでは公表されている全都道府県のグラフが見られる(不明日は線形補間してあることに注意)。データは都道府県別の検査数の公表状況(根拠URL付)からダウンロードできる。

厚労省も都道府県別のデータをPDFで公表するようになった。新型コロナウイルス感染症についてのページから「PCR検査実施人数(都道府県別)」「PCR検査総実施件数(都道府県別)」のような形でリンクされている。

東京都は都内の最新感染動向covid19-tokyo.netlify.com のCNAME)で情報提供を始めた。ソースはGitHubでオープンソースとして開発されている(https://github.com/tokyo-metropolitan-gov/covid19)。データは東京都オープンデータカタログサイトで公開されている。

上の東京都のソースを使った最新感染動向サイトが各地にできている(北海道神奈川県愛知県埼玉県三重県福岡市兵庫県など。最新のリストはHackMDにまとめられている)。

三重県

わが県は新型コロナウイルス感染症検査実施件数にまとめられているが,全角なので少々面倒(もっと簡単な方法があったらお教えください):

import re

Z2H = str.maketrans(" 0123456789", " 0123456789")

tables = pd.read_html('http://www.pref.mie.lg.jp/YAKUMUS/HP/m0068000071_00005.htm')
t = tables[0][1:-1].copy()
for i, x in t.iterrows():
    for j in range(4):
        x[j] = x[j].translate(Z2H)
    m = re.search(r'(\d+)月 *(\d+)日', x[0])
    if m:
        x[0] = pd.Timestamp(f'2020-{m[1]}-{m[2]}')
    for j in range(1, 4):
        x[j] = int(re.sub("件", "", x[j]))

fig, ax = plt.subplots()
locator = mdates.AutoDateLocator()
formatter = mdates.ConciseDateFormatter(locator)
ax.xaxis.set_major_locator(locator)
ax.xaxis.set_major_formatter(formatter)
ax.bar(t[0], t[1])
ax.bar(t[0], t[2])
ax.legend(['Negative', 'Positive'])
ax.set_yticks([0, 5, 10, 15])

fig.savefig('COVID-mie.svg', bbox_inches="tight")
三重県

関連サイトへのリンク


Last modified: