mplfinance设置x轴30分钟刻度过密触发MAXTICKS报错
问题描述
绘制单日E-mini盘中行情数据,数据为Datetime索引格式的标准OHLC数据,采用5分钟K线周期。预期x轴每隔30分钟显示刻度及对应网格线,但实际生成的刻度数量远超出预期,同时反复弹出如下报错:
Locator attempting to generate 5807 ticks ([-6.470138888888889, ..., 114.48819444444445]), which exceeds Locator.MAXTICKS (1000).
实际异常效果如下:
复现代码
fig, axlist = mpl.plot( df[['open', 'high', 'low', 'close', 'volume']].loc['2022-6-9 6:45':'2022-6-9 15:45'], type="candle", title = "Micro E-mini S&P 500 Price", style="yahoo", volume=True, figratio=(12.00, 5.75), returnfig=True ) # axlist[0].yaxis.set_major_formatter(FormatStrFormatter('$%.2f')) axlist[0].xaxis.set_major_locator(mdates.MinuteLocator(interval=30)) mpl.show()
问题原因
核心问题是坐标轴类型不匹配:
- mplfinance(即代码中简写的
mpl库)绘制K线时,默认使用分类序号x轴:每根K线对应一个整数序号(从0开始依次递增,单位为“单根K线位置”),而非原生datetime时间数值轴。 mdates.MinuteLocator是Matplotlib专门为datetime类型坐标轴设计的刻度定位器,它默认将x轴数值的单位识别为“天”,设置interval=30代表每30分钟一个刻度,对应x轴上的数值步长为30/(24*60)≈0.0208。- 你的x轴实际数值范围约为-6.47~114.49,按照0.0208的步长计算会生成近5800个刻度,远超过Locator默认的1000个最大刻度限制,因此触发报错,同时生成大量冗余刻度。
解决方法
方法1:使用mplfinance原生参数配置(推荐)
不需要手动调用Matplotlib的日期刻度定位器,直接在mpl.plot()中传入刻度配置即可,兼容性最好:
import pandas as pd import mplfinance as mpl # 生成30分钟间隔的刻度时间点 xtick_list = pd.date_range(start='2022-06-09 07:00', end='2022-06-09 15:30', freq='30T').to_pydatetime() fig, axlist = mpl.plot( df[['open', 'high', 'low', 'close', 'volume']].loc['2022-6-9 6:45':'2022-6-9 15:45'], type="candle", title = "Micro E-mini S&P 500 Price", style="yahoo", volume=True, figratio=(12.00, 5.75), returnfig=True, datetime_format='%H:%M', # x轴刻度显示为「时:分」格式 xticks=xtick_list, # 传入30分钟间隔的刻度点 xrotation=0, # 可选:设置刻度文字不旋转 gridstyle='--' # 可选:设置网格线样式 ) # 格式化y轴价格为美元格式 axlist[0].yaxis.set_major_formatter('${x:1.2f}') mpl.show()
方法2:切换为datetime原生x轴后再配置定位器
如果需要使用mdates.MinuteLocator,先通过show_nontrading=True参数强制mplfinance使用原生datetime数值x轴(注意该参数会显示非交易时段的空白间隔,单日盘中数据影响极小):
import mplfinance as mpl import matplotlib.dates as mdates fig, axlist = mpl.plot( df[['open', 'high', 'low', 'close', 'volume']].loc['2022-6-9 6:45':'2022-6-9 15:45'], type="candle", title = "Micro E-mini S&P 500 Price", style="yahoo", volume=True, figratio=(12.00, 5.75), returnfig=True, show_nontrading=True, # 关键:切换为datetime数值x轴 datetime_format='%H:%M' ) # 设置每小时0分、30分位置显示刻度 axlist[0].xaxis.set_major_locator(mdates.MinuteLocator(byminute=[0, 30], interval=1)) axlist[0].grid(which='major', axis='x', linestyle='--', alpha=0.7) axlist[0].yaxis.set_major_formatter('${x:1.2f}') mpl.show()
内容的提问来源于stack exchange,提问作者Dmitry
相关产品推荐
相关产品推荐

