Python基础指南之matplotlib刻度与格式控制设置详细说明

作者:袖梨 2026-08-10

精确控制坐标轴的刻度位置和标签格式,是实现专业图表的必要技能。

Python基础指南之matplotlib刻度与格式控制设置详解

Ticker — 刻度定位(Locator)

ticker 模块控制刻度的位置

内置 Locator

import matplotlib.pyplot as pltimport matplotlib.ticker as tickerimport numpy as npfig, axes = plt.subplots(3, 2, figsize=(12, 10))x = np.linspace(0, 10, 100)locators = [    ('AutoLocator', ticker.AutoLocator()),    ('MaxNLocator', ticker.MaxNLocator(nbins=5)),    ('LinearLocator', ticker.LinearLocator(numticks=10)),    ('MultipleLocator', ticker.MultipleLocator(base=0.5)),    ('FixedLocator', ticker.FixedLocator([0.5, 2, 4.7, 8.3])),    ('LogLocator', ticker.LogLocator(base=10)),]for (name, loc), ax in zip(locators, axes.flat):    ax.plot(x, np.sin(x))    ax.xaxis.set_major_locator(loc)    ax.set_title(name)

Locator 完整列表

Locator说明常用参数
AutoLocator自动选择(默认)
MaxNLocator最多 N 个刻度nbins, steps, integer
LinearLocator等距刻度numticks
MultipleLocator基数的倍数位置base
FixedLocator固定位置locs (列表)
IndexLocator等距 + 偏移base, offset
LogLocator对数刻度base, subs
SymmetricalLogLocator对称对数base, linthresh
NullLocator无刻度
# 常用 Locator 示例ax.xaxis.set_major_locator(ticker.MaxNLocator(nbins=6, integer=True, steps=[1, 2, 5, 10]))ax.yaxis.set_major_locator(ticker.MultipleLocator(0.2))     # 每 0.2 一个刻度ax.xaxis.set_major_locator(ticker.LogLocator(base=10, subs='all'))  # 对数ax.xaxis.set_major_locator(ticker.NullLocator())  # 隐藏刻度

主刻度与次刻度

fig, ax = plt.subplots(figsize=(10, 5))ax.plot(x, np.sin(x))# 主刻度(major ticks)ax.xaxis.set_major_locator(ticker.MultipleLocator(2))# 次刻度(minor ticks)ax.xaxis.set_minor_locator(ticker.MultipleLocator(0.5))# 开启次刻度网格ax.grid(which='major', color='gray', linestyle='-', linewidth=0.8)ax.grid(which='minor', color='lightgray', linestyle='--', linewidth=0.4)# AutoMinorLocator 自动设置次刻度ax.xaxis.set_minor_locator(ticker.AutoMinorLocator(n=4))  # 每个主刻度间 4 个次刻度

Formatter — 刻度格式化器

Formatter 控制刻度标签的显示格式

内置 Formatter

formatters = [    ('ScalarFormatter', ticker.ScalarFormatter()),    ('FormatStrFormatter', ticker.FormatStrFormatter('%.2f')),    ('PercentFormatter', ticker.PercentFormatter(xmax=100, decimals=1)),    ('FuncFormatter', ticker.FuncFormatter(lambda x, p: f'{x:.1f}°C')),    ('FixedFormatter', ticker.FixedFormatter(['A', 'B', 'C', 'D', 'E'])),    ('StrMethodFormatter', ticker.StrMethodFormatter('{x:.3f}')),    ('EngFormatter', ticker.EngFormatter(unit='V')),    ('LogFormatter', ticker.LogFormatter(base=10)),    ('NullFormatter', ticker.NullFormatter()),]

FormatStrFormatter— 格式化字符串

ax.yaxis.set_major_formatter(ticker.FormatStrFormatter('%.2f'))# 常用格式: '%.2f'(两位小数), '%.0f'(整数), '%d'(整数), '%e'(科学计数)

PercentFormatter— 百分比

# xmax=100: 0-100 范围显示为 0%-100%# xmax=1: 0-1 范围显示为 0%-100%ax.yaxis.set_major_formatter(ticker.PercentFormatter(xmax=1, decimals=0))

FuncFormatter— 自定义函数

# 自定义格式化函数# 接收两个参数: x(刻度值), pos(位置,通常不用)def currency_fmt(x, pos):    if x >= 1e6:        return f'¥{x/1e6:.1f}M'    elif x >= 1e3:        return f'¥{x/1e3:.0f}K'    else:        return f'¥{x:.0f}'ax.yaxis.set_major_formatter(ticker.FuncFormatter(currency_fmt))# Lambda 版本ax.yaxis.set_major_formatter(    ticker.FuncFormatter(lambda x, p: f'{x:,.0f}'))# 日期格式化from datetime import datetimeax.xaxis.set_major_formatter(    ticker.FuncFormatter(lambda x, p: datetime.fromtimestamp(x).strftime('%Y-%m')))

