はじめに
簡単なコロプレス図を作りたいと思ったときに、いろいろと調べたので備忘録代わりに記録しておく。以下、参考サイト。
- foliumn の使い方
- 使用したデータ
また、cartopy でのコロプレス図の作り方は「Python で COVID-19 のコロプレス図を作成する(cartopy版)」に書いてあるので、もし興味があれば参照してください。
folium のインストール
いつもの通り、pip, conda でインストールできる。
- pip の場合
$ pip install folium
- conda の場合
$ conda install folium -c conda-forge
いくつかの関数は、numpy, pandas, geopandas, altair, etc.などの他ライブラリに依存しているようなので、それらも必要に応じてインストールする必要がある。(※geopandas の conda でのインストールについては「Python で COVID-19 のコロプレス図を作成する(cartopy版)」に注意を載せている。)
前処理
国ごとの合算
Covid-19 の感染者数が地域ごとに記録されているので、これを国ごとのデータになるよう処理を行う。(以下、2022年2月17日のデータで行う。)
# 必要なモジュールのインポート
import pandas as pd
# データの取得
df = pd.read_csv("./02-17-2022.csv")
# 国ごとに合算しなおす
df_sum = df.groupby("Country_Region").sum()[["Confirmed", "Deaths"]].copy()
df_sum.reset_index(inplace=True)
# 致死率を計算
df_sum["CFR"] = df_sum["Deaths"] / df_sum["Confirmed"] * 100
# 結果の表示
print(df_sum.head())
出力は以下の通り。
Country_Region | Confirmed | Deaths | CFR | |
---|---|---|---|---|
0 | Afghanistan | 171673 | 7524 | 4.382751 |
1 | Albania | 269301 | 3430 | 1.273668 |
2 | Algeria | 263369 | 6772 | 2.571297 |
3 | Andorra | 37522 | 150 | 0.399765 |
4 | Angola | 98585 | 1899 | 1.926257 |
GeoJSON と国名の表記ゆれの確認
GeoJSON を geopandas を用いて中身を確認し、国名が一致するのかの確認と、一致しない場合の処理を行う。#ここが手作業で面倒なので、どなたか頭の良い方法が有ったら教えて下さい…。
# 必要なモジュールのインポート
import geopandas as gpd
# GeoJSON の読み込み
gdf = gpd.read_file('./countries.geojson')
# 集合演算を使って Covid-19 データの一致しない国名を抜き出す
set_covid_19 = set(df_sum["Country_Region"])
set_geojson = set(gdf["ADMIN"])
set_diff = set_covid_19 - set_geojson
# 結果の表示
print(set_diff)
{'Micronesia', 'Eswatini', 'Cabo Verde', "Cote d'Ivoire", 'Guinea-Bissau', 'Czechia', 'Burma', 'Timor-Leste', 'Summer Olympics 2020', 'Winter Olympics 2022', 'Diamond Princess', 'Holy See', 'North Macedonia', 'Tanzania', 'Bahamas', 'US', 'Congo (Kinshasa)', 'Serbia', 'MS Zaandam', 'Congo (Brazzaville)', 'West Bank and Gaza', 'Taiwan*', 'Korea, South'}
国の名前の他に、地域やクラスターが発生したクルーズ船の名前なども含まれている。これらを手作業で修正。set_geojson
の名前になるよう修正していく。
# 元の国名を保存
df_sum["Country_Region_conv"] = df_sum["Country_Region"]
# 以下、手作業で修正
df_sum.loc[
(df_sum["Country_Region"] == "Bahamas"), "Country_Region_conv"
] = "The Bahamas"
df_sum.loc[(df_sum["Country_Region"] == "Burma"), "Country_Region_conv"] = "Myanmar"
df_sum.loc[
(df_sum["Country_Region"] == "Cabo Verde"), "Country_Region_conv"
] = "Cape Verde"
df_sum.loc[
(df_sum["Country_Region"] == "Congo (Brazzaville)"), "Country_Region_conv"
] = "Republic of Congo"
df_sum.loc[
(df_sum["Country_Region"] == "Congo (Kinshasa)"), "Country_Region_conv"
] = "Democratic Republic of the Congo"
df_sum.loc[
(df_sum["Country_Region"] == "Cote d'Ivoire"), "Country_Region_conv"
] = "Ivory Coast"
df_sum.loc[
(df_sum["Country_Region"] == "Czechia"), "Country_Region_conv"
] = "Czech Republic"
df_sum.loc[
(df_sum["Country_Region"] == "Eswatini"), "Country_Region_conv"
] = "Swaziland"
df_sum.loc[
(df_sum["Country_Region"] == "Guinea-Bissau"), "Country_Region_conv"
] = "Guinea Bissau"
df_sum.loc[(df_sum["Country_Region"] == "Holy See"), "Country_Region_conv"] = "Vatican"
df_sum.loc[
(df_sum["Country_Region"] == "Korea, South"), "Country_Region_conv"
] = "South Korea"
df_sum.loc[
(df_sum["Country_Region"] == "Micronesia"), "Country_Region_conv"
] = "Federated States of Micronesia"
df_sum.loc[
(df_sum["Country_Region"] == "North Macedonia"), "Country_Region_conv"
] = "Macedonia"
df_sum.loc[
(df_sum["Country_Region"] == "Serbia"), "Country_Region_conv"
] = "Republic of Serbia"
df_sum.loc[(df_sum["Country_Region"] == "Taiwan*"), "Country_Region_conv"] = "Taiwan"
df_sum.loc[
(df_sum["Country_Region"] == "Tanzania"), "Country_Region_conv"
] = "United Republic of Tanzania"
df_sum.loc[
(df_sum["Country_Region"] == "Timor-Leste"), "Country_Region_conv"
] = "East Timor"
df_sum.loc[
(df_sum["Country_Region"] == "US"), "Country_Region_conv"
] = "United States of America"
# 修正できているかの確認
set_covid_19_conv = set(df_sum["Country_Region_conv"])
set_diff_conv = set_covid_19_conv - set_geojson
print(set_diff_conv)
{'MS Zaandam', 'Diamond Princess', 'West Bank and Gaza', 'Summer Olympics 2020', 'Winter Olympics 2022'}
国境ファイルのデータに該当しないものが残った。これらのプロットは諦める事とする。
コロプレス図の作成
cartopy と違い、folium には Coropleth という関数が存在している。
# 必要なモジュールのインポート
from folium import Map, LayerControl, Choropleth
# 地図の作成(中心は日本)
m = Map(location=[35.658581, 139.745433], zoom_start = 2)
# コロプレス図の作成
Choropleth(
geo_data="./countries.geojson", # GeoJSONファイル
name="choropleth", # map名(何でもよい)
data=df_sum, # Covid-19の致死率と国名が含まれているデータ
columns=["Country_Region_conv", "CFR"], # データのkey列(国名)とvalue列(致死率)を指定
key_on="properties.ADMIN", # GeoJSONファイル内のkey(国名)を指定
fill_opacity=0.7,
line_opacity=0.2,
line_color="blue",
fill_color="Reds",
).add_to(m)
LayerControl().add_to(m)
# 図の保存
m.save('coropleth.html')
これでカラーバー付きコロプレス図を作成することができた。cartopy に比べれるとだいぶ楽に作れる。北朝鮮、グリーンランド、トルクメニスタンなどではデータが無いので、黒く塗りつぶされている。
おわりに
今回は Covid-19 の致死率を題材にコロプレス図を作成してみた。GeoJSONとデータさえあれば、国毎でなく地域ごとにプロットを作ることも可能である。