こんな人にオススメ
日本の首都は関東の東京だけど、世界の首都ってどんな名称でどこにあるの?アメリカとかならわかるけど、他も知りたい。
どうせならplotly
でわかりやすく視覚化したい。
ということで、今回はplotly
のScattergeo
を使用して世界各国の首都の位置を世界地図に描画する方法を解説する。かなりお手軽に地球儀にも2Dにもプロット可能。
また、国境や川、湖も可視化することができるのでかなり楽しい。いつ使うかと言われれば使う機会が少ないというのが回答になるけど、楽しいからいいだろう。
python環境は以下。
- Python 3.9.7
- pandas 1.3.3
- plotly 5.3.1
- plotly-orca 3.4.2
作成したコード全文
下準備
import sys import pandas as pd import plotly.graph_objects as go import plotly.io as pio sys.path.append('../../') import plotly_layout_template as template
まずは下準備としてのimport
関連。plotly_layout_template
は自作のplotly
テンプレートで、これを使用することで簡単にキレイなグラフを作成可能。
-
-
【随時更新 備忘録】plotlyのグラフ即席作成コード
続きを見る
なお、このテンプレートの設定だと記事に載せるにはフォントサイズがデカすぎる問題が発生したので、グラフ作成時にフォントサイズを変更している。
使用するデータ
file = './h3104r2world_utf8.csv' # UTF-8版を使用するとencodingを気にしなくていい df = pd.read_csv(file, sep='\\t') print(df) # country_code name_jp ... lat lon # 0 AD アンドラ公国 ... 42.506317 1.521835 # 1 AE アラブ首長国連邦 ... 24.453884 54.377344 # 2 AF アフガニスタン・イスラム共和国 ... 34.555349 69.207486 # 3 AG アンティグア・バーブーダ ... 17.127410 -61.846772 # 4 AL アルバニア共和国 ... 41.327546 19.818698 # .. ... ... ... ... ... # 193 WS サモア独立国 ... -13.850696 -171.751355 # 194 YE イエメン共和国 ... 15.369445 44.191007 # 195 ZA 南アフリカ共和国 ... -25.747868 28.229271 # 196 ZM ザンビア共和国 ... -15.387526 28.322816 # 197 ZW ジンバブエ共和国 ... -17.825166 31.033510 # [198 rows x 9 columns]
今回は各国の首都の位置をプロットしたいということで、首都の緯度と軽度がわかればいい。そこで以下のサイト「アマノ技研」の「世界の首都の位置データ」を引用した。
このデータには以下の9つのデータが格納されている。
- 国コード
- 日本語の国名
- 日本の通称国名
- 日本語の首都名
- 英語の国名
- 英語の通称首都名
- 英語の首都名
- 経度
- 緯度
主に使用するのは緯度・軽度と国名と首都名。今回作成する図では国コードなども一緒に表記している。
# 国コード、日本語の国名、日本の通称国名、日本語の首都名、英語の国名、英語の通称首都名、 # 英語の首都名、緯度、経度 print(df.columns.values) # ['country_code' 'name_jp' 'name_jps' 'capital_jp' 'name_en' 'name_ens' # 'capital_en' 'lat' 'lon']
グラフ作成用の関数たち
ということで、早速グラフを作成するための関数たちを紹介する。予め関数を使用して処理を定義しておくことで、メインの処理がスッキリ見える。
また、他の部分での繰り返し使用や修正の楽さなども関数化するメリットだろう。plotly
と関数については以下参照。
-
-
【plotly&工夫】楽にグラフを描くためのplotlyの関数化
続きを見る
プロットデータ作成用の関数
# 世界地図に点をプロットするための関数 def scattergeo(): d = go.Scattergeo( lon=df['lon'], lat=df['lat'], # 軽度と緯度を入力 marker=dict(symbol='star', color='red', size=8,), customdata=df, # ホバー用にデータフレームを活用 hovertemplate='Code: %{customdata[0]}<br>' # 国コード + '(lat, lon) = (%{customdata[7]}, %{customdata[8]})<br>' # 座標 + 'name: %{customdata[1]}(%{customdata[4]})<br>' # 国名 + 'capital: %{customdata[3]}(%{customdata[6]})<br>' # 首都名 + '<extra></extra>', showlegend=False, # 凡例の表示はオフ ) return d
いきなり本命だが、今回使用するのはplotly
のgo.Scattergeo
。簡単にいうと地図上に点をプロットするというもの。引数のlon
とlat
に経度、緯度の値を入れる。
marker
ではプロット点の見た目を変更している。基本的にはこれだけで十分だが、ここではマウスを首都に乗せた時に表示するホバーも改良。
引数customdata
にdf
を使用し、hovertemplate
にこのdf
の内容を込めたホバーの内容を入れる。customdata[0]
がdf
の0
番目の列に該当する。1
以降も同じ。
customdata[0]
: 国コードcustomdata[1]
: 日本語の国名customdata[2]
: 日本語の通称国名customdata[3]
: 日本語の首都名customdata[4]
: 英語の国名customdata[5]
: 英語の通称首都名customdata[6]
: 英語の首都名customdata[7]
: 緯度customdata[8]
: 経度
レイアウト作成用の関数
# レイアウト作成用の関数 def set_layout(projection_type, resolution): layout = go.Layout( template=template.plotly_layout(), title=f"Countries & Captitals ({projection_type})", geo=dict( projection_type=projection_type, countrycolor='black', # 国境の色 lakecolor='violet', # 湖の色 landcolor='white', # 土地の色 oceancolor='lightskyblue', # 海の色 rivercolor='deepskyblue', # 川の色 showcountries=True, # 国境を表示するか否か showlakes=True, # 湖を表示するか否か(設定なしで表示) showland=True, # 土地の設定を反映させるか否か(設定なしで表示) showocean=True, # 海を表示するか否か showrivers=True, # 川を表示するか否か # 解像度を上げたい場合は50を選択。100と50のみ選択可能 resolution=resolution, ), # ホバーの情報量が多いのでホバーのフォントサイズを下げる hoverlabel_font_size=15, ) return layout
基本的なレイアウトは、自作テンプレートを反映させるのとグラフタイトルをつけるということ、そしてホバーのフォントサイズを下げることで実現。
Scattergeo
でのカスタムとしては地図の表示方法、国境の線の色、湖・土地・海・川の塗りつぶしの色とこれらを表示するか否か。基本的には引数の名称がそのままだからわかりやすい。
また、resolution
を設定することで、地図の解像度を上げることも可能。選択肢は50
と110
で、110
が1:110,000,000の比率。50
にすると解像度が上がり重たくなる。
グラフ保存用の関数
# グラフ保存用の関数 def save(fig, config, save_name): pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca' pio.write_html(fig, f"{save_name}.html", config=config,) pio.write_image(fig, f"{save_name}.png")
グラフの保存形式はhtmlとpngの2種類。htmlファイルにconfigを設定しておくことで、グラフ保存後のファイルでもツールバーを表示することが可能。
しかし、Scattergeoの場合は通常のScatterなどとは異なりこのツールバーが表示されない。恐らくグラフの描画方法が異なり対応していないためかと。
まあ、普段から設定しておいたら忘れないし、いつでもツールバーを活用することができるだろう。
世界地図に首都を描画
ということで実際に世界地図に首都を描画していく。今回は描画方法として以下の2種類を採用する。
- 正射図法(orthographic)
- パターソン図法(patterson)
執筆者は世界地図の描画方法についてはズブのトーシローなので何が良いのかわからないけど、とりあえずよく見るものをピックアップしておいた。
実は描画方法はめちゃくちゃありその総数は83にも上る。layout
の[geo](<https://plotly.com/python/reference/layout/geo/#layout-geo-projection-type>)
のページに全ての描画方法の記載があるので是非ともチェックしていただきたい。
世界地図に首都を描画する関数
# projection_typeで指定した描画方法で世界地図に首都を描画 def geo(projection_type, save_name, resolution=110): plot = [scattergeo()] layout = set_layout(projection_type=projection_type, resolution=resolution) fig = go.Figure(data=plot, layout=layout) config = template.plotly_config() fig.show(config=config) save(fig=fig, config=config, save_name=save_name)
世界地図に首都を描画する関数としてgeo
関数を定義したわけだが、これまでの色々と関数を定義したのでメインのこの関数はかなり短くなった。
やってることは、プロットの作成、レイアウトの作成、グラフ化、config
の作成、グラフの表示、グラフの保存。シンプル。
なお、作成するマップの解像度は引数resolution
で変更できるようにした。
pattersonで描画
まずはpatterson図法で解像度110で作成。この場合は2Dマップで経度の中心はイギリス。変更することもできるけど、基準がイギリスなのでこのまま。
こうしてみるとやはりアフリカやヨーロッパは大きな国が少なく細かくなっているため、その分首都の数も増えていることがわかる。
一方でアメリカ大陸やユーラシア大陸東部は国が1つ1つ大きくて国がドンとある感じなのがわかる。歴史系が関係してくると思うけど詳しくは知らない。
# 2D上に描画 geo(projection_type='patterson', save_name='patterson')
orthographicで描画
orthographic図法の場合は地球儀上に首都のマーカーが描画されることになる。これはこれで見やすい。
そもそも3Dのマップを2Dにすると歪みが生じるから3Dのものを3Dのまま表示しているこの方法は理にかなっているだろう。ただし、見ている媒体は2Dだが。
球形になっているとわかりやすいのが南極や北極。特に南極とオーストラリアって結構離れているということがわかりやすい。
# 地球儀上に描画 geo(projection_type='orthographic', save_name='orthographic')
解像度を上げてみる
解像度を挙げた版も作成してみる。ファイルサイズ自体は変わらないけど細かい島国や海岸線までも描画されていることがわかる。
川も追加で描画されており、日本では北海道の石狩川が追加されている。というより石狩川しかない。信濃川とかはない。
これはこれで発展できる
今回はplotly
のScattergeo
を使用して世界各国の首都の位置をプロットしてみた。ついでに川だったり湖も表示してみた。
以前にも世界地図を使用してマップを作成したけど、世界地図を作成できるとまた何かしら発展的なことができる。
最近はコロナも落ち着いていると思っているが、また何か世界的なイベントが起きたら今回の世界地図でマップ化できれば面白いだろう。
関連記事
-
-
【plotly&mapbox】感染者数と死者数の散布図コロナマップを作成
続きを見る
-
-
【plotly&レーダーチャート】plotlyのRadar Chartの使い方とか設定とか
続きを見る
-
-
【plotly&fill】goで領域を塗りつぶし
続きを見る