論文一覧に戻る 📚 用語集トップ 🗺 概念マップ
📚 用語解説
📚 用語解説
レーダーチャート
Radar Chart
可視化
別称: クモの巣図

🔖 キーワード索引(拡充版)

🎨 直感 📐 数式 🔬 数式を言葉で読み解く 🧮 手計算 🐍 matplotlib 🐍 plotly 🐍 重ね合わせ 🐍 面積比較 ⚠️ 落とし穴 🌐 関連手法 🔗 関連用語 📚 教材

💡 30 秒で分かる結論(拡充版)

📍 文脈ボックス

あなたが今見ているもの: 用語集 / 可視化カテゴリ / レーダーチャート (Radar/Spider Chart)

前提: 正規化 / 多変量データ

並列: 並列座標 / ヒートマップ / 弦図

応用: プロファイル分析 / KPI ダッシュボード / スポーツ選手能力比較

🎨 直感で掴む

「6 つの能力 (HP, 攻撃, 防御, 素早さ, 特攻, 特防) を放射状に並べたポケモンのステータス図」がレーダーチャートの代表例。 6 つの数値を 1 つの形 (六角形) として認識し、 異なるポケモン同士のステータス傾向を一目で比較できる。

SSDSE-B-2026 の 47 都道府県でも、 「人口・出生率・高齢化率・婚姻件数・死亡数・宿泊者数」の 6 軸でレーダーを描けば、 「東京は人口巨大だが出生率最低」「鳥取は全軸とも最小値で五角形が点に潰れる」「沖縄は出生率だけ突出」など、 各県の特徴が形として現れる。

3 つの読み解き視点:

📐 数式または定義

正規化: 各軸 $k$ の値 $x_{ik}$ を min-max スケーリング:

$$\tilde{x}_{ik} = \frac{x_{ik} - \min_i x_{ik}}{\max_i x_{ik} - \min_i x_{ik}} \in [0, 1]$$

軸の角度配置: $n$ 軸を等間隔配置: $\theta_k = \frac{2\pi (k-1)}{n}, \quad k = 1, ..., n$

多角形の頂点座標: 各軸の正規化値 $\tilde{x}_{ik}$ から

$$P_k = (\tilde{x}_{ik} \cos\theta_k,\ \tilde{x}_{ik} \sin\theta_k)$$

多角形の面積 (シューレース公式):

$$A = \frac{1}{2}\left|\sum_{k=1}^{n} (x_k y_{k+1} - x_{k+1} y_k)\right|$$

等しい正規化値 1 の理論最大面積 (n 軸正多角形):

$$A_{\max} = \frac{n}{2} \sin\frac{2\pi}{n}$$

例: $n=6$ で $A_{\max} = 3\sin(60°) \approx 2.598$。 $n=5$ で $A_{\max} = (5/2)\sin(72°) \approx 2.378$。

🔬 数式を言葉で読み解く

記号意味具体例 (SSDSE-B 47 都道府県)
$x_{ik}$県 i の軸 k の原値東京の人口=14,086,000
$\tilde{x}_{ik}$正規化値 ∈ [0, 1]東京の人口正規化=1.000 (最大)、 鳥取=0.000
$\theta_k$軸 k の方位角6 軸なら 0°, 60°, 120°, ..., 300°
$n$軸の数5-8 が読みやすい範囲
$P_k$多角形の頂点東京の人口軸頂点 = (1.000·cos 0°, 1.000·sin 0°) = (1.0, 0)
$A$多角形面積東京 1.732、 鳥取 0.000、 沖縄 0.061
$A_{\max}$理論最大面積 (全軸 1)6 軸 → 2.598、 充足率 = A/A_max

🧮 実値で計算してみる

使用データ: SSDSE-B-2026 (data/raw/SSDSE-B-2026.csv)。 使用列: A1101 人口・A4103 出生率・A1303 65 歳以上人口・A9101 婚姻件数・A4200 死亡数・G7102 外国人宿泊者数 の 6 軸。 使用行: R13000 東京都・R01000 北海道・R31000 鳥取県・R47000 沖縄県 の 4 県。 Step 1〜4 で正規化 → 面積 → 充足率まで段階展開。

Step 1: 生データの抽出 (4 県 × 6 軸)

県 A1101 A4103 A1303 A9101 A4200 G7102 東京 14,086,000 0.99 3,205,000 71,774 137,241 34,378,530 北海道 5,092,000 1.06 1,681,000 17,281 75,120 6,184,810 鳥取 537,000 1.44 179,000 1,810 8,290 57,500 沖縄 1,468,000 1.60 350,000 6,316 15,110 2,536,640

Step 2: 各軸を min-max 正規化 ($x' = (x - \min)/(\max - \min)$)

A1101 の min=鳥取 537,000、 max=東京 14,086,000 なので 東京の正規化値は (14,086,000 − 537,000) / (14,086,000 − 537,000) = 1.000。 鳥取は 0。 同様に 6 軸全てを正規化:

県 人口 出生率 65+ 婚姻 死亡 外国人宿泊 東京 1.000 0.000 1.000 1.000 1.000 1.000 ← 全軸最大 (出生率以外) 北海道 0.336 0.115 0.496 0.221 0.518 0.179 鳥取 0.000 0.738 0.000 0.000 0.000 0.000 ← ほぼ点 沖縄 0.069 1.000 0.057 0.064 0.053 0.073 ← 出生率だけ突出

※ 出生率 A4103 は逆方向 (鳥取・沖縄が高い、 東京が低い) なので、 正規化後の東京=0、 沖縄=1。

Step 3: 多角形面積 $A = \frac{1}{2}\sin(2\pi/n)\sum_{i=1}^{n} r_i r_{i+1}$ ($n=6$)

隣接軸の正規化値 $r_i, r_{i+1}$ の積を 6 ペア足し、 $\frac{1}{2}\sin(60°) = 0.4330$ を掛ける。 東京 (r = [1,0,1,1,1,1]) の場合:

Σ r_i · r_{i+1} = 1·0 + 0·1 + 1·1 + 1·1 + 1·1 + 1·1 = 4.000 A_東京 = 0.4330 × 4.000 = 1.7321

Step 4: 理論最大面積 $A_{\max}$ と充足率

全軸 1 のとき: Σ = 6, A_max = 0.4330 × 6 = 2.598 東京 : A = 1.7321, 充足率 = 1.7321/2.598 = 66.7% ← 出生率 0 のため最大値到達できず 北海道 : A = 0.2047, 充足率 = 7.9% 鳥取 : A = 0.0000, 充足率 = 0.0% ← 4 軸が 0 で面積消失 沖縄 : A = 0.0611, 充足率 = 2.4% ← 出生率だけ大きいので歪な小三角形

💬 結果の読み方: 東京は人口・婚姻・死亡・宿泊で正規化 1.0 だが、 出生率最小の影響で面積は理論最大の 66.7% にとどまる。 鳥取は人口・宿泊で min を取るため面積 0 (1 つの軸だけ非零でも 2 軸が 0 だと三角形にならない)。 沖縄の歪な多角形は「出生率特化県」の典型プロファイル。 軸の順序を変えると面積も変わる ことに注意 (隣接軸の積で計算するため)。

🐍 Python 実装

① matplotlib でレーダーチャート作図

🎯 このコードでやること: SSDSE-B-2026 の 47 都道府県から 6 軸を抽出し、 正規化して東京のレーダーチャートを描く。

📥 入力データ (SSDSE-B-2026.csv 抜粋):

Prefecture A1101 A4103 A1303 A9101 A4200 G7102 12 東京都 14086000 0.99 3205000 71774 137241 34378530 0 北海道 5092000 1.06 1681000 17281 75120 6184810 30 鳥取県 537000 1.44 179000 1810 8290 57500 46 沖縄県 1468000 1.60 350000 6316 15110 2536640
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import pandas as pd, numpy as np, matplotlib.pyplot as plt

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df.iloc[:,0]==2023].reset_index(drop=True)

feats = ['A1101','A4103','A1303','A9101','A4200','G7102']
labels = ['人口','出生率','65歳以上人口','婚姻件数','死亡数','外国人宿泊']

# 正規化 (min-max)
norm = pd.DataFrame()
for k in feats:
    v = df[k].astype(float)
    norm[k] = (v - v.min()) / (v.max() - v.min())

# 東京のレーダーチャート
tokyo = norm.iloc[12].values
angles = np.linspace(0, 2*np.pi, len(feats), endpoint=False).tolist()
values = list(tokyo) + [tokyo[0]]  # 閉じる
angles += [angles[0]]

fig, ax = plt.subplots(figsize=(8, 8), subplot_kw=dict(polar=True))
ax.fill(angles, values, color='#4DB6AC', alpha=0.4)
ax.plot(angles, values, color='#00695C', linewidth=2)
ax.set_xticks(angles[:-1])
ax.set_xticklabels(labels, fontsize=11, fontfamily='Hiragino Sans')
ax.set_ylim(0, 1)
ax.set_title('東京都プロファイル (SSDSE-B-2026)', y=1.08, fontsize=14)
plt.tight_layout(); plt.savefig('tokyo_radar.png', dpi=120)
print('正規化値:', dict(zip(labels, [round(v,3) for v in tokyo])))

📤 実行結果:

正規化値: {'人口': 1.0, '出生率': 0.0, '65歳以上人口': 1.0, '婚姻件数': 1.0, '死亡数': 1.0, '外国人宿泊': 1.0} tokyo_radar.png 保存 (5 軸が外周、 出生率軸だけ中央に凹む歪な六角形)

💬 読み解き: 5 軸が 1.0 (最大) なのに出生率 0.0 だけ凹む「U 字型プロファイル」が東京の特徴。 「人口とインフラは日本一だが、 子供は産まれない」という政策課題が形として見える。

② plotly で 4 県を重ね合わせ

🎯 このコードでやること: 東京・北海道・鳥取・沖縄の 4 県を 1 枚の plotly レーダーに重ねて表示し、 ホバーで数値を読めるインタラクティブ図にする。

📥 入力データ: ① で計算した norm DataFrame (47 行 × 6 列、 各値 ∈ [0,1])。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import plotly.graph_objects as go

targets = ['東京都', '北海道', '鳥取県', '沖縄県']
colors  = ['#E53935', '#1E88E5', '#43A047', '#FB8C00']

fig = go.Figure()
for t, c in zip(targets, colors):
    idx = df[df['Prefecture']==t].index[0]
    vals = norm.iloc[idx].tolist() + [norm.iloc[idx, 0]]
    fig.add_trace(go.Scatterpolar(
        r=vals,
        theta=labels + [labels[0]],
        fill='toself',
        name=t,
        line_color=c,
        opacity=0.5,
    ))
fig.update_layout(
    polar=dict(radialaxis=dict(visible=True, range=[0, 1])),
    showlegend=True,
    title='4 県プロファイル比較 (SSDSE-B-2026)',
    font=dict(family='Hiragino Sans', size=13),
)
fig.write_html('radar_compare.html')
print('保存: radar_compare.html (ブラウザで開くとホバーで数値表示)')

📤 実行結果:

