Plotly: How to change between daily and hourly candlesticks using a dropdown menu?

Viewed 589

I am trying to change graph data with dropdown button.

my graph is candlestick, and i want to change graph by day <-> minutes 60

I tried below code, but when i select dropdown items, candlestick graph disappear.

I guess passing parameter is problem. How can i fix this?

fig = make_subplots(specs=[[{"secondary_y": True}]])

fig.add_trace(go.Candlestick(x=df_price_day['date'],
                                    open=df_price_day['open'], high=df_price_day['high'],
                                    low=df_price_day['low'], close=df_price_day['close'],
                                    increasing_line_color= 'red', decreasing_line_color= 'blue', opacity=0.7,
                                    name='Day', yaxis='y'
                                  )
                   )

self.fig.add_trace(go.Bar(x=df_price_day['date'], y=df_price_day['volume'],
                          name='Volume', opacity=0.5
                          , yaxis='y2'
                          )
                   )

Day = dict(x = df_price_day['date'],
            open = df_price_day['open'], high = df_price_day['high'],
            low = df_price_day['low'], close = df_price_day['close'])
min60 = dict(x = df_price_min60['date'],
            open = df_price_min60['open'], high = df_price_min60['high'],
            low = df_price_min60['low'], close = df_price_min60['close'])


self.fig.update_layout(updatemenus=
                       [{'buttons': [
                           {'method': 'update',
                             'label': 'Day',
                             'args': [Day, ]},
                            {'method': 'update',
                             'label': 'Minute 60',
                             'args': [min60, ]}],
                'direction': 'down',
                'showactive': True, }])

self.fig.show()
1 Answers

This answer contains two suggestions using:

1. Two buttons in a dropdown menu

2. One button with toggle functionality


1: Dropdown

The following procedure uses a dropdown menu to build a candle chart using this data sample:

           Date   AAPL.Open   AAPL.High    AAPL.Low  AAPL.Close  AAPL.Volume
501  2017-02-10  132.460007  132.940002  132.050003  132.119995     20065500
502  2017-02-13  133.080002  133.820007  132.750000  133.289993     23035400
503  2017-02-14  133.470001  135.089996  133.250000  135.020004     32815500
504  2017-02-15  135.520004  136.270004  134.619995  135.509995     35501600
505  2017-02-16  135.669998  135.899994  134.839996  135.350006     22118000

Plot 1.1

enter image description here¨

Plot 1.2

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').tail(90)
df = df[df.columns[:6]]
df['Date'] = pd.date_range("2018-01-01", periods=len(df), freq="H")
# df = df.set_index('Date')

df.columns = df.columns.str.replace('AAPL.', '')
names = df.columns
dfd = df.groupby(pd.Grouper(key = 'Date', freq='D')).agg({'Open': 'first',
                                                          'High': 'max',
                                                          'Low': 'min',
                                                          'Close': 'last'}).reset_index()

fig = go.Figure(data=[go.Candlestick(
    x=df['Date'],
    open=df['Open'], high=df['High'],
    low=df['Low'], close=df['Close'],
#     increasing_line_color= 'cyan', decreasing_line_color= 'gray'
)])
# fig.show()
fig.update_layout(title = 'Hourly')

# construct menus
updatemenus = [{
#                 'active':1,
                'buttons': [{'method': 'update',
                             'label': 'Hourly',
                             'args': [
                                      # 1. updates to the traces
                                      {'open': [list(df.Open)],
                                       'high': [list(df.High)],
                                       'low': [list(df.Low)],
                                       'close': [list(df.Close)],
                                       'x':[list(df.Date)],
                                       'visible': True}, 
                                      
                                      # 2. updates to the layout
                                      {'title':'Hourly'},
                                      
                                      # 3. which traces are affected 
#                                       [0, 1],
                                      
                                      ],  },
                            {'method': 'update',
                             'label': 'Daily', 
                             'args': [
                                       # 1. updates to the traces  
                                       {'open': [list(dfd.Open)],
                                        'high': [list(dfd.High)],
                                        'low': [list(dfd.Low)],
                                        'close': [list(dfd.Close)],
                                        'x':[list(dfd.Date)],
                                       'visible': True},
                                      
                                       # 2. updates to the layout
                                       {'title':'Daily'},
                                       
                                       # 3. which traces are affected
#                                        [0, 1]
                                      ]
                            
                            },],
                'type':'dropdown',
#                 'type':'dropdown',
                'direction': 'down',
                'showactive': True,}]

# update layout with buttons, and show the figure
fig.update_layout(updatemenus=updatemenus)
fig.show()

2: Here's a suggestion using a reproducible data sample and a toggle button:

Plot 2.1 - Hourly

enter image description here

Plot 2.2 - Daily

enter image description here

If this is something you can use, I'll gladly explaing the details.

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').tail(90)
df = df[df.columns[:6]]
df['Date'] = pd.date_range("2018-01-01", periods=len(df), freq="H")
# df = df.set_index('Date')

df.columns = df.columns.str.replace(r'AAPL.', '')
names = df.columns
dfd = df.groupby(pd.Grouper(key = 'Date', freq='D')).agg({'Open': 'first',
                                                          'High': 'max',
                                                          'Low': 'min',
                                                          'Close': 'last'}).reset_index()


fig = go.Figure(data=[go.Candlestick(
    x=df['Date'],
    open=df['Open'], high=df['High'],
    low=df['Low'], close=df['Close'],
#     increasing_line_color= 'cyan', decreasing_line_color= 'gray'
)])
# fig.show()
fig.update_layout(title = 'Hourly')

# construct menus
updatemenus = [{
#                 'active':1,
                'buttons': [{'method': 'update',
                             'label': 'Toggle Hourly / Daily',
                             'args': [
                                      # 1. updates to the traces
                                      {'open': [list(df.Open)],
                                       'high': [list(df.High)],
                                       'low': [list(df.Low)],
                                       'low': [list(df.Close)],
                                       'x':[list(df.Date)],
                                       'visible': True}, 
                                      
                                      # 2. updates to the layout
                                      {'title':'Hourly'},
                                      
                                      # 3. which traces are affected 
#                                       [0, 1],
                                      
                                      ],
                             'args2': [
                                       # 1. updates to the traces  
                                       {'open': [list(dfd.Open)],
                                        'high': [list(dfd.High)],
                                        'low': [list(dfd.Low)],
                                        'low': [list(dfd.Close)],
                                        'x':[list(dfd.Date)],
                                       'visible': True},
                                      
                                       # 2. updates to the layout
                                       {'title':'Daily'},
                                       
                                       # 3. which traces are affected
#                                        [0, 1]
                                      ]
                              },
                            ],
                'type':'buttons',
#                 'type':'dropdown',
                'direction': 'down',
                'showactive': True,}]

# update layout with buttons, and show the figure
fig.update_layout(updatemenus=updatemenus)
fig.show()
Related