Plot horizontal lines in plotly

2.5k Views Asked by At

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

2

There are 2 best solutions below

1
On BEST ANSWER

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

0
On

Using example from @Hamza please see solution below:

df1 = pd.DataFrame(levels, columns = ['dates', 'levels'])

df1.set_index('dates', inplace=True)

for i in df1:
      df1['dates'] = df.date[df.index.isin(df1.index)]

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 row in df1.iterrows():
    fig.add_shape(type="line", x0= row[1]['dates'], 
                            y0 = row[1]['levels'],
                            x1 = df.date.max(),
                            y1 = row[1]['levels'], fillcolor = 'yellow')

plot(fig)