人口比? (2)

10万人あたり換算で統一したとしても、その図示がわかりやすいものになるかどうかはまた別。

これの続きというかなんというか。予測の話は含まない。まずは前提のデータ取得:

csvを自分の都合のいいデータに加工するスクリプト(4’’)(東洋経済オンラインのもの)
  1 # -*- coding: utf-8-unix -*-
  2 import io
  3 import csv
  4 import datetime
  5 import numpy as np
  6 
  7 
  8 _PREFCODE = {
  9     '北海道': 1,
 10     '青森県': 2,
 11     '岩手県': 3,
 12     '宮城県': 4,
 13     '秋田県': 5,
 14     '山形県': 6,
 15     '福島県': 7,
 16     '茨城県': 8,
 17     '栃木県': 9,
 18     '群馬県': 10,
 19     '埼玉県': 11,
 20     '千葉県': 12,
 21     '東京都': 13,
 22     '神奈川県': 14,
 23     '新潟県': 15,
 24     '富山県': 16,
 25     '石川県': 17,
 26     '福井県': 18,
 27     '山梨県': 19,
 28     '長野県': 20,
 29     '岐阜県': 21,
 30     '静岡県': 22,
 31     '愛知県': 23,
 32     '三重県': 24,
 33     '滋賀県': 25,
 34     '京都府': 26,
 35     '大阪府': 27,
 36     '兵庫県': 28,
 37     '奈良県': 29,
 38     '和歌山県': 30,
 39     '鳥取県': 31,
 40     '島根県': 32,
 41     '岡山県': 33,
 42     '広島県': 34,
 43     '山口県': 35,
 44     '徳島県': 36,
 45     '香川県': 37,
 46     '愛媛県': 38,
 47     '高知県': 39,
 48     '福岡県': 40,
 49     '佐賀県': 41,
 50     '長崎県': 42,
 51     '熊本県': 43,
 52     '大分県': 44,
 53     '宮崎県': 45,
 54     '鹿児島県': 46,
 55     '沖縄県': 47,
 56 }
 57 _COLSNM = (
 58     "testedPositive",
 59     "peopleTested",
 60     "hospitalized",
 61     "serious",
 62     "discharged",
 63     "deaths",
 64     "effectiveReproductionNumber",
 65 )
 66 def _tonpa(fn):
 67     # 元データ prefectures.csv の著作権:
 68     # 『東洋経済オンライン「新型コロナウイルス 国内感染の状況」制作:荻原和樹』
 69     #
 70     # 1. 開始日が NHK まとめと違う
 71     # 2. 更新のない都道府県は省略してある
 72     # 3. 日付は一応抜けなく連続している、今のところ
 73     #
 74     # NHKまとめのほうで密行列として扱った同じノリにしたい、ここでは面倒だけど。
 75     # つまり、列方向に都道府県、行方向に日付。
 76     result = {
 77         k: np.zeros((1, 47))
 78         for k in _COLSNM}
 79     reader = csv.reader(io.open(fn, encoding="utf-8-sig"))
 80     next(reader)
 81     def _f(d):
 82         if not d or d == "-":
 83             # 不明とか未報告の意味だと思う。
 84             return float("nan")
 85         return float(d)
 86 
 87     era = datetime.datetime(2020, 1, 16)  # NHKまとめのほうの起点日
 88     curdate = era
 89     for line in reader:
 90         date = datetime.datetime(*map(int, line[:3]))
 91         dadv = (date - curdate).days
 92         data = list(map(_f, line[5:]))
 93         p = _PREFCODE[line[3]]
 94         for i, k in enumerate(_COLSNM):
 95             for _ in range(dadv):
 96                 result[k] = np.vstack((result[k], np.zeros((1, 47))))
 97             result[k][-1, p - 1] = data[i]
 98         curdate = date
 99     # 元データについて、どうやら厚労省のオープンデータそのものを転記しただけの
