各国の1人当たりGDPと平均寿命

各国の1人当たりGDP(GDP per capita(PPP))と平均寿命のデータをWorld Bankから取得してグラフ化するpythonプログラムの備忘録。

データの取得はwbdataを使いたいと前から考えているのだが、まだうまくいかない（pythonのバージョン（3.10.11）のせいかもしれない）。ただ、world_bank_dataというパッケージが使えるみたいなので、今回はこれを使ってみることにした。そこで、world_bank_dataなんてパッケージはGoogle Colabにインストールはされていないので、まずは、インストール。

```python
! pip install world_bank_data
```

平均寿命のデータはWHOから2022年のものが公表されているらしいが、1人当たりGDPのデータは2021年くらいから推定値になっている国も多いので、今回は2020年のデータでグラフを作成することにした。

# matplotlibによる静的なグラフ
それぞれのデータの上位3か国（または地域）とG7＋中印はどの点か分かるようにしたグラフを描くことにする。
ラベルの重なりを防ぐために、ライブラリー（adjustText）を利用している（でも一部重なりあり）。このライブラリーもGoogle Colabにはインストールされていないので、ここでインストール。

```python
! pip install adjustText
```


以下描画のためのPythonコード。
```python
import world_bank_data as wb
import pandas as pd
import matplotlib.pyplot as plt
from adjustText import adjust_text

# 1人あたりGDPと平均寿命のデータを取得
gdp_per_capita = wb.get_series("NY.GDP.PCAP.PP.CD", date='2020')
life_expectancy = wb.get_series("SP.DYN.LE00.IN", date='2020')

# データフレームに変換し、不要なカラムを削除
gdp_df = pd.DataFrame(gdp_per_capita).reset_index().drop(columns=['Series', 'Year'])
le_df = pd.DataFrame(life_expectancy).reset_index().drop(columns=['Series', 'Year'])

# データフレームを結合
df = pd.merge(gdp_df, le_df, on=['Country'])

# カラム名を変更
df.columns = ['Country', 'GDP per Capita', 'Life Expectancy']

# GDP上位3カ国と平均寿命上位3カ国を特定
top3_gdp_countries = df.sort_values('GDP per Capita', ascending=False).head(3)['Country'].values
top3_le_countries = df.sort_values('Life Expectancy', ascending=False).head(3)['Country'].values

# G7と中国、インドを追加
highlight_countries = ['United States', 'United Kingdom', 'France', 'Germany', 'Italy', 'Canada', 'Japan', 'China', 'India']
highlight_countries.extend(top3_gdp_countries)
highlight_countries.extend(top3_le_countries)

# ハイライトする国とそれ以外でデータを分ける
highlight_df = df[df['Country'].isin(highlight_countries)]
other_df = df[~df['Country'].isin(highlight_countries)]

# グラフを描画
plt.figure(figsize=(10, 6))
plt.scatter(other_df['GDP per Capita'], other_df['Life Expectancy'], color='lightgray')
plt.scatter(highlight_df['GDP per Capita'], highlight_df['Life Expectancy'], color='red')

# ハイライトする国の名前を描画
texts = []
for i, row in highlight_df.iterrows():
    texts.append(plt.text(row['GDP per Capita'], row['Life Expectancy'], row['Country'], fontsize=9))

# テキストの重なりを調整
adjust_text(texts)

plt.xscale('log')
plt.xlabel('GDP per Capita (PPP) [USD]')
plt.ylabel('Life Expectancy [Years]')
plt.title('Relationship between GDP per Capita and Life Expectancy (2020)')
plt.grid(True)
plt.show()

```
これで以下のグラフが描けた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3305624/a21b46d5-cf4d-0aa0-275a-fc706773873d.png)


# plotlyによる動的なグラフ
上記のグラフでは一部の国しか国名が分からないので、動的なグラフにしてマウスオーバーすればどの国か分かるようにする。
```python
import world_bank_data as wb
import pandas as pd
import plotly.graph_objs as go

# 1人あたりGDPと平均寿命のデータを取得
gdp_per_capita = wb.get_series("NY.GDP.PCAP.PP.CD", date='2020')
life_expectancy = wb.get_series("SP.DYN.LE00.IN", date='2020')

# データフレームに変換し、不要なカラムを削除
gdp_df = pd.DataFrame(gdp_per_capita).reset_index().drop(columns=['Series', 'Year'])
le_df = pd.DataFrame(life_expectancy).reset_index().drop(columns=['Series', 'Year'])

# データフレームを結合
df = pd.merge(gdp_df, le_df, on=['Country'])

# カラム名を変更
df.columns = ['Country', 'GDP per Capita', 'Life Expectancy']

# GDP上位3カ国と平均寿命上位3カ国を特定
top3_gdp_countries = df.sort_values('GDP per Capita', ascending=False).head(3)['Country'].values
top3_le_countries = df.sort_values('Life Expectancy', ascending=False).head(3)['Country'].values

# G7と中国、インドを追加
highlight_countries = ['United States', 'United Kingdom', 'France', 'Germany', 'Italy', 'Canada', 'Japan', 'China', 'India']
highlight_countries.extend(top3_gdp_countries)
highlight_countries.extend(top3_le_countries)

# ハイライトする国とそれ以外でデータを分ける
highlight_df = df[df['Country'].isin(highlight_countries)]
other_df = df[~df['Country'].isin(highlight_countries)]

# グラフを描画
trace0 = go.Scatter(
    x=other_df['GDP per Capita'],
    y=other_df['Life Expectancy'],
    mode='markers',
    hoverinfo='text',
    text=other_df['Country'],
    marker=dict(color='lightgray')
)
![Something went wrong]()
![Something went wrong]()

trace1 = go.Scatter(
    x=highlight_df['GDP per Capita'],
    y=highlight_df['Life Expectancy'],
    mode='markers',
    hoverinfo='text',
    text=highlight_df['Country'],
    marker=dict(color='red')
)

layout = go.Layout(
    title='Relationship between GDP per Capita and Life Expectancy (2020)',
    xaxis=dict(type='log', title='GDP per Capita (PPP) [USD]'),
    yaxis=dict(title='Life Expectancy [Years]'),
    showlegend=False
)

fig = go.Figure(data=[trace0, trace1], layout=layout)
fig.show()
```
インタラクティブなグラフはできたが、ここに表示させる方法は今だわからず。
もう少し使いやすいグラフにしたいが、それは他日の課題にして今日はここまで。