Adding threshold lines in financial plots in plotly in python

Question:

I am plotting financial subplots in Plotly in python which I am able to successfully. But I need threshold lines (horizontal lines) to be plotted in the second sub plot but not able to d the same.

But I am able to plot threshold lines successfully in a standalone plot.

My code for standalone plot with three threshold lines

    fig = go.Figure(data=[go.Scatter(x=VipData['Date'], y=VipData['RSI5'], name='RSI5')])
fig.update_layout(
    title='VIP Stock',
    yaxis_title='Price',
    xaxis_title='Period',
    shapes=[# Top Threshold line
                        {
                            'type': 'line',
                            'xref': 'paper',
                            'x0': 0,
                            'y0': 70, # use absolute value or variable here
                            'x1': 1,
                            'y1': 70, # ditto
                            'line': {
                                'color': 'rgb(0, 100, 0)',
                                'width': 1,
                                'dash': 'dash',
                            },
                        },
                        # Bottom Threshold Line
                        {
                            'type': 'line',
                            'xref': 'paper',
                            'x0': 0,
                            'y0': 30, # use absolute value or variable here
                            'x1': 1,
                            'y1': 30, # ditto
                            'line': {
                                'color': 'rgb(255, 0, 0)',
                                'width': 1,
                                'dash': 'dash',
                            },
                        },
        # Middle Threshold Line
                        {
                            'type': 'line',
                            'xref': 'paper',
                            'x0': 0,
                            'y0': 50, # use absolute value or variable here
                            'x1': 1,
                            'y1': 50, # ditto
                            'line': {
                                'color': 'rgb(0, 0, 0)',
                                'width': 1,
                                'dash': 'dash',
                            },
                        },
                    ],
                      xaxis=dict(
        rangeselector=dict(
            buttons=list([
                dict(count=1,
                     label="1m",
                     step="month",
                     stepmode="backward"),
                dict(count=6,
                     label="6m",
                     step="month",
                     stepmode="backward"),
                dict(count=1,
                     label="YTD",
                     step="year",
                     stepmode="todate"),
                dict(count=1,
                     label="1y",
                     step="year",
                     stepmode="backward"),
                dict(step="all")
            ])
        ),
        rangeslider=dict(
            visible=True
        ),
        type="date"
    )
)

fig.show()

enter image description here
Below is the code for my subplots:

fig = make_subplots(
    rows=2, cols=1,
    shared_xaxes=True,
    vertical_spacing=0.01,
    specs=[[{"type": "Candlestick"}],
           [{"type": "scatter"}]]
)

fig.add_trace(go.Candlestick(x=VipData['Date'].tail(30), open=VipData['Open'].tail(30), high=VipData['High'].tail(30),
                             low=VipData['Low'].tail(30), close=VipData['Close'].tail(30), name='Candlestick'),row=1, col=1)

fig.add_trace(go.Scatter(x=VipData['Date'].tail(30), y=VipData['RSI5'].tail(30), name='RSI5'),row=2, col=1)


fig.update_layout(xaxis_rangeslider_visible=False)

enter image description here
What changes should I make to my code to plot similar three threshold lines to my second plot i.e. plot in the row 2.

Appreciating your time and guidance.

Regards
Sudhir

Adding the plot created as per the code shared by @As11
enter image description here


Sample Data