100     # 項目は累積でのみ管理しているらしく、この csv 全体では「累積だったりそうで
101     # なかったり」と大変使いにくい。ゆえ、累積のものは読み替えておく。
102     for k in ("testedPositive", "peopleTested", "discharged", "deaths",):
103         result[k][1:] = (
104             result[k] - np.roll(result[k], 1, axis=0))[1:]
105     #
106     # peopleTested の最新2日分はゴミ:
107     # ---
108     # 2021,1,28,東京都,Tokyo,  97571,  1303823.0,  14957.0,  150,  81767.0,  847,  0.74
109     # 2021,1,29,東京都,Tokyo,  98439,  1309999.0,  13807.0,  147,  83768.0,  864,  0.76
110     # 2021,1,30,東京都,Tokyo,  99208,  1309999.0,  13383.0,  141,  84942.0,  883,  0.77
111     # 2021,1,31,東京都,Tokyo,  99841,  1309999.0,  13257.0,  140,  85698.0,  886,  0.78
112     # ---
113     # 集計が3日遅れ、てこと、だろう。
114     result["peopleTested"][np.where(result["peopleTested"] == 0.0)] = float("nan")
115     # 移動平均
116     for k in ("testedPositive", "peopleTested", "hospitalized", "serious", "deaths"):
117         k1, k2 = k, k + "_movavg"
118         result[k2] = np.zeros(result[k1].shape)
119         for dt in range(len(result[k1])):
120             result[k2][dt, :] = result[k1][
121                 max(0, dt - 6):dt + 1, :].mean(axis=0)
122     #
123     np.savez(io.open("toyokeizai_online_covid19.npz", "wb"), **result)
124 
125 
126 if __name__ == '__main__':
127     _tonpa("prefectures.csv")

で、これでは示さなかったが、wikipedia からデータをコピペしてきてる、ワタシは:

pp.txt
 1 1	東京都	13000-1	13,515,271	13,960,236	+3.29	2021年1月1日
 2 2	神奈川県	14000-7	9,126,214	9,216,009	+0.98	2020年9月1日
 3 3	大阪府	27000-8	8,839,469	8,815,082	-0.28	2020年11月1日
 4 4	愛知県	23000-6	7,483,128	7,538,701	+0.74	2020年11月1日
 5 5	埼玉県	11000-1	7,266,534	7,342,682	+1.05	2020年12月1日
 6 6	千葉県	12000-6	6,222,666	6,281,869	+0.95	2021年1月1日
 7 7	兵庫県	28000-3	5,534,800	5,434,645	-1.81	2021年1月1日
 8 8	北海道	01000-6	5,381,733	5,231,685	-2.79	2020年11月30日
 9 9	福岡県	40000-9	5,101,556	5,108,038	+0.13	2020年9月1日
