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

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

言語 JA

二軸グラフで異なる指標を同時に表示

中級

06.4.4

二軸グラフで異なる指標を同時に表示

最終更新 2020-03-11 読了時間 2 分
まとめ
二軸グラフは、売上(百万円)と CVR(%)のように単位も桁も違う 2 つの指標を、左右に別々の縦軸を立てて同じ時間軸に重ねる図です。ax2 = ax1.twinx() で X 軸を共有し Y 軸だけ独立した 2 つ目の Axes を作り、それぞれに plot すれば 120〜210 の売上と 2.3〜3.2 の CVR が同じ高さの範囲に収まります。この章では 4 月から 9 月の 6 か月で両方が伸びる例を描き、軸ラベルと目盛りの色を線に揃える方法と、2 つの Axes に分かれた凡例を 1 つにまとめる方法を扱います。読み終えると、二軸が「関係がありそうに見せてしまう」図でもあることを理解し、set_ylim の根拠を示す、または正規化や上下 2 段の図に切り替える判断ができるようになります。

先に 複数ラインの推移比較 で同じ軸に 2 本を重ねる基本形を見ておくと、「なぜ軸を分ける必要があるか」がはっきりします。

直感 #

売上は 6 か月で 120 から 210 百万円に伸びました。同じ期間に CVR は 2.3% から 3.2% に上がっています。この 2 つを 1 本の縦軸に描くと、CVR の線は 0 付近に貼り付いた平らな線になり、上がったのか下がったのかさえ読めません。二軸グラフは左の軸を売上用、右の軸を CVR 用に分け、それぞれの範囲いっぱいに線を広げます。結果として 2 本の線が同じくらいの高さで並び、「売上が伸びた月に CVR も伸びているか」という同時性を目で追えるようになります。ただし右軸の範囲を変えれば CVR の線の傾きは自由に変わるので、見た目の「連動」は軸の取り方しだいでもあります。

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

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

見るポイント:折れ線でも軸の始点で印象が変わる。傾向を見たいなら移動平均を重ね、元データは薄く残す。

Python で描く #

次のコードは、ax1 に売上を青の丸マーカーで、ax1.twinx() で作った ax2 に CVR を橙の四角マーカーで描きます。左右の軸ラベルと目盛りの色を線の色に揃え、2 つの Axes に分かれた凡例を ax1.legend(lines, labels) で 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
26
27
import numpy as np
import matplotlib.pyplot as plt

months = ["Apr", "May", "Jun", "Jul", "Aug", "Sep"]
revenue = np.array([120, 140, 160, 180, 195, 210])
conversion = np.array([2.3, 2.5, 2.7, 2.9, 3.0, 3.2])

fig, ax1 = plt.subplots(figsize=(6.5, 4))
ax2 = ax1.twinx()

ax1.plot(months, revenue, marker="o", color="#2563eb", label="売上")
ax2.plot(months, conversion, marker="s", color="#f97316", label="CVR")

ax1.set_ylabel("売上(百万円)", color="#2563eb")
ax1.tick_params(axis="y", labelcolor="#2563eb")
ax2.set_ylabel("CVR(%)", color="#f97316")
ax2.tick_params(axis="y", labelcolor="#f97316")
ax1.set_title("売上とコンバージョン率の推移")

lines = ax1.get_lines() + ax2.get_lines()
labels = [line.get_label() for line in lines]
ax1.legend(lines, labels, loc="upper left")
ax1.grid(axis="y", alpha=0.3)

fig.tight_layout()

plt.show()

Axes.twinx() を使って右軸を追加しますの図

実行結果の読み方 #

青の売上は 120 から 210 へ 1.75 倍、橙の CVR は 2.3 から 3.2 へ 1.39 倍になり、どちらも 6 か月間ずっと右上がりです。2 本がほぼ並行に見えるのは、matplotlib がそれぞれの軸の範囲をデータの最小・最大に合わせて自動で決めた結果であって、伸び率が同じという意味ではありません。たとえば ax2.set_ylim(0, 10) と右軸を広げると、CVR の線は下のほうで寝た線になり、同じデータでも「売上だけが伸びている」印象に変わります。

使いどころと落とし穴 #

二軸グラフが向くのは、売上と CVR のように単位の異なる 2 指標を同じ月の軸で並べ、「伸びた時期が重なっているか」を確かめる場面です。3 指標以上になると軸を 3 本立てるわけにいきません。その場合は StandardScaler などで各系列を正規化して 1 本の軸に重ねるか、plt.subplots(nrows=2, sharex=True) で上下 2 段に分けます。最大の落とし穴は、set_ylim を調整すれば無関係な 2 指標でもぴったり重なって見えることで、右軸の範囲を変えた理由を注釈や本文に書く、または正規化した図を添えるのが対策です。もう 1 つは因果の誤認で、6 か月とも一緒に上がっているという事実は「CVR が上がったから売上が伸びた」を示しません。「相関であって因果ではない」と断る一文を図の下に添えておくと、読者が二軸の重なりだけで因果を結論づけるのを防げます。