seaborn

【Seaborn】2軸のグラフを作成する

MAX

スケールの異なるデータを1つのグラフにまとめたい時などは、y軸を左右の両方に作成すると見やすくなる。

2軸グラフを作成する場合、matplotlibでも作成可能だが、seabornの方がより簡単に見やすいグラフを作成できるため、seabornで作成する。

スポンサーリンク

データ準備

以下のようなスケールの異なるデータを例とする。

1import pandas as pd
2
3import matplotlib.pyplot as plt
4import seaborn as sns
5
6sns.set(font="meiryo")
7
8date_list = ["2020/1/1", "2020/2/1", "2020/3/1", "2020/4/1", "2020/5/1"]
9values = [[1, 150], [2, 140], [3, 130], [5, 120], [8, 110]]
10
11df = pd.DataFrame(data=values, index=date_list, columns=["colA", "colB"])
12# インデックスを日付型に変換
13df.index = pd.to_datetime(df.index)
14print(df)
15
16#             colA  colB
17# 2020-01-01     1   150
18# 2020-02-01     2   140
19# 2020-03-01     3   130
20# 2020-04-01     5   120
21# 2020-05-01     8   110

colAはフィボナッチ数列。colBは10ずつ減少。

スケールの異なるグラフ(1軸)

特にy軸の設定を何もしなければ、2つのcolAとcolBを同じグラフに描画すると、以下のようになる。

1fig = plt.figure(figsize=(12, 6.75), facecolor="w")
2# x軸の値設定
3x = df.index.strftime("%Y-%m").to_list()
4# 折れ線グラフ描画
5sns.lineplot(data=df, x=x, y="colA", color="red", label="colA")
6sns.lineplot(data=df, x=x, y="colB", color="blue",label="colB")
7plt.title("スケールの違うグラフ例")
8plt.tight_layout()
9plt.show()

一方は0付近、もう一方は100ちょいにあることは分かるが、分かりにくい。

2軸グラフ

y軸を左右でcolAとcolBに分ける。

subplots()で作成されたaxをtwinx()でコピーする。

seabornでグラフを作成する時に、引数axにそれぞれax1、ax2を設定する。

1fig = plt.figure(figsize=(12, 6.75), facecolor="w")
2
3ax1 = fig.subplots()
4# ax1のx軸をコピー
5ax2 = ax1.twinx()
6# x軸の値設定
7x = df.index.strftime("%Y-%m").to_list()
8# 折れ線グラフ描画
9sns.lineplot(data=df, x=x, y="colA", ax=ax1, color="red", label="colA")
10sns.lineplot(data=df, x=x, y="colB", ax=ax2, color="blue",label="colB")
11
12# 各y軸の範囲を設定
13ax1.set_ylim(0, 10)
14ax2.set_ylim(100, 180)
15# ax2のグリッド線を非表示にする
16ax2.grid(False)
17# 凡例を取得
18handler1, label1 = ax1.get_legend_handles_labels()
19handler2, label2 = ax2.get_legend_handles_labels()
20# ax1で凡例をまとめて表示
21ax1.legend(handler1 + handler2, label1 + label2, loc="upper center")
22# ax2の凡例は削除
23ax2.get_legend().remove()
24
25plt.title("2軸グラフ例")
26plt.tight_layout()
27plt.show()

y軸を分けたことで、colBは直線だが、colAは直線ではないことが分かる。

なお、左右の軸のグリッド線を合わせるためには、目盛の設定を合わせる必要があるため、どうしても必要という場合でなければ、どちらか一方のグリッド線を消す方がラク。

無理にグリッド線を合わせるよりも、2種類のグラフの特徴がよく分かるような目盛に設定する方が良い。

2軸グラフ(棒グラフと折れ線グラフ)

2軸グラフを作成する場合、2種類のグラフが混じるため、グラフの種類を変えた方が分かりやすいことが多い。

1fig = plt.figure(figsize=(12, 6.75), facecolor="w")
2
3ax1 = fig.subplots()
4# ax1のx軸をコピー
5ax2 = ax1.twinx()
6# x軸の値設定
7x = df.index.strftime("%Y-%m").to_list()
8# 折れ線グラフ描画
9sns.barplot(data=df, x=x, y="colA", ax=ax1, color="orange", label="colA", alpha=0.7)
10sns.lineplot(data=df, x=x, y="colB", ax=ax2, color="blue",label="colB")
11
12# 各y軸の範囲を設定
13ax1.set_ylim(0, 10)
14ax2.set_ylim(100, 180)
15# ax2のグリッド線を非表示にする
16ax2.grid(False)
17# 凡例を取得
18handler1, label1 = ax1.get_legend_handles_labels()
19handler2, label2 = ax2.get_legend_handles_labels()
20# ax1で凡例をまとめて表示
21ax1.legend(handler1 + handler2, label1 + label2, loc="upper center")
22# ax2の凡例は削除
23ax2.get_legend().remove()
24
25plt.title("2軸グラフ例")
26plt.tight_layout()
27plt.show()

lineplotをbarplotに変えるだけ。

折れ線グラフの方が前面になるようにした方が見やすい。

また、棒グラフはalphaを0.5~0.8辺りに設定してあげると、前面の折れ線グラフが見やすくなる。

シンプルなグラフだと、matplotlibでも十分だが、複数の棒グラフを並べたり、エラーバーを付けたりなどの場合、seabornを使う方が簡単にグラフを作成できるので、seabornにも慣れておくと便利。

まとめ

ポイントはseabornのグラフ描画時に、引数axを指定すること。

1ax1 = fig.subplots()
2# ax1のx軸をコピー
3ax2 = ax1.twinx()
4
5# グラフ描画。axにそれぞれax1、ax2を指定する
6sns.barplot(data=data, x=x, y=y, ax=ax1)
7sns.lineplot(data=data, x=x, y=y, ax=ax2)
スポンサーリンク
ABOUT ME
MAX
MAX
ITエンジニア、データサイエンティスト
新卒でSIerに入社し、フリーランスになってWEB系へ転向。
その後AIの世界へ足を踏み入れ、正社員に戻る。 テーブルデータの分析がメイン。
スポンサーリンク
記事URLをコピーしました