Pythonで実装する人口ピラミッドグラフ:2023年の年齢別死亡者数データの分析

人口統計データを可視化する場合、データラベルを追加することで、情報の正確性と読みやすさが大幅に向上します。本日は、人口ピラミッドグラフにデータラベルを追加して、2023年の年齢別死亡者数を可視化する方法をご紹介します。
データ概要
上記のPython可視化グラフの基礎データは、'24年2月に統計庁から発表された 2023年の出生・死亡統計(暫定)に基づいています。そのデータを表形式でまとめると以下のようになります。 死亡者数の単位は千人です。
| 年齢層 | 男性死亡者数 | 女性死亡者数 |
|---|---|---|
| 90+ | 15.3 | 42.1 |
| 80-89 | 63.5 | 69.6 |
| 70-79 | 45.5 | 24.6 |
| 60-69 | 34.3 | 13.2 |
| 50-59 | 18.0 | 7.2 |
| 40-49 | 7.0 | 3.8 |
| 30-39 | 2.8 | 1.5 |
| 20-29 | 1.7 | 0.9 |
| 10-19 | 0.4 | 0.4 |
| 1-9 | 0.2 | 0.1 |
| 0- | 0.3 | 0.3 |

上記の表で示した2023年の年齢別死亡者数データを人口ピラミッドグラフで表しながら、各年齢層ごとの正確な数値をデータラベルで表示し、より詳細な情報を提供します。
Pythonの可視化コードの実装
import numpy as np
import matplotlib.pyplot as plt
# データの準備
age_groups = ['90+', '80-89', '70-79', '60-69', '50-59', '40-49'、
'30-39', '20-29', '10-19', '1-9', '0-']].
male_deaths = [15.3, 63.5, 45.5, 34.3, 18.0, 7.0, 2.8, 1.7, 0.4, 0.2, 0.3].
female_deaths = [42.1, 69.6, 24.6, 13.2, 7.2, 3.2, 3.8, 1.5, 0.9, 0.4, 0.1, 0.3].
# GridSpecを使用して図形を生成します。
fig = plt.figure(figsize=(15, 8))
gs = fig.add_gridspec(1, 3, width_ratios=[4, 0.01, 4]) # 中央の列の比率を0.01に設定する
# 3つのサブプロットを作成します。
ax_left = fig.add_subplot(gs[0])
ax_center = fig.add_subplot(gs[1])
ax_right = fig.add_subplot(gs[2])
y_pos = np.range(len(age_groups))
# 左側プロット (男性)
male_bars = ax_left.barh(y_pos, -np.array(male_deaths), align='center'、
color='#5AB1EF', height=0.7)
#の右側プロット(メス)
female_bars = ax_right.barh(y_pos, female_deaths, align='center'、
color='#FFB848', height=0.7)
#のデータラベルを追加
def add_labels(ax, bars):
for bar in bars:
width = bar.get_width()
x = width
value = abs(width)
ax.text(x, bar.get_y() + bar.get_height()/2, f'{value}'、
ha='right' if width < 0 else 'left'、
va='center'、
fontsize=9、
fontweight='bold'、
color='black'です、
bbox=dict(pad=0.4, facecolor='none', edgecolor='none'))
add_labels(ax_left, male_bars)
add_labels(ax_right, female_bars)
# 中央プロット (年齢グループ)
ax_center.set_yticks(y_pos)
ax_center.tick_params(axis='y', length=0)
# 年齢ラベルの中央揃え
ax_center.set_yticklabels(age_groups, ha='center')
# 中央列のスタイル設定
ax_center.set_xlim(-0.5, 0.5) # x軸の範囲を縮小してラベルをより中央に配置するように調整する
ax_center.set_xticks([])
for spine in ax_center.spines.values():
spine.set_visible(False)
# 左と右のプロットのスタイル設定
for ax in [ax_left, ax_right]:
ax.grid(axis='x', linestyle='-', alpha=0.1)
ax.set_yticks([])
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
# x軸の範囲設定
max_value = max(max(male_deaths), max(female_deaths))
ax_left.set_xlim(-max_value*1.1, 0)
ax_right.set_xlim(0, max_value*1.1)
#軸のラベルを追加
ax_left.set_xlabel('Number of Deaths (thousands)', ha='right')
ax_right.set_xlabel('Number of Deaths (thousands)', ha='left')
# 男性/女性ラベルを追加
ax_left.text(-max_value/2, len(age_groups), 'Male', ha='center', va='bottom', fontsize=12)
ax_right.text(max_value/2, len(age_groups), 'Female', ha='center', va='bottom', fontsize=12)
# x軸目盛りのフォーマット設定
def format_ticks(x, p):
return f'{abs(x)}'
ax_left.xaxis.set_major_formatter(plt.FuncFormatter(format_ticks))
ax_right.xaxis.set_major_formatter(plt.FuncFormatter(format_ticks))
# グラフタイトル追加
fig.suptitle('Age-Specific Mortality by Gender', y=0.95, fontsize=14)
plt.tight_layout()
plt.subplots_adjust(top=0.9) #タイトルの余白を調整します。
plt.show()深いデータ分析の洞察力
1. 年齢別死亡率格差
- 80-89歳区間:男性(63.5千人)、女性(69.6千人)で最高点。
- 70代以下では全体的に男性の死亡率が高い
- 年齢増加に伴う男女格差パターンの変化の観察
2. ライフサイクルごとの特徴
- 乳幼児期(0歳):男女同じ死亡率(0.3千人)
- 若年層(20~49歳):男性の死亡率が女性の約2倍
- 高齢者(80歳以上):女性死亡率急増
3. 政策的意味合い
- 性別・年齢別にカスタマイズされた保健医療政策の必要性
- 高齢者女性向け医療サービス拡充を要求
- 中年男性死亡率低減のための予防医療の強化

