Search code examples
pythoncandlestick-chartmplfinance

How to add a string comment above every single candle using mplfinance.plot() or any similar package?


i want it to be like this Picture

i want to add a string Comment above every single candle using mplfinance package .

is there a way to do it using mplfinance or any other package ?

here is the code i used :

import pandas as pd
import mplfinance as mpf
import matplotlib.animation as animation
from mplfinance import *
import datetime
from datetime import date, datetime

fig = mpf.figure(style="charles",figsize=(7,8))
ax1 = fig.add_subplot(1,1,1 , title='ETH')

def animate(ival):
    idf = pd.read_csv("test1.csv", index_col=0)
    idf['minute'] = pd.to_datetime(idf['minute'], format="%m/%d/%Y %H:%M")

    idf.set_index('minute', inplace=True)

    ax1.clear()
    mpf.plot(idf, ax=ax1, type='candle',  ylabel='Price US$')

ani = animation.FuncAnimation(fig, animate, interval=250)

mpf.show()

Solution

  • You should be able to do this using Axes.text()

    After calling mpf.plot() then call

    ax1.text()
    

    for each text that you want (in your case for each candle).

    There is an important caveat regarding the x-axis values that you pass into ax1.text():

    • If you do not specify show_nontrading=True then it will default to False in which case the x-axis value that you pass into ax1.text() for the position of the text must be the row number corresponding to the candle where you want the text counting from 0 for the first row in your DataFrame.
    • On the other hand if you do set show_nontrading=True then the x-axis value that you pass into ax1.text() will need to be the matplotlib datetime. You can convert pandas datetimes from you DataFrame DatetimeIndex into matplotlib datetimes as follows:
    import matplotlib.dates as mdates
    my_mpldates = mdates.date2num(idf.index.to_pydatetime())
    

    I suggest using the first option (DataFrame row number) because it is simpler. I am currently working on an mplfinance enhancement that will allow you to enter the x-axis values as any type of datetime object (which is the more intuitive way to do it) however it may be another month or two until that enhancement is complete, as it is not trivial.


    Code example, using data from the mplfinance repository examples data folder:

    import pandas as pd
    import mplfinance as mpf
    
    infile = 'data/yahoofinance-SPY-20200901-20210113.csv'
    
    # take rows [18:28] to keep the demo small:
    df = pd.read_csv(infile, index_col=0, parse_dates=True).iloc[18:25]
    
    fig, axlist = mpf.plot(df,type='candle',volume=True,
                           ylim=(330,345),returnfig=True)
    
    x = 1
    y = df.loc[df.index[x],'High']+1
    axlist[0].text(x,y,'Custom\nText\nHere')
    
    x = 3
    y = df.loc[df.index[x],'High']+1
    axlist[0].text(x,y,'High here\n= '+str(y-1),fontstyle='italic')
    
    x = 5
    y = df.loc[df.index[x],'High']+1
    axlist[0].text(x-0.2,y,'More\nCustom\nText\nHere',fontweight='bold')
    
    mpf.show()
    

    Comments on the above code example:

    • I am setting the ylim=(330,345) in order to provide a little extra room above the candles for the text. In practice you might choose the high dynamically as perhaps high_ylim = 1.03*max(df['High'].values).

    • Notice that the for first two candles with text, the text begins at the center of the candle. The 3rd text call uses x-0.2 to position the text more over the center of the candle.

    • For this example, the y location of the candle is determined by taking the high of that candle and adding 1. (y = df.loc[df.index[x],'High']+1) Of course adding 1 is arbitrary, and in practice, depending on the maginitude of your prices, adding 1 may be too little or too much. Rather you may want to add a small percentage, for example 0.2 percent:

      y = df.loc[df.index[x],'High']
      y = y * 1.002
      
    • Here is the plot the above code generates:

    enter image description here