Search code examples
pythonmatplotlibplotplotly

Plotly: How to add volume to a candlestick chart


code:

from plotly.offline import init_notebook_mode, iplot, iplot_mpl
    
def plot_train_test(train, test, date_split):
    data = [Candlestick(x=train.index, open=train['open'], high=train['high'], low=train['low'], close=train['close'],name='train'),
           Candlestick(x=test.index, open=test['open'], high=test['high'], low=test['low'], close=test['close'],name='test')
            ]
            layout = {
                'shapes': [
                    {'x0': date_split, 'x1': date_split, 'y0': 0, 'y1': 1, 'xref': 'x', 'yref': 'paper',
                     'line': {'color': 'rgb(0,0,0)', 'width': 1}}],
                'annotations': [{'x': date_split, 'y': 1.0, 'xref': 'x', 'yref': 'paper', 'showarrow': False, 'xanchor': 'left','text': ' test data'},
                    {'x': date_split, 'y': 1.0, 'xref': 'x', 'yref': 'paper', 'showarrow': False, 'xanchor': 'right', 'text': 'train data '}] }
            figure = Figure(data=data, layout=layout)
            iplot(figure)

The above code is ok.But now I want to 'volume' in this candlestick chart

code:

from plotly.offline import init_notebook_mode, iplot, iplot_mpl
        
def plot_train_test(train, test, date_split):
    data = [Candlestick(x=train.index, open=train['open'], high=train['high'], low=train['low'], close=train['close'],volume=train['volume'],name='train'),
           Candlestick(x=test.index, open=test['open'], high=test['high'], low=test['low'],close=test['close'],volume=test['volume'],name='test')]
            layout = {
                'shapes': [
                    {'x0': date_split, 'x1': date_split, 'y0': 0, 'y1': 1, 'xref': 'x', 'yref': 'paper',
                     'line': {'color': 'rgb(0,0,0)', 'width': 1}}
                ],
                'annotations': [
                    {'x': date_split, 'y': 1.0, 'xref': 'x', 'yref': 'paper', 'showarrow': False, 'xanchor': 'left',
                     'text': ' test data'},
                    {'x': date_split, 'y': 1.0, 'xref': 'x', 'yref': 'paper', 'showarrow': False, 'xanchor': 'right',
                     'text': 'train data '}
                ]
            }
            figure = Figure(data=data, layout=layout)
            iplot(figure) 

error:

ValueError: Invalid property specified for object of type plotly.graph_objs.Candlestick: 'volume'


Solution

  • You haven't provided a complete code snippet with a data sample, so I'm going to have to suggest a solution that builds on an example here.

    In any case, you're getting that error message simply because go.Candlestick does not have a Volume attribute. And it might not seem so at first, but you can easily set up go.Candlestick as an individual trace, and then include an individual go.Bar() trace for Volumes using:

    1. fig = make_subplots(specs=[[{"secondary_y": True}]])
    2. fig.add_traces(go.Candlestick(...), secondary_y=True)
    3. fig.add_traces(go.Bar(...), secondary_y=False)

    Plot:

    enter image description here

    Complete code:

    import plotly.graph_objects as go
    from plotly.subplots import make_subplots
    import pandas as pd
    
    # data
    df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv')
    
    # Create figure with secondary y-axis
    fig = make_subplots(specs=[[{"secondary_y": True}]])
    
    # include candlestick with rangeselector
    fig.add_trace(go.Candlestick(x=df['Date'],
                    open=df['AAPL.Open'], high=df['AAPL.High'],
                    low=df['AAPL.Low'], close=df['AAPL.Close']),
                   secondary_y=True)
    
    # include a go.Bar trace for volumes
    fig.add_trace(go.Bar(x=df['Date'], y=df['AAPL.Volume']),
                   secondary_y=False)
    
    fig.layout.yaxis2.showgrid=False
    fig.show()