10 10	静岡県	22000-1	3,700,305	3,613,788	-2.34	2021年1月1日
11 11	茨城県	08000-4	2,916,976	2,852,499	-2.21	2021年1月1日
12 12	広島県	34000-6	2,843,990	2,793,470	-1.78	2020年11月1日
13 13	京都府	26000-2	2,610,353	2,566,341	-1.69	2021年1月1日
14 14	宮城県	04000-2	2,333,899	2,290,915	-1.84	2021年1月1日
15 15	新潟県	15000-2	2,304,264	2,195,068	-4.74	2021年1月1日
16 16	長野県	20000-0	2,098,804	2,031,795	-3.19	2021年1月1日
17 17	岐阜県	21000-5	2,031,903	1,975,397	-2.78	2020年9月1日
18 18	栃木県	09000-0	1,974,255	1,930,000	-2.24	2021年1月1日
19 19	群馬県	10000-5	1,973,115	1,924,116	-2.48	2021年1月1日
20 20	岡山県	33000-1	1,921,525	1,880,772	-2.12	2021年1月1日
21 21	福島県	07000-9	1,914,039	1,820,949	-4.86	2021年1月1日
22 22	三重県	24000-1	1,815,865	1,768,632	-2.60	2020年9月1日
23 23	熊本県	43000-5	1,786,170	1,734,231	-2.91	2021年1月1日
24 24	鹿児島県	46000-1	1,648,177	1,587,785	-3.66	2021年1月1日
25 25	沖縄県	47000-7	1,433,566	1,460,427	+1.87	2021年1月1日
26 26	滋賀県	25000-7	1,412,916	1,412,095	-0.06	2021年1月1日
27 27	山口県	35000-1	1,404,729	1,339,003	-4.68	2021年1月1日
28 28	愛媛県	38000-8	1,385,262	1,323,851	-4.43	2021年1月1日
29 29	長崎県	42000-0	1,377,187	1,308,277	-5.00	2021年1月1日
30 30	奈良県	29000-9	1,364,316	1,321,250	-3.16	2021年1月1日
31 31	青森県	02000-1	1,308,265	1,228,730	-6.08	2020年12月1日
32 32	岩手県	03000-7	1,279,594	1,209,457	-5.48	2021年1月1日
33 33	大分県	44000-1	1,166,338	1,124,309	-3.60	2020年11月1日
34 34	石川県	17000-3	1,154,008	1,129,362	-2.14	2020年12月1日
35 35	山形県	06000-3	1,123,891	1,062,239	-5.49	2021年1月1日
36 36	宮崎県	45000-6	1,104,069	1,062,180	-3.79	2021年1月1日
37 37	富山県	16000-8	1,066,328	1,033,981	-3.03	2020年11月1日
38 38	秋田県	05000-8	1,023,119	948,964	-7.25	2021年1月1日
39 39	香川県	37000-2	976,263	949,357	-2.76	2020年9月1日
40 40	和歌山県	30000-4	963,579	912,364	-5.32	2021年1月1日
41 41	山梨県	19000-4	834,930	805,339	-3.54	2021年1月1日
42 42	佐賀県	41000-4	832,832	808,074	-2.97	2021年1月1日
43 43	福井県	18000-9	786,740	762,272	-3.11	2020年11月1日
44 44	徳島県	36000-7	755,733	721,721	-4.50	2020年9月1日
45 45	高知県	39000-3	728,276	688,583	-5.45	2021年1月1日
46 46	島根県	32000-5	694,352	665,702	-4.13	2021年1月1日
47 47	鳥取県	31000-0	573,441	550,651	-3.97	2021年1月1日

この表を取り込んで、前回の表を作った。