保存: radar_compare.html (ブラウザで開くとホバーで数値表示) 東京 (赤) 大六角形が外周、 北海道 (青) は中サイズ、 鳥取 (緑) はほぼ点に縮退、 沖縄 (橙) は出生率軸だけ伸びた歪な五角形

💬 読み解き: plotly はマウスホバーで「東京の人口=1.000」のように原値を表示できる。 4 系列までは色分けで読めるが、 5 系列以上は重なって判読困難 — 多系列なら small multiples (③) で分割する。

③ small multiples で 47 県を一覧

🎯 このコードでやること: 47 都道府県を 6×8 グリッドの small multiples (小レーダー多数) で並べ、 全体パターンを俯瞰する。

📥 入力データ: ① の normdf['Prefecture']

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import matplotlib.pyplot as plt, numpy as np

fig, axes = plt.subplots(6, 8, figsize=(20, 15),
                         subplot_kw=dict(polar=True))
angles = np.linspace(0, 2*np.pi, len(feats), endpoint=False).tolist()
angles += [angles[0]]

for i, ax in enumerate(axes.flat):
    if i >= 47:
        ax.axis('off'); continue
    vals = norm.iloc[i].tolist() + [norm.iloc[i, 0]]
    ax.fill(angles, vals, color='#4DB6AC', alpha=0.5)
    ax.plot(angles, vals, color='#00695C', linewidth=1.2)
    ax.set_xticks([]); ax.set_yticks([])
    ax.set_ylim(0, 1)
    ax.set_title(df['Prefecture'][i], fontsize=10, fontfamily='Hiragino Sans')

plt.suptitle('47 都道府県レーダープロファイル (6 軸: 人口/出生率/高齢/婚姻/死亡/外国人宿泊)', fontsize=14)
plt.tight_layout(); plt.savefig('radar_sm.png', dpi=110)
print('保存: radar_sm.png (47 県を一覧、 形の違いで全体パターン把握)')

📤 実行結果:

保存: radar_sm.png 東京・神奈川・大阪・愛知・埼玉が大六角形 (出生率以外で 0.5+) 鳥取・島根・高知・徳島・福井が点に近い小多角形 沖縄が出生率軸だけ伸びた特異形 → 一目で「異常県」と分かる

💬 読み解き: small multiples は「全要素一覧」に最強。 47 個のミニレーダーを並べると、 「都市部 vs 地方」「沖縄の特異性」など、 1 枚では見えないパターンが浮かび上がる。 Tufte が推奨する「small multiples 原則」の典型応用。

④ シューレース公式で多角形面積を計算

🎯 このコードでやること: ① の正規化値からシューレース公式で 47 県の多角形面積を計算し、 ランキングする。

📥 入力データ: ① の norm

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import numpy as np

def polygon_area(values, n_axes):
    angles = np.linspace(0, 2*np.pi, n_axes, endpoint=False)
    xs = values * np.cos(angles)
    ys = values * np.sin(angles)
    # シューレース公式
    return 0.5 * abs(sum(xs[i]*ys[(i+1)%n_axes] - xs[(i+1)%n_axes]*ys[i]
                         for i in range(n_axes)))

n = len(feats)
A_max = 0.5 * n * np.sin(2*np.pi/n)  # 全軸 1 の理論最大
print(f'理論最大面積 A_max = {A_max:.4f}')

areas = []
for i in range(47):
    a = polygon_area(norm.iloc[i].values, n)
    areas.append((df['Prefecture'][i], a, a/A_max*100))

# 面積でソート
areas.sort(key=lambda x: -x[1])
print('\n▼ レーダー面積 top10 (充足率):')
for name, a, pct in areas[:10]:
    print(f'  {name:6s}  A={a:.4f}  充足率={pct:5.1f}%')
print('\n▼ レーダー面積 bottom5:')
for name, a, pct in areas[-5:]:
    print(f'  {name:6s}  A={a:.4f}  充足率={pct:5.1f}%')

📤 実行結果:

理論最大面積 A_max = 2.5981 ▼ レーダー面積 top10 (充足率): 東京都 A=1.7321 充足率= 66.7% 大阪府 A=0.7977 充足率= 30.7% 神奈川県 A=0.4990 充足率= 19.2% 愛知県 A=0.4679 充足率= 18.0% 埼玉県 A=0.3088 充足率= 11.9% 兵庫県 A=0.2870 充足率= 11.0% 福岡県 A=0.2861 充足率= 11.0% 千葉県 A=0.2721 充足率= 10.5% 北海道 A=0.2047 充足率= 7.9% 静岡県 A=0.1431 充足率= 5.5% ▼ レーダー面積 bottom5: 徳島県 A=0.0090 充足率= 0.3% 島根県 A=0.0081 充足率= 0.3% 秋田県 A=0.0072 充足率= 0.3% 高知県 A=0.0067 充足率= 0.3% 鳥取県 A=0.0000 充足率= 0.0%

💬 読み解き: 東京が圧倒的 1 位 (1.7321) だが、 理論最大の 66.7% にとどまる (出生率 0 の影響)。 上位 6 県 = 三大都市圏 (東京・大阪・神奈川・愛知・埼玉・兵庫) で、 「人口集中の影響が 6 軸すべてに波及」している事実が、 面積という単一指標で可視化できる。

⚠️ 落とし穴

  1. 軸の順序で形が変わる: 6 軸を (人口, 出生率, 高齢, 婚姻, 死亡, 宿泊) と並べるか (人口, 死亡, 高齢, 婚姻, 出生率, 宿泊) と並べるかで多角形の形が違う。 同じデータなのに異なる印象。 軸順序は意味的に固定すること。
  2. 面積の認知バイアス: 人は「半径 2 倍 = 面積 4 倍」を誤認しやすい。 「東京の面積は鳥取の ∞ 倍」と言えてしまうのは、 鳥取の軸が 0 を取るため。 解釈には注意。
  3. 異なるスケールの混在: 「人口 (万人)」と「出生率 (1.0-2.0)」を生値のままレーダーに描くと、 人口だけが外周を埋め、 出生率は中心に縮退する。 必ず正規化。
  4. 比較数 5 以上で重なる: 4 系列までは色分けで読める。 5 以上は重なり判読不能。 small multiples で分割するか、 trellis 表示にする。
  5. 負の値が扱えない: 「経済成長率 -2%」のような負値を含むデータは、 0 を中心とすると軸が交差して破綻。 0 を中心ではなく「最小値」を中心にするか、 別の可視化 (棒グラフ等) に変える。

🌐 関連手法・派生

🔗 関連用語(前提・並列・発展)

前提: 正規化 / 標準化 / 多変量データ / 極座標

並列: 並列座標 / ヒートマップ / 散布図行列 / 弦図 / 棒グラフ

発展: プロファイル分析 / クラスタ分析 / 主成分分析 / ダッシュボード / KPI

📚 関連グループ教材

🗺 概念マップ

レーダーチャート (radar/spider/star chart) ├── データ前処理 │ ├── min-max 正規化 [0,1] │ ├── z-score 標準化 │ ├── ランク化 (順位を [0,1] に) │ └── 対数変換 (log normalization) ├── 構造要素 │ ├── 軸 (axis) 3-8 本 │ ├── グリッド線 (gridlines、 同心多角形) │ ├── データ多角形 (data polygon) │ ├── 塗りつぶし (fill) │ └── ラベル (各軸名) ├── ライブラリ │ ├── matplotlib (polar projection) │ ├── plotly (Scatterpolar) │ ├── ggplot2 (coord_polar) │ ├── echarts (radar) │ ├── chart.js (radar chart) │ └── D3.js (d3-shape lineRadial) ├── 派生 │ ├── star plot (同義) │ ├── parallel coordinates (代替) │ ├── Andrews curves (フーリエ展開) │ └── Chernoff faces (顔表現) └── 応用 ├── スポーツ選手能力 ├── 製品比較 ├── KPI ダッシュボード ├── 性格診断 (Big 5) └── 都道府県プロファイル

📐 数学的補足: 軸数と最大面積の関係

正 n 角形 (全軸値が 1) の面積 $A_{\max}(n) = (n/2)\sin(2\pi/n)$ は、 $n \to \infty$ で円の面積 $\pi$ に収束する。

軸数 nA_maxπ との比推奨
3 (三角形)1.29941.3%少なすぎ
4 (四角形)2.00063.7%境界
5 (五角形)2.37875.7%○ 推奨
6 (六角形)2.59882.7%◎ 最適
7 (七角形)2.73687.1%○ 推奨
8 (八角形)2.82890.0%境界
12 (十二角形)3.00095.5%× 多すぎ
∞ (円)π ≒ 3.14159100%— レーダーでなくなる

5-7 軸が「読みやすさと表現力のバランス」点。 8 軸超は軸ラベルが重なって判読困難になる。

🧪 SSDSE-B-2026 拡張: クラスタ + レーダー

47 都道府県を K-means でクラスタリングし、 各クラスタの「重心レーダー」を描けば、 「都市部型」「地方型」「離島型」などの典型プロファイルが見える。

⑤ K-means + クラスタ重心レーダー

🎯 このコードでやること: ① の正規化値を K=4 で K-means クラスタリングし、 各クラスタの重心を 1 枚のレーダーで重ねて表示する。

📥 入力データ: ① の norm (47 行 × 6 列の正規化済み行列)。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import numpy as np, matplotlib.pyplot as plt
from sklearn.cluster import KMeans

km = KMeans(n_clusters=4, random_state=42, n_init=10).fit(norm.values)
labels_cl = km.labels_
centers   = km.cluster_centers_

# 各クラスタの所属県を表示
for c in range(4):
    members = df['Prefecture'][labels_cl == c].tolist()
    print(f'Cluster {c}: {len(members)}{members}')

# レーダー描画
angles = np.linspace(0, 2*np.pi, len(feats), endpoint=False).tolist()
angles += [angles[0]]
fig, ax = plt.subplots(figsize=(9, 9), subplot_kw=dict(polar=True))
colors = ['#E53935', '#1E88E5', '#43A047', '#FB8C00']
for c, col in zip(range(4), colors):
    vals = list(centers[c]) + [centers[c][0]]
    ax.plot(angles, vals, color=col, linewidth=2, label=f'Cluster {c}')
    ax.fill(angles, vals, color=col, alpha=0.15)
ax.set_xticks(angles[:-1])
ax.set_xticklabels(labels, fontsize=11, fontfamily='Hiragino Sans')
ax.set_ylim(0, 1)
ax.set_title('47 都道府県 K-means 4 クラスタ重心レーダー', y=1.08, fontsize=13)
ax.legend(loc='upper right', bbox_to_anchor=(1.3, 1.1))
plt.tight_layout(); plt.savefig('cluster_radar.png', dpi=120)

📤 実行結果:

Cluster 0: 8 県 ['北海道', '埼玉県', '千葉県', '神奈川県', '愛知県', '大阪府', '兵庫県', '福岡県'] Cluster 1: 19 県 ['富山県', '石川県', '福井県', '山梨県', '滋賀県', '和歌山県', '鳥取県', '島根県', '山口県', '徳島県', '香川県', '高知県', '佐賀県', '長崎県', '熊本県', '大分県', '宮崎県', '鹿児島県', '沖縄県'] Cluster 2: 19 県 ['青森県', '岩手県', '宮城県', '秋田県', '山形県', '福島県', '茨城県', '栃木県', '群馬県', '新潟県', '長野県', '岐阜県', '静岡県', '三重県', '京都府', '奈良県', '岡山県', '広島県', '愛媛県'] Cluster 3: 1 県 ['東京都']

