Skip to content

Matplotlibの軸目盛とフォーマッター: 読みやすいスケールを作る

Updated on

目盛りが詰まり、日付が重なり、数字がバラバラだとプロットは読みにくくなります。Tickの位置(Locator)と表示方法(Formatter)を明示的に決めれば、軸がすっきりし、流れが伝わります。

LocatorとFormatterの使い分け

目的ツール
一定間隔で置くMultipleLocatorxを5刻み
本数を制限MaxNLocatoryを6本以下
日付の目盛りAutoDateLocator月/年を自動調整
自作ラベルFuncFormatter単位やサフィックス追加
ラベル回転tick_params(rotation=...)密な日付を45°に

数値軸: 間隔と表示をそろえる

import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator, FuncFormatter
import numpy as np
 
x = np.linspace(0, 50, 200)
y = np.log1p(x) * 3.2
 
fig, ax = plt.subplots(figsize=(7, 4))
ax.plot(x, y, color="tab:blue")
 
# xは10刻み、yは1.5刻み
ax.xaxis.set_major_locator(MultipleLocator(10))
ax.yaxis.set_major_locator(MultipleLocator(1.5))
 
# 単位付きラベル
ax.yaxis.set_major_formatter(FuncFormatter(lambda val, _: f"{val:.1f} dB"))
 
ax.set_xlabel("Samples")
ax.set_ylabel("Signal (dB)")
ax.grid(True, axis="both", linestyle="--", alpha=0.3)
plt.tight_layout()
plt.show()

ポイント:

  • 範囲が変わる場合は MaxNLocator(nbins=6) で本数を制御。
  • Formatterは位置を変えず、文字列だけを変える。
  • 単位は軸ラベルかFormatterのどちらか1か所に。

日付軸: 重なりを防ぐ

import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import pandas as pd
 
dates = pd.date_range("2024-01-01", periods=120, freq="D")
values = pd.Series(range(len(dates))).rolling(7, min_periods=1).mean()
 
fig, ax = plt.subplots(figsize=(8, 4))
ax.plot(dates, values, color="tab:green")
 
ax.xaxis.set_major_locator(mdates.MonthLocator(interval=1))
ax.xaxis.set_major_formatter(mdates.DateFormatter("%b %Y"))
ax.xaxis.set_minor_locator(mdates.WeekdayLocator(byweekday=mdates.MO, interval=2))
 
plt.setp(ax.get_xticklabels(), rotation=30, ha="right")
ax.set_ylabel("7-day avg")
ax.grid(True, which="both", axis="x", linestyle=":", alpha=0.4)
plt.tight_layout()
plt.show()

ポイント:

  • マイナー目盛り(例: 週ごと)で文脈を示しつつラベルは抑える。
  • 日付ラベルは30–45°回転とha="right"で重なり防止。
  • 時間幅が変わるなら AutoDateLocator + ConciseDateFormatter を使う。

二軸の場合: 両方に設定

twinx/secondary_yaxis では各軸にLocatorとFormatterを設定し、色・単位・目盛りを揃える。凡例はセカンダリ軸記事の方法でまとめる。

トラブルシュート

  • 目盛りが飛ぶ? MultipleLocatorなど決定的なLocatorを指定。
  • ラベルが切れる? constrained_layout=True または plt.tight_layout().
  • 本数が多い? MaxNLocator(nbins=5)に下げるか、マイナーを消す (ax.tick_params(which="minor", length=0))。