物理の駅 Physics station by 現役研究者

テクノロジーは共有されてこそ栄える

Python+matplotlib: ログスケールでの目盛り、サブ目盛りを設定する

十分な広さのfigsizeにグラフを書くと、軸はそれなりに表示される

import matplotlib.pyplot as plt

fig, axes = plt.subplots(ncols=2, nrows=2)
for ax in axes.flat:
    ax.plot([1,2], [0.00001,1])
    ax.set_yscale("log")
plt.tight_layout()
plt.show()

グラフに使える面積が小さくなると、目盛りやラベルを勝手に省略してしまうことがある。例えば、4x4のsubplotsの場合は目盛りがほとんど表示されなくなる。

import matplotlib.pyplot as plt

fig, axes = plt.subplots(ncols=4, nrows=4)
for ax in axes.flat:
    ax.plot([1,2], [0.00001,1])
    ax.set_yscale("log")
plt.tight_layout()
plt.show()

対処療法として、文字サイズを小さくするか、figsizeを大きくする方法があるものの、根本解決ではない。

1つ目の対応策は、set_xticks() set_yticks() で、目盛り=ticksを明示的に設定し、必要なticksを表示させる。

import matplotlib.pyplot as plt

fig, axes = plt.subplots(ncols=4, nrows=4)
for ax in axes.flat:
    ax.plot([1,2], [0.00001,1])
    ax.set_xticks([1.0,1.5,2.0])
    ax.set_yscale("log")
    ax.set_yticks([1e-5,1e-4,1e-3,1e-2,1e-1,1e-0])
plt.tight_layout()
plt.show()

2つ目の対応策は、locator を使う方法である。set_ticks では設定できない minor ticksの設定が可能になる。また、描画範囲が変わった時でもコードの修正を必要としない。

import matplotlib.pyplot as plt
from matplotlib.ticker import (MultipleLocator, LogLocator)

fig, axes = plt.subplots(ncols=4, nrows=4)
for ax in axes.flat:
    ax.plot([1,2], [0.00001,1])
    ax.set_yscale("log")
    ax.xaxis.set_major_locator(MultipleLocator(0.5)) #major ticksは0.5刻み
    ax.xaxis.set_minor_locator(MultipleLocator(0.1)) #minor ticksは0.1刻み

    ax.yaxis.set_major_locator(LogLocator(base=100)) #基数 100で描画
    ax.yaxis.set_minor_locator(LogLocator(base=100,subs=[10])) #基数 100、その 10倍 も描画
    ax.yaxis.set_minor_formatter("") #minor ticksのlabelは表示されるので非表示に

plt.tight_layout()
plt.show()