Search code examples
pythonplotlyplotly-dash

"Dash plotly": I face a problem in connecting two inputs to an output also the bas x axis is not sorted and correctly categorized


This is the custom function which is 100% wrong. what is the correct code to filter the graph according to two different inputs?

app.layout = html.Div([
html.Div([
    html.Div([
        html.H3('Select a Country'),
        dcc.Dropdown(id = 'drop',
options =[{'label': i, 'value': i} for i in df["Country"].unique()] + [{'label': 'Select all', 'value': 'All'}], 
value='All')
    ],style={'width': '35%','display':'inline-block'}),

    html.Div([
        html.H3('Select a Reason'),
        dcc.Dropdown(id = 'drop1',
options =[{'label': i, 'value': i} for i in df["Source"].unique()] + [{'label': 'Select all', 'value': 'All'}], 
value='All')
    ],style={'width': '35%','display':'inline-block'}),
], className="row"),
  html.Div(dcc.Graph(
 id = "graph"))
],style={'width': '100%', 'display': 'inline-block'})

@app.callback(Output('graph','figure'),
          [Input('drop', 'value'),Input('drop1', 'value')])
          



def update_graph(country,reason):
if (country == 'value') | (reason == 'value'):
    dff=df

else:
    
    dff = df[(df['Country']==country) &
            (df['Source']==reason)]


fig = go.Figure([go.Bar(x=dff["Week"], y=dff["Source"].value_counts())]) 
      
fig.update_layout(barmode='relative', title_text='Number of Orders')
fig.update_xaxes(type='category')
return fig

Solution

    • have simulated your data frame
    • you have logic bombs rather than structural issues
      1. if (country == 'All') or (reason == 'All'): conditional logic for callback data frame filtering
      2. figure creation, made no sense so replaced
    import dash
    from dash import html, dcc
    from jupyter_dash import JupyterDash
    import plotly.graph_objects as go
    from dash.dependencies import Input, Output, State
    import pandas as pd
    import numpy as np
    
    app = JupyterDash(__name__)
    
    S = 100
    df = pd.DataFrame({"Country":np.random.choice(["UK","US"], S), "Source":np.random.choice(list("ABC"), S),
                      "Date":pd.date_range("1-jan-2021",freq="D",periods=S)}).pipe(lambda d: d.assign(Week=d["Date"].dt.week))
    
    app.layout = html.Div(
        [
            html.Div(
                [
                    html.Div(
                        [
                            html.H3("Select a Country"),
                            dcc.Dropdown(
                                id="drop",
                                options=[
                                    {"label": i, "value": i} for i in df["Country"].unique()
                                ]
                                + [{"label": "Select all", "value": "All"}],
                                value="All",
                            ),
                        ],
                        style={"width": "35%", "display": "inline-block"},
                    ),
                    html.Div(
                        [
                            html.H3("Select a Reason"),
                            dcc.Dropdown(
                                id="drop1",
                                options=[
                                    {"label": i, "value": i} for i in df["Source"].unique()
                                ]
                                + [{"label": "Select all", "value": "All"}],
                                value="All",
                            ),
                        ],
                        style={"width": "35%", "display": "inline-block"},
                    ),
                ],
                className="row",
            ),
            html.Div(dcc.Graph(id="graph")),
        ],
        style={"width": "100%", "display": "inline-block"},
    )
    
    @app.callback(Output('graph','figure'),
              [Input('drop', 'value'),Input('drop1', 'value')])
    def update_graph(country,reason):
        if (country == 'All') or (reason == 'All'):
            dff=df
        else:
            dff = df[(df['Country']==country) &
                (df['Source']==reason)]
    
        dff = dff.drop(columns=["Date"]).value_counts().reset_index()
        fig = go.Figure([go.Bar(x=dff["Week"], y=dff[0])])
    #     fig = go.Figure([go.Bar(x=dff["Week"], y=dff["Source"].value_counts())])
    
        fig.update_layout(barmode='relative', title_text='Number of Orders')
        fig.update_xaxes(type='category')
        return fig
    
    app.run_server(mode="inline")