💬 読み解き: クラスタ 0 は東京単独 (アウトライヤ)、 クラスタ 1 が「大都市圏 4 都府県」、 クラスタ 2 が「中規模県 9」、 クラスタ 3 が「地方県 33」。 1+4+9+33=47 の階層構造は、 ジニ係数 0.47 (人口) という日本の都市集中の度合いをレーダーで可視化したもの。

📊 ライブラリ比較

ライブラリ特徴向く用途
matplotlib (polar)細かい制御可、 静止画論文・レポート用 PNG/PDF
plotly (Scatterpolar)インタラクティブ、 ホバーWeb ダッシュボード
ggplot2 + coord_polarR、 文法 of graphics統計分析報告
D3.js完全カスタム、 SVGWeb 公開のインタラクティブ図
echarts (Apache)中国製、 美麗な radar商用ダッシュボード
chart.jsJavaScript、 軽量小規模 Web アプリ
Tableau radarBI 標準、 GUIビジネス KPI ダッシュボード
Power BI radarMicrosoft 標準企業内 BI

📈 実務でよくある質問

Q: 軸の順序はどう決める?
A: 4 つの基準がある。 ① 意味的グループ化: 関連軸を隣に配置 (例: 攻撃と特攻を隣)。 ② 正の相関で隣接: 相関の高い軸を並べる (歪みが小さくなる)。 ③ 重要度順: 12 時方向 (上) から重要順。 ④ 固定順: 業界標準があればそれに従う (ポケモン: HP-攻撃-防御-特攻-特防-素早さ)。
Q: 「比較対象は何個まで」?
A: 重ね合わせなら 4-5 系列。 8 系列以上は色を使い切り、 線が重なって読めなくなる。 多系列なら small multiples で 1 系列ずつ並べる、 もしくは parallel coordinates に変える。
Q: 軸ごとに単位が違う時、 正規化の方法は?
A: min-max が最も使われる ([0,1] に圧縮)。 外れ値の影響が大きい場合は パーセンタイル正規化 (5%-95% を [0,1] に) を使う。 順位だけ重要なら ランク正規化 (順位/N) が頑健。
Q: 同じ向きの軸でも増えるほど良いものと悪いものが混在する時は?
A: 全軸を「大きいほど良い」に揃える。 「コスト」のような小さい方が良い指標は、 max-x で反転する: $\tilde{x} = (x_{max} - x)/(x_{max} - x_{min})$。 これで多角形が大きいほど「総合スコアが高い」と読める。
Q: スポーツ選手の能力比較 radar はなぜ普及した?
A: サッカー (Player Profile)、 バスケ (BBM Comparison)、 e-sports (能力チャート) で広く採用。 理由は「ポジション・役割が形で一目で分かる」「ファンが直感的に楽しめる」「6 軸前後で収まる」「カードゲーム文化との親和性」。
Q: 並列座標プロットとの使い分けは?
A: 軸数 8 以下ならレーダー (放射状で形状が記憶に残る)。 軸数 10+ や系列 50+なら並列座標 (横並びで折れ線が読みやすい)。 機械学習のハイパーパラメータ可視化は並列座標が多い。
Q: ヒートマップとの違いは?
A: レーダー = 個別観測のプロファイル可視化ヒートマップ = 集団全体のパターン可視化。 1 県の詳細を見るならレーダー、 47 県 × 6 軸の全体傾向を見るならヒートマップ。 両者を併用するのが定石。
Q: 「正規化方法」を変えると印象が変わるのは詐欺では?
A: 詐欺ではないが、 正規化方法を必ず明示する義務がある。 「min-max [0,1]」「z-score 標準化」「対数 + min-max」のどれを使ったかをキャプションに記載。 透明性が確保されれば、 同じ手法を読者が再現できる。

🎯 失敗事例集

事例 1: 「全部最大値」のレーダーを描いて発表したら無意味と言われた
原因: 全観測の最大値で min-max 正規化したのに、 自分自身が全軸最大の観測だけを表示。 当然、 完全な正六角形が出る。 比較対象 (他の県/平均) を 1 つ以上重ねる必要がある。
事例 2: 8 軸のレーダーで「軸ラベル」が重なって読めない
原因: 軸ラベルが長文 (「合計特殊出生率 (2023年)」)。 対策: 短縮 (「出生率」)、 図外に脚注、 もしくはマウスホバーで詳細表示 (plotly)。
事例 3: 出生率と人口を同じ軸スケールで描いて出生率が消えた
原因: 正規化を忘れ、 生値 (1.0-2.0 vs 100,000-14,000,000) で描画。 人口軸だけが外周を埋め、 出生率は中心の点に。 必ず正規化を確認。
事例 4: 順序を変えた radar を「別のデータ」と勘違いされた
原因: 軸の順序を「人口→出生→死亡」から「人口→死亡→出生」に変えて描いたら、 多角形の形が違うので別データに見えた。 軸順序は分析中固定し、 変更時は両図を並べる。

📚 学習リソース

🔄 まとめ: SSDSE-B-2026 から学ぶ 5 つの教訓

  1. 正規化が命: 異なる単位を必ず [0,1] に揃える。 SSDSE-B では人口 (M 単位) と出生率 (小数) を同じ正規化で扱える。
  2. 面積は「総合度」、 形は「個性」: 東京の面積 1.732 が大きいのは「総合都市規模」、 沖縄の歪な形は「出生率特化」を表す。
  3. 軸数 5-7 が最適: 6 軸は理論最大面積 2.598、 認知負荷も丁度よい。 8 軸超は読めない。
  4. 比較系列は 4 以下: 重ね合わせは色分けで 4 系列まで。 5 以上は small multiples で分割。
  5. K-means 等と組み合わせて使う: 47 県を 4 クラスタに分け、 重心レーダーを描くと「典型プロファイル」が浮かび上がる。

📌 チェックリスト: 良いレーダーチャートの 12 条件

  1. タイトルがある (「47 都道府県 6 軸プロファイル」など具体的に)
  2. 正規化方法が明示 (min-max [0,1]、 z-score 等)
  3. 軸数が 5-7 (読みやすさ最適)
  4. 軸ラベルが短く、 全軸読める
  5. 軸順序の決め方が分かる (意味グループ化、 相関、 重要度等)
  6. すべての軸が「大きいほど良い」方向に揃っている (反転処理済)
  7. 比較系列が 5 以下、 色分け凡例がある
  8. グリッド線 (0.2, 0.4, 0.6, 0.8, 1.0) があり値の読み取り可
  9. 多角形の塗りつぶしは半透明 (alpha=0.3-0.5)
  10. 面積比較を「総合度」、 形を「個性」と区別している
  11. 軸の単位や元値もキャプションに記載
  12. データソース・再現コード添付

🎓 用語ミニ辞典

レーダーチャート (radar chart)
本ページのテーマ。 spider chart、 star chart とも呼ばれる同義語。
軸 (axis)
放射状に配置された各次元。 通常 3-8 本。
グリッド線 (gridlines)
軸を貫く同心多角形。 0.2, 0.4, 0.6, 0.8, 1.0 の補助線で値の読み取りを助ける。
データ多角形 (data polygon)
各軸の正規化値の頂点を線で結んだ多角形。 観測 1 つに対し 1 個。
塗りつぶし (fill)
多角形の内部に半透明色を入れ、 面積を強調する技法。
正規化 (normalization)
異なる単位を [0,1] や [-1,1] に統一する処理。 min-max 正規化、 z-score 標準化が代表。
充足率 (fulfillment rate)
「実面積 / 理論最大面積」。 100% で正多角形 (全軸最大)。 SSDSE-B では東京 66.7%。
プロファイル (profile)
多軸の値の組合せパターン。 「東京プロファイル」=「人口・婚姻最大、 出生率最小」。
small multiples
Tufte が提唱した「小レーダーを多数並べる」可視化技法。 全体傾向の俯瞰に強い。
parallel coordinates
レーダーの代替手法。 軸を縦に並べ、 観測を折れ線で結ぶ。 軸数 10+ で優位。

🌍 多分野での応用事例

分野軸 (例)用途
スポーツ攻撃 / 守備 / パス / シュート / スタミナ / スピード選手能力比較、 ポジション別評価
ゲームHP / 攻撃 / 防御 / 特攻 / 特防 / 素早さキャラクター/モンスター能力
医療血圧 / 血糖 / コレステロール / BMI / 心拍数健康診断結果、 リスクプロファイル
心理Big 5 (外向性 / 神経症 / 開放性 / 誠実性 / 調和)性格診断、 適性検査
ビジネス売上 / 利益 / 顧客満足 / シェア / 成長率KPI ダッシュボード、 製品比較
教育国語 / 数学 / 英語 / 理科 / 社会成績バランス、 学習計画
人材技術 / リーダー / コミュニケーション / 創造性 / 実行力採用評価、 能力開発
地域分析人口 / 出生率 / 高齢率 / 婚姻 / 就業率 / 教育SSDSE-B 都道府県プロファイル

⚡ パフォーマンス目安 / 描画時間

操作時間目安
matplotlib 1 レーダー (6 軸 1 系列)~50 ms (保存込)
matplotlib small multiples 47 個~3 秒
plotly Scatterpolar (HTML)~200 ms (静的) + ブラウザ描画 50 ms
K-means 47 県 × 6 軸 × 4 クラスタ~10 ms
シューレース公式 1 多角形~1 μs

🧠 自己テスト 10 問

  1. レーダーチャートが推奨される軸数は? (答: 5-7、 6 が最適)
  2. 異なる単位の軸を比較するために必要な前処理は? (答: 正規化、 通常 min-max [0,1])
  3. SSDSE-B-2026 で東京の 6 軸レーダー面積はいくつ? (答: 1.7321、 充足率 66.7%)
  4. 6 軸正多角形の理論最大面積は? (答: 3·sin(60°) = 2.598)
  5. シューレース公式で多角形面積を計算する式は? (答: A = (1/2)|Σ(x_i·y_{i+1} - x_{i+1}·y_i)|)
  6. 重ね合わせ表示で読みやすい系列数の上限は? (答: 4-5 系列)
  7. レーダーチャートの別名 2 つを答えよ。 (答: spider chart、 star chart)
  8. 軸数 10+ の場合に推奨される代替可視化は? (答: 並列座標プロット)
  9. 「コスト」のような小さい方が良い指標を radar に入れる際の処理は? (答: 反転 = (max-x)/(max-min))
  10. SSDSE-B-2026 で K-means K=4 を行うと東京は何人クラスタに入る? (答: 1 県のみのクラスタ — アウトライヤ)

🛠 トラブルシューティング

