Search code examples
pythonplotlyplotly-dashplotly-python

Showing graphs Two dropdown that can choose multiple


I'm new in plotly and dash. I'm trying to make two dropdown menu that can choose multiple options. When I choose 1 and 2 on first dropdown menu and choose 2 and 3 on second dropdown menu, my expectation is showing line graphs(1-2,1-3,2-2,2-3) Here is my expectation.

Example for Expectation dropdown menu

Example for graphs

Here is my code for not able to select multi dropdown menu

import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import numpy as np
from dash.dependencies import Output, Input


data = pd.read_csv("data/testTemp02.csv")
data["Time"] = pd.to_datetime(data["Time"], format="%H:%M:%S").dt.time
data.sort_values("Time", inplace=True)


app = dash.Dash(__name__)

app.layout = html.Div(
    children=[
        html.Div(
            children=[
                html.H1(
                    children="TempMon Analytics",
                    className="header_title",
                ),
                html.P(
                    children="Testing TempMon Analytics",
                    className="header_description",
                ),                 
            ],
            className="header",
        ),
        html.Div(
            children=[
                html.Div(
                    children=[
                        html.Div(
                            children="Slot", 
                            className="menu-title"),
                        dcc.Dropdown(
                            id="slot-filter",
                            options=[
                                {"label": Slot, "value": Slot}
                                for Slot in np.sort(data.Slot.unique())
                            ],
                            value="Select Slot(s)",
                            clearable=False,
                            className="dropdown",
                        ),
                    ],
                ),
                html.Div(
                    children=[
                        html.Div(
                            children="Dut", 
                            className="menu-title"),
                        dcc.Dropdown(
                            id="dut-filter",
                            options=[
                                {"label": Dut, "value": Dut}
                                for Dut in data.Dut.unique()
                            ],
                            value="Select Dut(s)",
                            clearable=False,
                            searchable=False,
                            #multi=True,
                            className="dropdown",
                        ),
                    ],
                ),
            ],
            className="menu",
        ),
        html.Div(
            children=[
                html.Div(
                    children=dcc.Graph(
                        id="dut-chart",
                        config={"displayModeBar": True},
                    ),
                    className="card",
                ),
            ],
            className="wrapper",
        ),

    ]
)
@app.callback(
    Output("dut-chart", "figure"),
    [
        Input("slot-filter", "value"),
        Input("dut-filter", "value"),
    ],
)
def update_charts(Slot, Dut):
    mask = (
        (data.Slot == Slot)
        & (data.Dut == Dut)
    )
    filtered_data = data.loc[mask, :]

    dut_chart_figure = {
        "data": [
            {
                "x": filtered_data["Time"],
                "y": filtered_data["DutTemp"],
                "type": "lines",
            },
        ],
        "layout": {
            "title": {
                "text": "Dut temp(°C)", 
                },
                "colorway": ["#E12D39"],
        },
    }
    return dut_chart_figure

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

and Here is my data named testTemp02.csv

Slot,Time,Dut,DutTemp
1,0:00:01,1,0
1,0:00:02,1,11
1,0:00:03,1,21
1,0:00:04,1,24
1,0:00:05,1,27
1,0:00:06,1,40
1,0:00:07,1,42
1,0:00:08,1,45
1,0:00:09,1,60
1,0:00:10,1,90
1,0:00:01,2,0
1,0:00:02,2,15
1,0:00:03,2,23
1,0:00:04,2,17
1,0:00:05,2,27
1,0:00:06,2,33
1,0:00:07,2,42
1,0:00:08,2,48
1,0:00:09,2,69
1,0:00:10,2,88
1,0:00:01,3,0
1,0:00:02,3,25
1,0:00:03,3,10
1,0:00:04,3,28
1,0:00:05,3,38
1,0:00:06,3,45
1,0:00:07,3,37
1,0:00:08,3,49
1,0:00:09,3,66
1,0:00:10,3,92
2,0:00:01,1,10
2,0:00:02,1,10
2,0:00:03,1,10
2,0:00:04,1,10
2,0:00:05,1,10
2,0:00:06,1,10
2,0:00:07,1,10
2,0:00:08,1,10
2,0:00:09,1,10
2,0:00:10,1,10
2,0:00:01,2,0
2,0:00:02,2,25
2,0:00:03,2,60
2,0:00:04,2,30
2,0:00:05,2,49
2,0:00:06,2,36
2,0:00:07,2,23
2,0:00:08,2,6
2,0:00:09,2,100
2,0:00:10,2,25
2,0:00:01,3,9
2,0:00:02,3,48
2,0:00:03,3,29
2,0:00:04,3,48
2,0:00:05,3,9
2,0:00:06,3,29
2,0:00:07,3,129
2,0:00:08,3,34
2,0:00:09,3,23
2,0:00:10,3,57

