はじめに
2021年3月,COVID-19が猛威を振るい,夕方にはその日の感染者数がニュース速報として表示されていました.私はふと,「この数値だけを見てCOVID-19を怖がることは、我々にとって意味のあることなのか」と疑問に思いました.ネットで感染者データの解析結果を調べてみると,都道府県ごとに感染者数が示された画像ばかり出てきました[1].
より詳細な可視化を行うことで人々が正しく怖がることができるデータが生まれると考えた私は,市町村単位で感染者情報を提示しようと考えました.市町村単位の感染者情報を地理的に提示することで・・・
- 県内の人は感染リスクの高い場所に行かないようになる
- 隣県に住んでいる人でも,感染者数が高い市町村と距離が近いことを知れれば警戒心をもつことができる
というメリットがあります.
可視化のために,私の出身である群馬県のホームページから感染者データと各市町村の人口データのCSVファイルをダウンロードし,GeoPandasを用いて各市町村の感染者割合を地図上で可視化してみました.
対象者
この記事は下記のような人を対象にしています.
- 可視化してみたい人
- geopandasを触ってみたい人
使ったもの
※全て2021年5月18日に取得したものです.
- Google Colaboratory
- 下記のデータ
-
01kanja.csv
群馬県内のコロナウイルス感染者データ
(http://stopcovid19.pref.gunma.jp/cards/number-of-confirmed-cases/ より入手) -
population.csv
群馬県内の人口データ
(http://toukei.pref.gunma.jp/nbj/ より入手したデータ(nbj2021.xls)を手作業で加工したもの) -
gunma.csv
下記の「前処理」にて作成したファイルに,群馬県内の各市町村の緯度・経度データを手作業で入力したもの.
市町村別の感染者の割合などを示す. -
japan.geojson
日本地図のデータ
実際の緯度・経度に対応しているため,任意の緯度・経度データを散布図としてプロットすることで可視化が可能
(https://github.com/dataofjapan/land より入手)
-
ソースコード
ライブラリのインポートとcsvの読み込み
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns
import tqdm
from datetime import datetime as dt
import re
#日本語化matplotlibを使用
!pip install japanize-matplotlib
import japanize_matplotlib as plt_jp
#日本語フォント設定
sns.set(font="IPAexGothic")
#csvの読み込み
gunma = pd.read_csv("01kanja.csv")
population = pd.read_csv("population.csv")
前処理
先述したgunma.csvを作成します.
infect = gunma["居住地"].value_counts()
#series型をdataframe型に変更
infect = pd.DataFrame(infect)
#データを統合できるように整理
infect_improve = infect.reset_index()
infect_improve = infect_improve.rename(columns = {"index" : "municipalities"})
infect_improve.head(10)
a = population[["municipalities", "pop_all"]]
#正規表現を用いて人口データからカンマを取り除く
b = np.zeros(a["pop_all"].size)
for i in range(a["pop_all"].size):
b[i] = re.sub(r"\D", "", a["pop_all"].iloc[i])
a["pop_all"] = b.astype(int)
#dataframe型に変更
a = pd.DataFrame(a)
#indexと居住地を入れ替えて、infectと同じ形式にする
a.head(10)
#市町村名をキー値として合併
c = pd.merge(infect_improve, a)
#群馬県全体の感染者数を1としたときの、市町村ごとの感染者割合を算出
d = c["居住地"] / c["pop_all"] * 10
c["infect_per"] = d/d.sum()
一旦,円グラフとして出力してみます.
fig, ax = plt.subplots(figsize=(15.0, 15.0))
d = c[["municipalities", "infect_per"]]
plt.pie(d["infect_per"], labels = d["municipalities"], autopct = '%.0f%%',counterclock = False,
#explodeのn番目の値を0から変えると、その値を半径とする円の分だけ、n番目のデータを切り離す
textprops = {"fontsize" : "18"}, explode = (0, 0, 0, 0, 0.2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
これをcsvファイルとして出力します.
from google.colab import files
c.to_csv('gunma.csv', index=False)
files.download("gunma.csv")
そこに,群馬県内の各市町村の緯度・経度データを手作業で入力しました.
こちら[2]を参考にした方が楽にできそうです.
これで,gunma.csvの準備はOKです.
geopandasを用いて地図上で可視化
先ほど円グラフで示したデータを,geopandasを用いて地図上で可視化します.
!pip install --upgrade geopandas
!pip install --upgrade pyshp
!pip install --upgrade shapely
!pip install --upgrade descartes
import geopandas as gpd
#日本地図を読み込み
df = gpd.read_file('japan.geojson')
locations = pd.read_csv("gunma.csv", encoding = "SHIFT_JIS")
#つまり全データ
locations = (locations.query("infect_per >= 0"))
# 表示
with plt.style.context("ggplot"):
#境界線の色、土地の色、境界線の太さを設定
df.plot(figsize=(15,15), edgecolor='#444', facecolor='white', linewidth = 0.7);
#群馬県の地図の範囲のみを表示
plt.xlim([138.2,139.75])
plt.ylim([35.8, 37.2])
plt.scatter(locations.Longitude, locations.Latitude, marker='o', s=locations.infect_per * 50000, c=locations.infect_per, cmap="Reds", vmin=0, vmax=0.23, alpha=0.9)
plt.colorbar()
南東側(地元民がよく言う,鶴の頭の部分)の感染者割合が多いですね.
このグラフを見ることで,栃木県西部や埼玉県北部にお住いの方は警戒心をもつことができると思います.
とはいえ,県ごとにオープンデータの中身が異なると思うので,そこに対応しなければならないですね.
今後対応予定です.
参考記事
[1] 全国のコロナ感染確認 過去最多の19万5159人 22都道府県で最多(2023年2月26日参照)
[2] Excel の WEBSERVICE 関数でジオコーディング(2023年2月26日参照)