pythonmatplotlibdatetimexticksmplfinance

Setting ticks to 30 minutes on x axis in mplfinance creates too frequent ticks


I am trying to plot intraday E-mini data for one day. Datetime index with usual OHLC data and 5 mins candles. I would like to display x axis ticks and corresponding grid lines every half an hour. Somehow I get way above the desired number of ticks (see below).

Also, there is a recurrent message as following:

Locator attempting to generate 5807 ticks ([-6.470138888888889, ..., 114.48819444444445]), which exceeds Locator.MAXTICKS (1000).

What am I doing wrong?

Thanks!

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()

enter image description here


Solution

  • I suspect the problem is because, under the hood, mplfinance uses the dataframe row number as the x-ordinate when show_nontrading=False (the default value). Try setting kwarg show_nontrading=True and see if that works. (This setting will revert the x-ordinate to mdates) Please let me know if this suggestion works. (I am currently working on an enhancement to mplfinance that will make it easier to control the x-axis ticks. In the meantime, this suggestion may help).

    I ran a test and confirmed my hypothesis (see my comment under the question) ... indeed setting kwarg show_nontrading=True in the call to mpf.plot() will allow the axlist[0].xaxis.set_major_locator(mdates.MinuteLocator(interval=30)) to work correctly.

    However it may not set the ticks on exactly the 30 minute mark, rather each tick will be 30 minutes from the previous tick.

    It appears that the way to set the ticks exactly on the 00 and 30 minute mark is, instead of interval=30 say byminute=[0,30], thus:

    axlist[0].xaxis.set_major_locator(mdates.MinuteLocator(byminute=[0,30]))