Here is my current Showing one graphs with choosing two dropdown


Solution

  • In this case, if the two conditions allow multiple drop-down selections, the graph must be created even if there are single and multiple selections. The data frames extracted from the values of each dropdown are created. The graph cannot be created as is. Extract from the value of the direct product of the two conditions from the value of the selected dropdown, for the data frame. I am not sure if this method is best practice.

    import dash
    import dash_core_components as dcc
    import dash_html_components as html
    import pandas as pd
    import numpy as np
    from dash.dependencies import Output, Input
    from itertools import product 
    import plotly.graph_objects as go
    
    
    app = dash.Dash(__name__)
    
    app.layout = html.Div(
        children=[
            html.Div(
                children=[
                    html.H1(
                        children="TempMon Analytics",
                        className="header_title",
                    ),
                    html.P(
                        children="Testing TempMon Analytics",
                        className="header_description",
                    ),                 
                ],
                className="header",
            ),
            html.Div(
                children=[
                    html.Div(
                        children=[
                            html.Div(
                                children="Slot", 
                                className="menu-title"),
                            dcc.Dropdown(
                                id="slot-filter",
                                options=[
                                    {"label": Slot, "value": Slot}
                                    for Slot in np.sort(data.Slot.unique())
                                ],
                                multi=True,
                                value=["Select Slot(s)"],
                                clearable=False,
                                className="dropdown",
                            ),
                        ],
                    ),
                    html.Div(
                        children=[
                            html.Div(
                                children="Dut", 
                                className="menu-title"),
                            dcc.Dropdown(
                                id="dut-filter",
                                options=[
                                    {"label": Dut, "value": Dut}
                                    for Dut in data.Dut.unique()
                                ],
                                value=["Select Dut(s)"],
                                clearable=False,
                                searchable=False,
                                multi=True,
                                className="dropdown",
                            ),
                        ],
                    ),
                ],
                className="menu",
            ),
            html.Div(
                children=[
                    html.Div(
                        children=dcc.Graph(
                            id="dut-chart",
                            config={"displayModeBar": True},
                        ),
                        className="card",
                    ),
                ],
                className="wrapper",
            ),
    
        ]
    )
    @app.callback(
        Output("dut-chart", "figure"),
        [
            Input("slot-filter", "value"),
            Input("dut-filter", "value"),
        ],
    )
    def update_charts(Slot, Dut):
        mask = (
            (data.Slot.isin(Slot))
            & (data.Dut.isin(Dut))
        )
        filtered_data = data.loc[mask, :]
        
        conditions = product(Slot, Dut)
        fig = go.Figure()
        for v in conditions:
            # print('Slot', v[0], 'Dut', v[1])
            df = filtered_data[(filtered_data['Slot'] == v[0]) & (filtered_data['Dut'] == v[1])] 
            fig.add_trace(go.Scatter(
                x=df['Time'],
                y=df['DutTemp'],
                name='Slot:{} Dut:{}'.format(v[0],v[1])
            ))
        fig.update_layout(title="Dut temp(°C)")
        return fig
    
    if __name__ == "__main__":
        app.run_server(debug=True)
    

    enter image description here