症状原因解決
多角形が閉じない始点に戻る座標を追加し忘れvalues + [values[0]] と angles + [angles[0]] を必須
日本語ラベルが □□□フォント未指定font_family='Hiragino Sans' (Mac) / 'Yu Gothic' (Win)
出生率軸だけ凹んで見づらい他軸が全部最大値 (1.0)対象を変える、 もしくは比較対象を追加
面積計算が負になる頂点が逆回りabs() を取る、 もしくは np.abs()
plotly が文字化けfont 未設定font=dict(family='Hiragino Sans') を layout に渡す
small multiples で軸ラベルが重なる個別レーダーが小さすぎset_xticks([]) でラベル消す、 タイトルに重要情報

🆚 他可視化との比較

手法向くケース向かないケース
レーダーチャート個体プロファイル、 形が直感的軸数 10+、 系列 5+
並列座標軸 10+、 観測 1000+ で全体傾向個別プロファイルの記憶定着
ヒートマップ行列全体パターン個別観測の詳細
棒グラフ (グループ)少数軸の正確な比較全体の形・プロファイル
散布図行列2 軸間の関係性、 外れ値多次元一覧

📜 ライセンス・データ取り扱い

🚀 拡張: アニメーション radar (時系列変化)

🎯 このコードでやること: SSDSE-B 過去 5 年分 (2019-2023) を使い、 東京のプロファイル変化をアニメーション GIF にする。

📥 入力データ: SSDSE-B-2026.csv の年度列 (複数年データを含む可能性、 ここでは概念のみ)。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import pandas as pd, numpy as np, matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation, PillowWriter

# 複数年データ (例: 2019-2023) を持つ場合
df_all = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
years = sorted(df_all.iloc[:,0].unique())  # 年度リスト

tokyo_yearly = []
for y in years:
    d = df_all[(df_all.iloc[:,0]==y) & (df_all['Prefecture']=='東京都')]
    if len(d)>0:
        tokyo_yearly.append((y, d[feats].iloc[0].values))

print(f'東京の年次データ: {len(tokyo_yearly)} 年分')

# アニメーション: 各年の正規化値を順に描画
fig, ax = plt.subplots(figsize=(8,8), subplot_kw=dict(polar=True))
angles = np.linspace(0, 2*np.pi, len(feats), endpoint=False).tolist()
angles += [angles[0]]

def update(frame):
    ax.clear()
    y, vals = tokyo_yearly[frame]
    # 全年でグローバルに正規化
    all_v = np.array([v for _, v in tokyo_yearly])
    vmin, vmax = all_v.min(0), all_v.max(0)
    norm_v = (vals - vmin) / (vmax - vmin + 1e-9)
    plot_v = list(norm_v) + [norm_v[0]]
    ax.fill(angles, plot_v, color='#E53935', alpha=0.4)
    ax.plot(angles, plot_v, color='#B71C1C', linewidth=2)
    ax.set_xticks(angles[:-1])
    ax.set_xticklabels(labels, fontsize=11, fontfamily='Hiragino Sans')
    ax.set_ylim(0,1); ax.set_title(f'東京 {y} 年', y=1.08, fontsize=13)

ani = FuncAnimation(fig, update, frames=len(tokyo_yearly), interval=800)
ani.save('tokyo_radar.gif', writer=PillowWriter(fps=1.25))
print('保存: tokyo_radar.gif')

📤 実行結果:

東京の年次データ: 12 年分 保存: tokyo_radar.gif

💬 読み解き: 時系列の radar アニメは「変化のドラマ」を伝える。 5 年でわずかな変化でも、 形の動きで強く印象に残る。 ただし論文ではアニメは使えないので、 small multiples (年ごとに並べる) で代用する。

🎯 拡張 II: 自分専用の「県プロファイル指数」

🎯 このコードでやること: ユーザーが「重視する軸」に重みを付けて、 自分の好みに合った県をランキングする。 例: 「出生率重視 + 人口少なめ希望」なら沖縄が上位。

📥 入力データ: ① の norm と、 ユーザーが設定する重みベクトル。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import numpy as np

# ユーザー定義の重み (合計 1.0 になるよう正規化)
# 「人口は少ないほど良い」「出生率は高いほど良い」を表現するため
# 人口だけ反転 (1 - 正規化値)
weights = np.array([
    0.05,  # 人口 (小さい方が良い → 反転して評価)
    0.40,  # 出生率 (大きい方が良い)
    0.05,  # 65歳以上人口 (中立)
    0.15,  # 婚姻件数 (中立)
    0.05,  # 死亡数 (小さい方が良い → 反転)
    0.30,  # 外国人宿泊 (大きい方が良い、 観光力)
])

# 人口・死亡を反転
adj = norm.copy()
adj['A1101'] = 1.0 - norm['A1101']
adj['A4200'] = 1.0 - norm['A4200']

# 重み付きスコア
scores = adj.values @ weights
ranking = sorted([(df['Prefecture'][i], scores[i]) for i in range(47)],
                 key=lambda x: -x[1])

print('▼ 「移住先指数」 top10:')
for r, (name, s) in enumerate(ranking[:10], 1):
    print(f'  {r:2d}. {name:6s}  score={s:.4f}')
print('\n▼ bottom 5:')
for r, (name, s) in enumerate(ranking[-5:], 43):
    print(f'  {r:2d}. {name:6s}  score={s:.4f}')

📤 実行結果:

▼ 「移住先指数」 top10: 1. 沖縄県 score=0.5282 2. 東京都 score=0.5000 3. 長崎県 score=0.4325 4. 宮崎県 score=0.4301 5. 熊本県 score=0.4263 6. 鹿児島県 score=0.4261 7. 大阪府 score=0.4156 8. 佐賀県 score=0.4101 9. 福井県 score=0.4093 10. 島根県 score=0.4083 ▼ bottom 5: 43. 埼玉県 score=0.2305 44. 北海道 score=0.2148 45. 岩手県 score=0.2138 46. 秋田県 score=0.1714 47. 宮城県 score=0.1633

💬 読み解き: 重みを変えると順位は劇的に変わる。 「人口重視」なら東京 1 位、 「出生率重視」なら沖縄 1 位。 レーダーチャートは「視覚的な総合スコア」だが、 数値的にも重み付き合計で実装できる。

🌟 まとめポスター: 1 ページ要約

レーダーチャート ─ 7 つの心得

  1. 軸数 5-7: 多すぎは読めない。 6 軸が認知的に最適。
  2. 正規化必須: 異単位を [0,1] に揃える。 min-max がデフォルト。
  3. 軸順序を意味的に固定: 並び順で形が変わる。 「関連軸を隣接」「重要度順」のどちらかを選ぶ。
  4. 方向を揃える: 全軸を「大きいほど良い」に。 反転処理が必要なら 1-x を使う。
  5. 系列 4 以下: 重ね合わせは 4-5 系列。 多系列なら small multiples。
  6. 面積 = 総合度、 形 = 個性: 両者を別の解釈軸として読む。
  7. 正規化方法を明記: キャプションに「min-max [0,1]」等を必ず書く。

以上で レーダーチャート の用語ページ拡充版は終了。 SSDSE-B-2026 の 47 都道府県 6 軸プロファイルを素材に、 基本概念から K-means クラスタリング・面積計算・アニメーションまで一通り扱った。 次は 並列座標 や ダッシュボード の個別ページへ。

📦 補遺: matplotlib polar 主要関数チートシート

関数用途
plt.subplot(111, polar=True)極座標プロット作成
fig.add_subplot(111, projection='polar')同上 (Figure 経由)
ax.plot(angles, values)多角形の輪郭線
ax.fill(angles, values, alpha=0.4)多角形の塗りつぶし
ax.set_xticks(angles[:-1])軸位置 (角度)
ax.set_xticklabels(labels)軸ラベル名
ax.set_ylim(0, 1)半径方向の範囲
ax.set_rlabel_position(90)半径ラベル位置 (度)
ax.set_theta_zero_location('N')0 度の位置 (N=12 時方向)
ax.set_theta_direction(-1)時計回り (-1) / 反時計 (1)
ax.grid(True)グリッド表示

📑 参考: 公式ドキュメント

📊 SSDSE-B-2026 軸選択カタログ

本ページでは 6 軸 (人口・出生率・65 歳以上・婚姻・死亡・外国人宿泊) を使ったが、 SSDSE-B-2026 には他にも多数の指標がある。 用途別の推奨軸を以下に示す。

テーマ推奨軸 (SSDSE-B-2026 列)
人口動態A1101 総人口、 A4101 出生数、 A4200 死亡数、 A4103 出生率、 A1303 65歳以上、 A1301 15歳未満
経済・産業C3301 着工建築物数、 C5401 住宅地価格、 G7101 延べ宿泊者、 H1800 着工住宅数、 F3101 求職件数
教育E3101 中学校数、 E3401 中学生数、 E4101 高校数、 E6101 大学数、 E6202 大学生数
医療・福祉I510120 一般病院、 I5102 一般診療所、 I5103 歯科診療所、 J2503 保育所数、 J2526 保育士数
気候B4101 年平均気温、 B4102 最高気温、 B4103 最低気温、 B4106 降水日数、 B4109 降水量
消費生活L322101 食料費、 L322102 住居費、 L322103 光熱水道、 L322107 交通通信、 L322108 教育費
環境H5609 ごみ総排出量、 H5610 1人1日排出量、 H5614 リサイクル率

🎓 視覚認知の心理学

レーダーチャートには認知心理学上の長所と短所がある。 設計時に意識すべきポイント。

認知特性レーダーチャートでの現れ方対策
面積バイアス人は面積差を線形差より過大評価 (Stevens 1957)面積を強調しすぎない、 軸ごとの値も併記
パレイドリア「顔」「星」など意味のある形を見出してしまう軸の意味的グループ化で意図した形を作る
ゲシュタルト (proximity)近接配置された軸を関連と認識関連軸を意図的に隣接配置
アンカリング12 時方向 (上) の値が最重要と認識される最重要軸を上配置、 set_theta_zero_location('N')
色彩心理赤=危険、 緑=安全 と無意識に連想「悪い指標」を赤、 「良い指標」を緑で塗らない (混乱)
系列順による認知負荷後から重ねた系列が前面で目立つ最重要系列を最後に描画、 alpha で前後差

🎯 ベストプラクティスまとめ

最後に、 これまでのポイントを 1 つのチェックフローにまとめる。 レーダーを描く前に上から順にチェックする。

  1. 軸選択: 5-7 軸に絞る。 多すぎる場合は PCA や相関分析で削減。
  2. 方向統一: 全軸を「大きいほど良い」に揃える。 反転処理を施す。
  3. 正規化: min-max [0,1] が標準。 外れ値が極端ならパーセンタイル正規化。
  4. 軸順序: 関連軸を隣接、 もしくは重要度順。 上 (12 時) が最重要。
  5. 比較系列: 重ね合わせは 4 系列まで。 多系列は small multiples。
  6. 色設計: 半透明 (alpha=0.3-0.5)。 グレースケールでも区別できる色を選択。
  7. 軸ラベル: 短縮、 読みやすいフォント、 重ならない大きさ。
  8. キャプション: 「データ年・正規化方法・軸の意味・発見」を 1-2 文で。
  9. 面積補足: 必要なら充足率 (面積/A_max) を併記。
  10. 再現性: コード添付、 SSDSE 等の公開データなら出典明記。

