plotly dash: two dropdowns and two dataframes

Question:

I have a problem with dropdowns and can’t handle two DataFrames…here is my code

from dash import Dash, html, dcc
import plotly.express as px
import numpy as np
import pandas as pd
import plotly.io as pio
from dash.dependencies import Input, Output
pio.renderers.default = "browser"

raw_cut = pd.read_excel(r"C:TestTest.xlsx",)

My Df looks like:

GESCHLECHT_VP1 B_oder_R
M B
W B
W R
M R
M R

Here, I have a column called "GESCHLECHT_VP1" with the gender M and W and I have a column called "B_oder_R", which tell me if a person have the option "B" or "R".

What I want to do is to bar plot interactive the number and percentage of gender and of the options B and R independently – here: 3/5 M, 2/5 W and 2/5 B, 3/5 R. I actually do NOT want to know "B or R" per Gender…for example for gender M there is one time B and two times R are not interesting.

I want that the user can first 1) choose between "Geschlecht" and "B- und R-Abschluss".
After that, I want that the user can 2) see the number or percentage of one of these two.

I made it, that one can choose between number and percentage for Geschlecht, but I don’t know how to make the switch between the two graphs/dataframes "Geschlecht" and "B- und R-Abschluss".

# gender m or w
mf = (
    raw_cut["GESCHLECHT_VP1"]
    .value_counts()
    .rename_axis("Geschlecht")
    .reset_index(name="Anzahl")
)
mf["Prozent"] = mf["Geschlecht"].map(
    raw_cut["GESCHLECHT_VP1"].value_counts(normalize=True).mul(100).round(1)
)

# B and R 
br = (
    raw_cut["B_oder_R"]
    .value_counts()
    .rename_axis("BR")
    .reset_index(name="Anzahl")
)
br["Prozent"] = br["BR"].map(
    raw_cut["B_oder_R"].value_counts(normalize=True).mul(100).round(1)
)

Now I make the Dash App

app = Dash(__name__)

# here I define a new DataFrame to switch between the two options of 1)
wasliste = pd.DataFrame()
wasliste["was"] = ["Geschlecht", "B- und R-Abschluss"]

app.layout = html.Div(
    [
        html.Div(
            [
                html.H1("Übersicht: Risp und Inzidenzn - Datengrundlage"),
                html.P("Einheit"),
                dcc.Dropdown(
                    id="was",
                    options=[
                        {"label": "Geschlecht", "value": "was"},
                        {"label": "B- und R-Abschluss", "value": "was"},
                    ],
                    value="Geschlecht",
                ),
                dcc.Dropdown(
                    id="einheitdropdown",
                    options=[
                        {
                            "label": "Anzahl",
                            "value": "Anzahl",
                        },
                        {"label": "Prozent", "value": "Prozent"},
                    ],
                    value="Prozent",
                ),
                dcc.Graph(id="Ohne Differenzierung"),
            ]
        ),
        html.Div(),  # hier Layout für rechts einfügen (wenn das klappt)
    ]
)

@app.callback(
    Output("Ohne Differenzierung", "figure"),
    [Input("einheitdropdown", "value"), Input("was", "value")],
)
def updaten(einheitdropdown, what):
    if what == "Geschlecht":

        if einheitdropdown == "Prozent":
            figure1 = px.bar(
                mf,
                x="Geschlecht",
                y="Prozent",
                color="Geschlecht",
                barmode="group",
            )
        if einheitdropdown == "Anzahl":
            figure1 = px.bar(
                mf,
                x="Geschlecht",
                y="Anzahl",
                color="Geschlecht",
                barmode="group",
            )
    return figure1

    if what == "B- und R-Abschluss":

        if einheitdropdown == "Prozent":
            figure2 = px.bar(
                br,
                x="BR",
                y="Prozent",
                color="BR",
                barmode="group",
            )
        if einheitdropdown == "Anzahl":
            figure2 = px.bar(
                br,
                x="BR",
                y="Anzahl",
                color="BR",
                barmode="group",
            )
    return figure2


if __name__ == "__main__":
    app.run_server(debug=True, port=3040)

This is not working. Can someone help?

Thank you!

Asked By: Eli Hektor

||

Answers:

I got it!

app.layout = html.Div(
    [
        html.Div(
            [
                html.H1("Übersicht: Risp und Inzidenzen - Datengrundlage"),
                html.P("Kriterium"),
                dcc.Dropdown(
                    id="kriteriumsdropdown",
                    options=[
                        {"label": i, "value": i}
                        for i in zs.Kriterium.drop_duplicates()
                    ],
                    value="Geschlecht",
                ),
                html.P("Einheit"),
                dcc.Dropdown(
                    id="einheitdropdown",
                    options=[
                        {
                            "label": "Anzahl",
                            "value": "Anzahl",
                        },
                        {"label": "Prozent", "value": "Prozent"},
                    ],
                    value="Prozent",
                ),
                dcc.Graph(id="Ohne Differenzierung"),
            ]
        ),
        html.Div(
            [html.H2("Platzhalter")]
        ), 
    ]
)


@app.callback(
    Output("Ohne Differenzierung", "figure"),
    [Input("einheitdropdown", "value"), Input("kriteriumsdropdown", "value")],
)
def updaten(einheitdropdown, kriteriumsdropdown):
    if kriteriumsdropdown == "Geschlecht":
        if einheitdropdown == "Prozent":
            figure1 = px.bar(
                mf,
                x="Konkret",
                y="Prozent",
                color="Konkret",
                barmode="group",
                labels={"Konkret": "Geschlecht"},
                # color_discrete_map= {"W": "pink", "M": "gray"}
                # wenn y stetig und nicht diskret ist: color_continuos_scale = px.colors.diverging.Picnic, range_color = [1,1000]
            )
        if einheitdropdown == "Anzahl":
            figure1 = px.bar(
                mf,
                x="Konkret",
                y="Anzahl",
                color="Konkret",
                barmode="group",
                labels={"Konkret": "Geschlecht"},
            )
        return figure1

    elif kriteriumsdropdown == "BR":
        if einheitdropdown == "Prozent":
            figure2 = px.bar(
                br,
                x="Konkret",
                y="Prozent",
                color="Konkret",
                barmode="group",
                labels={"Konkret": "B oder R"},
            )
        if einheitdropdown == "Anzahl":
            figure2 = px.bar(
                br,
                x="Konkret",
                y="Anzahl",
                color="Konkret",
                barmode="group",
                labels={"Konkret": "B oder R"},
            )
        return figure2


if __name__ == "__main__":
    app.run_server(debug=True, port=3040)
Answered By: Eli Hektor