Skip to content

Matplotlib 轴刻度与格式化:让刻度可读可控

Updated on

刻度拥挤、日期重叠、数字杂乱会让图表难以阅读。明确指定刻度位置(Locator)和显示方式(Formatter),就能让每条轴讲清楚故事。

Locator vs 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 之一,避免重复。

日期轴:避免重叠

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,保证颜色、刻度和单位一致。图例的整理可参考双轴指南。

快速排查

  • 刻度跳动?设定确定性 locator(如 MultipleLocator)。
  • 标签被裁剪?启用 constrained_layout=Trueplt.tight_layout()
  • 刻度太多?降到 MaxNLocator(nbins=5) 或隐藏次刻度 (ax.tick_params(which="minor", length=0))。