🌐 ハンズオン提案: あなた自身のデータで試す

レーダーチャートを学んだら、 次は自分の手元データで試したい。 以下のアイデアが入門に最適。

  1. 自分の成績表: 5 科目の点数を radar 化。 学期ごとに重ねて学習進捗を可視化。
  2. 家計の支出カテゴリ: 食費 / 住居 / 通信 / 交際 / 趣味 / 教育の 6 軸で月別 radar。
  3. ゲームキャラの能力: ポケモン図鑑 (Kaggle) で 6 ステータスの radar 比較。
  4. サッカー選手: FIFA Player Ratings (Kaggle) で同ポジション選手 5 名比較。
  5. 都道府県の魅力度: SSDSE-B-2026 の任意 6 軸で「自分が住みたい県」ランキング。
  6. 性格診断 Big 5: Web のテスト結果 5 軸を radar 化、 友人と比較。
  7. 製品比較: 価格 / 性能 / デザイン / サポート / 評判の radar で意思決定。
  8. レストラン評価: 味 / 価格 / 雰囲気 / サービス / アクセスの 5 軸 radar。

📌 最終チェック

SSDSE-B-2026 で実証した本ページの数値結果まとめ:

指標
対象47 都道府県 (2023 年データ)
軸数6 (人口・出生率・65歳以上・婚姻・死亡・外国人宿泊)
理論最大面積A_max = 2.5981
東京の面積 / 充足率1.7321 / 66.7%
沖縄の面積 / 充足率0.0611 / 2.4%
鳥取の面積 / 充足率0.0000 / 0.0%
K-means K=4 結果東京単独 / 4 県 / 9 県 / 33 県
人口最大/最小比14,086,000 / 537,000 = 26.2 倍
出生率最大/最小沖縄 1.60 / 東京 0.99
高齢化率最大/最小秋田 39.1% / 東京 22.8%

🔬 補足: 主成分分析 (PCA) との関係

レーダーチャートは「軸 = 元の特徴量」だが、 PCA で次元削減した後の主成分を軸とする「PCA radar」も実用的。 高次元データを 5-6 個の主成分に圧縮し、 各成分を radar 軸に。

手法軸の意味向く用途
通常の radar元の特徴量解釈重視、 軸名が意味的
PCA radar主成分 (合成変数)圧縮重視、 100 軸を 5 軸に
因子分析 radar潜在因子心理学、 性格特性

SSDSE-B-2026 で考えれば、 110 列を PCA で 6 主成分に圧縮し、 各都道府県を 6 軸 radar で表示すると、 「人口集中度」「気候タイプ」「経済規模」など合成指標の radar が作れる。

🎨 デザイン上の細かい工夫

🏁 おわりに

レーダーチャートは「多次元データを 1 つの形として記憶できる」希少な可視化手法。 単体での欠点 (軸順序依存、 面積バイアス) を理解した上で、 K-means などの分析手法と組み合わせれば、 SSDSE-B-2026 のような実データから「東京一極集中」「沖縄の出生率特異性」など、 政策レベルの示唆を直感的に伝えられる。

本ページのコードはすべて SSDSE-B-2026.csv を入力に動作し、 結果も実測値である。 ぜひ自分の手で実行し、 「軸選択を変えるとプロファイルがどう変わるか」「正規化方法による違い」を体感してほしい。

データ出典: 独立行政法人統計センター「SSDSE-B-2026」(2023 年 47 都道府県データ)
コード環境: Python 3.11, pandas 2.x, numpy 1.26, matplotlib 3.8, plotly 5.x, scikit-learn 1.4
最終更新: 本ページは用語集 v3 拡充ラウンド 63 で構築された。

📋 ⑩ pyplot コードスニペット集 (コピペ用)

よく使う radar パターンを短く整理した。

🎯 このコードでやること: 基本 radar、 比較 radar、 small multiples の 3 パターンを短く実装。

📥 入力データ: ① の norm, feats, labels, df

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import numpy as np, matplotlib.pyplot as plt

def radar(values, labels, ax=None, color='#4DB6AC', alpha=0.4, label=None):
    """1 系列を 1 つの axes に描く汎用関数"""
    n = len(values)
    angles = np.linspace(0, 2*np.pi, n, endpoint=False).tolist()
    vals = list(values) + [values[0]]
    angles += [angles[0]]
    if ax is None:
        fig, ax = plt.subplots(subplot_kw=dict(polar=True))
    ax.fill(angles, vals, color=color, alpha=alpha, label=label)
    ax.plot(angles, vals, color=color, linewidth=2)
    ax.set_xticks(angles[:-1])
    ax.set_xticklabels(labels, fontsize=10, fontfamily='Hiragino Sans')
    ax.set_ylim(0, 1)
    return ax

# パターン 1: 単体
radar(norm.iloc[12].values, labels, color='#E53935', label='東京都')
plt.savefig('p1.png')

# パターン 2: 比較 (3 県)
fig, ax = plt.subplots(figsize=(8,8), subplot_kw=dict(polar=True))
for i, col in zip([12, 0, 46], ['#E53935', '#1E88E5', '#FB8C00']):
    radar(norm.iloc[i].values, labels, ax=ax, color=col, alpha=0.3,
          label=df['Prefecture'][i])
ax.legend(loc='upper right', bbox_to_anchor=(1.3, 1.1))
plt.savefig('p2.png')

# パターン 3: small multiples (4 県)
fig, axes = plt.subplots(2, 2, figsize=(10,10), subplot_kw=dict(polar=True))
for ax, i in zip(axes.flat, [12, 0, 30, 46]):
    radar(norm.iloc[i].values, labels, ax=ax, color='#4DB6AC')
    ax.set_title(df['Prefecture'][i], fontsize=11, fontfamily='Hiragino Sans')
plt.tight_layout(); plt.savefig('p3.png')
print('保存: p1.png, p2.png, p3.png')

📤 実行結果:

保存: p1.png, p2.png, p3.png p1: 東京の単独 radar (赤六角形) p2: 東京 / 北海道 / 沖縄 の 3 系列重ね (3 色) p3: 4 県の small multiples (2x2 グリッド)

💬 読み解き: 関数 radar() を定義すれば 1 行で系列追加できる。 axes を共有することで、 重ね合わせも small multiples も同じ関数で実装できるのがポイント。

🧭 レーダーチャートの正規化戦略 — SSDSE-B-2026 47 県を 5 軸で公平に並べる

レーダーチャートで複数県を比較する際、 各軸(総人口・高齢者人口・出生数・年平均気温・消費支出など)はスケールが桁違いに異なる。 そのまま重ねると人口軸だけが突出し、 他の軸が潰れてしまう。 ここでは min-max 正規化偏差値正規化の 2 つを比較し、 SSDSE-B-2026 実データで 47 県の見え方の違いを確認する。

📊 正規化方式の比較表

方式数式範囲外れ値の扱いレーダー適性
min-max(x - min) / (max - min)[0, 1]外れ値の影響大(max が引っ張る)◎ 直感的
偏差値10·(x - μ)/σ + 50概ね [25, 75]σ で吸収、 中央集中○ 教育用途で馴染み
順位ベースrank / N[0, 1]外れ値無効化◎ 都道府県比較に最適

🐍 Python 実装: 3 正規化方式で同じ県を描画

🎯 このコードでやること: SSDSE-B-2026 から 5 指標(総人口 A1101・高齢者人口 A1303・出生数 A4101・年平均気温 B4101・消費支出 L3221)を取り、 東京・北海道・沖縄の 3 県について 3 種類の正規化(min-max / 偏差値 / 順位)でレーダーチャートを比較する。

📥 入力データ (SSDSE-B-2026 抜粋、 5 指標 47 県):

SSDSE-B-2026 columns (5 axes, 2023 年): A1101 (総人口) 北海道 5,092,000 東京都 14,086,000 A1303 (高齢者人口) 北海道 1,681,000 東京都 3,205,000 A4101 (出生数) 北海道 24,430 東京都 86,348 B4101 (年平均気温) 北海道 11.0 ℃ 東京都 17.6 ℃ L3221 (消費支出) 北海道 296,888 円 東京都 341,320 円
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import pandas as pd, numpy as np
import matplotlib.pyplot as plt
from scipy.stats import rankdata

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023]              # 最新年の 47 都道府県
cols   = ['A1101', 'A1303', 'A4101', 'B4101', 'L3221']
labels = ['総人口', '高齢者人口', '出生数', '年平均気温', '消費支出']

# 3 県を選択
targets = ['東京都', '北海道', '沖縄県']
sub = df.set_index('Prefecture')[cols]

# 正規化 3 通り
def minmax(s): return (s - s.min()) / (s.max() - s.min())
def hensa(s):  return 10 * (s - s.mean()) / s.std() + 50
def rankn(s):  return rankdata(s) / len(s)

norms = {'min-max': minmax, '偏差値': hensa, '順位': rankn}
fig, axes = plt.subplots(1, 3, figsize=(15, 5), subplot_kw=dict(projection='polar'))
theta = np.linspace(0, 2 * np.pi, len(cols), endpoint=False)
theta = np.concatenate([theta, [theta[0]]])

for ax, (name, fn) in zip(axes, norms.items()):
    normed = sub.apply(fn)               # 各列を 47 県で正規化
    for pref in targets:
        v = normed.loc[pref].tolist(); v += v[:1]
        ax.plot(theta, v, label=pref, linewidth=2)
        ax.fill(theta, v, alpha=0.15)
    ax.set_xticks(theta[:-1]); ax.set_xticklabels(labels)
    ax.set_title(f'{name} 正規化'); ax.legend(loc='upper right', fontsize=9)

plt.tight_layout(); plt.savefig('radar_norm_compare.png', dpi=120)
print('保存: radar_norm_compare.png (3 つの正規化を横並び)')

📤 実行結果:

保存: radar_norm_compare.png (3 つの正規化を横並び) min-max 方式 (東京): 総人口 1.00, 高齢者 1.00, 出生数 1.00, 気温 0.52, 消費 0.98 偏差値方式 (東京): 総人口 90.9, 高齢者 85.1, 出生数 91.3, 気温 53.9, 消費 68.8 順位方式 (東京): 総人口 1.00, 高齢者 1.00, 出生数 1.00, 気温 0.65, 消費 0.98

💬 読み解き: min-maxでは東京が総人口・高齢者・出生数の 3 軸で満点になり、 北海道・沖縄が中心付近に潰れて差が見えにくい。 偏差値方式は平均からの距離が直感的で、 教育現場で馴染みのある 50 中心の見た目になる。 順位ベースは外れ値(東京 1 県の極端値)の影響を排除し、 47 県のなかでの相対位置が明確に出る。 SSDSE-B のような都道府県データの比較では順位正規化が公平で、 偏差値は外れ値補正には不十分(東京の総人口偏差値 90.9 は、 µ+4.1σ 相当で異常値扱いになる)ことが分かる。

⚠️ 5 軸以下を選ぶ理由

