Change the values of dropdown in y axis based on values depend on x axis

I want to populate y axis dropdown only for specific values in their respective values in x axis .But for example when I selected Name in x axis no options were present in y axis dropdwn corresponding to it.

from datetime import date
import pandas as pd
from dash.dependencies import Input, Output, State
import dash_core_components as dcc
import dash_html_components as html
from plotly import graph_objs as go
import dash
from datasets import data
import plotly.express as px
from app import app,indicator
import dash_bootstrap_components as dbc


df1,df2,df3,df = data.getapi()

cols = df.columns



dropdwn_option = [{'label':x,'value':x} for x in cols]
employee_drpdwn = [{'label':x,'value':x} for x in df['Name'].unique()]




layout = [
    dbc.Row([
        dbc.Col([

            html.Div(
                className="control dropdown-styles",
                children=dcc.Dropdown(
                    id="x_axis",
                    options=dropdwn_option,
                    value=cols[0],
                ),
            ),


        ],width='3'),

        dbc.Col([
            html.Div(
                className="control dropdown-styles",
                children=dcc.Dropdown(
                    id="y_axis",
                ),
            ),
        ],width='3'),

        dbc.Col([
            html.Div(
                className="control dropdown-styles",
                children=dcc.Dropdown(
                    id="employees",
                    options=employee_drpdwn,
                    clearable=False,
                    multi=True
                ),
            ),

        ],width='6')
    ]),

    dbc.Row([
        dbc.Col([
            html.Div(
                id="converted_count_container",
                className="chart_div pretty_container",
                children=[
                    html.P(id='dynamic_axis_title',children=''),
                    dcc.Graph(
                        id="converted_count",
                        config=dict(displayModeBar=True),
                    ),
                ],
            ),

        ],width='12'),
    ])

]


@app.callback(Output(component_id='y_axis',component_property='options'),
              [Input(component_id='x_axis',component_property='value')])
def populate_y_vals(x_name):
    if x_name == 'Name':
        print(x_name)
        poss_vals = ['BugsRaisedCnt']
        return [{'label':x,'value':x} for x in poss_vals]
    elif x_name == 'Days QA':
        return [{'label':'Name','value':''Name'}]
    elif x_name == 'Location':
        return [{'label':'Count','value':'Count'}]

@app.callback(
    Output("converted_count", "figure"),
    Output('dynamic_axis_title','children'),
    [Input("x_axis", "value"),
     Input("y_axis", "value"),
     Input("employees","value")],
)
def create_graph(x_axis,y_axis,selected_employees):
    if len(selected_employees) == 0:
        return dash.no_update
    else:
        clrs = 'rgb(222,0,0)'
        dff = df[(df.Name.isin(selected_employees))]
        # if((is_numeric_dtype(dff[x_val]) == False) or (is_numeric_dtype(dff[y_val]) == False)):
        #     return dash.no_update,True
        #fig = px.bar(dff, x=x_axis, y=y_axis, color='Name',orientation='h')
        x_val = dff[x_axis]
        y_val = dff[y_axis]
        data = [
            go.Bar(
                y=x_val,
                x=y_val,
                orientation="h",
                name='Name'
            )
        ]  # x could be any column value since its a count
        print(x_axis)
        print(y_axis)
        heading = x_axis+' vs '+y_axis
        layout = go.Layout(
            autosize=True,
            barmode="group",
            paper_bgcolor="white",
            plot_bgcolor="white",
            title=heading,
            xaxis= dict(title=y_axis),
            yaxis = dict(title=x_axis)
        )

        return {"data": data, "layout": layout},heading


I am new to plotly dash , can someone plz help me out ?
Thanks .

Hi @Maverick06 welcome and thank you for your post.

One way to do this would be to create first a dictionary where you define the specific values you want for x and the corresponding values in y:

all_options = {
"xvalue1": ("yvalueA","yvalueB" etc),
"xvalue2":  ("yvalueC","yvalueD" etc)
}

Then create a callback that defines the options available for y axis dropdown depending on x axis dropdown value:

@app.callback(
    Output('y_axis', 'options'),
    [Input('x_axis', 'value')],
)
def set_y_options(selected_x):
    return [{'label': i, 'value': i} for i in all_options[selected_x]]

And finally, another callback allowing the user to chose a value for y axis dropdown between the available values

@app.callback(
    Output('ydropdown-id', 'value'),
    [Input('ydropdown-id', 'options')],
)
def set_y_value(available_options):
    return available_options[0]['value']

Does that help?

1 Like

Thanks @davi , It worked .

1 Like

You are welcome, great to hear I could help!