の上で。「10万人あたり」という見方で統一すれば、全国を一気に見ることが出来る:

  1 # -*- coding: utf-8-unix -*-
  2 import io
  3 import csv
  4 import datetime
  5 import numpy as np
  6 import matplotlib as mpl
  7 import matplotlib.pyplot as plt
  8 import matplotlib.font_manager
  9 import matplotlib.ticker as ticker
 10 
 11 
 12 _PREFCODE = {
 13     '北海道': 1,
 14     '青森県': 2,
 15     '岩手県': 3,
 16     '宮城県': 4,
 17     '秋田県': 5,
 18     '山形県': 6,
 19     '福島県': 7,
 20     '茨城県': 8,
 21     '栃木県': 9,
 22     '群馬県': 10,
 23     '埼玉県': 11,
 24     '千葉県': 12,
 25     '東京都': 13,
 26     '神奈川県': 14,
 27     '新潟県': 15,
 28     '富山県': 16,
 29     '石川県': 17,
 30     '福井県': 18,
 31     '山梨県': 19,
 32     '長野県': 20,
 33     '岐阜県': 21,
 34     '静岡県': 22,
 35     '愛知県': 23,
 36     '三重県': 24,
 37     '滋賀県': 25,
 38     '京都府': 26,
 39     '大阪府': 27,
 40     '兵庫県': 28,
 41     '奈良県': 29,
 42     '和歌山県': 30,
 43     '鳥取県': 31,
 44     '島根県': 32,
 45     '岡山県': 33,
 46     '広島県': 34,
 47     '山口県': 35,
 48     '徳島県': 36,
 49     '香川県': 37,
 50     '愛媛県': 38,
 51     '高知県': 39,
 52     '福岡県': 40,
 53     '佐賀県': 41,
 54     '長崎県': 42,
 55     '熊本県': 43,
 56     '大分県': 44,
 57     '宮崎県': 45,
 58     '鹿児島県': 46,
 59     '沖縄県': 47,
 60 }
 61 def _vis(dattko):
 62     reader = csv.reader(io.open("pp.txt", encoding="cp932"), delimiter="\t")
 63     fac = []
 64     for row in reader:
 65         fac.append((_PREFCODE[row[1]], int(row[4].replace(",", ""))))
 66     fac.sort()
 67     fac = np.array([(100000. / n) for pc, n in fac])
 68     #
 69     era = datetime.date(2020, 1, 16)
 70     #
 71     fontprop = matplotlib.font_manager.FontProperties(
 72         fname="c:/Windows/Fonts/meiryo.ttc")
 73 
 74     era = "2020/1/16"  # 木曜日
 75     era = datetime.date(*map(int, era.split("/")))
 76     #
 77     k = "testedPositive_movavg"
 78     #k = "hospitalized"
 79     #k = "deaths"
 80     #
 81     Z = dattko[k] * fac
 82     Z[np.argwhere(np.isnan(Z))] = 0
 83 
 84     T = np.array([era + datetime.timedelta(t) for t in range(len(Z))])
 85     Y = np.arange(48)
 86     X, Y = np.meshgrid(T, Y)
 87     #
 88     fig, ax1 = plt.subplots(tight_layout=True)
 89     fig.set_size_inches(16.53 * 1.2, 11.69)
 90     ax1.invert_yaxis()
 91     ax1.yaxis.set_major_formatter(
 92         ticker.FuncFormatter(
 93             lambda x, pos=None: {pc: pn for (pn, pc) in _PREFCODE.items()}.get(x + 1, "")))
 94     for lab in ax1.get_yticklabels():
 95         lab.set_fontproperties(fontprop)
 96     CS = ax1.pcolor(X, Y, Z.T)
 97     ax1.set_yticks(range(47))
 98     cbar = fig.colorbar(CS)
 99     ax1.grid(True)
100     ax1.set_xlabel(
101         "入院治療等を要する者(10万人あたり)\n「東洋経済オンライン「新型コロナウイルス 国内感染の状況」制作:荻原和樹」を加工",
102         fontproperties=fontprop)
103 
104     fig.savefig("hospitalized_per100000.png")
105     plt.close(fig)
106 
107 
108 if __name__ == '__main__':
109     _vis(np.load(io.open("toyokeizai_online_covid19.npz", "rb")))
2021-02-08追記:
ごめん、上で「Z[np.argwhere(np.isnan(Z))] = 0」としてる部分、「Z[np.where(np.isnan(Z))] = 0」でないとダメ。失礼。

ほんとか?:
hospitalized_per100000
それほどわかりやすいとは言えないよな。なお、3D プロットも試みたが、そっちはもっとダメ、読めたもんじゃない。この pcolor がはるかにいい。

ちなみに、「都道府県コード」っておおよそは日本地図の位置関係に対応しているんだけれど、たとえば宮城県の位置がおかしくて、ほんとは「北海道→青森→秋田→岩手→山形→宮城→福島」であって欲しいんだけどそうなってない。緯度経度の関係順に並べる、ってことそのものが、一次元リストでは無理なことだとはいえ、せめて緯度順にはなってて欲しかった。それでも、とはいえ、これでも一応「生活圏」のかたまりで広がる様子はなんとなくは出てて、尾身会長の言ってた「首都圏から染み出している」が、なんとなくは出てる。