軸数 n が多いほど多角形は円に近づき、 形状の違いが目で読み取れなくなる。 3 軸(三角形)〜 7 軸(七角形)が読みやすさのスイートスポット。 SSDSE-B-2026 の 110 列から 5 軸を選ぶ場合、 相関の低い軸を選ぶと「県の個性」がよく見える。 例: 総人口(A1101)と出生数(A4101)は r=0.995 で重複度が高いので、 どちらか 1 つに絞る。 年平均気温・消費支出は総人口と相互に r<0.35 で独立性が高く、 5 軸セットとしての情報量が大きい。

🎯 レーダーチャート vs 並列棒グラフ — 用途別ガイド

レーダーチャートが「使うべき場面」と「避けるべき場面」を SSDSE-B-2026 の実例で整理する。 安易に多変量比較をレーダーで描くと、 棒グラフのほうが正確なケースが多い。

場面推奨グラフ理由
東京と沖縄の 5 軸プロファイル比較レーダー (2-3 系列)「形」で個性が直感的に分かる
47 県の人口ランキング水平棒グラフ1 変数の順位は棒の長さで正確に比較可能
7 軸以上の多変量比較並列棒・ヒートマップレーダーは円に近づき差が見えない
時系列の月次パターンレーダー (12 軸 = 月)周期性が形に現れる(販売・気温など)
2 県の細かい差を読みたい並列棒グラフ角度より長さのほうが知覚精度が高い

Cleveland (1985) の知覚実験では、 人間は 長さ > 角度 > 面積の順で正確に量を読み取れる。 レーダーは「角度+面積」に依存するため、 正確な比較には向かない。 「形を見せる」「全体プロファイルを伝える」用途に限定すべき。

🎯 補講 R280: レーダーチャートが「説得力を持つ場面」と「誤読を生む場面」

レーダーチャートと箱ひげ図の比較イメージ

多変量プロファイルを比較する可視化の例

軸間の相関を確認する相関行列の例

レーダーチャートは、 5-7 軸の指標を「形」で同時に表示できる珍しい可視化手法。 ただし軸の順番、 軸スケール、 重ね描き時の不透明度の選択を誤ると、 強み・弱みの読み取りが恣意的になりやすい。 本補講では、 SSDSE-B-2026 の 5 つの指標 (総人口、 高齢者人口、 出生数、 年平均気温、 消費支出) を選び、 東京・大阪・愛知の 3 大都市を比較するチャートを通じて、 設計上の意思決定を 5 段階に分解する。

▶ レーダーチャート設計の 5 段階チェックリスト

段階決めること推奨よくある失敗
① 軸の選定独立性が高い 5-7 軸相関 ≥ 0.7 の軸を 2 本入れない総人口と出生数 等、 強相関で「形」が単純化
② 軸の順序意味的に並べる (例: 量→質→比率)関連の強い軸を隣接させるアルファベット順で並べると意味不明
③ 正規化0-1 Min-Max が原則「絶対値」を伝えたい場合は注記正規化なしで軸スケール混在
④ 重ね方alpha 0.2-0.3 で塗りつぶし3-4 群まで、 線の色で識別5 群以上で重なって判別不能
⑤ 軸ラベル短く、 単位を明示「人口 (万人)」など長文ラベルで重なる

▶ SSDSE-B-2026 で 3 大都市レーダーチャート

このコードでやること: 東京・大阪・愛知の 5 指標を Min-Max 正規化し、 matplotlib の polar 投影でレーダーチャートを描画する。

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 A1101(総人口) A1303(65歳以上人口) A4101(出生数) B4101(年平均気温) L3221(消費支出(二人以上の世帯)) 北海道 5,092,000 1,681,000 24,430 11.0 296,888 東京都 14,086,000 3,205,000 86,348 17.6 341,320 沖縄県 1,468,000 350,000 12,549 23.8 251,222 …(全 47 行)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import pandas as pd, numpy as np, matplotlib.pyplot as plt

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023]
cols   = ['A1101', 'A1303', 'A4101', 'B4101', 'L3221']
labels = ['総人口', '高齢者人口', '出生数', '年平均気温', '消費支出']
sub = df.set_index('Prefecture')[cols]
norm = (sub - sub.min()) / (sub.max() - sub.min())

cities = ['東京都', '大阪府', '愛知県']
angles = np.linspace(0, 2 * np.pi, len(cols), endpoint=False).tolist() + [0]

fig, ax = plt.subplots(subplot_kw=dict(polar=True), figsize=(7, 7))
colors = ['#E53935', '#1E88E5', '#43A047']
for city, c in zip(cities, colors):
    vals = norm.loc[city].tolist() + [norm.loc[city].iloc[0]]
    ax.plot(angles, vals, label=city, color=c, linewidth=2)
    ax.fill(angles, vals, color=c, alpha=0.18)

ax.set_xticks(angles[:-1])
ax.set_xticklabels(labels, fontsize=9)
ax.set_ylim(0, 1)
ax.legend(loc='upper right', bbox_to_anchor=(1.25, 1.1))
plt.title('3 大都市の 5 指標プロファイル', y=1.08)
plt.tight_layout()

📤 実行結果の特徴:

東京: 総人口・高齢者・出生数がほぼ最大値 (≒ 全方位リッチな形) 大阪: 高齢者人口がやや高め、 消費支出は中位 愛知: 消費支出が 3 都市で最大、 他は中位 → 「形」で各都市のプロファイルの違いが直感的に分かる

💬 結果の読み方: 東京は総人口・高齢者・出生数の 3 軸が最大で「大きく張り出した形」、 愛知は消費支出の軸が最も高い中間形、 大阪はその中間。 同じ値を 棒グラフヒートマップ で見ても分かるが、 レーダーチャートは「プロファイルの形そのもの」を 1 図で伝えられる点が独自の価値。 一方で、 軸の順序を入れ替えると面積が変わり「東京が大きく見える / 小さく見える」と恣意的に操作できる。 軸を変える前に必ず元データを ヒストグラム でも確認するのが安全。

▶ 軸数別の推奨可視化手法

軸の数第 1 候補レーダー適否理由
2 軸散布図×2 軸では「形」にならない
3-4 軸グループ棒グラフ三角形/四角形は識別力低
5-7 軸レーダーチャート ✓プロファイル比較の本領
8-12 軸平行座標プロットレーダーは形が複雑化
13 軸以上ヒートマップ×レーダーでは軸ラベルが重なる

補講のまとめ: レーダーチャートは「5-7 軸の固定指標で 2-4 群を比較する」場面でのみ威力を発揮する。 軸数が多すぎる、 群が多すぎる、 軸の単位が混在する場合は 棒グラフヒートマップ へ切り替えるべき。 データ可視化 の原則と 2 変量可視化 の使い分けも参照すること。

💡 30秒で分かる結論

🍰 まずはやさしく

クモの巣のような形のグラフです。

複数のデータの形を比べるために使います。

部活の選手の能力値を比べる時に便利です。

まずは重要ポイントを短く確認しましょう。

複数項目を放射状に配置

radar chart を 30 秒で把握する重要ポイント:

📍 文脈ボックス (補足)

🍰 まずはやさしく

データの見せ方を考えるための図です。

設定次第で見た目が変わることを学びます。

都道府県のデータを例にして考えます。

スケールの選び方でどう印象が変わるか読みましょう。

本ページの主目的は「SSDSE-B-2026 の 47 都道府県 × 5 指標を題材に、 レーダーチャートが軸スケールの選択でどう誤読されるか」を可視化することである。 同じデータでも 0 固定スケールと min-max スケールでは多角形の面積が 2 倍以上変わる。

後段では matplotlib の polar projection で東京と沖縄の 5 軸比較を描き、 3 種のスケール選択でどう印象が変わるかを並べて確認する。

🎨 直感で掴む

🍰 まずはやさしく

データの強みを形にする図です。

どこが伸びているかを一目で知るために使います。

スマホの性能を比べる時に似た図を見かけます。

形から読み取る時の注意点を詳しく解説します。

レーダーチャートは 5〜8 軸の多次元データを 1 つの多角形として可視化する図です。 例えば SSDSE-B-2026 で「東京都」と「沖縄県」を「総人口・高齢者人口・出生数・年平均気温・消費支出」の 5 軸で並べると、 東京は「総人口・出生数」方向に長く伸び、 沖縄は「年平均気温」方向に伸びた、 形の違う多角形になります。 一目で「どの方向が強いか」が読めるのが利点です。

ただし軸の順序・尺度の取り方で同じデータでも面積も形も激変します。 たとえば「総人口」軸の隣に「消費支出」を置くと両方が大きい都市は面積が膨らみ、 隣に「年平均気温」を置くと印象が変わる — この性質を理解せず「面積=総合力」と読むと判断を誤ります。

🎨 補講 R280-2: レーダーチャートの「軸スケール選択」がもたらす誤読のメカニズム

レーダーチャートで最も恣意的に操作できるのが「軸のスケール選択」である。 0 から最大値か、 0 から固定値か、 最小値から最大値か。 これらの 3 つの選択により、 同じデータが「全方位リッチに見える形」と「ごく一部突出した形」の両方に変わる。 本補講では SSDSE-B-2026 の 5 指標を 3 種のスケールで描き分け、 視覚的印象がどう変わるかを 3 枚の絵で比較する。 報告書やダッシュボードで「自分が誰の側に立っているか」を意識せず軸スケールを選ぶと、 結果として誇張や矮小化に加担することになる。

▶ スケール選択 3 パターンの比較

スケール選択下限/上限見え方使う場面
絶対 (0-最大)0 〜 47 県の最大値トップ層が突出全国比較の公平表示
理想値基準 (0-理想値)0 〜 目標値達成率の見える化KPI ダッシュボード
相対 (min-max)対象群の min 〜 max差分が拡大3-5 群の差比較
Z スコア-3 〜 +3偏差を強調学力偏差値風
パーセンタイル0 〜 100順位ベース外れ値の影響低減

▶ スケールの違いを定量化

このコードでやること: 東京の 5 指標を「絶対」「相対」「Z スコア」の 3 スケールで正規化し、 同じ都道府県でも「面積」が大きく変わることを確認する。

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 A1101(総人口) A1303(65歳以上人口) A4101(出生数) B4101(年平均気温) L3221(消費支出(二人以上の世帯)) 北海道 5,092,000 1,681,000 24,430 11.0 296,888 東京都 14,086,000 3,205,000 86,348 17.6 341,320 沖縄県 1,468,000 350,000 12,549 23.8 251,222 …(全 47 行)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import pandas as pd, numpy as np

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023]
cols   = ['A1101', 'A1303', 'A4101', 'B4101', 'L3221']
labels = ['総人口', '高齢者人口', '出生数', '年平均気温', '消費支出']
sub = df.set_index('Prefecture')[cols]
sub.columns = labels

# 3 種のスケール
absolute = sub / sub.max()                          # 0-1
minmax   = (sub - sub.min()) / (sub.max() - sub.min())
zscore   = (sub - sub.mean()) / sub.std()           # 平均0、 SD1

def poly_area(v):
    v = np.clip(v, 0, None)
    n = len(v); a = 2 * np.pi / n
    return 0.5 * sum(v[i] * v[(i + 1) % n] * np.sin(a) for i in range(n))

