1
votes

I am trying to plot a 3-subplot PlotLy graph. From top to bottom: Candlesticks, normal line graph, normal line graph.

Here is my code:

def chart_strategy(df):

    # Initialize figure with subplots
    fig = make_subplots(rows=3, cols=1)

    fig.add_trace(go.Figure( data = [go.Candlestick( x = df.index,
                                                    open = df['Open'],
                                                    close = df['Close'],
                                                    low = df['Low'],
                                                    high = df['High'])]),
                 row = 1, col = 1)


    fig.add_trace(go.Scatter(x = df.index, y = df['System Quality Number']), row = 2, col = 1)

    fig.add_trace(go.Scatter(x = df.index, y = df['Action']), row = 3, col =1)

    return fig

I get the following error:

ValueError: 
Invalid element(s) received for the 'data' property of 
    Invalid elements include: [Figure({
'data': [{'close': array([120.88, 120.93, 120.72, ..., 116.23, 115.78, 115.63]),
          'high': array([121.31, 121.2 , 121.11, ..., 116.86, 116.43, 115.73]),
          'low': array([120.8 , 120.79, 120.48, ..., 115.94, 115.68, 115.32]),
          'open': array([121.  , 120.81, 120.92, ..., 116.36, 116.23, 115.71]),
          'type': 'candlestick',
          'x': array([datetime.datetime(2019, 7, 19, 0, 0),
                      datetime.datetime(2019, 7, 22, 0, 0),
                      datetime.datetime(2019, 7, 23, 0, 0), ...,
                      datetime.datetime(2020, 5, 12, 0, 0),
                      datetime.datetime(2020, 5, 13, 0, 0),
                      datetime.datetime(2020, 5, 14, 0, 0)], dtype=object)}],
'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: ['area', 'bar', 'barpolar', 'box',
                 'candlestick', 'carpet', 'choropleth',
                 'choroplethmapbox', 'cone', 'contour',
                 'contourcarpet', 'densitymapbox', 'funnel',
                 'funnelarea', 'heatmap', 'heatmapgl',
                 'histogram', 'histogram2d',
                 'histogram2dcontour', '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, ...}])

I tried just plotting the candlestick chart alone and that worked fine so I'm pretty it has something to do with the row and column part, just not sure what to search next.

I used the following resources to write this code: https://plotly.com/python/table-subplots/ https://plotly.com/python/candlestick-charts/

1

1 Answers

2
votes

The problem is how your adding the first trace. You are using:

fig.add_trace(go.Figure( data = [go.Candlestick( x = df.index,...

but it should be:

fig.add_trace(go.Candlestick(x = df.index,...

import numpy as np
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots

N=14
df = pd.DataFrame({'Open': np.random.randint(1,29,N),
                   'Close': np.random.randint(1,29,N),
                   'Low': np.random.randint(1,29,N),
                   'High': np.random.randint(1,29,N),
                   'Action': np.random.choice(['sell', 'buy'],N),
                   'System Quality Number': np.random.randint(1,29,N)})


def chart_strategy(df):
    fig = make_subplots(rows=3, cols=1)

    fig.add_trace(go.Candlestick(x = df.index,
                                open = df['Open'],
                                close = df['Close'],
                                low = df['Low'],
                                high = df['High']),
                 row = 1, col = 1)

    fig.add_trace(go.Scatter(x = df.index, y = df['System Quality Number']), 
                             row = 2, col = 1)

    fig.add_trace(go.Scatter(x = df.index, y = df['Action']), row = 3, col =1)

    fig.update_xaxes(row=1, col=1, rangeslider_thickness=0.05)
    fig.update_layout(width=900, height=900)

    return fig

chart_strategy(df)