仕上げ
データラベル付きの人口ピラミッドグラフは、年齢別の死亡者数の正確な数値を直感的に把握することができます。このような視覚化は、人口統計分析と保健医療政策の策定に重要な基礎資料として活用することができます。コードの詳細解説は下記をご参照ください。
もし、死亡者数と対極にある概念である合計特殊出生率についての情報を知りたいという方は 合計特殊出生率の意味と計算方法: Rでトレンディな視覚化まで 記事を参考にしてみてください。
# コード詳細解説
1.必要なライブラリのインポート
import numpy as np import matplotlib.pyplot as plt
numpy: 数値計算のためのライブラリmatplotlib.pyplot: グラフ作成のためのライブラリ2.データの準備
age_groups = ['90+', '80-89', '70-79', '60-69', '50-59', '40-49'、 '30-39', '20-29', '10-19', '1-9', '0-']]. male_deaths = [15.3, 63.5, 45.5, 34.3, 18.0, 7.0, 2.8, 1.7, 0.4, 0.2, 0.3]. female_deaths = [42.1, 69.6, 24.6, 13.2, 7.2, 3.2, 3.8, 1.5, 0.9, 0.4, 0.1, 0.3].年齢層と各性別の死亡者数データをリストとして定義します。
3.グラフ構造の設定
fig = plt.figure(figsize=(15, 8)) gs = fig.add_gridspec(1, 3, width_ratios=[4, 0.01, 4])
figsize=(15, 8):グラフの全体サイズを設定(横15、縦8)add_gridspec: グラフを3つの列に分割します。比率を[4, 0.01, 4]に設定し、中央の列を非常に狭くします。4.サブプロットの作成
ax_left = fig.add_subplot(gs[0]) ax_center = fig.add_subplot(gs[1]) ax_right = fig.add_subplot(gs[2])3つのサブプロット(左、中央、右)を生成します。
5.棒グラフを描く
y_pos = np.range(len(age_groups)) male_bars = ax_left.barh(y_pos, -np.array(male_deaths), align='center'、 color='#5AB1EF', height=0.7) female_bars = ax_right.barh(y_pos, female_deaths, align='center'、 color='#FFB848', height=0.7)
バー: 水平棒グラフを描画する関数- 男性データはマイナスに変換して左側に表示します。
- 女性データは右側に表示
6.データラベルの追加
def add_labels(ax, bars): for bar in bars: width = bar.get_width() x = width value = abs(width) ax.text(x, bar.get_y() + bar.get_height()/2, f'{value}'、 ha='right' if width < 0 else 'left'、 va='center'、 fontsize=9、 fontweight='bold'、 color='black'です、 bbox=dict(pad=0.4, facecolor='none', edgecolor='none')) add_labels(ax_left, male_bars) add_labels(ax_right, female_bars)各バーに対応する数値をラベルとして追加します。
7.中央列のスタイル設定
ax_center.set_yticks(y_pos) ax_center.tick_params(axis='y', length=0) ax_center.set_yticklabels(age_groups, ha='center') ax_center.set_xlim(-0.5, 0.5) ax_center.set_xticks([]) for spine in ax_center.spines.values(): spine.set_visible(False)中央の列に年齢グループラベルを表示し、不要な軸と境界線を削除します。
8.左右のプロットのスタイル設定
ax_left, ax_right]のaxにaxを指定します: ax.grid(axis='x', linestyle='-', alpha=0.1) ax.set_yticks([]) ax.spines['top'].set_visible(False) ax.spines['right'].set_visible(False)左右のプロットにグリッドを追加し、不要な軸を削除します。
9.x軸範囲設定とラベル追加
max_value = max(max(male_deaths), max(female_deaths)) ax_left.set_xlim(-max_value*1.1, 0) ax_right.set_xlim(0, max_value*1.1) ax_left.set_xlabel('Number of Deaths (Thousands)', ha='right') ax_right.set_xlabel('Number of Deaths (thousands)', ha='left') ax_left.text(-max_value/2, len(age_groups), 'Male', ha='center', va='bottom', fontsize=12) ax_right.text(max_value/2, len(age_groups), 'Female', ha='center', va='bottom', fontsize=12)x軸の範囲を設定し、軸ラベルと性別ラベルを追加します。
10.X軸目盛りのフォーマット設定
def format_ticks(x, p): return f'{abs(x)}' ax_left.xaxis.set_major_formatter(plt.FuncFormatter(format_ticks)) ax_right.xaxis.set_major_formatter(plt.FuncFormatter(format_ticks))x 軸目盛りの値を絶対値で表示します。
11.グラフの仕上げ
fig.suptitle('Age-Specific Mortality by Gender', y=0.95, fontsize=14) plt.tight_layout() plt.subplots_adjust(top=0.9) plt.show()グラフにタイトルを追加し、レイアウトを調整した後、グラフを表示します。






