Inside of data science
データサイエンスに纏わる様々な視点を発信しています

Python

チャート再現:書籍「FACTFULNESS(ファクトフルネス)」やTED talkで有名なハンス・ロスリング

こんにちは、データミックスメディア編集長の藤田です。

2020年。データミックスからは「データサイエンスのスキルで、どのようなことが出来るようになるのか」これを、専門的な知見だけではなく、身近な事柄をテーマに解説するなど、今まで以上に解り易く、そして楽しんでいただける情報を発信して参ります。

是非、読者の皆さんからもフィードバックをいただきながら、編集部一同、データサイエンスのスキルに「磨き」をかけて参ります。

そして、今回が第1回目。そのテーマは・・・

Hans Rosling(ハンス・ロスリング)

皆さん、Hans Roslingさんをご存知でしょうか。

彼はスウェーデン出身の学者(医者かつ公衆衛生学者)で、著作の「FACTFULNESS」やTED Talkで、人々がいかにマスメディアの情報や思い込みによって先入観を植え付けれているのか、これを解り易く示し、全世界で大絶賛されました。

著作の「FACTFULNESS」は日本語版だけでも国内50万部以上の発行部数を誇り、TED Talkは1400万回以上再生されています。

 

作中に登場するチャート

なぜ、彼の説明が面白く、そして世界から注目されたのでしょうか。

それは、ずばり「チャート」の力です。

よく知られているのは、横軸に平均所得(人口あたりのGDP)や女性一人あたりの出産数、縦軸に平均寿命をとったバブルチャートで、バブルの大きさが人口を示したものです。

ある時点のスナップショットではなく、経年変化を動的に表現しているのが特に面白いポイントです。例えば、戦後の日本・中国を中心としたアジアの経済成長などが、うまく可視化されています。

Pythonで再現してみた

その面白いチャート。再現してみたい。

そんな思い付きもあって、わたくし、編集長。PythonのMatbplotlibでやってみました。(編集長はほとんどPython素人です)

拘った点としては、以下の通りです。

  • 長いコードは嫌い。だから、長くても50行程度に留めたい
  • Regionを色で分けて、凡例として表示する
  • 日本・アメリカ・中国・イギリス・南アフリカの5カ国のみデータポイントにラベルをつける(全ての国につけるともはや読めなくなるので)

GapMinderのデータは多様な種類がありますが、今回は、TED Talkにおいて氏が解説している、横軸にFertility rate(女性あたり平均出産数)、縦軸にLife Expectancy(平均寿命)をプロットしたものを再現しました。

結論としては、pythonでグラフにアニメーションを足そうとするとコードが複雑になりそうだったので、ImageMaricを使い、各年のチャートを結合してgifファイルにする方法により簡単にできました!

 

データは、GapMinderのサイトから取得し、gsheetで整形したものをcsvで用意した。1900年から各年取得したので20000行程度。 pythonのコードは、以下を参照ください。

 

# libraries
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
sns.set_style("white")
import pandas as pd
 
# Data Prep
data = pd.read_csv('Gapminder_1.csv')
s_country = ['Japan','United States','China','United Kingdom','South Africa']
r_dict = {
  "Asia": "blue",
  "Europe": "green",
  "Africa": "red",
  "Americas": "grey"
}
c_dict = {
  "Japan": "JP",
  "United States": "US",
  "China": "China",
  "United Kingdom": "UK",
  "South Africa": "SA"
}

# create scatter for each year and append it to images array
for i in range(1941, 2019,2):
    fig, ax = plt.subplots()
    tmp_data = data[ data.Year == i ]

    for ctnt in tmp_data['Continent'].unique():
        tmp = tmp_data[ tmp_data.Continent == ctnt ]
        x = tmp['Babies_per_woman'].values.tolist()
        y = tmp['Life_expectancy'].values.tolist()
        n = tmp['Country'].values.tolist()
        ax.scatter(x,
                    y,
                    s = tmp['Population']/300000,
                    c = r_dict[ctnt],
                    alpha = 0.8,
                    edgecolors = "white",
                    linewidth = 2,
                    label = ctnt)
        for j, txt in enumerate(n):
            if txt in s_country:
                ax.annotate(c_dict[txt], (x[j], y[j]))
    ax.set_xlabel("Babies per Woman")
    ax.set_ylabel("Life Expectancy")
    ax.text(0.5,0.5, str(i),
        horizontalalignment='center',
        verticalalignment='center',
        fontsize=100, color='black',
        alpha=0.15,
        transform=ax.transAxes)
    # ax.set_title(str(i))
    ax.set_ylim(20,90)
    ax.set_xlim(9,1)
    ax.legend(markerscale=.25,fontsize=8, loc = 'lower right')
    filename='Gapminder_1_'+str(i)+'.png'
    plt.savefig(filename, dpi = 96)
    

### TERMINAL ###
convert -delay 80 Gapminder_1_*.png animated_gapminder.gif

チャートの再現結果

結果、このようになりました。

やはり、バブルチャートが動くと格好が良いですよね!

内容としては、経済的に裕福な先進国では、乳児・子供が安全に生き延びられるため、女性1人あたりの平均出産数は少なくなります(多くの子供を産む必要がないので)。さらに医療技術や食生活も進んでいるので、平均寿命も長くなります。したがって、先進国は右上にプロットされるわけですが、チャートでは戦後の日本の経済成長、中国の一人っ子政策や、アフリカ大陸が2000年以降徐々に先進国に近づきつつあるのが見て取れます。

解り易いチャートになりました!

このように、Python使うと、面白いチャートや綺麗なチャートを作れるようになります。
Pythonについて学んでみたい人は、サンプルテキストを公開しているので、チェックしてみてください。

«
»

ブログ一覧