ところで、ここ数日作業してて、今一番危険信号なのは千葉県なんではないかとみているのだが、知事はじめ報道も全然騒いでないよね、いいのかそれで?


2021-02-08追記:
どうにかもう少しクリアに見えんかなぁと思ってやってたが、これだと結構いいかな?:

PowerNormの活用。
  1 # -*- coding: utf-8-unix -*-
  2 import io
  3 import csv
  4 import datetime
  5 import numpy as np
  6 import matplotlib as mpl
  7 import matplotlib.pyplot as plt
  8 import matplotlib.font_manager
  9 import matplotlib.ticker as ticker
 10 from matplotlib.colors import LogNorm, PowerNorm
 11 
 12 
 13 _PREFCODE = {
 14     '北海道': 1,
 15     '青森県': 2,
 16     '岩手県': 3,
 17     '宮城県': 4,
 18     '秋田県': 5,
 19     '山形県': 6,
 20     '福島県': 7,
 21     '茨城県': 8,
 22     '栃木県': 9,
 23     '群馬県': 10,
 24     '埼玉県': 11,
 25     '千葉県': 12,
 26     '東京都': 13,
 27     '神奈川県': 14,
 28     '新潟県': 15,
 29     '富山県': 16,
 30     '石川県': 17,
 31     '福井県': 18,
 32     '山梨県': 19,
 33     '長野県': 20,
 34     '岐阜県': 21,
 35     '静岡県': 22,
 36     '愛知県': 23,
 37     '三重県': 24,
 38     '滋賀県': 25,
 39     '京都府': 26,
 40     '大阪府': 27,
 41     '兵庫県': 28,
 42     '奈良県': 29,
 43     '和歌山県': 30,
 44     '鳥取県': 31,
 45     '島根県': 32,
 46     '岡山県': 33,
 47     '広島県': 34,
 48     '山口県': 35,
 49     '徳島県': 36,
 50     '香川県': 37,
 51     '愛媛県': 38,
 52     '高知県': 39,
 53     '福岡県': 40,
 54     '佐賀県': 41,
 55     '長崎県': 42,
 56     '熊本県': 43,
 57     '大分県': 44,
 58     '宮崎県': 45,
 59     '鹿児島県': 46,
 60     '沖縄県': 47,
 61 }
 62 def _vis(dattko):
 63     reader = csv.reader(io.open("pp.txt", encoding="cp932"), delimiter="\t")
 64     fac = []
 65     for row in reader:
 66         fac.append((_PREFCODE[row[1]], int(row[4].replace(",", ""))))
 67     fac.sort()
 68     fac = np.array([(100000. / n) for pc, n in fac])  #10万人換算
 69     #fac = np.array([(fac[12][1] / n) for pc, n in fac])  #東京換算
 70     #
 71     era = datetime.date(2020, 1, 16)
 72     #
 73     fontprop = matplotlib.font_manager.FontProperties(
 74         fname="c:/Windows/Fonts/meiryo.ttc")
 75 
 76     era = "2020/1/16"  # 木曜日
 77     era = datetime.date(*map(int, era.split("/")))
 78     #
 79     #k = "testedPositive_movavg"
 80     #k = "hospitalized"
 81     #k = "deaths"
 82     #k = "serious_movavg"
 83     k = "serious"
 84     #
 85     skip = 0  #7*4*7
 86     Z = dattko[k] * fac
 87     Z = Z[skip:]
 88     Z[np.where(np.isnan(Z))] = 0
 89     #
 90     T = np.array([era + datetime.timedelta(t + skip) for t in range(len(Z))])
 91     Y = np.arange(48)
 92     X, Y = np.meshgrid(T, Y)
 93     #
 94     fig, ax1 = plt.subplots(tight_layout=True)
 95     fig.set_size_inches(16.53 * 1.2, 11.69)
 96     ax1.invert_yaxis()
 97     ax1.yaxis.set_major_formatter(
 98         ticker.FuncFormatter(
 99             lambda x, pos=None: {pc: pn for (pn, pc) in _PREFCODE.items()}.get(x + 1, "")))
