mplfinance
mplfinance copied to clipboard
How to change xtick positions and labels
I'm trying to make a simple Intraday (5m) chart and I'm having a bit of trouble with the xlabels when I don't have a complete dataset:
I'm generating the graph using mpf.plot(df, ...)
. I've figured out how to make the xlims static from market open to close, but I'd like the labels to be uniformly spaced in 30m intervals and appear even where there is no data (in the morning, only a few xticks are shown). How can I do this?
I am currently working on an enhancement to allow users to modify tick placement and tick labels along the x-axis. It will be some time (maybe another month or two) as I am not working on it full time, and it can get quite complex to implement to be able to handle many cases in a general way.
In the meantime, I can suggest a workaround for you, that can handle the simple case of a single trading day as you have in your image above.
First let me clarify, however, that when you say "I'm having a bit of trouble with the xlabels," I believe you mean "xtick labels".
The term "xlabel" would refer to a single label for the xaxis, such as "Date" or "Time", just as "ylabel" would refer to the text "Shares Traded". The term "xtick labels" refers to the time texts "09:30", "10:20" etc. that label each of the ticks along the xaxis.
That said, the following code example will work for the case of a single trading day for which you know the date. (It can potentially be extrapolated for more than one trading day, but with a bit more work).
# First generate a pandas datetime index with the specific times we want, using the pandas.date_range() function:
# In this example, we do every 30 minutes from 9:30 till 15:55
ticks = pd.date_range('2021-08-02 09:30:00','2021-08-02 15:55:00',freq='30T')
# Next, determine the tick locations, and the tick labels:
ticklocations = [ df.index.get_loc(tick) for tick in ticks ]
ticklabels = [ tick.time().strftime('%H:%M') for tick in ticks ]
# Generate the plot, gaining access to the Axes objects using `returnfig=True`:
fig, axlist = mpf.plot(df.loc['2021-08-02'],type='candle',volume=True,returnfig=True)
# Set the tick locations and labels on the 2nd to last Axes object (the primary axis of the bottom panel)
axlist[-2].xaxis.set_ticks(ticklocations)
axlist[-2].set_xticklabels(ticklabels)
# Display:
mpf.show()
In the above example, if you want the ticks every hour (9:30,10:30,11:30,...) just change the freq=30T
to freq=1H
.
By the way I like your custom style. If you would like to contribute it to be available to other mplfinance users, you can pass the custom style object to write_style_file()
which will generate a style file that can be integrated into mplfinance:
mpf.write_style_file(mystyle,'mystyle.py')
Please consider doing that, and contributing the file to mplfinance. Thanks. All the best. --Daniel
This works, except I think you meant get_loc
not get_lock
Actually, I tested this on a full dataset, but wouldn't get_loc
not work if the 4 PM EST data point is not in df.index
?
Yes, get_loc()
; thanks for noticing the typo.
Yes, for this method to work, each of the tick times generated by
ticks = pd.date_range('2021-08-02 09:30:00','2021-08-02 15:55:00',freq='30T')
have to be in the dataframe index. That's why I stopped my generation at 15:55. Because 16:00 is not in the data set. For purposes of generating the ticks, you could add it manually. This is one of the complications that I am encountering as part of this enhancement. I had to write a method to extrapolate the index in both directions, especially in the forward time direction, to be able to handle the case of someone wanting to plot a trend line into the future, and then be able to show the proper datetime ticks along the x-axis for the future where there is no actual data.
Here’s the style file, let me know if it works.
On Aug 5, 2021, at 4:05 PM, Daniel Goldfarb @.@.>> wrote:
Yes, thanks for noticing the typo. Yes, for this method to work, each of the tick times generated by
ticks = pd.date_range('2021-08-02 09:30:00','2021-08-02 15:55:00',freq='30T')
have to be in the dataframe index. That's why I stopped my generation at 15:55. Because 16:00 is not in the data set. For purposes of generating the ticks, you could add it manually. This is one of the complications that I am encountering as part of this enhancement. I had to write a method to extrapolate the index in both directions, especially in the forward time direction, to be able to handle the case of someone wanting to plot a trend line into the future, and then be able to show the proper datetime ticks along the x-axis for the future where there is no actual data.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://github.com/matplotlib/mplfinance/issues/428#issuecomment-893875609, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AJDUJBPPZPGVSHNQSU662EDT3MKLPANCNFSM5BURBCTA. Triage notifications on the go with GitHub Mobile for iOShttps://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Androidhttps://play.google.com/store/apps/details?id=com.github.android&utm_campaign=notification-email.
@alvarozamora It looks like you replied to the GitHub notification email. Apparently that does not work correctly. They have a bug and don't know if/when it will be fixed. I'm guessing you had attached the style to the email because it is not found and, as mentioned, replying to GitHub notification emails does not work correctly.
You can email me directly at [email protected]
the above workaround makes the y_on_right option of mpl_style stop working. the y label and ticks are still on the right, but the figure area does not move left so it cut off some y-axis values.
@daovn
can you post example code, and example plot image, so I can better understand? If possible show both with and without y_on_right
. thanks.
Hi @DanielGoldfarb , any updates on the enhancement?
I'm also trying to plot 1D:1min charts and have the axis be in 30min increments at either (H:00 or H:30). However, since my data starts at the previous close, after 8PM EST (prev day) there will be no data until 4AM EST (current day) at the least.
Using the set_major_locator method I've been able to increase the number of axis labels and have them roughly from 30 in 30min. However, they do not follow a H:00 or H:30 pattern. https://drive.google.com/file/d/1OEE2L10oqXlcsOilpQLLDdmXABN7DwDq/view?usp=sharing
I've also using the above code with some tweaks managed to get the axis labels just how I wanted them post open, but the issues are that I don't have data for every 30min increment between the previous close and the market open, and that I might not have data for one of the labels (say the stock is halted or no trades go through at 10:30 for instance). https://drive.google.com/file/d/14l9cmP9gGOXWAEbFklKZGoVUjXh6XEdU/view?usp=sharing
Is there a way for me to have the axis like in this example? https://drive.google.com/file/d/1eId7Y3_eug_obnaz1S9zJfCS2fKEs3vZ/view?usp=sharing A couple other things: Would be great to be able to have the dotted line (gray hline) only start at the current day and not at the previous close. How can I double the ammount of y labels? (so it shows more prices) Also, I tried to have a shadded area like this example for when the market is not open (from 4PM EST to 09:30AM EST), but although I can have 2 vertical lines for each end, I can't have a shadded rectangle/area.
Thanks!
Hi @DanielGoldfarb ,
I am using your library for my finance research and really enjoying it. Great work. I think above issue is still relevant. Let me know if I can contribute a solution that would be merged to your repo. The missing piece seems to be a lack of option to control the xtick and yticks scale. Would be glad to discuss what should be proper solution.
Thanks,
Gary