Spaces:
Sleeping
Sleeping
# -*- coding: utf-8 -*- | |
# import json | |
# import urllib | |
import plotly.graph_objects as go | |
from dash import Dash, Input, Output, dcc, html | |
from dash.exceptions import PreventUpdate | |
app = Dash(__name__) | |
app.layout = html.Div( | |
[ | |
html.H1("Sankey diagram"), | |
html.P("Data"), | |
dcc.Input(id="SM1", placeholder="SM1"), | |
dcc.Input(id="SM2", placeholder="SM2"), | |
dcc.Input(id="SM3", placeholder="SM3"), | |
dcc.Input(id="SM4", placeholder="SM4"), | |
dcc.Input(id="SM5", placeholder="SM5"), | |
dcc.Input(id="BS1", placeholder="BS1"), | |
dcc.Input(id="BS2", placeholder="BS2"), | |
dcc.Input(id="BS3", placeholder="BS3"), | |
dcc.Input(id="BS4", placeholder="BS4"), | |
dcc.Input(id="BS5", placeholder="BS5"), | |
dcc.Input(id="rainfall", placeholder="Rainfall"), | |
dcc.Input(id="et", placeholder="ET"), | |
html.Button("Calculate", id="submit"), | |
html.H4("Water conservation diagram"), | |
dcc.Graph(id="graph"), | |
html.P("Opacity"), | |
dcc.Slider(id="slider", min=0, max=1, value=0.5, step=0.1), | |
] | |
) | |
def get_excess_clipped_moist_ETb(moisture, bucket_size): | |
excess = 0 if moisture <= bucket_size else moisture - bucket_size | |
moist_out = moisture if moisture <= bucket_size else bucket_size | |
moist_out = moist_out if moisture >= 0 else 0 | |
ETb = 0 if moisture >= 0 else -moisture | |
return ETb, moist_out, excess | |
def model(prev_state, R, ET, buckets): | |
old = {x + "_prev": y for x, y in prev_state.items()} | |
# layer 0 to 5 cm | |
SM1 = 0.2 * old["SM1_prev"] + R - 0.5 * ET | |
Exc1, SM1, ETb1 = get_excess_clipped_moist_ETb(SM1, buckets["BS1"]) | |
# layer 5 to 15 cm | |
SM2 = 0.95 * old["SM2_prev"] + 0.8 * old["SM1_prev"] - 0.2 * ETb1 + Exc1 | |
Exc2, SM2, ETb2 = get_excess_clipped_moist_ETb(SM2, buckets["BS2"]) | |
# Run Off | |
if (SM1 > buckets["BS1"]) * (SM2 > buckets["BS2"]): | |
Exc2 = 0 | |
run_off = Exc2 | |
else: | |
run_off = 0 | |
# layer 15 to 30 cm | |
SM3 = 0.95 * old["SM3_prev"] + 0.05 * old["SM2_prev"] - 0.15 * ETb2 + Exc2 | |
Exc3, SM3, ETb3 = get_excess_clipped_moist_ETb(SM3, buckets["BS3"]) | |
# layer 30 to 60 cm | |
SM4 = 0.95 * old["SM4_prev"] + 0.05 * old["SM3_prev"] - 0.1 * ETb3 + Exc3 | |
Exc4, SM4, ETb4 = get_excess_clipped_moist_ETb(SM4, buckets["BS4"]) | |
# layer 60 to 100 cm | |
SM5 = 0.99 * old["SM5_prev"] + 0.01 * old["SM4_prev"] - 0.05 * ETb4 + Exc4 | |
Exc5, SM5, ETb5 = get_excess_clipped_moist_ETb(SM5, buckets["BS5"]) | |
DD = 0.01 * old["SM5_prev"] + Exc5 | |
return [ | |
{ | |
"SM1": SM1, | |
"SM2": SM2, | |
"SM3": SM3, | |
"SM4": SM4, | |
"SM5": SM5, | |
"DD": DD, | |
}, | |
{ | |
"ETb1": ETb1, | |
"ETb2": ETb2, | |
"ETb3": ETb3, | |
"ETb4": ETb4, | |
"ETb5": ETb5, | |
}, | |
{ | |
"Exc1": Exc1, | |
"Exc2": Exc2, | |
"Exc3": Exc3, | |
"Exc4": Exc4, | |
"Exc5": Exc5, | |
}, | |
run_off, | |
] | |
def display_sankey( | |
opacity, SM1, SM2, SM3, SM4, SM5, BS1, BS2, BS3, BS4, BS5, R, ET, submit | |
): | |
if submit == 0 or submit is None: | |
raise PreventUpdate | |
buckets = { | |
"BS1": BS1, | |
"BS2": BS2, | |
"BS3": BS3, | |
"BS4": BS4, | |
"BS5": BS5, | |
} | |
prev_state = { | |
"SM1": SM1, | |
"SM2": SM2, | |
"SM3": SM3, | |
"SM4": SM4, | |
"SM5": SM5, | |
} | |
SMs, ETbs, Excs, run_off = model(prev_state, R, ET, buckets) | |
node = dict( | |
pad=15, | |
thickness=20, | |
line=dict(color="black", width=0.5), | |
label=[ | |
"SM1_prev", | |
"SM2_prev", | |
"SM3_prev", | |
"SM4_prev", | |
"SM5_prev", # 0-4 | |
"SM1", | |
"SM2", | |
"SM3", | |
"SM4", | |
"SM5", # 5-9 | |
"ETb1", | |
"ETb2", | |
"ETb3", | |
"ETb4", | |
"ETb5", # 10-14 | |
"Exc1", | |
"Exc2", | |
"Exc3", | |
"Exc4", | |
"Exc5", # 15-19 | |
"R", | |
"ET", | |
"DD", | |
"runoff", | |
], # 20, 21, 22, 23 | |
color="blue", | |
) | |
link = dict( | |
source=[0, 0, 1, 1, 2, 2, 3, 3, 4, 4], # indices correspond to labels | |
target=[5, 6, 6, 7, 7, 8, 8, 9, 9, 22], | |
value=[], | |
) | |
fig = go.Figure(go.Sankey(link=link, node=node)) | |
fig.update_layout(font_size=10) | |
return fig | |
app.run_server(debug=True) | |