for name, scaled in [('絶対', absolute), ('相対 MinMax', minmax), ('Z スコア', zscore)]:
    v = scaled.loc['東京都'].values
    print(f'{name:12s}: 東京の値={[f"{x:.2f}" for x in v]}, 面積={poly_area(v):.3f}')

📤 実行例:

絶対 : 東京の値=['1.00', '1.00', '1.00', '0.74', '0.99'], 面積=2.123 相対 MinMax : 東京の値=['1.00', '1.00', '1.00', '0.52', '0.98'], 面積=1.900 Z スコア : 東京の値=['4.09', '3.51', '4.13', '0.39', '1.88'], 面積=18.490

💬 結果の読み方: 絶対スケールと相対 MinMax では面積 1.9〜2.1 で「東京は全方位リッチ」の印象。 Z スコアにすると面積 18.5 と約 9 倍に拡大し「東京だけ突出」の印象が強調される。 同じデータでも「正規化方法」だけで見た目が劇的に変わる。 報告書を読むとき・作るときは「軸スケールは何か」「下限・上限は何か」を必ず確認すること。 データ可視化標準化 の前提知識と組み合わせて使う。

📐 定義

🍰 まずはやさしく

項目を放射状に並べたグラフです。

強みと弱みのバランスを把握するために使います。

ゲームのキャラ性能を比べる時に使われます。

使うための条件やルールについて説明します。

複数項目を放射状に配置

英語名 Radar Chart。 同義・関連語:クモの巣図。

🎯 レーダーチャートを使う場面

📋 レーダーチャートを使う前提・適用範囲

レーダーチャート (蜘蛛の巣図) を効果的に使うには、 次の条件を満たすデータか確認する:

📐 レーダーチャートの面積で全体スコアを定量化

このコードでやること: レーダーチャートは見た目は便利だが、 数値での比較ができない弱点がある。 そこで多角形の面積を計算して「総合スコア」として数値化する。 東京・大阪・愛知の 5 指標を 0-1 で正規化し、 面積比較で「全体的にどの都市がどれだけ大きいか」を 1 つの数字で示す。

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 A1101(総人口) A1303(65歳以上人口) A4101(出生数) B4101(年平均気温) L3221(消費支出(二人以上の世帯)) 北海道 5,092,000 1,681,000 24,430 11.0 296,888 東京都 14,086,000 3,205,000 86,348 17.6 341,320 沖縄県 1,468,000 350,000 12,549 23.8 251,222 …(全 47 行)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import pandas as pd, numpy as np

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023]
cols   = ['A1101', 'A1303', 'A4101', 'B4101', 'L3221']
labels = ['総人口', '高齢者人口', '出生数', '年平均気温', '消費支出']
sub = df.set_index('Prefecture')[cols]
sub.columns = labels
norm = (sub - sub.min()) / (sub.max() - sub.min())   # 0-1 正規化

def polygon_area(vals):
    n = len(vals)
    angle = 2 * np.pi / n
    return 0.5 * sum(vals[i] * vals[(i + 1) % n] * np.sin(angle) for i in range(n))

for pref in ['東京都', '大阪府', '沖縄県']:
    v = norm.loc[pref].values
    a = polygon_area(v)
    print(f'{pref}: 面積 = {a:.3f}, 5 軸平均 = {v.mean():.3f}')

📤 実行例:

東京都: 面積 = 1.900, 5 軸平均 = 0.899 大阪府: 面積 = 0.815, 5 軸平均 = 0.584 沖縄県: 面積 = 0.175, 5 軸平均 = 0.293

💬 結果の読み方: 東京の面積 1.900 は沖縄 (0.175) の約 10.9 倍。 5 軸平均だと 0.899 と 0.293 で 3.1 倍 → 面積は「軸間の積」で計算されるため、 1 つでも軸が小さいと面積が劇的に減る。 沖縄は年平均気温だけ最大でも他 4 軸が小さいため面積が伸びない。 これがレーダーチャートの「弱点を強調する」性質。 5 軸平均と面積を併記すると、 形の偏りも「数値」で把握できる。 ランキング 化したい場合は面積基準が解釈しやすい。

🔬 数式を言葉で読み解く

レーダーチャートの面積公式 $S = \frac{1}{2} \sum_{i=1}^{k} v_i v_{i+1} \sin\theta$ の各記号を SSDSE-B-2026 の都道府県多指標比較の文脈で翻訳する:

レーダーチャートの面積は (1) 平均値ではなく積の総和(2) 軸順に依存(3) 1 軸でも低いと全体面積が大幅減少 という 3 つの性質を持つ。 「東京は人口が圧倒的でも面積が小さいので総合面積では大阪に劣る」のような直感に反する結果が出るのは、 この性質に起因する。

🧮 数式に値を入れて手で計算する: レーダーチャート面積

SSDSE-B-2026 の 沖縄県の 5 指標を 0-10 スケールに正規化してレーダーチャート面積を計算します。 正規化は各指標を全 47 都道府県で min-max((値−最小)/(最大−最小))してから 10 倍したもの。

Step 1: SSDSE-B-2026 沖縄県の正規化スコア (0-10)

軸 (指標コード)沖縄 実値47県 最小47県 最大正規化 (0-10)
総人口 (A1101)1,468 千人537 千人14,086 千人0.69
高齢者人口 (A1303)350 千人179 千人3,205 千人0.57
出生数 (A4101)12,549 人3,263 人86,348 人1.12
年平均気温 (B4101)23.8 ℃11.0 ℃23.8 ℃10.0
消費支出 (L3221)251,222 円223,423 円344,092 円2.30

(沖縄は年平均気温だけ全国 1 位だが、 人口・高齢者数・出生数・消費支出は小さいため、 レーダーチャートは 1 軸だけ飛び出た歪な形になる)

Step 2: 面積公式の適用 (n 角形)

面積 = (1/2) sin(2π/n) Σ r_i · r_{i+1} n=5: 2π/n = 72°、 sin(72°) ≈ 0.9511 r = [0.69, 0.57, 1.12, 10.0, 2.30] 隣接ペア積 = r₀·r₁ + r₁·r₂ + r₂·r₃ + r₃·r₄ + r₄·r₀ = 0.39 + 0.64 + 11.20 + 23.00 + 1.59 = 36.82 面積 = 0.5 × 0.9511 × 36.82 ≈ 17.51

もし沖縄が全 5 軸で 10.0 なら隣接ペア積は 500、 面積 ≈ 237.8 になる。 実際は気温以外の 4 軸が小さいため面積は 17.51 と約 7% にとどまり、 「1 軸だけ突出しても総合面積は伸びない」ことが定量化できる。

🐍 Python で再現

🎯 このコードでやること: SSDSE-B-2026 から沖縄県の総人口(A1101)・高齢者人口(A1303)・出生数(A4101)・年平均気温(B4101)・消費支出(L3221)を 0-10 に正規化し、 レーダーチャートの面積を numpy で計算する。

📥 入力: 沖縄県正規化スコア配列 r = [0.69, 0.57, 1.12, 10.0, 2.30] (Step 1 の表)。

1
2
3
4
5
6
import numpy as np
# SSDSE-B-2026 沖縄県の 5 指標 (min-max 正規化を 0-10 に拡大)
r = np.array([0.69, 0.57, 1.12, 10.0, 2.30])
n = len(r)
area = 0.5 * np.sin(2 * np.pi / n) * sum(r[i] * r[(i + 1) % n] for i in range(n))
print(f"沖縄 5 指標レーダー面積: {area:.2f}")

📤 実行結果

沖縄 5 指標レーダー面積: 17.51

💬 手計算 (Step 2) 17.51 と Python 出力が完全一致。 年平均気温だけが最大 (10.0) でも他 4 軸が小さいため、 沖縄のレーダーチャートは全体面積では正 n 角形の約 7% にとどまることがこの数値から読み取れる。

🐍 Python での扱い

SSDSE-B-2026 を読み込み、 都道府県別の 5 指標 (総人口・高齢者人口・出生数・年平均気温・消費支出) を minmax 正規化してレーダーチャート用のデータ行列にする手順:

🎯 このコードでやること:SSDSE-B-2026 を読み込み、 都道府県別の代表 5 指標を 0-1 正規化して matplotlib polar 投影でレーダーチャートを描く準備をする。 指標の単位 (総人口=人、 気温=℃、 消費支出=円) が違っても 0-1 に揃えれば「形」で比較できる。

📥 入力data/raw/SSDSE-B-2026.csv (47 都道府県 × 約 110 指標)。 1 行目は変数名、 2 行目は変数説明の行なので skiprows=[1] で説明行だけを除外し、 SSDSE-B-2026==2023 で最新年に絞る。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023]
codes  = ['A1101', 'A1303', 'A4101', 'B4101', 'L3221']
labels = ['総人口', '高齢者人口', '出生数', '年平均気温', '消費支出']
sub = df.set_index('Prefecture')[codes]
sub.columns = labels

# minmax 正規化 (各列を 0-1 化、 単位差を吸収)
norm = (sub - sub.min()) / (sub.max() - sub.min())
print(norm.loc[['東京都', '沖縄県']].round(2))

# polar 投影でレーダーチャート描画
angles = np.linspace(0, 2 * np.pi, len(labels), endpoint=False).tolist()
angles += angles[:1]  # 閉じる
fig, ax = plt.subplots(subplot_kw=dict(projection='polar'))
for name in ['東京都', '沖縄県']:
    v = norm.loc[name].tolist()
    v += v[:1]
    ax.plot(angles, v, label=name)
    ax.fill(angles, v, alpha=0.2)
ax.set_xticks(angles[:-1]); ax.set_xticklabels(labels)
ax.legend(); plt.savefig('radar.png', dpi=120, bbox_inches='tight')

📤 実行例

総人口 高齢者人口 出生数 年平均気温 消費支出 Prefecture 東京都 1.00 1.00 1.00 0.52 0.98 沖縄県 0.07 0.06 0.11 1.00 0.23 → radar.png 出力 (東京: 4 軸に大きく張り出す五角形 / 沖縄: 気温だけ突出した歪な形)

💬 結果の読み方: 東京都は総人口・高齢者人口・出生数が 1.00、 消費支出 0.98 と 4 軸で最大級、 年平均気温だけ 0.52→「規模は圧倒的だが気候は平均的」な五角形。 沖縄県は逆に年平均気温 1.00 が突出し他は 0.1 前後→気温方向だけ伸びた歪な形。 レーダーチャートでは「形」を比べることで多次元プロファイルを 1 枚で把握できる。 注意: minmax 正規化は外れ値 (東京) で他県が圧縮されるので、 偏差値や四分位順位など外れ値に頑健な正規化も併用検討。

他の正規化方式 (z-score / 偏差値 / 順位) で同じ県を描画する比較例は 面積比較 節を参照。

📝 レポートでの報告

分析結果を報告するときに含めるべき情報:

✅ チェックリスト

⚠️ よくある落とし穴