Index Date  Open    High    Low Close   Volume  RSI5    RSI7    RSI14   RSI20
4629    2021-02-24  381.899994  396.500000  366.200012  384.000000  432314  70.793970   68.529922   62.909907   60.583804
4630    2021-02-25  388.799988  403.500000  385.049988  391.799988  595109  78.694615   74.588730   66.485293   63.246338
4631    2021-02-26  389.950012  414.950012  381.000000  400.700012  1657646 84.626277   79.772785   70.034771   66.004475
4632    2021-03-01  409.399994  412.500000  396.000000  406.149994  1564155 87.327001   82.345797   71.990981   67.573037
4633    2021-03-02  408.350006  412.799988  396.049988  398.000000  974849  65.739595   67.389979   65.142286   62.997502
4634    2021-03-03  402.700012  418.000000  396.799988  408.549988  601591  75.528227   74.409265   69.223823   66.123166
4635    2021-03-04  410.000000  422.000000  406.799988  409.950012  1203652 76.635561   75.234577   69.730348   66.518241
4636    2021-03-05  416.799988  417.899994  400.950012  411.399994  757044  77.928511   76.163442   70.275987   66.938582
4637    2021-03-08  416.399994  416.399994  405.600006  409.299988  474313  70.832312   71.624317   68.354198   65.681480
4638    2021-03-09  412.500000  412.500000  400.100006  402.899994  447689  52.589322   59.100838   62.724568   61.949272
4639    2021-03-10  405.000000  405.000000  397.799988  401.000000  374909  48.001544   55.726081   61.115323   60.868426
4640    2021-03-12  403.000000  406.750000  390.000000  392.850006  387427  32.704021   43.340983   54.639686   56.423455
4641    2021-03-15  391.500000  392.000000  379.049988  384.200012  351942  22.985685   33.987634   48.737186   52.167366
4642    2021-03-16  386.500000  387.149994  376.450012  379.899994  398165  19.402892   30.206902   46.072717   50.186440
4643    2021-03-17  375.350006  388.899994  373.049988  380.450012  812165  21.362683   31.346550   46.475797   50.439827
4644    2021-03-18  387.000000  387.000000  366.250000  372.399994  282166  14.785330   24.512076   41.577488   46.774263
4645    2021-03-19  373.000000  381.250000  370.000000  376.250000  394137  28.032068   32.699461   44.585582   48.652822
4646    2021-03-22  379.750000  380.950012  371.000000  375.399994  257526  26.878940   31.810773   44.046361   48.256999
4647    2021-03-23  372.149994  382.000000  372.000000  373.149994  234016  23.658731   29.347633   42.578426   47.187317
4648    2021-03-24  373.149994  376.950012  361.000000  367.399994  571290  17.110434   23.843211   39.001213   44.531932
4649    2021-03-25  365.399994  366.750000  352.250000  357.299988  292795  10.642696   17.223262   33.652906   40.335152
4650    2021-03-26  363.500000  363.500000  348.000000  350.299988  260489  8.017250    14.065566   30.528256   37.740355
4651    2021-03-30  351.049988  356.950012  338.700012  347.250000  367289  7.067658    12.866452   29.253742   36.658738
4652    2021-03-31  349.000000  357.250000  347.500000  354.149994  248493  30.384842   28.871121   35.785243   40.705512
4653    2021-04-01  357.000000  361.200012  351.000000  354.450012  192683  31.321411   29.527758   36.061654   40.878392
4654    2021-04-05  354.450012  354.450012  339.000000  342.200012  275972  18.570212   20.508825   30.322389   36.326258
4655    2021-04-06  345.000000  348.799988  340.000000  343.399994  237563  22.436682   23.190015   31.472914   37.049091
4656    2021-04-07  343.700012  347.350006  340.200012  342.500000  232796  21.480478   22.525218   31.058690   36.719996
4657    2021-04-08  345.750000  347.000000  341.399994  343.600006  255827  26.280462   25.567863   32.232666   37.434998
4658    2021-04-09  345.399994  345.500000  340.000000  341.000000  144333  22.259995   23.069502   30.893569   36.411390
Asked By: kbsudhir

||

Answers:

I was unable to reproduce your graph as I do not have the data that you are using, but with what I was able to figure out, you should be able to get the threshold lines by doing the same thing that you did in the standalone plot. So the complete code should look something like this:

fig = make_subplots(
rows=2, cols=1,
shared_xaxes=True,
vertical_spacing=0.01,
specs=[[{"type": "Candlestick"}],
       [{"type": "scatter"}]]
)

fig.add_trace(go.Candlestick(x=VipData['Date'].tail(30), open=VipData['Open'].tail(30), high=VipData['High'].tail(30),
                             low=VipData['Low'].tail(30), close=VipData['Close'].tail(30), name='Candlestick'),row=1, col=1)

fig.add_trace(go.Scatter(x=VipData['Date'].tail(30), y=VipData['RSI5'].tail(30), name='RSI5'),row=2, col=1)


fig.update_layout(xaxis_rangeslider_visible=False)

fig.update_layout(
    title='VIP Stock',
    yaxis_title='Price',
    xaxis_title='Period',
     shapes=[# Top Threshold line
                    {
                        'type': 'line',
                        'xref': 'paper',
                        'yref': 'y2',
                        'x0': 0,
                        'y0': 70, # use absolute value or variable here
                        'x1': 1,
                        'y1': 70, # ditto
                        'line': {
                            'color': 'rgb(0, 100, 0)',
                            'width': 1,
                            'dash': 'dash',
                        },
                    },
                    # Bottom Threshold Line
                    {
                        'type': 'line',
                        'xref': 'paper',
                        'yref': 'y2',
                        'x0': 0,
                        'y0': 30, # use absolute value or variable here
                        'x1': 1,
                        'y1': 30, # ditto
                        'line': {
                            'color': 'rgb(255, 0, 0)',
                            'width': 1,
                            'dash': 'dash',
                        },
                    },
    # Middle Threshold Line
                    {
                        'type': 'line',
                        'xref': 'paper',
                        'yref': 'y2',
                        'x0': 0,
                        'y0': 50, # use absolute value or variable here
                        'x1': 1,
                        'y1': 50, # ditto
                        'line': {
                            'color': 'rgb(0, 0, 0)',
                            'width': 1,
                            'dash': 'dash',
                        },
                    },
       ],
                      xaxis=dict(
        rangeselector=dict(
            buttons=list([
                dict(count=1,
                     label="1m",
                     step="month",
                     stepmode="backward"),
                dict(count=6,
                     label="6m",
                     step="month",
                     stepmode="backward"),
                dict(count=1,
                     label="YTD",
                     step="year",
                     stepmode="todate"),
                dict(count=1,
                     label="1y",
                     step="year",
                     stepmode="backward"),
                dict(step="all")
            ])
        ),
        rangeslider=dict(
            visible=True
        ),
        type="date"
    )
)

fig.show()

To show it on the second subplot, you must add 'yref':'y2' in each of your line shapes as seen in the code above.

Answered By: AS11

If you use Plotly Studio you can very easily create shapes that will draw whatever threshold shape you need. You need to create an account if you want do download the JSON but this free if you save the graph as public.

You can also just view the JSON tree and get the shape for you code from there if you don’t want to create an account:

https://chart-studio.plotly.com/

Answered By: Zaffer