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

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

言語 JA

バブルチャートで第三の変数を表現

入門

06.5.2

バブルチャートで第三の変数を表現

最終更新 2020-02-12 読了時間 2 分
まとめ
バブルチャートは、散布図の横軸と縦軸に加えて、点の面積で 3 つ目の変数を表す図です。matplotlib では ax.scatter(x, y, s=サイズ) の s に 3 つ目の変数を渡すだけで、s はポイントの 2 乗で測った面積なので値をそのまま渡せば面積が値に比例します。この章では Enterprise から Consumer まで 5 つのセグメントの売上(横)・利益率(縦)・顧客数(面積)を 1 枚に収め、ax.text でラベルを点の中央に書き、fig.colorbar で色の意味を添えます。読み終えると、45 から 520 までの顧客数が面積としてどう見えるか、半径に値を渡すと差が 2 乗で誇張される理由、大きなバブルが小さなバブルを隠すときの対処が分かります。

先に 散布図の基本形 で 2 変数の点の打ち方を見ておくと、この章で増えるのが s と c の 2 引数だけだと分かります。

直感 #

5 つの顧客セグメントについて、売上は Enterprise の 320 百万円が最大、利益率も Enterprise の 28% が最大、しかし顧客数は Consumer の 520 社が最大だとします。売上と利益率の散布図だけでは Consumer は左下の小さな点に見え、「顧客数が最も多いセグメント」という事実が消えてしまいます。バブルチャートは点の面積を顧客数に比例させるので、左下に大きな円、右上に小さな円が置かれ、「売上と利益率は低いが客数は多い」と「客数は少ないが 1 社あたりが大きい」の対比が 1 枚で読めます。面積で表すのは、人の目が円の大きさを半径ではなく面積で感じ取るためで、半径を 2 倍にした円は 4 倍大きく見えます。

何が起きているか(ステップで見る) #

コードを読む前に、この手法が図の上で何をしているかを追ってみましょう。「再生」を押すか、スライダーを動かすと 1 手順ずつ進みます。

見るポイント:r は「直線に沿う強さ」。曲線的な関係や外れ値があると、r だけでは関係を見誤る。

Python で描く #

次のコードは、5 セグメントの売上を横軸、利益率を縦軸に置き、顧客数を s に渡して面積にします。色 c にも利益率を使って Blues のカラーマップで塗り、セグメント名を ax.text で円の中央に書き、fig.colorbar で色の意味を右側に添えます。

 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
import numpy as np
import matplotlib.pyplot as plt

segments = ["Enterprise", "SMB", "Startup", "Consumer", "Partner"]
revenue = np.array([320, 180, 90, 70, 150])
margin = np.array([28, 22, 15, 12, 20])
customers = np.array([45, 110, 260, 520, 160])

fig, ax = plt.subplots(figsize=(6, 4))
scatter = ax.scatter(
    revenue,
    margin,
    s=customers,
    c=margin,
    cmap="Blues",
    alpha=0.7,
    edgecolors="#1f2937",
)

for x, y, label in zip(revenue, margin, segments):
    ax.text(x, y, label, fontsize=10, ha="center", va="center")

ax.set_xlabel("売上(百万円)")
ax.set_ylabel("利益率(%)")
ax.set_title("セグメント別 売上・利益率・顧客数")
ax.grid(alpha=0.3)

cbar = fig.colorbar(scatter, ax=ax)
cbar.set_label("利益率(%)")

fig.tight_layout()

plt.show()

売上(x 軸)、利益率(y 軸)、顧客数(バブルサイズ)の 3 変数を同時に表示する例ですの図

実行結果の読み方 #

右上に小さく濃い Enterprise(売上 320、利益率 28%、顧客 45 社)、左下に大きく淡い Consumer(売上 70、利益率 12%、顧客 520 社)が置かれ、売上・利益率と顧客数が逆方向に並ぶ構図が見えます。SMB と Partner は中央付近で面積が 110 と 160 と近く、円の大きさの差は目でぎりぎり区別できる程度です。面積の差が 1.5 倍以下になると人の目は正確に見分けられないので、顧客数の細かい比較は図ではなく表に任せ、バブルは「桁が違う」ことを伝える役割と割り切ります。

使いどころと落とし穴 #

バブルチャートが向くのは、売上・利益率・顧客数のように 3 つの連続変数を同時に比べ、第 3 の変数の桁の違いを直感的に伝えたい場面です。変数が 4 つ以上になると c に 4 つ目を載せても読みきれないので、散布図行列 やパラレルコーディネートに切り替えます。落とし穴の 1 つ目は面積と半径の混同で、s は面積なのに「半径を顧客数にしたい」と s=customers**2 のように渡すと、Consumer と Enterprise の面積比が 133 倍に跳ね上がります。2 つ目はバブルの重なりで、面積 520 の円が近くの小さな円を完全に覆うことがあるため、alpha を 0.7 以下にするか、np.argsort(customers)[::-1] の順で大きい円から先に描いて小さい円を前面に出します。