精确控制坐标轴的刻度位置和标签格式,是实现专业图表的必要技能。
ticker — 刻度定位(locator)
ticker 模块控制刻度的位置。
内置 locator
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import numpy as np
fig, 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 datetime
ax.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=0
ax.spines['bottom'].set_position(('data', 0)) # 下框移到 y=0
ax.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 mdates
from 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)
# 日期 locator
ax.xaxis.set_major_locator(mdates.monthlocator(interval=1)) # 每月
ax.xaxis.set_minor_locator(mdates.weekdaylocator(byweekday=mdates.mo)) # 每周一
# 日期 formatter
ax.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))
到此这篇关于python基础指南之matplotlib刻度与格式控制设置详解的文章就介绍到这了,更多相关python matplotlib内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论