Return html.Div in callback with different plots

Hi,
I’m trying to return an html.Div element that contains different plots depending on a dropdown parameter. Here’s my code:

app = JupyterDash(__name__)
app.config.suppress_callback_exceptions = True

### app layout made of two Div. with the first one the user selects the (operation, method, vol_col, flag) and the second one calls a callback
# to a function that returns another div with the suitable plots


app.layout = html.Div([
    html.Div(
    [
        html.P("Choose operation:"),
        dcc.Dropdown(
            id="operation",
            options=[{"value": x, "label": x} for x in ops],
            value='ant-1',
            clearable=False,
            style={"width": "40%"}
        ),
        html.P("Choose method:"),
        dcc.Dropdown(
            id="method",
            options=[{"value": x, "label": x} for x in meth],
            value='bs',
            clearable=False,
            style={"width": "40%"}
        ),
        html.P("Choose volatility column:"),
        dcc.Dropdown(
            id="vol_col",
            options=[{"value": x, "label": x} for x in vc],
            value='10_day_vol',
            clearable=False,
            style={"width": "40%"}
        )
    ]),
        html.Div(id='plotter', children=html.Div())
    
    ])


@app.callback(
    [
        Output(component_id="plotter", component_property="children")
    ],
    [
        Input(component_id="operation", component_property="value"),
        Input(component_id="method", component_property="value"),
        Input(component_id="vol_col", component_property="value")
    ]
)
def plotter(operation, method, vol_col, flag):
    if (operation in mm_operations) and (operation in op_operations):
        
        return html.Div(children=[dcc.Graph(plot_mm_metrics(pnl, operation)),
                 dcc.Graph(plot_price_call(pnl, operation, vol_col)),
                 dcc.Graph(plot_valuation(pnl, operation, vol_col, method)),
                 dcc.Graph(plot_valuation_change(pnl, operation, vol_col, method)),
                 dcc.Graph(plot_metrics(pnl, operation, vol_col)),
                 dcc.Graph(plot_pnl(pnl, operation, vol_col, method))]
                 )
    elif (operation in mm_operations) and (not operation in op_operations):
        return html.Div(children=[dcc.Graph(plot_mm_metrics(pnl, operation)),
                 dcc.Graph(plot_metrics(pnl, operation, vol_col)),
                 dcc.Graph(plot_pnl(pnl, operation, vol_col, method))]
                )
    else: #(not operation in mm_operations) and (operation in op_operations):
        return html.Div(children=[dcc.Graph(plot_price_call(pnl, operation, vol_col)),
                 dcc.Graph(plot_valuation(pnl, operation, vol_col, method)),
                 dcc.Graph(plot_valuation_change(pnl, operation, vol_col, method)),
                 dcc.Graph(plot_pnl(pnl, operation, vol_col, method))]
                 )    

However I get an error that I cannot understand:
TypeError: id prop must be a string or dict, not Figure

What id is it referring to? can anyone help me on this? Thanks

HI @davflo welcome to the forums.

I suppose, your different plotting functions return a figure object.

so instead of doing dcc.Graph(plot_metrics(pnl, operation, vol_col)) try dcc.Graph(figure=plot_metrics(pnl, operation, vol_col))

Right now, you are not using keyword arguments, so the figure object is associated with the first parameter of the dcc.Graph() which is the ID

Cool! Thanks for the explanation! yes, it works great now!

1 Like