1

I am making a plot with subplot 1 and subplot 2. The subplot 1 is the stock price plot, and subplot 2 is the index plot. I want to compare each stock with each index side by side. So, I intend to make two dropdown menus with one controlling subplot 1 and another one controlling subplot 2.

ash=JupyterDash(__name__)

stocks=['stock1','stock2']
indexs = ['index1', 'index2']

fig=go.Figure()
dash.layout = html.Div([dcc.Graph(id = 'plot', figure = fig), 
                html.P([html.Label("stocks"),
                        dcc.Dropdown(id='stock', 
                                     options=[{'label': i, 'value': i} for i in stocks], 
                                     value=stocks[0])], 
                       [html.Label("indexs"), 
                        dcc.Dropdown(id='index', 
                                     options=[{'label': i, 'value': i} for i in indexs], 
                                     value=labels[0])], style={'width': '80%', 
                                                               'padding-left':'4%',
                                                               'padding-right': '14%',
                                                               'display': 'inline block', 
                                                               'align-items': 'center', 
                                                               'justify-content': 'center'})])

                                                             
                                                              
@dash.callback(Output('plot', 'figure'),
             [Input('stock', 'value'),
             Input('index', 'value')])

def update_figure(X,Y):
   
    if X=='stock1':
        fig1=make_subplots(rows=2, cols=1)
        fig1.add_trace(go.Scatter(x = list(stock1['date']), y = list(stock1['price'])), row=1, col=1)
        
        if Y=='index1':
            fig1.add_trace(go.Candlestick(x=index1['date'],
                open=index1['open'],
                high=index1['high'],
                low=index1['low'],
                close=index1['close']), row=2, col=1)
         
            fig1.update_layout(xaxis2_rangeslider_visible=False)
            
        if Y=='index2':
            fig1.add_trace(go.Candlestick(x=index2['date'],
                open=index2['open'],
                high=index2['high'],
                low=index2['low'],
                close=index2['close']), row=2, col=1)
         
            fig1.update_layout(xaxis2_rangeslider_visible=False)
            
        return fig1
    
    if X=='stock2':
        .... #same format
        
dash.run_server(mode='inline')     

It's not working; please help me!

1 Answer 1

1
  • there are multiple issues with your dash layout. Have fixed these and re-formatted to make it more readable
  • your callback is basically ok, but repeated conditional code is not needed if you structure your data appropriately. For purposes of demonstration I have used yfinance data and structured to group by ticker
from jupyter_dash import JupyterDash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
from plotly.subplots import make_subplots
import plotly.graph_objects as go

import yfinance as yf
import datetime as dt

stocks=['SPY','AAPL', "MSFT"]
data = yf.download(" ".join(stocks), start="2020-01-01", end=dt.datetime.today(), group_by="ticker")

indexs = ["^DJI", "^GSPC", "^IXIC", "^NYA"]
idx = yf.download(" ".join(indexs), start="2020-01-01", end=dt.datetime.today(), group_by="ticker")

dash = JupyterDash(__name__)

fig = go.Figure()
dash.layout = html.Div(
    [
        dcc.Graph(id="plot", figure=fig),
        html.P(
            [
                html.Label("stocks"),
                dcc.Dropdown(
                    id="stock",
                    options=[{"label": i, "value": i} for i in stocks],
                    value=stocks[0],
                ),
                html.Label("indexs"),
                dcc.Dropdown(
                    id="index",
                    options=[{"label": i, "value": i} for i in indexs],
                    value=indexs[0],
                ),
            ]
        ),
    ],
    style={
        "width": "80%",
        "padding-left": "4%",
        "padding-right": "14%",
        "display": "inline block",
        "align-items": "center",
        "justify-content": "center",
    },
)


@dash.callback(
    Output("plot", "figure"), [Input("stock", "value"), Input("index", "value")]
)
def update_figure(X, Y):
    fig = make_subplots(rows=2, cols=1)
    fig.add_trace(go.Scatter(x=data[X].index, y=data[X]["Close"], name=X), row=1, col=1)
    fig.add_trace(
        go.Candlestick(
            x=idx[Y].index,
            open=idx[Y]["Open"],
            high=idx[Y]["High"],
            low=idx[Y]["Low"],
            close=idx[Y]["Close"],
            name=Y,
        ),
        row=2,
        col=1,
    )
    return fig


dash.run_server(mode="inline")
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.