Matplotlibの基本概念を「Pythonでグラフを描画できる「Matplotlib」への理解を深める」でまとめました。
今回はMatplotlibの中でもまだよく理解していない「軸(axis)」に焦点を当てて調整方法を学んでみたいと思います。
前回の記事でも描いたグラフを元に「オブジェクト指向方式」でコードを変更していこうと思います。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import AutoMinorLocator
from matplotlib import rcParams
rcParams['font.family'] = 'Hiragino Sans' # Macの場合
#rcParams['font.family'] = 'Meiryo' # Windowsの場合
#rcParams['font.family'] = 'VL PGothic' # Linuxの場合
# 0秒 ~ 10秒の間で100個の値を作成する
time = np.linspace(0, 10, 100)
# 振幅
amplitude = np.sin(time)
# FigureとAxesの作成
fig, ax = plt.subplots()
# Axesのヘルパーメソッドで各要素(Artist)をAxesに追加
ax.plot(time, amplitude, linewidth=2.0)
ax.set_title("タイトル", color="black")
ax.set_ylabel("Yラベル")
ax.set_xlabel("Xラベル")
# 描画
plt.show()
Axisの設定を色々試してみる
まずはベースグラフの作成をする関数を作成
毎回長いコードを記載するのはナンセンスなので、共通部分は関数化しておきます。
def call_base_image():
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import AutoMinorLocator
from matplotlib import rcParams
rcParams['font.family'] = 'Hiragino Sans' # Macの場合
#rcParams['font.family'] = 'Meiryo' # Windowsの場合
#rcParams['font.family'] = 'VL PGothic' # Linuxの場合
# 0秒 ~ 10秒の間で100個の値を作成する
time = np.linspace(0, 10, 100)
# 振幅
amplitude = np.sin(time)
# FigureとAxesの作成
fig, ax = plt.subplots()
# Axesのヘルパーメソッドで各要素(Artist)をAxesに追加
ax.plot(time, amplitude, linewidth=2.0)
ax.set_title("タイトル", color="black")
ax.set_ylabel("Yラベル")
ax.set_xlabel("Xラベル")
return fig,ax
関数の動作確認です。
X軸のラベルを「Xラベル」から「Xラベル2」と変更して見ようと思います。
fig,ax = call_base_image()
ax.set_xlabel("Xラベル2")
きちんとX軸のラベルが「Xラベル2」に変更になっていることが確認できました。
X軸とY軸の数値上限と下限を設定する
外れ値を除いて表示したい時などに使ったことがあります。
fig,ax = call_base_image()
# https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.axis.html
ax.set(xlim=(0, 5), ylim=(-0.5, 0.5))
ズームインされたようなグラフになりました。
fig,ax = call_base_image()
ax.set(xlim=(0, 5)) # ax.set_xlim(0,5) という記載方法もありました。
自由自在に変更できます。
X軸とY軸を消す
画像情報をmatplotlibで表示するときなどに軸情報が必要ない場合などに使えるかも知れません。
fig,ax = call_base_image()
ax.set_axis_off() # ax.axis('off')でもOK
X軸とY軸を消すことが出来ました。
それではX軸のみ消すのはどうしたらよいでしょうか?
調べてみたら各artistはそれぞれ可視/不可視の設定がset_visibleメソッドで出来るようです。
x軸のオブジェクトを取得し、set_visibleメソッドで非表示にすれば良さそうです。
fig,ax = call_base_image()
ax.xaxis.set_visible(False)
出来ました。X軸の情報が非表示になっていることが確認できます。
ちなみにspinesと呼ばれるグラフの周囲の黒い線も非表示にしたい場合は、ax.spines['bottom'].set_visible(False)などで不可視にすることで実現可能です。
fig,ax = call_base_image()
ax.xaxis.set_visible(False)
ax.spines['bottom'].set_visible(False) # 下の線を非表示にする
消せました。下のラインが消えたことが確認出来たと思います。
目盛り(Ticks)の調整
次は「軸」の次は「目盛り」の調整方法を試してみたいと思います。
目盛りには主目盛り(major ticks)と補助目盛り(minor ticks)が存在します。
major ticksは1、5、10、15など大まかな表示で、minor ticksより長い目盛りで表現されています。
一方でminor ticksは2,3,4,6,7,8,9などmajor ticksを補助する役割を持っていて、短い目盛りで表現されています。
それぞれ、set_xxx_locatorで目盛りをどう刻むか設定し、set_xxx_formatterで設定した目盛りのフォーマットをパーセンテージ表記などに変更できます。
詳しくはticker_apiに記載があります。
major locatorのデフォルトはAutoLocator(MaxNLocatorが選択される)で、minor locatorのデフォルトはNullLocatorのようです。
(なのでデフォルトでは補助目盛りが表示されない)
○ 目盛りを調整するメソッド一覧
・ax.xaxis.set_major_locator(locator)
・ax.yaxis.set_major_locator(locator)
・ax.xaxis.set_minor_locator(locator)
・ax.yaxis.set_minor_locator(locator)
・ax.xaxis.set_major_formatter(formatter)
・ax.yaxis.set_major_formatter(formatter)
・ax.xaxis.set_minor_formatter(formatter)
・ax.yaxis.set_minor_formatter(formatter)
Locatorの設定
主目盛りと補助目盛りの両方を指定してみようと思います。
from matplotlib.ticker import MaxNLocator,MultipleLocator,AutoMinorLocator
fig,ax = call_base_image()
# [Y軸(主)] 最大20目盛り、最低15目盛りで設定する
ax.yaxis.set_major_locator(MaxNLocator(nbins=20,min_n_ticks=15))
# [X軸(主)] 1.5刻みで目盛りを設定する
ax.xaxis.set_major_locator(MultipleLocator(1.5))
# [X軸(補助)] 0.1刻みで補助目盛りを設定する
ax.yaxis.set_minor_locator(MultipleLocator(0.1))
# [X軸(補助)] major_ticksを元に3分割で補助目盛りを設定
ax.xaxis.set_minor_locator(AutoMinorLocator(3))
思った通り自由度高く設定が出来ました。
AutoMinorLocatorを使うと自動で補助目盛りの幅を設定してくれるので便利ですね。
LocatorとFormatterの設定
Locatorの設定にFormatterの設定を追加しました。Y軸をパーセンテージで表記することが簡単に出来ます。
またtick_paramsで線の太さや色を変更することが出来るので試してみました。
from matplotlib.ticker import MaxNLocator,MultipleLocator,AutoMinorLocator
from matplotlib.ticker import PercentFormatter
fig,ax = call_base_image()
# [Y軸(主)] 最大20目盛り、最低15目盛りで設定する
ax.yaxis.set_major_locator(MaxNLocator(nbins=20,min_n_ticks=15))
# [X軸(主)] 1.5刻みで目盛りを設定する
ax.xaxis.set_major_locator(MultipleLocator(1.5))
# [X軸(補助)] 0.1刻みで補助目盛りを設定する
ax.yaxis.set_minor_locator(MultipleLocator(0.1))
# [X軸(補助)] major_ticksを元に3分割で補助目盛りを設定
ax.xaxis.set_minor_locator(AutoMinorLocator(3))
# [Y軸(主)] 数値の1を100%とし、小数点第一位まで表示するように変更する
ax.yaxis.set_major_formatter(PercentFormatter(xmax=1, decimals=1, symbol='%'))
# X軸(主)の太さを5pointsにし、色を赤に変更する
ax.tick_params(axis='x',which='major',width=5,color='red')
あんまり見たことないグラフになってしまいましたが、数値を割合表示にするのが便利ですね。
その他軸を設定する関連のサンプル
まとめ
Matplotlibの軸の調整は以前までだと少し苦手意識があったかと思いますが、前回のMatplotlibの構成でaxesとaxisの違いとは何かを理解しつつ今回の軸の設定を勉強するととても理解しやすかったと思います。
他にもmatploblibでは、twinxというメソッドで2つ目の情報を共通のX軸を使って1つのグラフ上に表現することが可能になります。
例えば、年齢別の体重と身長のグラフを表現したい場合に左側は体重、右側は身長の目盛りを情報として追加することが出来ます。(X軸である年齢は共通)
Create a twin Axes sharing the xaxis.
Create a new Axes with an invisible x-axis and an independent y-axis positioned opposite to the original one (i.e. at right)
引用: https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.twinx.html
まだまだ調整できることは多いですが、また折を見てMatplotlibの使い方はまとめていこうと思います。