diff --git a/app.jl b/app.jl index a2bccf1..d369522 100644 --- a/app.jl +++ b/app.jl @@ -8,6 +8,7 @@ using ..Delhi using ..Utils @genietools + const prod_mode = (haskey(ENV, "GENIE_ENV") && ENV["GENIE_ENV"] == "prod") ? "true" : "false" const button_color = prod_mode == "true" ? "grey" : "primary" const button_tooltip = prod_mode == "true" ? "Run the app locally to enable this button" : "" @@ -21,9 +22,7 @@ else @save "data.jld2" train_df test_df scaling end -if isfile("params.jld") - @load "params.jld" θ -end + const features = [:meantemp, :humidity, :wind_speed, :meanpressure] const units = ["Celsius", "g/m³ of water", "km/h", "hPa"] const feature_names = ["Mean temperature", "Humidity", "Wind speed", "Mean pressure"] @@ -39,16 +38,18 @@ const obs_grid = 4:4:20 # we train on an increasing amount of the first k obs const maxiters = 150 const lr = 5e-3 const N_steps = 100 # number of points in prediction over the full time range -_, θ_new, init_state = neural_ode(train_df.t, length(features)) +_, _, init_state = neural_ode(train_df.t, length(features)) t_grid = range(minimum(data.t), maximum(data.t), length=N_steps) |> collect -# We cache the predictions for the full time range to avoid recomputing them +# We can cache the predictions for the full time range to avoid recomputing them #= const ŷ_cached = predict(Vector(train_df[1,features]), t_grid, θ, init_state) =# +@load "params.jld2" θ + @app begin @in start=false @in animate=false @out prod_mode = prod_mode - @out θ=θ + @private θ=θ @out losses = Float32[] @out temp_pdata = [PlotlyBase.scatter(x=[1,2,3])] @out hum_pdata = [PlotlyBase.scatter(x=[1,2,3])] @@ -61,7 +62,7 @@ t_grid = range(minimum(data.t), maximum(data.t), length=N_steps) |> collect @in r = 30 @in pstep=1 @out mse = [0.0,0.0,0.0,0.0] - @in k = 20 + @private k = 20 @private state = init_state @onbutton start begin @@ -72,7 +73,7 @@ t_grid = range(minimum(data.t), maximum(data.t), length=N_steps) |> collect # We pass the Observable version of θ to `train` , which will update its value during training. # When the training is finished we store the final value in θ θ, state = train(Vector(train_df[!,:t]), Matrix(train_df[!,features]), obs_grid, maxiters, lr, rng, __model__.θ; progress=true); - @save "params.jld" θ + @save "params.jld2" θ end @onchange r begin k = 20 diff --git a/app.jl.html b/app.jl.html index 8a1d55f..ef79115 100644 --- a/app.jl.html +++ b/app.jl.html @@ -29,13 +29,13 @@

Mean-squared error

- + $button_tooltip

- + This app uses a neural ordinary differential equation (NODE) to forecast weather data from Delhi. The forecast is implemented with the DiffeqFlux, DifferentialEquations, Optimization and Lux packages, and the code is based on the blog post by Sebastian Callh. @@ -46,22 +46,22 @@

Mean-squared error

-
-

Temperature

+
+

Temperature

-
-

Humidity

+
+

Humidity

-
-

Wind

+
+

Wind

-
-

Pressure

+
+

Pressure

