環境システム株式会社公式HP

〒660-0083 兵庫県尼崎市道意町7-1-3
尼崎リサーチ・インキュベーションセンター512

アイコン06-6657-5130

アイコンsales@hydrolab.co.jp

お問い合わせ

アイコン06-6657-5130

アイコンsales@hydrolab.co.jp

お問い合わせ

蛇使いな彼女BLOG

【第34回】 pythonのグラフ描画②ーMatplotlibグラフの目盛調整

2021.05.07

この前の記事ではグラフ構造について大雑把に話したと思うので、今日は前回作ったグラフの見た目をよくしていこうと思います。
グラフの書式やスタイル変更についてはMatplotlibの公式ページや多くのブログに全て書いてくれているので、水質を扱う上で特によく使う“x・y軸目盛についての調整”に焦点を当てます。

●日付形式のx軸について、データ間隔(日毎だったり月毎だったり…)を整える。
●y軸に対して目盛の個数と範囲を設定する。

これらの点に着目してコード追加していきます☆
(グラフでは赤枠の部分に当たります。)

■目盛調整について

まずtickerとmatplotlib.datesを使った軸の調整について例を挙げます。
matplotlib.datesは時系列データに対して有効なツールで、簡単に目盛の調整ができちゃいます。

以下のツールをインポートしてください。
import matplotlib.ticker as ticker
import matplotlib.dates as mdates

Tickerとmdatesを使った軸の調整
fig = plt.figure(figsize = (8, 5))
ax = fig.add_subplot(111)

x=date       # 日付時刻
y=temp[0,1:]       # 最表層の水温

ax.plot(x,y,color='k',label='water temperature')       # 時系列plot

# x軸主目盛を日ごとに設定
# x軸主目盛を文字列にフォーマット
ax.xaxis.set_major_locator(mdates.DayLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter("%m/%d %H:%M"))

# y軸の最小値、最大値を設定
# y軸主目盛の数を5に設定
ax.set_ylim(int(np.nanmin(y)),int(np.nanmax(y))+1)
ax.yaxis.set_major_locator(ticker.LinearLocator(numticks=5))

# エラー箇所を重ねて表示
ex=[x[i] for i in EN]
ey=y[EN]

#ax.scatter(ex,ey,label='Unreliable data',color='r',alpha=0.5) # Error発生
ax.plot_date(ex,ey,label='Unreliable data',color='r',alpha=0.5) # 推奨

# 凡例の追加
plt.legend(loc='lower right')
plt.show()

このようにset_major_locatorで主目盛(大目盛)に対して変更を与える方法は、やや抽象的な書き方に見えますが、mdates.DayLocator()の引数はデフォルトで(bymonthday = None( range(1,32))、interval = 1、tz = None )なので、月の毎日(=bymonthday)を1日間隔(=interval)、タイムゾーン無し(=tz)でx軸の目盛を設定してくれています。
y軸側のticker.LinearLocator()のデフォルトは(numticks=None)なのでnumticks=5とし、set_ylimで設定した最小から最大の範囲を均等に5分するように値を入れました。

パラメータの指定をすればPython側がいい感じに見た目を調整してくれることが分かります。

これとは別にもう一つ別の方法も下に示していますが、こちらはax.set_xticks()/ax.set_yticks()の指定をすることで、データの値によって直接主目盛の位置を設定しています。

set_xticks()/set_yticks()を使った軸の調整
fig = plt.figure(figsize = (8, 5))
ax = fig.add_subplot(111)

…(省略)
# 日付のデータの範囲を5等分するインデックスを取得
# インデクスに等しい日時を主目盛の位置に設定
xtick=np.linspace(0,len(x)-1,5).astype(int)
xtick=[x[i] for i in xtick]
ax.set_xticks(xtick)

# y軸の最小値、最大値を設定
# 0~25の範囲を10等分するインデックスを取得
# インデクスに等しい値を主目盛の位置に設定
ax.set_ylim(int(np.nanmin(y)),int(np.nanmax(y))+1)
ytick=np.linspace(int(np.nanmin(y)),int(np.nanmax(y))+1,10)
ytick=[round(i,1)for i in ytick]
ax.set_yticks(ytick)

…(省略)
plt.show()

あれ?
xtick=np.linspace(0,len(x)-1,5).astype(int)
これでほぼ等間隔になるように目盛指定しはずですが、5月25日から5月28日の間2日が抜けてますね。
計測する時間間隔だったり、日ごとの測定データ数を均一に整えないまま可視化すると、こういう事が起こります(笑)
しかしこの方法だと、(自分で調整が必要ですが)忠実に主目盛を設定する事ができます。
狙った位置に目盛を設置したい場合は有効ですね!

また、目盛を設定するときの順番は私の経験上、「目盛設定→ラベル設定」 とすると上手くいきやすいです。
というのも、中にはグラフを作成する段階でパラメータとして軸ラベルの指定が可能なものもありますが、こういう所で行数をケチって「ラベル設定→目盛設定」と逆になった状態で可視化を行うと、稀におかしな値のグラフが出来上がることがあります。

(失敗例)
p1=sns.heatmap(d1,cmap=cm,xticklabels=False,yticklabels=yticks,ax=ax1,cbar=False)
ax1.yaxis.set_major_locator(ticker.LinearLocator(numticks=5))


そういう失敗を防ぐためにも(失敗例)の下線部分は消して、
3行目にラベル設定のコードを書き足すのをお勧めします。


次回はSeabornのグラフと、軸目盛の調整方法にも注目してみたいと思います。


[参考書籍]
※Pythonデータサイエンスハンドブック―Jupyter,Numpy,pandas,Matplotlib,scikit-learnを使ったデータ分析、機械学習 /
(株)オーム社

pagetop