How to save and access multiple data frames from dcc.Store in plotly dash

Hi @UdayGuntupalli

Here is another example to get you started:


import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State, MATCH, ALL
import pandas as pd
import base64
import io


# Declare Constants
DROPDOWN_LIST = ["GOOG", "FB", "AAPL", "AMZN", "BABA"]


# App Layout
app = dash.Dash(
    __name__, meta_tags=[{"name": "viewport", "content": "width=device-width"}],
)
app.title = "Dash Tool"
server = app.server


def parse_data(contents, filename) -> pd.DataFrame:
    content_type, content_string = contents.split(",")

    decoded = base64.b64decode(content_string)
    try:
        if "csv" in filename:
            # Assume that the user uploaded a CSV or TXT file
            df = pd.read_csv(io.StringIO(decoded.decode("utf-8")))
        elif "xls" in filename:
            # Assume that the user uploaded an excel file
            df = pd.read_excel(io.BytesIO(decoded))
        elif "txt" or "tsv" in filename:
            # Assume that the user upl, delimiter = r'\s+'oaded an excel file
            df = pd.read_csv(io.StringIO(decoded.decode("utf-8")), delimiter=r"\s+")
    except Exception as e:
        print(e)
        return html.Div(["There was an error processing this file."])

    return df


app.layout = html.Div(
    [
        # empty Div to trigger javascript file for graph resizing
        html.Div(id="output-clientside"),
        html.Div(
            [
                html.Div(
                    [
                        html.Img(
                            src=app.get_asset_url("dash-logo.png"),
                            id="plotly-image",
                            style={
                                "height": "60px",
                                "width": "auto",
                                "margin-bottom": "25px",
                            },
                        )
                    ],
                    className="one-third column",
                ),
                html.Div(
                    [
                        html.Div(
                            [html.H3("Dash Tool", style={"margin-bottom": "0px"},),]
                        )
                    ],
                    className="one-half column",
                    id="title",
                ),
            ],
            id="header",
            className="row flex-display",
            style={"margin-bottom": "25px"},
        ),
        html.Div(
            [
                html.Div(
                    [
                        html.P("Number of Dynamic Objects:", className="control_label"),
                        dcc.Slider(
                            id="dynamic_objects",
                            min=2.0,
                            max=10.0,
                            value=2.0,
                            step=1.0,
                            marks={
                                2: "2",
                                3: "3",
                                4: "4",
                                5: "5",
                                6: "6",
                                7: "7",
                                8: "8",
                                9: "9",
                                10: "10",
                            },
                            className="dcc_control",
                        ),
                        html.P("Load Dynamic Objects:", className="control_label"),
                        dcc.Checklist(
                            id="load_flag",
                            options=[{"label": "Yes", "value": "Y"},],
                            value=["Y"],
                            labelStyle={"display": "inline-block"},
                        ),
                        html.Div(id="dropdown_container", children=[]),
                        html.Div(id="dropdown_container_output"),
                        html.Div(id="file_container", children=[]),
                        html.Div(id="file_container_output"),
                    ],
                    className="pretty_container four columns",
                    id="cross-filter-options",
                ),
                html.Div(
                    [
                        html.Div(
                            [dcc.Graph(id="count_graph")],
                            id="countGraphContainer",
                            className="pretty_container",
                        ),
                    ],
                    id="right-column",
                    className="eight columns",
                ),
            ],
            className="row flex-display",
        ),
    ],
    id="mainContainer",
    style={"display": "flex", "flex-direction": "column"},
)


# Define callbacks
@app.callback(
    Output(component_id="dropdown_container_output", component_property="children"),
    [
        Input(component_id="dynamic_objects", component_property="value"),
        Input(component_id="load_flag", component_property="value"),
    ],
)
def update_source_dropdowns(n_dynamic_objects: int, flag: list) -> list:
    """Controls the number of drop-downs available"""
    if flag == ["Y"]:
        children = []
        for i in range(0, n_dynamic_objects):
            new_dropdown = html.Div(
                [
                    dcc.Dropdown(
                        id={
                            "index": f"""source_dropdown_{str(i)}""",
                            "type": "dynamic-dropdown",
                        },
                        options=[{"label": v, "value": v} for v in DROPDOWN_LIST],
                    ),
                    dcc.Store(
                        id={
                            "type": "dynamic-store",
                            "index": f"""source_dropdown_{str(i)}""",
                        }
                    ),
                    dcc.Upload(
                        id={
                            "type": "dynamic-button",
                            "index": f"""source_dropdown_{str(i)}""",
                        },
                        children=html.Button("Upload File"),
                    ),
                ]
            )
            children.append(new_dropdown)
        return children


@app.callback(
    Output({"type": "dynamic-store", "index": MATCH}, "data"),
    [
        Input({"type": "dynamic-button", "index": MATCH}, "contents"),
        Input({"type": "dynamic-button", "index": MATCH}, "filename"),
    ],
    State({"type": "dynamic-dropdown", "index": MATCH}, "value"),
)
def save_data_to_store(contents, filename, dd_value):
    print(filename)
    if contents:
        df = parse_data(contents, filename)
        data = {"dropdown": dd_value, "df": df.to_dict("records")}
        return data


@app.callback(
    Output("file_container_output", "children"),
    Input({"type": "dynamic-store", "index": ALL}, "data"),
)
def display_output(data):
    output = ""
    if data is []:
        return dash.no_update
    for d in data:

        dropdown = "" if d is None else d["dropdown"]
        uploaded_df = "" if d is None else d["df"]

        print(dropdown)
        print(uploaded_df)

        # create whatever you want to display with the data for each
        output = html.Div("Output data")

    return output


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

1 Like