東洋経済ONLINEの新型コロナウイルス国内感染の状況は国内の状況を一覧できる便利なサイトである。残念ながらGitHub上のデータの更新は2021-01-31で終了してしまった。そこで,東洋経済のサイトから直接データをダウンロードすることによって追加のグラフを描いてみる。
データはサイト上の data.json というファイルに収められている。これを直接 Python で読み込むこともできるが,ここではいったんファイルに落とす:
wget -N https://toyokeizai.net/sp/visual/tko/covid19/data/data.json
これを読み込む:
import json
import numpy as np
import matplotlib.pyplot as plt
with open("data.json") as f:
data = json.load(f)
データの構造を見るため,簡単な関数を定義する:
def foo(x, depth=0):
if type(x) == dict:
for i in x.keys():
print(" " * 4 * depth, i, sep="")
foo(x[i], depth + 1)
foo(data)
updated
last
ja
en
demography
ja
en
transition
carriers
from
values
cases
from
values
discharged
from
values
serious
from
values
deaths
from
values
pcrtested
from
values
pcrtests
from
values
reproduction
from
values
demography
prefectures-data
prefectures-map
最初の部分は更新日時などである:
data["updated"]["last"]["ja"] # => '最終更新:2021年4月9日' data["updated"]["demography"]["ja"] # => '4月7日時点'
以下では都道府県ごとの累計の検査陽性者数と死亡者数を調べる:
carriers = np.array(
[np.sum(data["prefectures-data"][i]["carriers"]["values"]) for i in range(47)]
)
deaths = np.array(
[np.sum(data["prefectures-data"][i]["deaths"]["values"]) for i in range(47)]
)
これをプロットする:
kenmei = ["北海道", "青森", "岩手", "宮城", "秋田", "山形", "福島",
"茨城", "栃木", "群馬", "埼玉", "千葉", "東京", "神奈川",
"新潟", "富山", "石川", "福井", "山梨", "長野", "岐阜",
"静岡", "愛知", "三重", "滋賀", "京都", "大阪", "兵庫",
"奈良", "和歌山", "鳥取", "島根", "岡山", "広島", "山口",
"徳島", "香川", "愛媛", "高知", "福岡", "佐賀", "長崎",
"熊本", "大分", "宮崎", "鹿児島", "沖縄"]
plt.clf()
plt.scatter(carriers, deaths)
for x, y, s in zip(carriers, deaths, kenmei):
plt.text(x, y, s)
plt.xlabel("感染者数")
plt.ylabel("死者数")
感染者数・死者数は当然比例する。人口あたりにすると地域差が見えてくる:
# 2019-10-01推計人口(単位1000人)
population = np.array([5250, 1246, 1227, 2306, 966, 1078, 1846,
2860, 1934, 1942, 7350, 6259, 13921, 9198, 2223, 1044, 1138, 768,
811, 2049, 1987, 3644, 7552, 1781, 1414, 2583, 8809, 5466, 1330,
925, 556, 674, 1890, 2804, 1358, 728, 956, 1339, 698, 5104, 815,
1327, 1748, 1135, 1073, 1602, 1453])
plt.scatter(carriers / population, deaths / population)
for x, y, s in zip(carriers / population, deaths / population, kenmei):
plt.text(x, y, s)
plt.xlabel("人口1000人あたり感染者数")
plt.ylabel("人口1000人あたり死者数")
これでもまだ横軸・縦軸の相関が強いので,次のようにしてみる:
plt.scatter(carriers / population, deaths / carriers)
for x, y, s in zip(carriers / population, deaths / carriers, kenmei):
plt.text(x, y, s)
plt.xlabel("人口1000人あたり感染者数")
plt.ylabel("死者数/感染者数")
左ほどばらついているように見えるので,エラーバー(Clopper-Pearson 95%信頼区間)を描いてみる。エラーバーなしのときのyの範囲を覚えておき,それと同じ範囲を描くようにした:
from statsmodels.stats.proportion import proportion_confint
ci0, ci1 = proportion_confint(deaths, carriers, method='beta')
plt.scatter(carriers / population, deaths / carriers)
y0, y1 = plt.ylim()
plt.errorbar(carriers / population, deaths / carriers,
[deaths / carriers - ci0, ci1 - deaths / carriers],
fmt="o", capsize=5)
plt.ylim(y0, y1)
for x, y, s in zip(carriers / population, deaths / carriers, kenmei):
plt.text(x, y, s)
plt.xlabel("人口1000人あたり感染者数")
plt.ylabel("死者数/感染者数")
Last modified: