Adi Putra
Adi Putra

Reputation: 35

Python plotting figure on subplot using plotly

I have this below which is working but I want to plot the moving average also inside the candlestick chart at col=1 and row=1

import plotly.graph_objects as go
from plotly.subplots import make_subplots

        fig = make_subplots(rows=3, cols=1, shared_xaxes=True, vertical_spacing=0.03, row_width=[0.3, 0.2, 0.7])
        fig.add_trace(go.Candlestick(x=df.index,open=df['Open'], high=df['High'], low=df['Low'], close=df['Close'], name='Price'), row=1, col=1) ###line need to change
        fig.add_trace(go.Bar(x=df.index, y=df['Volume'], name='Volume'), row=2, col=1)
        fig.add_trace(go.Scatter(x=df.index, y=df['RSI'], line=dict(color="black"), name='RSI'), row=3, col=1)
        fig.add_hrect(y0=0, y1=30, fillcolor="red", opacity=0.25, line_width=0, row=3, col=1)
        fig.add_hrect(y0=70, y1=100, fillcolor="green", opacity=0.25, line_width=0, row=3, col=1)
        fig.update_yaxes(title_text='Price', row=1, col=1)
        fig.update_yaxes(title_text='Volume', row=2, col=1)
        fig.update_yaxes(title_text='RSI', row=3, col=1)

so I change the line marked by comment ###line need to change above with following code which I verified to be working if running alone.

    fig = go.Figure(data=[go.Candlestick(x=df.index,
                                     open=df.Open, 
                                     high=df.High,
                                     low=df.Low,
                                     close=df.Close), 
                      go.Scatter(x=df.index, y=df.SMA20, line=dict(color='orange', width=1)),
                      go.Scatter(x=df.index, y=df.SMA50, line=dict(color='green', width=1))])

as such the final code looked like shown below but somehow is not working. any idea? Any clue will be appreciated. Thanks!

import plotly.graph_objects as go
from plotly.subplots import make_subplots

        fig = make_subplots(rows=3, cols=1, shared_xaxes=True, vertical_spacing=0.03, row_width=[0.3, 0.2, 0.7])
        fig.add_trace(go.Figure(data=[go.Candlestick(x=df.index,
                                     open=df.Open, 
                                     high=df.High,
                                     low=df.Low,
                                     close=df.Close), 
                      go.Scatter(x=df.index, y=df.SMA20, line=dict(color='orange', width=1)),
                      go.Scatter(x=df.index, y=df.SMA50, line=dict(color='green', width=1))]), row=1, col=1) ###line need to change
        fig.add_trace(go.Bar(x=df.index, y=df['Volume'], name='Volume'), row=2, col=1)
        fig.add_trace(go.Scatter(x=df.index, y=df['RSI'], line=dict(color="black"), name='RSI'), row=3, col=1)
        fig.add_hrect(y0=0, y1=30, fillcolor="red", opacity=0.25, line_width=0, row=3, col=1)
        fig.add_hrect(y0=70, y1=100, fillcolor="green", opacity=0.25, line_width=0, row=3, col=1)
        fig.update_yaxes(title_text='Price', row=1, col=1)
        fig.update_yaxes(title_text='Volume', row=2, col=1)
        fig.update_yaxes(title_text='RSI', row=3, col=1)

the error is :

ValueError: 
    Invalid element(s) received for the 'data' property of 
        Invalid elements include: [Figure({
    'data': [{'close': array([452.04, 460.04, 459.63, ..., 146.14, 146.09, 145.6 ]),
              'high': array([453.1 , 464.17, 460.  , ..., 147.11, 146.7 , 147.71]),
              'low': array([441.19, 455.71, 452.18, ..., 145.63, 145.52, 145.3 ]),
              'open': array([441.99 , 457.72 , 459.315, ..., 146.35 , 146.2  , 146.44 ]),
              'type': 'candlestick',
              'x': [2020-08-12 00:00:00, 2020-08-13 00:00:00, 2020-08-14 00:00:00,
                    ..., 2021-08-06 00:00:00, 2021-08-09 00:00:00, 2021-08-10
                    00:00:00]},
             {'line': {'color': 'orange', 'width': 1},
              'type': 'scatter',
              'x': [2020-08-12 00:00:00, 2020-08-13 00:00:00, 2020-08-14 00:00:00,
                    ..., 2021-08-06 00:00:00, 2021-08-09 00:00:00, 2021-08-10
                    00:00:00],
              'y': array([409.057 , 412.7545, 416.4705, ..., 146.4395, 146.519 , 146.517 ])},
             {'line': {'color': 'green', 'width': 1},
              'type': 'scatter',
              'x': [2020-08-12 00:00:00, 2020-08-13 00:00:00, 2020-08-14 00:00:00,
                    ..., 2021-08-06 00:00:00, 2021-08-09 00:00:00, 2021-08-10
                    00:00:00],
              'y': array([378.5454, 381.2438, 383.99  , ..., 137.7988, 138.215 , 138.6348])}],
    'layout': {'template': '...'}
})]

    The 'data' property is a tuple of trace instances
    that may be specified as:
      - A list or tuple of trace instances
        (e.g. [Scatter(...), Bar(...)])
      - A single trace instance
        (e.g. Scatter(...), Bar(...), etc.)
      - A list or tuple of dicts of string/value properties where:
        - The 'type' property specifies the trace type
            One of: ['bar', 'barpolar', 'box', 'candlestick',
                     'carpet', 'choropleth', 'choroplethmapbox',
                     'cone', 'contour', 'contourcarpet',
                     'densitymapbox', 'funnel', 'funnelarea',
                     'heatmap', 'heatmapgl', 'histogram',
                     'histogram2d', 'histogram2dcontour', 'icicle',
                     'image', 'indicator', 'isosurface', 'mesh3d',
                     'ohlc', 'parcats', 'parcoords', 'pie',
                     'pointcloud', 'sankey', 'scatter',
                     'scatter3d', 'scattercarpet', 'scattergeo',
                     'scattergl', 'scattermapbox', 'scatterpolar',
                     'scatterpolargl', 'scatterternary', 'splom',
                     'streamtube', 'sunburst', 'surface', 'table',
                     'treemap', 'violin', 'volume', 'waterfall']

        - All remaining properties are passed to the constructor of
          the specified trace type

        (e.g. [{'type': 'scatter', ...}, {'type': 'bar, ...}])

Upvotes: 0

Views: 1381

Answers (1)

r-beginners
r-beginners

Reputation: 35115

In this case, adding the moving average as a stand-alone graph is no problem; the RSI indicator requires a new library, so we have replaced it with the closing price, so please correct that item. This graph does not have enough vertical size, so we have added the height of the graph.

import plotly.graph_objects as go
from plotly.subplots import make_subplots

fig = make_subplots(rows=3, cols=1,
                    shared_xaxes=True,
                    vertical_spacing=0.03,
                    row_width=[0.3, 0.2, 0.7]
                   )

fig.add_trace(go.Candlestick(x=df.index,
                             open=df.Open, 
                             high=df.High,
                             low=df.Low,
                             close=df.Close),row=1, col=1)
fig.add_trace(go.Scatter(x=df.index, 
                         y=df.SMA20, 
                         line=dict(color='orange', width=1),
                         name='SMA20'
                        ), row=1, col=1)
              
fig.add_trace(go.Scatter(x=df.index, 
                         y=df.SMA50, 
                         line=dict(color='green', width=1),
                         name='SMA50'
                        ), row=1, col=1)

fig.add_trace(go.Bar(x=df.index, 
                     y=df['Volume'],
                     name='Volume'), row=2, col=1)

fig.add_trace(go.Scatter(x=df.index, 
                         y=df['Close'],
                         line=dict(color="black"),
                         name='Close'), row=3, col=1)

fig.add_hrect(y0=0, y1=30, 
              fillcolor="red",
              opacity=0.25,
              line_width=0, row=3, col=1)

fig.add_hrect(y0=70, y1=100,
              fillcolor="green", 
              opacity=0.25,
              line_width=0, row=3, col=1)

fig.update_yaxes(title_text='Price', row=1, col=1)
fig.update_yaxes(title_text='Volume', row=2, col=1)
fig.update_yaxes(title_text='RSI', row=3, col=1)

fig.update_layout(height=800)

fig.show()

enter image description here

Upvotes: 1

Related Questions