Python

Python初心者向け:グラフに第2軸を設定する方法を基本から解説

スポンサーリンク


▶ カテゴリごとにプロットして比較する方法は以下をご覧ください。

▶ グラフのグリッド表示に関しては以下をご覧ください。

はじめに

一つのグラフ領域に2つのプロットするケースでは、第2軸を設定したくなることがありますよね。また、データを比較する場合でも、それぞれのデータのスケールが大きく異なる場合は、別の軸を設定することがあります。今回はこのようなケースでの軸の設定方法について扱います。

サンプルデータの準備

店舗数と販売数量を月ごとに記録したデータをプロットすることにしましょう。以下のコードでこのサンプルデータを作りましょう。

df=pd.DataFrame({'年月':['2019-04','2019-05','2019-06','2019-07','2019-08','2019-09',
                       '2019-10','2019-11','2019-12','2020-01','2020-02','2020-03'],
               '店舗数':[5,7,7,7,8,8,9,9,9,10,11,13],
               '販売数量':[135,150,186,170,165,180,178,200,193,213,208,222]})
df

2つの軸の設定

では、さっそく作成したサンプルデータをグラフにしてみましょう。普通に1つのグラフ領域に2つのプロットをします。単純にプロットするだけだと、次の二様にできます。

# グラフ領域、サブプロットの作成
fig,ax=plt.subplots(figsize=(16,4))

# 描画する
ax.bar(df['年月'],df['店舗数'],label='店舗数',color='orange')
ax.plot(df['年月'],df['販売数量'],label='販売数量',marker='^')

# グラフ周りの設定
plt.title('店舗数と販売数量の推移')
plt.xlabel('年月')
plt.ylabel('店舗数・販売数量')

# gridの設定
plt.grid()

# 凡例の設定
plt.legend()

グラフを描くことができましたが、店舗数に関してはその変化がよくわかりません。これは、「店舗数」は「販売数量」に比べて小さな数字になるのに、同じ軸で表しているため、わかりにくくなっています。

では、2つの軸を設定していくことにしましょう。2つの軸を設定するには、1つ目のグラフは普通に描き、2つの目のグラフを描く際に 、ax2=ax1.twinx()のようにして生成したax2を使って描きます。

# グラフ領域、サブプロットの作成
fig,ax1=plt.subplots(figsize=(16,4))
ax2=plt.twinx(ax1)

# 描画する
ax1.bar(df['年月'],df['店舗数'],color='orange',alpha=0.7,label='店舗数')
ax2.plot(df['年月'],df['販売数量'],label='販売数量',marker='^')

# グラフ周りの設定
plt.title('店舗数と販売数量の推移')
ax1.set_xlabel('年月')
ax1.set_ylabel('店舗数')
ax2.set_ylabel('販売数量')

# 表示範囲の設定
ax2.set_ylim(0,300)

# gridの設定
plt.grid()

だいぶ見やすくなりましたが、凡例がないとよくわからないですね。2軸の場合の凡例はちょっと複雑です。

凡例の設定

これまでの知識で凡例を表示しようとすると、次のようになります。

# グラフ領域、サブプロットの作成
fig,ax1=plt.subplots(figsize=(16,4))
ax2=plt.twinx(ax1)

# 描画する
ax1.bar(df['年月'],df['店舗数'],color='orange',alpha=0.7,label='店舗数')
ax2.plot(df['年月'],df['販売数量'],label='販売数量',marker='^')

# グラフ周りの設定
plt.title('店舗数と販売数量の推移')
ax1.set_xlabel('年月')
ax1.set_ylabel('店舗数')
ax2.set_ylabel('販売数量')

# 表示範囲の設定
ax2.set_ylim(0,300)

# gridの設定
plt.grid()

# 凡例の表示
ax1.legend()
ax2.legend()

それぞれの凡例を表示させることができました。ただこのように凡例が別々に表示されているのは、望ましくないでしょう。そこで、凡例を一つにまとめることを考えます。 凡例を一つにまとめるには、最後のax1.legend()の代わりに、ax1ax2の凡例のhandlerとlabelのリストを結合してax1.legendに渡すことで実現できます。

# グラフ領域、サブプロットの作成
fig,ax1=plt.subplots(figsize=(16,6))
ax2=plt.twinx(ax1)

# 描画する
ax1.bar(df['年月'],df['店舗数'],color='orange',alpha=0.7,label='店舗数')
ax2.plot(df['年月'],df['販売数量'],label='販売数量',marker='^')

# グラフ周りの設定
plt.title('店舗数と販売数量の推移\n',fontsize=30)
ax1.set_xlabel('年月',fontsize=15)
ax1.set_ylabel('店舗数',fontsize=15)
ax2.set_ylabel('販売数量',fontsize=15)

# 表示範囲の設定
ax2.set_ylim(0,300)

# gridの設定
plt.grid()

# 凡例
# グラフの本体設定時に、ラベルを手動で設定する必要があるのは、barplotのみ。plotは自動で設定される>
handler1, label1 = ax1.get_legend_handles_labels()
handler2, label2 = ax2.get_legend_handles_labels()
# 凡例をまとめて出力する
ax1.legend(handler1 + handler2, label1 + label2)

get_legend_handles_labels()でhandlerとlabelを取得します。handlerで対象のプロット、labelで凡例を取得します。ax1,ax2それぞれについて、対象のプロット(handler1, handler2)と凡例(label1, label2)を取得しています。これらをax1.legend()に渡して凡例をまとめて出力しています。

その他、グラフタイトル、軸ラベルも併せて設定して完成です。

スポンサーリンク

まとめ

いかがでしたか?ここまでくるとだいぶややこしいかもしれませんね。でも、だいぶ表現力のあるグラフが描けるようになったかと思います。次は、データを可視化したあと、グラフに水平線や垂直線などを加える方法を扱います。

▶ グラフを見やすく設定する記事をまとめています。下記からどうぞ。

コメント

タイトルとURLをコピーしました