100     for lab in ax1.get_yticklabels():
101         lab.set_fontproperties(fontprop)
102     #CS = ax1.pcolor(X, Y, Z.T, cmap="coolwarm")
103     #CS = ax1.pcolor(X, Y, Z.T, norm=LogNorm(clip=True))
104     #CS = ax1.pcolor(X, Y, Z.T, norm=LogNorm(), cmap="coolwarm")
105     CS = ax1.pcolor(X, Y, Z.T, norm=PowerNorm(0.4), cmap="coolwarm")
106     ax1.set_yticks(range(47))
107     cbar = fig.colorbar(CS)
108     ax1.grid(True)
109     ax1.set_xlabel(
110         "重症者(10万人あたり)\n「東洋経済オンライン「新型コロナウイルス 国内感染の状況」制作:荻原和樹」を加工",
111         fontproperties=fontprop)
112 
113     fig.savefig("{}_per100000.png".format(k))
114     plt.close(fig)
115 
116 
117 if __name__ == '__main__':
118     _vis(np.load(io.open("toyokeizai_online_covid19.npz", "rb")))

serious_per100000
緊急事態宣言解除されてない10都道府県で今一番前のめりで解除に向けて動いてる大阪が、実は一番悪い状態である、てことがはっきりわかる、よね。つまり、こういう図示をしようとする努力をし、そしてそれを共有しようぜ、てことね。そうすりゃぁ吉村知事も「間違えない」と思うんだよなぁ。


2021-02-09追記:
本質的な話ではなくてすまん。上のスクリプトに以下を追加:

「ax1.invert_yaxis()」の直後あたりに
1     ax1.tick_params(labelright=True)

とすると、ちょっとだけ使いやすくなる:
serious_per100000_
両サイドに都道府県名を描画、てだけね。

大阪問題は騒がれていないことはないんだけど、例の失言問題などで取り上げ方がなんだか異様に薄く、ちょっと気になる。オリンピック問題は確かに問題なのだが、果たして「欽…」を何時間もかけて伝える意味が、今あるのかどうか。コロナのことばっかやってんじゃないよ、って反発はわからんでもないけれどもだな、その反動で選ぶのがソレなの? なんだかなぁって思うよ。


2021-02-12追記:
大阪問題については、まだ言いたい。重症病床使用率が60%未満になったからおkだ、としてまた突っ走ろうとしてるようだが、繰り返すが「大阪が今一番ヤバい状態にある」。もう少し見やすくならんかなぁと思った。一つにはやはり「東京で言うと」の数字で見せることの意義ね。インパクトがあろう。「10万人あたり2.3人」なんて言われるよりも。もう一つは、「(流行)波の形」なのよ。伝わるかなぁ? まずは二つの絵をみてみて:
serious_asTokyo_0_2021-02-10
serious_asTokyo_1_2021-02-10
上の絵はわかるよね、「東京でいうところの250人である」てこと。下の絵は各都道府県ごとの最大値で割った値で、つまりはピーク位置を強調した絵。これをみれば、大阪のピークアウト開始が東京より随分遅く始まったのがわかる、かなと思うんだけど、どう? 死亡者は、これまでのところ、重症者の波の2週遅れという推移を辿ってきているので、大阪はまだ何日も死亡者数は増加傾向が続き、東京はこれから下がり続けるということがわかる。

繰り返す。「今日本で一番マズい状態にあるのは大阪」。東京ではない。吉村知事はそこを見誤ってるのではないのか。ちょっと前に書いたけど、やっぱり「医療体制拡充前の状態で言うところの逼迫度」もやっぱり同時にみた方がいいんではないかと思ってる。たとえば「自衛隊5万人に助けを求めたので感染者が5万人増えていい」というのと根本的に同じことをしようとしてるのだ、大阪は。結局これも「じぶんごと」として考えることが出来るかどうかだよなぁ、って思う。