蛇使いな彼女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を使ったデータ分析、機械学習 /
(株)オーム社