Matplotlib 刻度与格式
精确控制坐标轴的刻度位置和标签格式,是实现专业图表的必要技能。
🔢 Ticker — 刻度定位器(Locator)
ticker模块控制刻度的位置。
内置 Locator
importmatplotlib.pyplotaspltimportmatplotlib.tickerastickerimportnumpyasnp 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),axinzip(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(lambdax,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(位置,通常不用)defcurrency_fmt(x,pos):ifx>=1e6:returnf'¥{x/1e6:.1f}M'elifx>=1e3:returnf'¥{x/1e3:.0f}K'else:returnf'¥{x:.0f}'ax.yaxis.set_major_formatter(ticker.FuncFormatter(currency_fmt))# Lambda 版本ax.yaxis.set_major_formatter(ticker.FuncFormatter(lambdax,p:f'{x:,.0f}'))# 日期格式化fromdatetimeimportdatetime ax.xaxis.set_major_formatter(ticker.FuncFormatter(lambdax,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('--')🎯 日期刻度格式化
importmatplotlib.datesasmdatesfromdatetimeimportdatetime,timedelta# 生成日期数据dates=[datetime(2024,1,1)+timedelta(days=i)foriinrange(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=(lambdax:x/y_total*100,# forwardlambdax: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))# 只保留左/下边框forspinein['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))[[matplotlib3-总览|← 返回总览]]