FACTFULNESS 女性一人あたり出産人数~平均寿命 チャート再現
DataMixのブログ「チャート再現:書籍「FACTFULNESS(ファクトフルネス)」やTED talkで有名なハンス・ロスリング」の記事に inspire され、自分でもチャートを作ってみました。
チャートの味方ですが、〇の一つ一つが国を表しています。
X軸が、その国の女性一人あたりの出産数
Y軸が、平均寿命(その年に生まれた子供の平均余命)
〇の面積が、その国の人口(面積と人口が比例するよう、半径は人口の平方根に比例させています)
これらのデータは、Factfulness の Gapminder 社のサイトからいただいてきました。
(最初、横幅の大きなGIFファイル(1536x960)をUPしようとしたところ、自動縮小が上手く行かず、画像が崩れてしまいました。画像の幅を小さくし、620px以下にすると、画像が崩れないことに気が付き、UPし直しました
コードはちょっと長くなってしまいましたが、こんな感じ。
import numpy as np
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
import seaborn as sns
# 国名から、2文字コード、大陸コードを引き当てるため、別に作った csv を読み込む。
country_continentDF = pd.read_csv('data/country_to_ContinentCode2.csv',
encoding='cp932', index_col=0,
keep_default_na=False)
# 平均寿命
path = './data/life_expectancy_years.csv'
LE = pd.read_csv(path, index_col=0 )
# 平均出産数
path = './data/children_per_woman_total_fertility.csv'
CPW = pd.read_csv(path, index_col=0)
# 人口
path = './data/population_total.csv'
ppl = pd.read_csv(path, index_col=0)
# 大陸を示すコードを返す関数
def get_continenct_code(country_name):
countries = country_continentDF[country_continentDF['name']
==country_name]
return countries.iloc[0,2]
# 国名を示す2文字コードを返す関数
def get_2letters(country_name):
countries = country_continentDF[country_continentDF['name']==country_name]
return countries.iloc[0,1]
# 国の名前から、大陸コードを取得し、それに応じた色名を返す関数
def get_color(country_name):
cont_code = get_continenct_code(country_name)
if cont_code == 'EU': #Europe
return 'blue'
elif cont_code == 'AS': # Asia
return 'red'
elif cont_code == 'OC': # Oceania
return 'purple'
elif cont_code == 'SA': # South America
return 'yellow'
elif cont_code == 'NA': # North America
return 'green'
else: #Africa or Antarctica
return 'grey'
# グラフのサイズを大きくする。
plt.rcParams["figure.figsize"] = (16,10)
# 定数を準備
cont_code_name = ['EU', 'AS', 'OC', 'NA', 'SA', 'AF']
color_order = ['blue', 'red', 'purple', 'yellow', 'green', 'gray']
ここまでが、前準備。
target_countries = ['JP','US','CN','IN','GB', 'ID' ]
filenames = []
# 5年毎にグラフを作成
for Y in range(1920,2021,5):
plt.clf()
plt.xlabel("Babies per Woman")
plt.ylabel("Life Expectancy")
plt.text(5,50, str(Y),
horizontalalignment='center',
verticalalignment='center',
fontsize=100, color='black',
alpha=0.15)
plt.xlim(9,1)
plt.ylim(10,90)
# 凡例表示
for i in range(6):
plt.scatter(8.8, 85 - 5*i , c=(color_order[i]), s=120, alpha = 0.5)
plt.text(8.7, (84 - 5*i), cont_code_name[i], size=16, color ='black', alpha = 1 )
for i in range(len(CPW)):
c_name = CPW.index[i]
c_LE = LE.loc[c_name, str(Y)]
c_CPW = CPW.loc[c_name, str(Y)]
c_ppl = ppl.loc[c_name, str(Y)]
c_color = get_color(c_name)
c_ctnt = get_continenct_code(c_name)
c_2letters = get_2letters(c_name)
plt.scatter(c_CPW,
c_LE,
c = c_color,
s=c_ppl**0.5/5,
alpha = 0.5)
if c_2letters in target_countries:
plt.annotate(c_2letters, xy=(c_CPW, c_LE), size = 14 )
filename = './data/Gapminder_' + str(Y) + '.png'
filenames.append(filename)
plt.savefig(filename, dpi = 38)
from PIL import Image
# GIFファイルを生成
images = []
for filename in filenames:
img = Image.open(filename)
images.append(img)
images[0].save('./data/gapminder.gif',
save_all=True, append_images=images[1:],
optimize=False, duration=1000, loop=1)
以下、チャートを見て気が付いたことを雑多に。
1960年ごろの中国
中国を示す円が1960年だけ右下に動いています。
(一人あたりの出産数が4人台に、平均寿命が30歳台に)
何があったのかと調べてみたら、毛沢東がやらかしちゃった頃だったんですね。そりゃ、子供も作れないし、作れたとしても産まれた子供の生存率も低く、平均寿命も短くなりますね。
2010年ごろのハイチ
2010年に、平均寿命が30-40歳のあたりに、緑色の〇がポコンと飛び出ているのも目につきます。これは、調べてみるとハイチ。2010年1月に、大地震が発生し、さらにコレラが蔓延し、政権は崩壊し、、と最悪な年だったためのようです。
乳幼児の死亡率と比べたチャートを作ってみると、上記の傾向が、より明確に見えてくるかもしれませんね。
この記事が気に入ったらサポートをしてみませんか?