EngFormatter— 工程计数法

ax.yaxis.set_major_formatter(ticker.EngFormatter(unit='Hz'))# 自动使用 k, M, G, m, μ 等单位前缀

ScalarFormatter— 偏移量

formatter = ticker.ScalarFormatter()formatter.set_powerlimits((-3, 4))   # 超出范围才用科学计数法formatter.set_useOffset(True)         # 使用偏移量formatter.set_useMathText(True)       # LaTeX 风格ax.yaxis.set_major_formatter(formatter)

刻度外观

刻度线样式

# 刻度线参数ax.tick_params(    axis='both',           # 'x', 'y', 'both'    which='major',         # 'major', 'minor', 'both'    direction='in',        # 'in', 'out', 'inout'    length=8,              # 刻度线长度    width=1.5,             # 刻度线宽度    color='red',           # 刻度线颜色    pad=8,                 # 刻度与标签的间距    labelsize=12,          # 标签字体大小    labelcolor='black',    # 标签颜色    labelrotation=45,      # 标签旋转角度    top=True,              # 是否显示顶部刻度    right=True,            # 是否显示右侧刻度    bottom=True,           # 是否显示底部刻度    left=True              # 是否显示左侧刻度)# 单独设置ax.tick_params(axis='x', labelrotation=45, labelsize=10)ax.tick_params(axis='y', which='minor', length=4, color='gray')

轴边框(Spine)

fig, ax = plt.subplots(figsize=(8, 5))ax.plot(x, np.sin(x))# 隐藏上方和右侧边框ax.spines['top'].set_visible(False)ax.spines['right'].set_visible(False)# 移动边框位置ax.spines['left'].set_position(('data', 0))     # 左框移到 x=0ax.spines['bottom'].set_position(('data', 0))   # 下框移到 y=0ax.spines['left'].set_position(('axes', 0.05))  # 左框在 5% 处ax.spines['left'].set_position('center')         # 左框在中间# 边框样式ax.spines['bottom'].set_color('red')ax.spines['bottom'].set_linewidth(2)ax.spines['bottom'].set_linestyle('--')

日期刻度格式化

import matplotlib.dates as mdatesfrom datetime import datetime, timedelta# 生成日期数据dates = [datetime(2024, 1, 1) + timedelta(days=i) for i in range(365)]values = np.random.randn(365).cumsum()fig, ax = plt.subplots(figsize=(14, 5))ax.plot(dates, values)# 日期 Locatorax.xaxis.set_major_locator(mdates.MonthLocator(interval=1))   # 每月ax.xaxis.set_minor_locator(mdates.WeekdayLocator(byweekday=mdates.MO))  # 每周一# 日期 Formatterax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %d'))      # "Jan 01"ax.xaxis.set_major_formatter(mdates.ConciseDateFormatter(    ax.xaxis.get_major_locator()))  # 简洁自适应格式(推荐)# 自动格式化fig.autofmt_xdate(rotation=45, ha='right')  # 自动旋转日期标签# 日期 Locator 速查# DayLocator, HourLocator, MinuteLocator, SecondLocator# MonthLocator, YearLocator# WeekdayLocator, AutoDateLocator

实战: 定制坐标轴

双格式坐标轴

fig, ax = plt.subplots(figsize=(10, 6))ax.plot(x, y)# 左侧用原始值ax.yaxis.set_major_formatter(ticker.FormatStrFormatter('%.1f'))# 右侧辅助轴用百分比secax = ax.secondary_yaxis('right', functions=(    lambda x: x / y_total * 100,       # forward    lambda x: x / 100 * y_total        # inverse))secax.yaxis.set_major_formatter(ticker.PercentFormatter())secax.set_ylabel('Percentage')

自定义刻度样式(Tufte 风格)

fig, ax = plt.subplots(figsize=(10, 5))ax.plot(x, np.sin(x))# 只保留左/下边框for spine in ['top', 'right']:    ax.spines[spine].set_visible(False)# 刻度线朝外ax.tick_params(axis='both', direction='out', length=5, width=1)# 网格ax.grid(True, which='major', axis='y',        color='lightgray', linestyle='-', linewidth=0.5)# 偏移边框ax.spines['left'].set_position(('outward', 10))ax.spines['bottom'].set_position(('outward', 10))

相关文章

精彩推荐