こんにちは、その日暮らしです。
Pythonでmatplotlibパッケージを使って三角関数のグラフを描いてみたところ\(x\)軸の目盛が2.5ごとに表示されてしました。
ちょっとダサいですよね?
調べてみたところ、FuncFormatterというものを使うと目盛を\(\pi\)ごととかで表示できることがわかりました。
当記事では、そんな小ネタをシェアしてみたいと思います。
なお、プログラマ向けQ&Aサイトとして有名なStack Overflowの以下のページを参考にしました。
普通に描いた三角関数グラフ
まず、普通に三角関数のグラフを描いてみます。
コードは、こんな感じ。
# パッケージをインポートする。
import numpy as np
import matplotlib.pyplot as plt
# FigureとAxesを作成する。
fig, ax = plt.subplots()
# データを用意する。
x = np.arange(-np.pi * 3, np.pi * 3, 0.1)
s = np.sin(x)
c = np.cos(x)
# データを描画する。
ax.plot(x, s)
ax.plot(x, c)
# グリッドを表示する。
ax.grid()
# グラフを表示する。
plt.show()
出力されるグラフはこんな感じです。
なにもしてないので\(x\)軸の目盛が2.5の整数倍で並んでいます。ちょっとカッコよくないですよね。
カッコよく描いた三角関数グラフ
以下のコードを3行目と18行目辺りに追加してみます。
import matplotlib as mpl
# x軸の目盛用のFuncFormatterを用意する。
def format_func_major(x, pos):
n = int(np.round(x / np.pi))
if n == 0:
# "0"を返す。
return "0"
elif n == 1:
# "π"を返す。
return r"$\pi$"
elif n == -1:
# "-π"を返す。
return r"$-\pi$"
elif np.abs(n) >= 2:
# "nπ"を返す(nは絶対値が2以上の整数)。
return r"${%s}\pi$" % n
# x軸の目盛の位置とラベルを設定する。
ax.xaxis.set_major_locator(mpl.ticker.MultipleLocator(np.pi))
ax.xaxis.set_major_formatter(mpl.ticker.FuncFormatter(format_func_major))
# x軸の補助目盛用のFuncFormatterを用意する。
def format_func_minor(x, pos):
n = int(np.round(2 * x / np.pi))
if n % 2 != 0:
# "nπ/2"を返す(nは奇数)。
return r"$\frac{%s}{2}\pi$" % n
# x軸の補助目盛の位置とラベルを設定する。
ax.xaxis.set_minor_locator(mpl.ticker.MultipleLocator(np.pi / 2))
ax.xaxis.set_minor_formatter(mpl.ticker.FuncFormatter(format_func_minor))
\(x\)軸の目盛と補助目盛の表示にMultipleLocatorというロケータとFuncFormatterというフォーマッタを使って、目盛りは\(n\pi\,(nは整数)\)のときに、補助目盛は\(\frac{n}{2}\pi\,(nは整数)\)のときに表示されるようにしてみました。
目盛では、MultipleLocatorを使って\(x\)の値が\(n\pi\,(nは整数)\)のときに目盛が表示されるようにすると、FuncFormatterで指定した関数format_func_majorが目盛表示時に呼ばれるので、そのときの\(x\)の値から目盛のラベルを計算し文字列で返しています。
補助目盛では、MultipleLocatorを使って\(x\)の値が\(\frac{n}{2}\pi\,(nは整数)\)のときに補助目盛が表示されるようにすると、FuncFormatterで指定した関数format_func_minorが目盛表示時に呼ばれるので、そのときの\(x\)の値から補助目盛のラベルを計算し文字列で返しています。
なお、目盛りと補助目盛の表示がダブったとき(例えば\(x\)が\(\pi\)のとき)には補助目盛は表示されず目盛だけ表示されるようです。ダブった場合にformat_func_minorが呼ばれないことをデバッガで確認しました(念のため呼ばれてもいいようにif文でチェックはしている)。
また、目盛のラベル表示ではすべてLaTexを使っています。
出力されるグラフはこんな感じです。カッコいいかどうかは主観の問題ですが、コードの通り\(x\)軸の目盛が表示されてます。
どうでしょうか。補助目盛が余計な気もしますが、2.5ごとの目盛よりましですよね。
以上、「Pythonでmatplotlibパッケージを使ってグラフを描くときのFuncFormatterの使い方の件」でした。
コメント