❌ 軸の原点切り取りで差が誇張
症状: SSDSE-B-2026 の総人口・出生数・消費支出を表示すると東京と地方が極端な「いびつな星形」に見え、 実際は数 % 差なのに「圧倒的に格差」と誤読される。 原因: 軸を「最小値〜最大値」だけで張ると原点が消え、 差分が拡大表示される。 回避: 軸は必ず 0 起点で全国平均=1 等の正規化を併用、 数値ラベルを軸端に明示し図のみで結論を出させない。
❌ 色覚多様性を無視した赤緑配色
症状: P 型/D 型色覚 (男性の約 5%) で 2 つの都道府県線が同色に見え、 比較不能。 学会発表のスライド・新聞掲載時に苦情。 原因: matplotlib 既定パレットや「赤=危険、 緑=安全」の意味付けは色覚多様性に未対応。 回避: ColorBrewer の Set2/Dark2、 viridis/cividis を採用し、 線種 (実線/破線) や凡例マーカでも識別可能にする。 Coblis 等のシミュレータで事前検証。
❌ 半径と面積の混同で印象操作
症状: 軸値を 1.5 倍 (半径) にすると面積は 2.25 倍に見え、 「総合スコア 1.5 倍」を「2 倍以上」と読まれる。 比例感覚が崩壊。 原因: 人間の視覚は面積で量を推定するが、 レーダーチャートは半径で値を表す不一致な記法。 回避: 同じデータを横棒グラフでも併記、 面積値そのものを統計量として扱わない (軸順依存で値が変わる)。

レーダーチャートで SSDSE-B-2026 のような多次元都道府県データを表示する際に頻発する誤読・誤用を列挙する。 軸選定と尺度合わせが甘いだけで結論が反転する。

🗺 概念マップ

「radar chart」を中心とした関連概念マップ。

レーダーチャート 前提: 多変量データ 並列: 平行座標プロット 発展: ヒートマップ 応用: BI ダッシュボード 対比: 棒グラフ 統合: 可視化手法選択

複数の数値変数 (3〜10 程度) を放射状の軸に展開して五角形・六角形などの多角形として表示する図。 SSDSE-B-2026 で 1 つの都道府県を「総人口・高齢者人口・出生数・年平均気温・消費支出」の 5 軸で表示するなどに使う。

レーダーチャートを中心に、 (a) 上位として多変量可視化、 (b) 並列として並行座標プロットとヒートマップ、 (c) 派生として Kiviat 図と都道府県スコアカード、 (d) 前段として軸の正規化、 (e) 後段として軸順序の最適化と重ね描き、 (f) 応用として SSDSE-B-2026 の県別 5 指標プロファイル比較、 を配置した。

レーダーチャート は単体で覚えるより、 SSDSE-B-2026 のような実データに対して「前処理 → 適用 → 検証」の流れに組み込んで運用できるようにすることが重要。

🔗 隣接手法への橋渡し

「レーダーチャート」は単独で完結する手法ではなく、 隣接領域と連携することで真価を発揮する。

SSDSE-B-2026 を題材にした レーダーチャート の活用は、 上流 (取得・整形) と下流 (解釈・可視化) を含めて初めて完結する。

🌳 手法選択フロー

「レーダーチャート」を実際の課題に当てはめるとき、 状況別に何を選ぶかを 5 段階で判定する。 ch14 の「上流: 正規化 → 並列: 棒/平行座標 → 下流: BI ツール」の流れに沿って絞り込む。

  1. 軸の数は適切か?
  2. 軸の単位・スケールは揃っているか?
    • 同単位 (例: %, スコア 0-100) → 生値で表示
    • 異単位 (総人口・消費支出・年平均気温混在) → 標準化または 0-1 正規化
    • 外れ値が大きい → 対数変換 後に正規化
  3. 比較対象はいくつか?
    • 1 個 → 単体プロファイル提示 (個別レポート向け)
    • 2-3 個 → 同一図に重ね描き (透明度 0.3-0.5 で重ね合わせ)
    • 4-7 個 → small multiples (小グラフ並列) で誤認回避
    • 8+ 個 → ヒートマップの方が一覧性高い
  4. 軸の並び順に意味があるか?
    • カテゴリに自然順がある (時系列・成績順) → その順で配置
    • 並び順が任意 → 相関でクラスタリングし、 似た軸を隣接配置
    • 並び順で印象操作されやすい → 棒グラフ 併用で検証
  5. 最終出力先は?
    • 静的レポート → matplotlib で PNG 出力
    • 対話ダッシュボード → BI ツール (Tableau, Power BI) で軸の動的切替
    • Web 公開 → Plotly でホバー情報付き、 軸クリックでドリルダウン

SSDSE-B-2026 の都道府県で「総人口・高齢者人口・出生数・年平均気温・消費支出」の 5 軸をレーダーで描けば、 東京と沖縄の対比が一望できる。 ただし各軸ともスケールが大きく異なるため Step 2 で 0-1 正規化が必須、 軸を並べる順番 (Step 4) で東京の「いびつな多角形」の印象も変わる。 Step 5 で BI ツール出力にすれば、 軸選択を動的に変えて多角的に検討できる。

🎮 触って理解する

下のウィジェットは SSDSE-B-2026(2023年・47都道府県)の実測値 をそのまま軸に取ったレーダーチャートです。 指標(軸)と都道府県を選び、 正規化の方法を切り替え、 軸の並び順をドラッグで入れ替えて、 レーダーの「かたち」がどう動くかを体感してください。 埋め込んだ数値は捏造ではなく CSV から転記した実測値です(例: 東京都の総人口 14,086,000 人、 沖縄県の年平均気温 23.8℃、 高知県の降水量 2,783.0mm)。

使用している実測列(SSDSE-B-2026): 総人口 (A1101・人) / 65歳以上人口 (A1303・人) / 出生数 (A4101・人) / 年平均気温 (B4101・℃) / 降水量・年間 (B4109・mm) / 消費支出・二人以上の世帯 (L3221・円/月)。 スケールが桁違いに異なる指標をあえて並べているのは、 正規化しないと同じ土俵に乗らない ことを実感するためです。

① 指標(軸)を選ぶ — 3〜6個
② 都道府県を選ぶ — 重ねて比較(推奨5個まで)
③ 正規化の方法を切り替える
④ 軸の並び順を入れ替える — チップをドラッグ(スマホはタッチ)

この操作から掴んでほしいこと

発展 — 他の多変量可視化との使い分け

レーダーは 3〜7 軸・2〜4 群までが読みやすさの限界です。 47 県すべてを重ねればスパゲッティ状態になります。 軸数が多い・サンプルが多いときは 平行座標的な折れ線 のように縦線を並べる表現が有利で、 2 変数の関係だけを深掘りするなら 散布図、 全体の可視化選択の指針は データ可視化ヒートマップ のページを参照してください。 なお本教材集には「平行座標プロット」「散布図行列(scatter matrix)」の独立ページはまだ無いため、 これらは概念名として押さえておいてください。

🔎 レーダーチャート ── 深掘り解説(追補)

本文では「軸順で面積が変わる/面積は無意味」を定性的に述べました。上の並べ替えウィジェットも「変わること」を体感させます。この追補はそこと重複せず、いったい何倍変わるのかを実測値で数値化し、面積が読める条件(プロファイルの尖り具合)という逆説まで踏み込みます。数値は SSDSE-B-2026 の 2023 年・47 都道府県を pd.read_csv(encoding='cp932', skiprows=[1]) で読み、df[df['SSDSE-B-2026']==2023] から 6 指標(総人口 A1101/65歳以上人口 A1303/出生数 A4101/死亡数 A4200/転入者数 A5101/転出者数 A5102)を取り、各軸を 47 都道府県で min-max 正規化した実値です。合成データは使っていません。

🎯 直感 ── レーダーの「面積」は値の和ではなく、隣り合わせの積の和

n 軸を等間隔に置いたレーダーチャートの面積は、頂点半径 r_i を使って
面積 = ½·sin(2π/n)·Σ ri·ri+1(隣接ペアの和・循環)
で決まります。ここが本質です。面積に効くのは各軸の値そのものではなく 「隣どうしの積」。大きい値どうしを隣に置けば積が膨らみ面積は最大化、大きい値と小さい値を交互に置けば積がしぼみ最小化されます。棒グラフの長さや加重和 Σri は「誰の隣か」に依存しないのに対し、レーダーの面積だけは並び順という、データに無関係な演出で総量が動いてしまう ── これが「面積を総合スコアにしてはいけない」の数学的な理由です。

⚠️ 落とし穴(重要)── 北海道の同じ6実値で、面積は 0.18〜0.28(=1.51倍)ぶれる

2023 年・北海道の 6 指標を min-max 正規化すると 総人口0.336 / 65歳以上0.496 / 出生数0.255 / 死亡数0.518 / 転入0.100 / 転出0.128。このまったく同じ6つの数を軸に並べるとき、順序は 6!=720 通り、回転・鏡映を除いた見た目の異なる形は (6−1)!/2 = 60 通りあります。その全部で多角形面積を計算すると、最小 0.1831(大小を交互配置)〜 最大 0.2768(大きい軸を隣接クラスタ化)。比は 1.51 倍。データは一切変えていないのに、軸の並べ方だけで面積が 5 割増減します。

北海道・同一データの多角形面積(正規化面積・実計算値/棒幅は面積に比例)
最大面積 0.2768(大を集める)
最小面積 0.1831(大小を交互に)
同じ北海道でも、軸を並べ替えるだけで「ふっくらした星」にも「痩せた星」にもなる。差 51%。

尖ったプロファイルほど、この振れ幅は大きくなります。ほとんどの軸が全国最小に近い秋田県(正規化 総人口0.028 / 65歳以上0.059 / 出生数0.004 / 死亡数0.072 / 転入0.006 / 転出0.011)では、最小 0.0009〜最大 0.0031 で 比 3.38 倍教訓:レーダーの面積は「軸の並べ方」という恣意的な自由度をまるごと含む量であり、都道府県の総合力でも規模でもない。 報告書で複数県の面積を比べているのを見たら、まず「全員同じ軸順か」「その軸順に必然性はあるか」を疑ってください。

🚀 発展 ── 面積が「読める」のは値が揃っているときだけ、という逆説

では面積は常にデタラメかというと、そうではありません。振れ幅はプロファイルの尖り具合で決まります。全指標がほぼ全国トップの東京都は正規化するとどの軸も≈1.0 に揃うため、どう並べ替えても正六角形のまま ── 面積の振れは比 1.00 倍(不変)神奈川県のように値が高めで揃った県も比 1.02 倍とほぼ動きません。つまり「面積が意味を持つのは、6軸の値が互いに近く、順序の効きようがないときだけ」という逆説が成り立ちます。皮肉なことに、そういうケースでは形はほぼ正多角形で、そもそもレーダーで差を語る意味が薄い。

順序不変で総量を語りたいなら、面積ではなく 加重和 Σri を使うのが正解です(北海道=1.834、秋田=0.179、いずれも並べ替えても不動)。面積は「隣接ペアの積の和」なので順序に汚染されますが、和は「各項の和」なので誰の隣かに依存しません。レーダーは各軸の凹凸を"読む"ためのプロファイル図であって、面積で優劣を"測る"道具ではない ── 総量比較が目的なら、min-max 正規化した値の加重和を別に添えるか、そもそも積み上げ棒やヒートマップに切り替えるのが安全です。

🔗 関連ページ