|
| 1 | +import streamlit as st |
| 2 | +import pandas as pd |
| 3 | +import pickle |
| 4 | +import datetime |
| 5 | +import joblib |
| 6 | +from keras.models import load_model |
| 7 | +from streamlit_extras.metric_cards import style_metric_cards |
| 8 | +from streamlit_extras.stylable_container import stylable_container |
| 9 | +from tools import * |
| 10 | + |
| 11 | +# page config |
| 12 | +page_config(title="Flood") |
| 13 | + |
| 14 | +# function |
| 15 | +def plot_tab1(range, data_plot): |
| 16 | + st.caption(f"Here's the height chart for {range}") |
| 17 | + st.area_chart(data=data_plot, |
| 18 | + y="height (cm)") |
| 19 | +def convert_df(df): |
| 20 | + return df.to_csv().encode('utf-8') |
| 21 | +def download_csv(data_df, name): |
| 22 | + st.dataframe(data_df) |
| 23 | + st.caption("Need the data?") |
| 24 | + if st.download_button(label="Download data as CSV", |
| 25 | + data=convert_df(data_df), |
| 26 | + file_name=name, |
| 27 | + mime='text/csv'): |
| 28 | + st.toast('Download complete!', icon = "✅") |
| 29 | +def data_plot_tab2(history, pred): |
| 30 | + # history |
| 31 | + data_history = history.reset_index() |
| 32 | + data_history['index'] = data_history['index'] - 287 |
| 33 | + data_history = data_history.set_index('index') |
| 34 | + data_plot_X = data_history[['height (cm)']] |
| 35 | + data_plot_X = data_plot_X.rename(columns = {'height (cm)':'height_history (cm)'}) |
| 36 | + # future |
| 37 | + data_pred = pred.reset_index() |
| 38 | + data_pred['index'] = data_pred['index'] + 1 |
| 39 | + data_pred = data_pred.set_index('index') |
| 40 | + #concat |
| 41 | + data_plot_2 = pd.concat([data_plot_X, data_pred]) |
| 42 | + return data_history, data_pred, data_plot_2 |
| 43 | + |
| 44 | +@st.cache_resource(ttl=3600) |
| 45 | +def load_data_banjir(): |
| 46 | + with open("dataset/data_simulasi_banjir.pkl", 'rb') as file: |
| 47 | + data = pickle.load(file) |
| 48 | + return data |
| 49 | + |
| 50 | +@st.cache_resource(ttl=3600) |
| 51 | +def load_scaler_banjir(): |
| 52 | + scaler_X_klas = joblib.load('scaler/scaler_X_klasifikasi_banjir.save') |
| 53 | + scaler_X_pred = joblib.load('scaler/scaler_X_prediksi_banjir.save') |
| 54 | + scaler_y_pred = joblib.load('scaler/scaler_y_prediksi_banjir.save') |
| 55 | + return scaler_X_klas, scaler_X_pred, scaler_y_pred |
| 56 | + |
| 57 | +@st.cache_resource(ttl=3600) |
| 58 | +def load_model_banjir(): |
| 59 | + model_klas = load_model('model/model_klasifikasi_banjir.h5') |
| 60 | + model_pred = load_model('model/model_prediksi_banjir.h5') |
| 61 | + return model_klas, model_pred |
| 62 | + |
| 63 | +# load data, scaler, model |
| 64 | +data_banjir = load_data_banjir() |
| 65 | +scaler_X_klasifikasi, scaler_X_prediksi, scaler_y_prediksi = load_scaler_banjir() |
| 66 | +model_klasifikasi_banjir, model_prediksi_banjir = load_model_banjir() |
| 67 | + |
| 68 | +# title |
| 69 | +st.title("Flood") |
| 70 | +# tabs |
| 71 | +tab1, tab2 = st.tabs(["**Dashboard**", "**Prediction**"]) |
| 72 | + |
| 73 | +# konten tab 1 (Dashboard) |
| 74 | +with tab1: |
| 75 | + col_datetime1, col_metric1, col_metric2= st.columns(3) |
| 76 | + # datetime |
| 77 | + with col_datetime1: |
| 78 | + date1 = st.date_input("d", |
| 79 | + value=datetime.datetime(2022,9,30), |
| 80 | + min_value=datetime.datetime(2022,9,9), |
| 81 | + max_value=datetime.datetime(2022,9,30), |
| 82 | + label_visibility="collapsed") |
| 83 | + time1 = st.time_input("t", |
| 84 | + value=datetime.time(10,30), |
| 85 | + step=600, |
| 86 | + label_visibility="collapsed") |
| 87 | + st.caption("Set date and time 👆") |
| 88 | + # data tab 1 |
| 89 | + datetime1 = str(date1)+" "+str(time1) |
| 90 | + data_tab1 = data_banjir.loc[data_banjir['datetime']<=datetime1].reset_index(drop=True) |
| 91 | + data_metric = data_tab1[['datetime','height (cm)']].head(2) |
| 92 | + data_metric = data_metric.rename(columns={'datetime':'date', |
| 93 | + 'height (cm)':'height'}) |
| 94 | + data_metric = klasifikasi_banjir(X=data_metric, # get status |
| 95 | + scaler_X=scaler_X_klasifikasi, |
| 96 | + model=model_klasifikasi_banjir) |
| 97 | + |
| 98 | + metric1_value = data_metric.height[0].round(2) |
| 99 | + metric1_delta = (data_metric.height[0] - data_metric.height[1]).round(2) |
| 100 | + |
| 101 | + metric2_value = data_metric.status_pred[0] |
| 102 | + metric2_delta = int(metric2_value - data_metric.status_pred[1]) |
| 103 | + |
| 104 | + # metric 1 |
| 105 | + with col_metric1: |
| 106 | + st.metric(label="Last height:", |
| 107 | + value=f"{metric1_value} cm", |
| 108 | + delta=metric1_delta, |
| 109 | + delta_color="inverse") |
| 110 | + # metric 2 |
| 111 | + with col_metric2: |
| 112 | + st.metric(label="Last status:", |
| 113 | + value=f"Siaga {metric2_value}", |
| 114 | + delta=metric2_delta, |
| 115 | + delta_color="off") |
| 116 | + # metric style |
| 117 | + style_metric_cards(background_color="#f0f2f6", |
| 118 | + border_left_color="#E84545", |
| 119 | + border_size_px=0, |
| 120 | + border_radius_px=10, |
| 121 | + box_shadow=False) |
| 122 | + |
| 123 | + # plot |
| 124 | + data_plot1 = data_tab1[['datetime','height (cm)']].set_index("datetime") # set 'date' as index |
| 125 | + col_plot1,col_plot2 = st.columns([2,1]) |
| 126 | + col_plot1.subheader("Visualizing height changes:") |
| 127 | + data_plot1_range = col_plot2.selectbox("Plot range:", |
| 128 | + ("last day","last week","last month","last year","all data"), |
| 129 | + label_visibility="collapsed") |
| 130 | + if data_plot1_range == "last day": # last day |
| 131 | + plot_tab1(range="the last day", |
| 132 | + data_plot=data_plot1.head(144)) |
| 133 | + elif data_plot1_range == "last week": # last week |
| 134 | + plot_tab1(range="the last week", |
| 135 | + data_plot=data_plot1.head(1008)) |
| 136 | + elif data_plot1_range == "last month": # last month |
| 137 | + plot_tab1(range="the last month", |
| 138 | + data_plot=data_plot1.head(4320)) |
| 139 | + elif data_plot1_range == "last year": # last year |
| 140 | + plot_tab1(range="the last year", |
| 141 | + data_plot=data_plot1.head(52560)) |
| 142 | + elif data_plot1_range == "all data": # all data |
| 143 | + plot_tab1(range="all data", |
| 144 | + data_plot=data_plot1) |
| 145 | + |
| 146 | + # data history |
| 147 | + col_data1,col_data2 = st.columns([2,1]) |
| 148 | + col_data1.subheader("Historical data table:") |
| 149 | + data_tab1_range = col_data2.selectbox("Data range:", |
| 150 | + ("last day","last week","last month","last year","all data"), |
| 151 | + label_visibility="collapsed") |
| 152 | + if data_tab1_range == "last day": # last day |
| 153 | + download_csv(data_df=data_tab1.head(144), |
| 154 | + name="last_day.csv") |
| 155 | + elif data_tab1_range == "last week": # last week |
| 156 | + download_csv(data_df=data_tab1.head(1008), |
| 157 | + name="last_week.csv") |
| 158 | + elif data_tab1_range == "last month": # last month |
| 159 | + download_csv(data_df=data_tab1.head(4320), |
| 160 | + name="last_month.csv") |
| 161 | + elif data_tab1_range == "last year": # last year |
| 162 | + download_csv(data_df=data_tab1.head(52560), |
| 163 | + name="last_year.csv") |
| 164 | + elif data_tab1_range == "all data": # all data |
| 165 | + download_csv(data_df=data_tab1, |
| 166 | + name="all_data.csv") |
| 167 | + |
| 168 | +with tab2: |
| 169 | + col_date2, col_time2, col_caption2= st.columns([1,1,1]) |
| 170 | + # datetime |
| 171 | + date2 = col_date2.date_input("Date:", |
| 172 | + value=datetime.datetime(2022,9,30), |
| 173 | + min_value=datetime.datetime(2022,9,11), |
| 174 | + max_value=datetime.datetime(2022,9,30), |
| 175 | + label_visibility="collapsed") |
| 176 | + time2 = col_time2.time_input("Time:", |
| 177 | + value=datetime.time(4,30), |
| 178 | + step=600, |
| 179 | + label_visibility="collapsed") |
| 180 | + col_caption2.caption("👈 Set date and time") |
| 181 | + datetime2 = str(date2)+" "+str(time2) |
| 182 | + |
| 183 | + # proses |
| 184 | + col_button1,col_button2= st.columns([1,2]) |
| 185 | + if col_button1.button("Predict ", use_container_width=True,type="primary"): |
| 186 | + col_button2.caption(":green[Predicted!]") |
| 187 | + # klasifikasi |
| 188 | + X_klasifikasi = data_banjir.loc[data_banjir['datetime'] == datetime2].reset_index(drop=True) |
| 189 | + X_klasifikasi = X_klasifikasi[['datetime','height (cm)']].rename(columns={'datetime':'date', |
| 190 | + 'height (cm)':'height'}) |
| 191 | + y_klasifikasi = klasifikasi_banjir(X=X_klasifikasi, |
| 192 | + scaler_X=scaler_X_klasifikasi, |
| 193 | + model=model_klasifikasi_banjir) |
| 194 | + # prediksi |
| 195 | + X_prediksi = get_X_prediksi(data=data_banjir, |
| 196 | + date=datetime2) |
| 197 | + y_pred = prediksi_banjir(data=data_banjir, |
| 198 | + date=datetime2, |
| 199 | + X=X_prediksi, |
| 200 | + scaler_X=scaler_X_prediksi, |
| 201 | + scaler_y=scaler_y_prediksi, |
| 202 | + model=model_prediksi_banjir) |
| 203 | + y_pred_status = klasifikasi_banjir(X=y_pred, |
| 204 | + scaler_X=scaler_X_klasifikasi, |
| 205 | + model=model_klasifikasi_banjir) |
| 206 | + y_pred_status = y_pred_status.rename(columns = {'height':'height_pred (cm)'}) |
| 207 | + |
| 208 | + # info |
| 209 | + with stylable_container(key="container_with_border", |
| 210 | + css_styles="""{ |
| 211 | + border: 3px solid #dedede; |
| 212 | + border-radius: 0.5rem; |
| 213 | + padding: calc(1em - 1px)}"""): |
| 214 | + get_info_banjir(y_klasifikasi=y_klasifikasi, |
| 215 | + y_pred_status=y_pred_status) |
| 216 | + |
| 217 | + # plot grafik |
| 218 | + st.write("**Plot prediction data 📈**") |
| 219 | + |
| 220 | + if y_pred_status.shape[1] == 4: |
| 221 | + data_historical,data_future,data_plot2 = data_plot_tab2(history=X_prediksi, |
| 222 | + pred=y_pred_status) |
| 223 | + st.area_chart(data=data_plot2, |
| 224 | + y=["height_history (cm)", |
| 225 | + "height_true (cm)", |
| 226 | + "height_pred (cm)"]) |
| 227 | + |
| 228 | + elif y_pred_status.shape[1] == 2: |
| 229 | + data_historical,data_future,data_plot2 = data_plot_tab2(history=X_prediksi, |
| 230 | + pred=y_pred_status) |
| 231 | + st.area_chart(data=data_plot2, |
| 232 | + y=["height_history (cm)", |
| 233 | + "height_pred (cm)"]) |
| 234 | + |
| 235 | + # data |
| 236 | + with st.expander("**Explore prediction data**"): |
| 237 | + st.write("**Historical data:**") |
| 238 | + st.dataframe(data_historical) |
| 239 | + st.write("**Future/predicted data:**") |
| 240 | + st.dataframe(data_future) |
| 241 | + |
| 242 | + "---" |
| 243 | + st.button("Click to reset") |
0 commit comments