Search code examples
pythonplotlyhorizontal-line

Plot horizontal lines in plotly


I am trying overlay horizontal lines to a candlestick chart using plotly. However, when I am unable to get the horizontal lines to start at the their 'x' coordinate which is found in df['date'][level[0]]. Instead the horizontal lines are starting a x=0.

Below is what I have managed to muster together so far, which I imagine is not pretty to an experienced eye.

However any pointers to assist would be much appreciated:

import plotly.graph_objects as go
from plotly.offline import plot
import datetime as dt
from pandas import DataFrame
import numpy as np
import pandas as pd



hovertext=[]
for i in range(len(df['bidopen'])):
    hovertext.append('Datetime: '+str(df['date'][i])+'<br>Open: '+str(df['bidopen'][i])+'<br>Close: '+str(df['bidclose'][i]))


fig = go.Figure(data=go.Candlestick(x=df['date'],
                open=df['bidopen'],
                high=df['bidhigh'],
                low=df['bidlow'],
                close=df['bidclose'],
                text=hovertext,
                hoverinfo='text'))

for level in levels:
    fig.add_hline(level[1], df['date'][level[0]], exclude_empty_subplots=True)


plot(fig)

Here is a screen shot of what my plotly code currently produces (current output):

enter image description here

Below is what what I am trying to achieve in respect to the horizontal lines (desired output):

enter image description here

..this second screenshot represents what I was able to produce with matplotlib


Solution

  • Since hline() extends the plots to infinity on both sides, you can use add_shape() method.

    Considering a dataframe like:

    df = pd.DataFrame(data = {'levels':np.random.random(10)*10, 
                              'dates':pd.date_range(start = '2020-11-01', periods = 10)})
    df
    
        levels  dates
    0   9.149079    2020-11-01
    1   0.294123    2020-11-02
    2   5.401443    2020-11-03
    3   4.043063    2020-11-04
    4   8.878100    2020-11-05
    5   5.275614    2020-11-06
    6   4.425696    2020-11-07
    7   8.228720    2020-11-08
    8   7.632410    2020-11-09
    9   7.045191    2020-11-10
    

    & a figure already having dates you want as indices:

    enter image description here

    You can do something like:

    for row in df.iterrows():
        fig.add_shape(type="line", x0= row[1]['dates'], 
                                y0 = row[1]['levels'],
                                x1 = df.dates.max(),
                                y1 = row[1]['levels'], fillcolor = 'yellow')
    fig
    

    Which results in:

    enter image description here