I have problems formulating a dashboard, so that the the number of inputs to a callback can change depending on settings.
Currently I have some input data (wind, solar, temp) for a country (UK) that each have a slider, so I can filter some of these values out and see a new output.
My challenge is, that when choosing another country e.g. France, I will another set of input data (wind, temp) and so I will have another number of input data to the last callback.
The following code slips needs to be changed:
dbc.CardColumns(
[
dbc.Card(CardRangeSlider('Wind', int(Data['Wind'].max()), int(Data['Wind'].min()))),
dbc.Card(CardRangeSlider('Solar', int(Data['Solar'].max()), int(Data['Solar'].min()))),
dbc.Card(CardRangeSlider('Temp', int(Data['Temp'].max()), int(Data['Temp'].min())))
]
)
----------------------------------------
@app.callback(Output('Output', 'figure'), [Input('intermediate-value', 'children'),
Input('Wind', 'value'),
Input('Solar', 'value'),
Input('Temp', 'value')])
----------------------------------------
def update_table(jsonified_data, Wind, Solar, Temp):
I have been looking into pattern matching callbacks, as a solution but can not get my head around a solution.
Do you have an idea of how this can be done?
Beneath is a simplified example of the code.
# -------------------- IMPORTS --------------------
import dash
from dash.dependencies import Output, Input
import dash_core_components as dcc
import dash_bootstrap_components as dbc
import dash_html_components as html
import pandas as pd
import numpy as np
Data= pd.DataFrame(np.random.rand(10,4)*100, columns=list(['Wind', 'Solar', 'Temp', 'Output']))
# ---------------------- APP ----------------------
app = dash.Dash(external_stylesheets=[dbc.themes.BOOTSTRAP])#app = dash.Dash(external_stylesheets=[dbc.themes.BOOTSTRAP], update_title=None)
app.title = 'Consumption'
# -------------------- Cards --------------------
def CardRangeSlider(ID, Max, Min):
card=[
dbc.CardHeader(ID),
dbc.CardBody(
[dcc.RangeSlider(
id=ID,
min=Min,
max=Max,
value=[Min, Max],
allowCross=False,
marks={i: str(i) for i in range(Min, Max, int((Max-Min)/6))}
),
])
]
return card
# -------------------- Naming --------------------
Features=Data.columns.values.tolist()
Country=['Austria','Belgium', 'France', 'Germany', 'Netherlands', 'Switzerland', 'UK']
# -------------------- LAYOUT --------------------
app.layout = html.Div([
dbc.Navbar(
[dbc.Col(html.Div([dcc.Dropdown(
id='Country dropdown',
options=[
{"label": i, "value": i}
for i in Country
],
value = 'UK'
)],style={'width': '30%', 'display': 'border-radius'})),
], color='rgb(000, 081, 135)',
dark=True),
dbc.Row(
[dbc.Col(dbc.Card(
dbc.CardColumns(
[
dbc.Card(CardRangeSlider('Wind', int(Data['Wind'].max()), int(Data['Wind'].min()))),
dbc.Card(CardRangeSlider('Solar', int(Data['Solar'].max()), int(Data['Solar'].min()))),
dbc.Card(CardRangeSlider('Temp', int(Data['Temp'].max()), int(Data['Temp'].min())))
]
)
),),
],
align="start"),
dbc.Row(
[
dbc.Col(dcc.Graph(id='Output', animate=True),)
], justify="center",
),
html.Div(id='intermediate-value', style={'display': 'none'}) # Hidden table containing Data
])
@app.callback(Output('intermediate-value', 'children'), [Input('Country dropdown', 'value')])
def DataSaving(Country):
Data= pd.DataFrame(np.random.rand(10,4)*100, columns=list(['Wind', 'Solar', 'Temp', 'Output']))
return Data.to_json(date_format='iso', orient='split')
@app.callback(Output('Output', 'figure'), [Input('intermediate-value', 'children'),
Input('Wind', 'value'),
Input('Solar', 'value'),
Input('Temp', 'value')])
def update_table(jsonified_data, Wind, Solar, Temp):
Data = pd.read_json(jsonified_data, orient='split')
Data['RollingOutput']=Data['Output'].cumsum()
Datai=Data.loc[(Data['Wind']>=Wind[0])&(Data['Wind']<=Wind[1])]
Datai=Datai.loc[(Datai['Solar']>=Solar[0])&(Datai['Solar']<=Solar[1])]
Datai=Datai.loc[(Datai['Temp']>=Temp[0])&(Datai['Temp']<=Temp[1])]
Datai['RollingOutputSpecific']=Datai['Output'].cumsum()
# Structuring figure data
datafig = []
datafig.append({'x': Data.index, 'y': Data['RollingOutput'], 'type': 'line', 'name': 'Rolling Output', 'line':dict(color="#870000")})
datafig.append({'x': Datai.index, 'y': Datai['RollingOutputSpecific'], 'type': 'lines', 'name': 'Rolling Output Specific', 'line':dict(color="#ff8c00", width=4)})
# Max and min values of the graph
# Max_y=max(max(Data['Output']),max(Datai['Output']))
#Min_y=min(min(Data['Output']),min(Datai['Output']))
Min_x=Data.index[0]
Max_x=Data.index[-1]
fig = {
'data': datafig,
'layout': {
'title': 'Output',
'margin':dict(l= 100, b= 100, t=100, r= 100,pad=4),
'legend':dict( orientation="h",
yanchor="bottom",
y=1.02,
xanchor="right",
x=1),
'xaxis' : dict(
title='DateTime',
range=[Min_x, Max_x],
titlefont=dict(
family='Courier New, monospace',
size=20,
color='#7f7f7f',
shape='hvh'
)),
'yaxis' : dict(
title='Output',
# range=[Min_y, Max_y],
titlefont=dict(
family='Helvetica, monospace',
size=20,
color='#7f7f7f',
shape='hvh'
))
}
}
return fig
if __name__ == '__main__':
app.run_server()