简体   繁体   中英

Dynamically changing bar chart according to inputs in Plotly Dash

For a quite period of time I am trying to design my first Dash app. But I am not succesful and therefore I would like to ask for a help.

What I am trying to achieve is an app, where in the first instance I input some numbers according to which I do some calculations over given dataframe and then do a bar chart . This shouldn't be hard.

So far what I have got:


app = Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div(
    [
        html.I("Get me the first input needed", style={"margin-right": "115px"}),
        html.I("Get me an additional input to the first one too!"),
        html.Br(),
        dcc.Input(id="input1", type="number", placeholder="", style={'marginRight':'10px'}),
        dcc.Input(id="input11", type="number", placeholder="", style={'marginRight':'10px'}),
        ... another 3 very similar blocks for inputs,
        dcc.Slider(min=0, max=10, step=1,
               value=5,
               id='my_slider',
               marks={
                        1: {'label': '1 year', 'style': {'color': '#77b0b1'}},
                        2: {'label': '2 years'},
                        3: {'label': '3 years'},
                        4: {'label': '4 years'},
                        5: {'label': '5 years'},
                        6: {'label': '6 years'},
                        7: {'label': '7 years'},
                        8: {'label': '8 years'},
                        9: {'label': '9 years'},
                        10: {'label': '10 years'}
                    }),
        dcc.Graph(id='bar-chart'),
        dcc.Store(id='intermediate-value')
    ]
)

Slider part is not really used because I am stucked, but just for sure I showed you all. After this part, callback part, where I would like to use those inputs to manipulate given dataframe. Before that, my inspiration for all this is here: >https://dash.plotly.com/sharing-data-between-callbacks

@app.callback(
    [Output('intermediate-value', 'data')],
#     [Output(component_id="bar-chart", component_property="figure")],
    [Input("input1", "value"),
    Input("input11", "value"),
    Input("input2", "value"),
    Input("input22", "value"),
    Input("input3", "value"),
    Input("input33", "value"),
    Input('my_slider', 'value')]
)
def get_output(input1, input11, input2, input22, input3, input33, my_slider):
    global dff  
    user_adapt_perc= [0.025, 0.135, 0.34, 0.34, 0.16]
    
    first_positions = df.shape[0] * input11
    first_money= df.iloc[:int(first_positions ),]['count'].sum() * input1 * 12

    second_positions = df.shape[0] * (input22)
    second_money= df.iloc[int(first_positions):int(second_positions ),]['count'].sum() * input2 * 12

    third_positions = df.shape[0] * (input33)
    third_money = df.iloc[int(second_positions ):int(third_positions ),]['count'].sum() * input3 * 12

    total_money = first_money + second_money + third_money
    
    dff = pd.DataFrame({"year":[1,2,3,4,5], "cash":list(np.cumsum(user_adapt_perc) * all_money) - total_money })
    
    return dff.to_dict() 

Variable all_money is something pre-calculated before whole Dash app, lets say 10 000 000. And df is just a dataframe of some input numbers used to calculate an important part. I have to return something else than DataFrame as it is not supported.

After this part, where all those calculations are correct, I am trying to plot a bar chart based on these calculations:

@app.callback(Output(component_id="bar-chart", component_property="figure"), Input('intermediate-value', 'data'))
def get_figure(dictionary_data):
    dff2 = pd.DataFrame(dictionary_data)
    barchart = px.bar(
        data_frame=dff2,
        x="rok",
        y="uspora",
        opacity=0.9,
        barmode='group')
    
    return barchart

When I input everything, I get an error:

dash._grouping.SchemaTypeValidationError: Schema: [<Output `intermediate-value.data`>]
Path: ()
Expected type: (<class 'tuple'>, <class 'list'>)
Received value of type <class 'dict'>:

which I guess has something even before bar chart. I was also trying to add into output part bar-chart figure, but I have never came to that point.

Any help? Much appreciated.

Could you hint me/help me please?

Try changing what you have:

return dff.to_dict() 

to this:

return dff.to_dict(orient='records') 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM