Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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'

like image 895
William Avatar asked Nov 04 '20 23:11

William


3 Answers

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()
like image 191
vestland Avatar answered Oct 10 '22 06:10

vestland


Here is my improvement implementation based on the previous answer by Vestland, with some labelling and colouring improvements.

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

candlesticks = go.Candlestick(
    x=candles.index,
    open=candles['open'],
    high=candles['high'],
    low=candles['low'],
    close=candles['close'],
    showlegend=False
)

volume_bars = go.Bar(
    x=candles.index,
    y=candles['volume'],
    showlegend=False,
    marker={
        "color": "rgba(128,128,128,0.5)",
    }
)

fig = go.Figure(candlesticks)
fig = make_subplots(specs=[[{"secondary_y": True}]])
fig.add_trace(candlesticks, secondary_y=True)
fig.add_trace(volume_bars, secondary_y=False)
fig.update_layout(title="ETH/USDC pool after Uniswap v3 deployment", height=800)
fig.update_yaxes(title="Price $", secondary_y=True, showgrid=True)
fig.update_yaxes(title="Volume $", secondary_y=False, showgrid=False)
fig.show()

enter image description here

You can find the full source code in this open-source notebook.

like image 2
Mikko Ohtamaa Avatar answered Oct 10 '22 05:10

Mikko Ohtamaa


If you looking add smaller subplot of volume just below OHLC chart, you can use:

  1. rows and cols to specify the grid for subplots.
  2. shared_xaxes=True for same zoom and filtering
  3. row_width=[0.2, 0.7] to change height ratio of charts. ie. smaller volume chart than OHLC

Plot: Plotly Chart

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

# data
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv')


# Create subplots and mention plot grid size
fig = make_subplots(rows=2, cols=1, shared_xaxes=True, 
               vertical_spacing=0.03, subplot_titles=('OHLC', 'Volume'), 
               row_width=[0.2, 0.7])

# Plot OHLC on 1st row
fig.add_trace(go.Candlestick(x=df["Date"], open=df["AAPL.Open"], high=df["AAPL.High"],
                low=df["AAPL.Low"], close=df["AAPL.Close"], name="OHLC"), 
                row=1, col=1
)

# Bar trace for volumes on 2nd row without legend
fig.add_trace(go.Bar(x=df['Date'], y=df['AAPL.Volume'], showlegend=False), row=2, col=1)

# Do not show OHLC's rangeslider plot 
fig.update(layout_xaxis_rangeslider_visible=False)
fig.show()
like image 24
Mega J Avatar answered Oct 10 '22 05:10

Mega J