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

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

言語 JA

ストリームグラフで構成比のうねりを見る

中級

06.7.10

ストリームグラフで構成比のうねりを見る

最終更新 2020-06-03 読了時間 2 分
まとめ
ストリームグラフは、積み上げ面グラフの基準線を 0 に固定せず、全体の揺れが最小になるように上下に動かして、各カテゴリの厚みの変化を川の流れのような滑らかな帯で見せる図です。基準線が水平でないため個々の値は読みにくくなりますが、「昼の時間帯に SNS の帯が太る」といった構成の推移を有機的な形として伝えられます。matplotlib では ax.stackplot(x, stacked, baseline="wiggle") の baseline 引数を変えるだけで、"zero"(通常の積み上げ)から "wiggle"(ストリーム)に切り替わります。読み終えると、位相を 3 時間ずつずらした 4 チャネルの波がどう重なるかを理解し、baseline を "sym" や "weighted_wiggle" に変えて自分の構成比データで試せるようになります。

直感 #

Web サイトへの流入を 24 時間 × 4 チャネル(自然検索・広告・SNS・紹介)で記録し、「どの時間帯にどのチャネルが太いか」を見たいとします。通常の積み上げ面グラフは下端を 0 に固定するので、一番下のカテゴリは読みやすいが上に積まれたカテゴリは下の揺れに振り回されます。ストリームグラフは下端を固定せず、全体の中心が水平に近くなるように基準線を上下させます。すると各チャネルは自分の厚みだけで描かれた帯になり、太る時間帯と細る時間帯が川の支流のように読めます。全体の総量は上端と下端の距離で読み、wiggle の中心線が水平なら総量が安定していることになります。

Python で描く #

次のコードは、周期 12 時間の正弦波の位相を 3 時間ずつずらした 4 チャネルの系列を作り、stackplot の baseline="wiggle" で上下に揺れる積み上げとして描きます。チャネル名は凡例で示します。

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

x = np.arange(0, 24)
rng = np.random.default_rng(24)
segments = []
for phase in range(4):
    trend = 12 + 6 * np.sin(2 * np.pi * (x + phase * 3) / 12)
    noise = rng.normal(0, 1.2, size=x.size)
    segments.append(np.clip(trend + noise, 0, None))
stacked = np.vstack(segments)

fig, ax = plt.subplots(figsize=(6.4, 4))
colors = ["#0ea5e9", "#22d3ee", "#818cf8", "#f472b6"]
ax.stackplot(x, stacked, baseline="wiggle", colors=colors, alpha=0.9)
ax.set_xticks(range(0, 24, 3), labels=[f"{h}時" for h in range(0, 24, 3)])
ax.set_title("チャネル別流入構成のストリームグラフ")
ax.set_ylabel("セッション数")
ax.set_xlabel("時間帯")
ax.spines[["right", "top"]].set_visible(False)
ax.grid(axis="x", alpha=0.15)

legend_labels = ["自然検索", "広告", "SNS", "紹介"]
ax.legend(legend_labels, loc="upper left", frameon=False)

fig.tight_layout()

plt.show()

上下対称の波で割合の変化が視覚的になりますの図

実行結果の読み方 #

4 色の帯の厚みがそのチャネルのセッション数で、厚くなる時間帯がそのチャネルのピークです。位相を 3 時間ずつずらしているので、4 つの帯のピークが 3 時間ごとに順番に現れ、全体として「流れの中心が入れ替わる」形になります。帯の上端と下端の距離が総量で、baseline="wiggle" によって中心が上下に揺れるため、個々の帯の値を Y 軸の目盛りから直接読むことはできません。SNS の帯が昼に厚くなっていれば、投稿の拡散タイミングと流入のずれを調べる手がかりになります。

使いどころと落とし穴 #

ストリームグラフは、音楽ジャンルの人気や流入チャネルの構成のように、5〜10 カテゴリの構成比が時間とともに入れ替わる様子を「印象として」伝えたいプレゼン向きの図です。基準線が揺れるので個別の値を正確に読む用途には向かず、定量的な比較が必要なら baseline="zero" の積み上げ面グラフか、100% 積み上げに切り替えてください。データ点が 24 点程度と少ないと帯の輪郭がカクカクするため、pd.Series.rolling(3).mean() などで平滑化した系列を渡すと滑らかな川の形になります。変動の大きいカテゴリを segments の中央に置くと全体が大きく揺れて見えるので、安定したカテゴリを中央、変動の大きいものを外側に並べると図が落ち着きます。