K_DM Book
用語集
対象者 標準
対象者別の入口 →

対象者の設定はこのブラウザの中にだけ保存されます。

言語 JA

バレットチャートで目標達成度を凝縮表示

中級

06.7.8

バレットチャートで目標達成度を凝縮表示

最終更新 2020-05-06 読了時間 2 分
まとめ
バレットチャートは、1 本の横棒に「実績」「目標」「評価の段階」の 3 つの情報を重ねて、KPI の達成状況を 1 行で伝える図です。背景に 3 段階の帯(この例では base / good / excellent)を敷き、その上に細い実績バーを載せ、目標値を赤い縦線で刺すことで、ゲージやメーターよりはるかに省スペースで同じ内容を表せます。matplotlib では ax.barh を帯の数だけ重ね描きし、ax.plot で短い縦線を引くだけで作れます。読み終えると、CVR 4.6% が目標 5.0% にどれだけ足りないかを帯の色と線の位置から読み取り、自分の KPI の帯の境界値を決めて同じ図を描けるようになります。

直感 #

週次レポートで「CVR は 4.6%、目標 5.0%、客単価は 12,300 円で目標 12,000 円を超過」と 4 つの KPI を文章で並べると、どれが順調でどれが遅れているかを読者が頭の中で計算することになります。バレットチャートはこの計算を図に肩代わりさせます。横棒の長さが実績 actual、赤い縦線が目標 target なので、棒が線を越えていれば達成、届いていなければ未達が一目で分かります。さらに背景の帯を薄いグレーから濃いグレーへ 3 段階に塗っておくと、「未達でも good 帯には入っている」「達成しているが excellent にはまだ遠い」といった程度まで同時に読めます。

Python で描く #

次のコードは 4 つの KPI について、thresholds に入れた 3 つの境界値で背景帯を描き、actual の実績バーと target の目標線を重ねます。指標ごとに単位が違う(CVR は 0.046、客単価は 12,300)ため、1 つの X 軸に無理に載せている点に注意して読んでください。

 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
38
39
40
41
42
43
44
45
46
47
import matplotlib.pyplot as plt
import numpy as np

metrics = ["CVR", "客単価", "サブスク継続率", "NPS"]
actual = np.array([0.046, 12_300, 0.78, 32])
target = np.array([0.05, 12_000, 0.8, 35])
thresholds = np.array(
    [
        [0.02, 0.04, 0.06],
        [9000, 11_000, 13_500],
        [0.6, 0.75, 0.85],
        [10, 25, 40],
    ]
)

fig, ax = plt.subplots(figsize=(6.2, 4))
for idx, name in enumerate(metrics):
    base, good, excellent = thresholds[idx]
    ax.barh(idx, excellent, color="#f1f5f9", height=0.8)
    ax.barh(idx, good, color="#cbd5f5", height=0.8)
    ax.barh(idx, base, color="#94a3b8", height=0.8)
    ax.barh(idx, actual[idx], color="#38bdf8", height=0.3)
    ax.plot(
        [target[idx], target[idx]],
        [idx - 0.4, idx + 0.4],
        color="#ef4444",
        linewidth=2,
    )
    ax.text(
        actual[idx] * 1.02,
        idx,
        f"{actual[idx]:.2f}" if idx != 1 else f"{actual[idx]:,.0f}",
        va="center",
        ha="left",
        fontsize=9,
    )

ax.set_yticks(range(len(metrics)), labels=metrics)
ax.set_xlabel("指標の値")
ax.set_title("主要KPIの進捗(バレットチャート)")
ax.set_xlim(0, max(thresholds[:, -1]) * 1.05)
ax.grid(axis="x", alpha=0.2)
ax.spines[["right", "top"]].set_visible(False)

fig.tight_layout()

plt.show()

帯の背景に基準領域を敷くことで、達成度のレベルも同時に伝えられますの図

実行結果の読み方 #

水色の実績バーが赤い縦線を越えていれば目標超過、届いていなければ未達です。客単価は 12,300 円のバーが目標線 12,000 円を右に越えており、唯一の達成項目と読めます。背景の帯は左から濃いグレー(base)、薄いグレー(good)、ほぼ白(excellent)の順で、バーの先端がどの帯にあるかで「未達でも許容範囲か」が分かります。この例のように単位の異なる指標を 1 枚に載せると、スケールの小さい CVR や NPS の帯が 0 付近に潰れてしまうので、読み方を確認したら指標ごとに軸を分ける改良を試してください。

使いどころと落とし穴 #

バレットチャートが活きるのは、週次レポートやダッシュボードで 3〜8 個の KPI を 1 枚に並べ、実績と目標と評価段階を同時に見せたいときです。帯を 4 段階以上にすると #f1f5f9 と #cbd5f5 のようなグレーの差が見分けられなくなるので、3 段階までに抑えます。帯の意味(base / good / excellent)を凡例か注釈で書かないと、読者はグレーの濃淡を飾りと受け取るので、ax.text で帯の名前を添えるか凡例を付けてください。目標線が背景やバーと同化すると最も大事な情報が消えるため、赤のようなコントラストの強い色と linewidth=2 以上の太さを保ちます。達成率だけを示したいなら、進捗バーや単純な棒グラフの方が説明なしで伝わります。