diff --git a/lib/utils.jl b/lib/utils.jl index 6d05604..fd1784b 100644 --- a/lib/utils.jl +++ b/lib/utils.jl @@ -21,10 +21,13 @@ end get_layout(title, xlabel, ylabel) = PlotlyBase.Layout( #= title=title, =# + Dict{Symbol,Any}(:paper_bgcolor => "rgb(242, 246, 247)", + :plot_bgcolor => "rgb(242, 246, 247)"); xaxis=attr( title=xlabel, showgrid=false), yaxis=attr( title=ylabel, showgrid=true), #= margin=attr(l=5, r=5, t=15, b=5), =# legend=attr( x=1, y=1.02, yanchor="bottom", xanchor="right", orientation="h"), + backgroundcolor="red", ) function get_traces(t_train, t_predict, y_train, ŷ, y_test, quantity_idx) diff --git a/params.jld b/params.jld deleted file mode 100644 index 2de3297..0000000 Binary files a/params.jld and /dev/null differ diff --git a/params.jld2 b/params.jld2 new file mode 100644 index 0000000..cd35b4a Binary files /dev/null and b/params.jld2 differ diff --git a/public/css/autogenerated.css b/public/css/autogenerated.css new file mode 100644 index 0000000..c15ffce --- /dev/null +++ b/public/css/autogenerated.css @@ -0,0 +1,2 @@ +* { box-sizing: border-box; } body {margin: 0;}*{box-sizing:border-box;}body{margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;}*{box-sizing:border-box;}body{margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;}#i5od{text-align:center;color:rgb(44, 62, 80);margin-bottom:2rem;font-family:"Helvetica Neue", Helvetica, Arial, sans-serif;font-size:2.5rem;text-shadow:rgba(0, 0, 0, 0.1) 2px 2px 4px;}#i22q{padding-top:15px;padding-right:15px;padding-bottom:15px;padding-left:15px;}#ieq0z{text-align:center;}#i3a6p{margin-top:15px;}#it9ge{margin-top:15px;}#igu04{text-align:center;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;}#ilykk{text-align:center;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;}#ia776{text-align:center;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;}#ibuqi{text-align:center;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;}#i4vhf{text-align:center;margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;} +* diff --git a/public/css/theme.css b/public/css/theme.css new file mode 100644 index 0000000..2ad2d95 --- /dev/null +++ b/public/css/theme.css @@ -0,0 +1,255 @@ +:root.stipple-core { + /* ===================== VARIABLES ===================== */ + + /* ===================== main colors ===================== */ + /* ----------- background colors ------------ */ + --st-background-color-1: #ffffff; + --st-background-color-2: #efefef; + --st-background-color-3: #c4c4c4; + + /* ----------- foreground colors ------------ */ + --st-foreground-color-1: #000000; + --st-foreground-color-2: #393939; + --st-foreground-color-3: #747474; + + /* =========== border colors =========== */ + --st-border-color-1: #cccccc80; + --st-border-color-2: #cccccc40; + --st-border-color-3: #cccccc20; + + /* =========== text colors =========== */ + --st-head-color: #111827; + + /* =========== framework colors =========== */ + --q-color-primary: #38bdf8; + --q-color-secondary: #8ea8c3; + --q-color-accent: #bea7e5; + --q-color-info: #373b44; + --q-color-positive: #72c8a9; + --q-color-negative: #c10015; + --q-color-warning: #f2c037; + + /* =========== dashboard colors =========== */ + --st-dashboard-line: #e2e2e2; + --st-dashboard-module: #fcfcfc; + --st-skeleton: #e1e5ee; + + /* =========== actionable =========== */ + --st-action-color: #38bdf8; + --st-action-color-hover: #09d1f9; + + /* =========== font sizes =========== */ + --st-font-size-normal: 13px; + + /* =========== decorations =========== */ + --st-box-shadow-color: #00000020; + --st-scrollbar-thumb: #619abd; + +} +:root.stipple-core.dark { + /* ===================== VARIABLES ===================== */ + + /* ===================== main colors ===================== */ + /* ----------- background colors ------------ */ + --st-background-color-1: #101827; + --st-background-color-2: #162134; + --st-background-color-3: #202f47; + + /* ----------- foreground colors ------------ */ + --st-foreground-color-1: #e6e6e6; + --st-foreground-color-2: #575454; + --st-foreground-color-3: #5a6460; + + /* =========== border colors =========== */ + --st-border-color-1: #cccccc80; + --st-border-color-2: #cccccc40; + --st-border-color-3: #cccccc20; + + /* =========== text colors =========== */ + --st-head-color: #38bdf8; + + /* =========== framework colors =========== */ + --q-color-primary: #38bdf8; + --q-color-secondary: #8ea8c3; + --q-color-accent: #bea7e5; + --q-color-info: #373b44; + --q-color-positive: #72c8a9; + --q-color-negative: #c10015; + --q-color-warning: #f2c037; + + /* =========== dashboard colors =========== */ + --st-dashboard-line: #e2e2e2; + --st-dashboard-module: #fcfcfc; + --st-skeleton: #e1e5ee; + + /* =========== actionable =========== */ + --st-action-color: #38bdf8; + --st-action-color-hover: #09d1f9; + + /* =========== font sizes =========== */ + --st-font-size-normal: 13px; + + /* =========== decorations =========== */ + --st-box-shadow-color: #2483ab70; + --st-scrollbar-thumb: #153f6c; + +} + +/* ===================== DERIVED ===================== */ +/* =========== Derived colors =========== */ +:root.stipple-core { + --st-text-1: var(--st-foreground-color-1); + --st-text-2: var(--st-foreground-color-2); + --st-text-3: var(--st-foreground-color-3); + + --st-dashboard-bg: var(--st-background-color-1); + --q-color-white: var(--st-background-color-1); +} + + +/* ===================== Global Text ===================== */ +:root.stipple-core body { + color: var(--st-text-1); + font-size: var(--st-font-size-normal); +} + +/* ===================== HEADERS ===================== */ +:root.stipple-core h1{ + color: var(--st-head-color); + font-weight: bold; + font-size: 2.2rem; +} +:root.stipple-core h2{ + color: var(--st-head-color); + font-weight: bold; + font-size: 1.8rem; +} +:root.stipple-core h3{ + color: var(--st-head-color); + font-weight: bold; + font-size: 1.5rem; +} +:root.stipple-core h4{ + color: var(--st-head-color); + font-weight: bold; + font-size: 1.3rem; +} +:root.stipple-core h5{ + color: var(--st-head-color); + font-weight: bold; + font-size: 1.1rem; +} +:root.stipple-core h6 { + color: var(--st-head-color); + font-weight: bold; + font-size: 1rem; +} + + +/* ===================== LINKS ===================== */ +.stipple-core a { + color: var(--st-action-color); +} +.stipple-core a:hover { + color: var(--st-action-color-hover); +} + +/* ===================== Modules ===================== */ +.stipple-core .st-module { + padding-top: 10px !important; + border: 3px solid var(--st-border-color-3); +} +.container{ + max-width: 100% !important; +} + +/* ===================== Components ===================== */ +.stipple-core .q-btn { + color: var(--st-background-color-1) !important; +} + +.q-field__input, +.q-field__native, +.q-field__prefix, +.q-field__suffix { + color: var(--st-text-1); +} +.q-field__label { + color: var(--st-text-1); + opacity: 0.6; +} +.q-field--standard .q-field__control:before { + border-bottom: 1px solid var(--st-border-color-2); +} +.q-field--standard .q-field__control:hover { + border-bottom: 1px solid var(--st-border-color-1); +} + +.q-field__marginal { + color: var(--st-border-color-1); +} + +.q-menu { + background-color: var(--q-color-white); + box-shadow: 1px 3px 10px 2px var(--st-box-shadow-color); +} + +.q-chip { + vertical-align: middle; + outline: 0; + position: relative; + max-width: 100%; + margin: 4px; + background: var(--q-color-primary); + color: var(--st-background-color-1) !important; + padding: 3px 6px 3px 10px !important; + font-weight: normal !important; + font-size: 0.8em; +} + +.stipple-core .q-time__clock-position, .stipple-core .q-date button, .stipple-core .q-date__calendar-item{ + color: #000 !important; +} + + + +/* ===================== Scrollbars ===================== */ +*::-webkit-scrollbar { + width: 5px; + height: 5px; +} + +*::-webkit-scrollbar-track { + border-radius: 5px; + background-color: var(--st-border-color-3); + border: none; +} + +*::-webkit-scrollbar-thumb { + border-radius: 5px; + background-color: var(--st-scrollbar-thumb); +} + + +/* ===================== Genie Logo (WIP) ===================== */ +._genie_logo { + filter: brightness(11); + margin-left: 5px; +} + +/* ===================== Charts (WIP) ===================== */ +.main-svg { + background: none; +} + +svg .xgrid, +svg .ygrid, +svg .xzl, +svg .yzl { + stroke: #192a45 !important; + stroke-width: 1px !important; +} +svg .draglayer { + background-color: #2a446e !important; +} +