Search code examples
subplotplotly-python

Error with Specs parameter of Plotly Subplots


I am getting Value Error:

The 'specs' argument to make_subplots must be a 2D list of dictionaries with dimensions (1 x 1). Received value of type <class 'list'>: [[{'secondary_y': False}], [{'secondary_y': True}], [{'colspan': 1}, None]]

I refer to the existing post plotly subplots issue with specs, value error and followed the same but error still persists.

Below is the code snippet:

import talib as ta
import yfinance as yf
import pandas as pd


import plotly.io as pio
pio.renderers.default='browser'
import plotly.graph_objects as go
from plotly.subplots import make_subplots

'''
Extracting the data
'''
VIP = yf.Ticker('VIPIND.NS')
df = VIP.history(period="max")
df.reset_index(inplace = True)
df['Date'] = pd.to_datetime(df['Date'])


'''
Creating the technical indicators
'''
df['EMA_Close'] = ta.EMA(df.Close,100)
df['MA_Close']  = ta.MA(df.Close,60)

df['MACD'],df['MACDsig'],df['MACDhist']=ta.MACD(df.Close,30,60,15)

'''
###############################
Creating Plots
###############################
'''

'''
Declaring subplots
'''
fig = make_subplots(rows=2, cols=1)#, shared_xaxes=True,print_grid=True)
fig = make_subplots(specs=[[{"secondary_y": False}],[{"secondary_y": True}],[{"colspan": 1}, None]])

'''
Ploting the first row with OHLC, EMA and MA lines
'''
fig.add_trace(go.Candlestick(x=df["Date"], open=df["Open"], high=df["High"],
                low=df["Low"], close=df["Close"], name="OHLC",showlegend=True),
                row=1, col=1,secondary_y=False)

fig.add_trace(go.Scatter(x=df['Date'], y=df['EMA_Close'], showlegend=True,
                         name="EMA Close",line=dict(color="MediumPurple")
                        ), row=1, col=1,secondary_y=False)

fig.add_trace(go.Scatter(x=df['Date'], y=df['MA_Close'], showlegend=True,
                         name="MA Close",line=dict(color="Orange")
                        ), row=1, col=1,secondary_y=False)

'''
Ploting the second row with MACD & MACDSig lines and MACDHist as histogram/bar
'''
fig.add_trace(go.Bar(x=df.Date,
                     y=df['MACDhist'],showlegend=True,name="MACD Hist",marker=dict(color='black')
                    ), row=2, col=1,secondary_y=False)


fig.add_trace(go.Scatter(x=df['Date'], y=df['MACDsig'], showlegend=True,
                         name="MACD Signal",line=dict(color="MediumPurple")
                        ), row=2, col=1,secondary_y=True)

fig.add_trace(go.Scatter(x=df['Date'], y=df['MACD'], showlegend=True,
                         name="MACD",line=dict(color="red")
                        ), row=2, col=1,secondary_y=True)

'''
Upadting the layout of the plot
'''
fig.update(layout_xaxis_rangeslider_visible=False)

fig.update_layout(height=600, width=1250)

fig.update_layout(
    title='OHLC and Volume',
    yaxis_title='Prices (Rs)',
    xaxis_title='Dates')

fig.update_layout(template="plotly_white")

fig.update_layout(
    margin=dict(l=20, r=20, t=40,b=20),)

# Providing desired Fonts for the plots
fig.update_layout(
    font_family="Courier New",
    font_color="blue",
    title_font_family="Times New Roman",
    title_font_color="red",
    legend_title_font_color="green")

fig.show()

Requesting guidance on where am I going wrong.

Regards Sudhir


Solution

  • You are getting the error because the dimension of your specs does not match the number of rows and cols you defined in your subplot. You have 2 rows and 1 col, which means your specs must be a list with 2x1 shape (i.e. a list of two lists. Here is an example:

    specs=[[{"secondary_y": True, "colspan": X, "rowspan": X, "b": 0.05, etc}] , 
           [{"secondary_y": False}]]).
    

    Also, keep in mind the max value that colspan can take is the value you define for the col parameter. Finally, if you need to pass more settings for each subplot you can simply add them inside their corresponding dictionary