都道府県別の人口動態を可視化してみた−MatplotlibでBubbleプロット


はじめに

matplotlibでbubbleプロットをする記事がqiitaで見当たらなかったのでやってみました。
サンプルデータとして国勢調査の男女別人口-全国,都道府県(大正9年~平成27年) を使っています。

バブルプロット

先に結果を見せると、バブルプロットはこんな感じのプロットです。1つ1つの円が都道府県、円の大きさが人口の数を表しています。座標の位置はランダムです。

データの整形

今回は普通にpandas.read_csvで読み込んで条件でフィルタをかけてやるだけです。注意すべき点としては元データのエンコーディングがShift-JISであることと、Seriesに対してある文字列を1つでも含む条件を書いているところでしょうか。ちなみにプロットする都道府県は、岩手、東京、愛知、高知、福岡、鹿児島を選びました。全く意味はありません。

data = pd.read_csv("./c01.csv", encoding="Shift-JIS", skipfooter=2)
target_pref = ["岩手県", "東京都", "愛知県", "高知県", "福岡県", "鹿児島県"]
data_target = data[data.都道府県名.str.contains("|".join(target_pref))]
d = data_target[data_target['西暦(年)'] == 1920]
都道府県コード 都道府県名 元号 和暦(年) 西暦(年) 人口(総数) 人口(男) 人口(女)
3 03 岩手県 大正 9 1920 NaN 845540 421069 424471
13 13 東京都 大正 9 1920 NaN 3699428 1952989 1746439
23 23 愛知県 大正 9 1920 NaN 2089762 1033860 1055902
39 39 高知県 大正 9 1920 NaN 670895 332087 338808
40 40 福岡県 大正 9 1920 NaN 2188249 1116818 1071431
46 46 鹿児島県 大正 9 1920 NaN 1415582 682243 733339

バブルプロットの描画

matplotlibでバブルプロットを描画する場合、散布図を描画する関数plt.scatterで点のサイズを個別に変化させることで対応します。今回の解析ではx,yをランダムに生成したうえで、円のサイズz、色cを個別に指定しています。これで冒頭のグラフができるはずです。

c = np.arange(0,12,2)
z = d['人口(総数)'].astype(int) / 1000
x = np.random.rand(6)
y = np.random.rand(6)
plt.scatter(x, y, s = z, alpha=0.5, c=c)
for i, t in enumerate(target_pref):
    plt.text(x[i]-0.025,y[i], t, fontsize=15)

おまけ

せっかくなので年度毎にプロットしてアニメーションもつけてみました。東京・愛知・福岡は人口が増えているのに対して、岩手、高知、鹿児島はほとんど変化していません。1945年で東京の人口ががくっとへるあたりなどは、第二次世界大戦の影響の大きさを示唆しています。

以下にコードを載せます。アニメーションはいったんすべてpngに出力した後にconvertでgifに変換して生成しています。

bubble_anim.gif
for year in range(1920, 2016, 5):
    z = data_target[data_target["西暦(年)"] == year]['人口(総数)'].astype(int) / 1000
    plt.figure()
    plt.scatter(x, y, s = z, alpha=0.5, c=c)
    for i, t in enumerate(target_pref):
        plt.text(x[i]-0.025,y[i], t, fontsize=15)
    plt.xlim((-0.2,1.2))
    plt.ylim((-0.2,1.2))
    plt.title("{0}年".format(year))
    plt.axis('off')
    plt.savefig("./bubble/{0}.png".format(year))