Spaces:
Build error
Build error
| import streamlit as st | |
| import pandas as pd | |
| import numpy as np | |
| from scipy.stats import percentileofscore | |
| import plotly.graph_objects as go | |
| from scipy.interpolate import interp1d | |
| import matplotlib.pyplot as plt | |
| def refine_curve(x, p, num_points=200): | |
| interp_func = interp1d(x, p, kind='cubic') | |
| x_refined = np.linspace(x[0], x[-1], num=num_points) | |
| p_refined = interp_func(x_refined) | |
| return x_refined, p_refined | |
| def calculate_flooding_impact(threshold, slr_interL_20, slr_interH_20, slr_interL_50, slr_interH_50, file): | |
| df_water_levels = pd.read_excel(file) | |
| df_water_levels['t'] = pd.to_datetime(df_water_levels['t']) | |
| df_water_levels['date'] = df_water_levels['t'].dt.date | |
| # Plotting water levels | |
| fig1 = go.Figure() | |
| fig1.add_trace(go.Scatter(x=df_water_levels['t'], y=df_water_levels['v'], mode='lines', name='Water Level', line=dict(color='blue'))) | |
| fig1.update_layout( | |
| yaxis=dict(range=[-7, 7], title='Elevation (ft)', showgrid=False), | |
| xaxis=dict(title="Year", showgrid=False), | |
| legend=dict(x=0.02, y=0.98) | |
| ) | |
| # Calculate highest water levels and exceedances | |
| highest_water_levels = df_water_levels.groupby('date')['v'].max() | |
| exceedances_by_year = {} | |
| for date, water_level in highest_water_levels.items(): | |
| year = date.year | |
| if year in exceedances_by_year: | |
| exceedances_by_year[year].append((date, water_level)) | |
| else: | |
| exceedances_by_year[year] = [(date, water_level)] | |
| exd_year = [] | |
| num_exd = [] | |
| for year, exceedances in exceedances_by_year.items(): | |
| num_exceedances = len([exceedance for exceedance in exceedances if exceedance[1] > threshold]) | |
| exd_year.append(year) | |
| num_exd.append(num_exceedances) | |
| # Bar plot for exceedances | |
| fig2 = go.Figure(data=[go.Bar(x=exd_year, y=num_exd, marker_color='blue')]) | |
| fig2.update_layout( | |
| title='Occurrences of Threshold Value Exceedance for Each Year', | |
| xaxis_title='Year', | |
| yaxis_title='Number of Days of Exceedance', | |
| xaxis=dict( | |
| tickvals=exd_year, | |
| ticktext=[str(year) for year in exd_year], | |
| tickangle=90, | |
| ), | |
| ) | |
| # Impact Flooding Analysis | |
| surfaceEl = highest_water_levels.tolist() | |
| surfaceEl = [x for x in surfaceEl if not np.isnan(x)] | |
| surfaceEl_SLR_L = [num + slr_interL_20 for num in surfaceEl] | |
| surfaceEl_SLR_H = [num + slr_interH_20 for num in surfaceEl] | |
| surfaceEl_SLR_L_50 = [num + slr_interL_50 for num in surfaceEl] | |
| surfaceEl_SLR_H_50 = [num + slr_interH_50 for num in surfaceEl] | |
| bin_magnitude = 0.2 | |
| max_mag = (max(surfaceEl)*10)/10 | |
| min_mag = (min(surfaceEl)*10)/10 | |
| P = np.arange(min_mag, max_mag + bin_magnitude, bin_magnitude) | |
| p = [percentileofscore(surfaceEl, z)/100 for z in P] | |
| # Calculate P and p for different scenarios | |
| P_slrL, p_slrL = refine_curve(P, [percentileofscore(surfaceEl_SLR_L, z)/100 for z in P]) | |
| P_slrH, p_slrH = refine_curve(P, [percentileofscore(surfaceEl_SLR_H, z)/100 for z in P]) | |
| P_slrL_50, p_slrL_50 = refine_curve(P, [percentileofscore(surfaceEl_SLR_L_50, z)/100 for z in P]) | |
| P_slrH_50, p_slrH_50 = refine_curve(P, [percentileofscore(surfaceEl_SLR_H_50, z)/100 for z in P]) | |
| # Calculate days impacted | |
| days_impacted_current = (100 - percentileofscore(surfaceEl, threshold)) * 365 / 100 | |
| days_impacted_slrL = (100 - percentileofscore(surfaceEl_SLR_L, threshold)) * 365 / 100 | |
| days_impacted_slrH = (100 - percentileofscore(surfaceEl_SLR_H, threshold)) * 365 / 100 | |
| days_impacted_slrL_50 = (100 - percentileofscore(surfaceEl_SLR_L_50, threshold)) * 365 / 100 | |
| days_impacted_slrH_50 = (100 - percentileofscore(surfaceEl_SLR_H_50, threshold)) * 365 / 100 | |
| # Bar plot for SLR | |
| fig3, ax = plt.subplots() | |
| bars = ['2040', '2070'] | |
| bar1_min, bar1_max = round(days_impacted_slrL), round(days_impacted_slrH) | |
| bar2_min, bar2_max = round(days_impacted_slrL_50), round(days_impacted_slrH_50) | |
| x = range(len(bars)) | |
| ax.bar(x, [bar1_max, bar2_max], alpha=0.7, width=0.4, align='center', label='Intermediate High') | |
| ax.bar(x, [bar1_min, bar2_min], alpha=1, width=0.4, align='center', label='Intermediate Low') | |
| ax.set_xticks(x) | |
| ax.set_xticklabels(bars) | |
| ax.set_ylabel('Days') | |
| ax.set_title('Number of Days of Exceedance with SLR') | |
| ax.set_ylim(0, 365) | |
| ax.legend() | |
| # Plot PDF | |
| fig4 = go.Figure() | |
| fig4.add_trace(go.Scatter(x=P[:-1], y=np.diff(p), mode='lines', name='Current', line_color='green', fill='tozeroy')) | |
| fig4.add_trace(go.Scatter(x=P_slrL[:-1], y=np.diff(p_slrL), mode='lines', name='20 Yr SLR Intermediate Low (IL)', line_color='yellow', fill='tozeroy')) | |
| fig4.add_trace(go.Scatter(x=P_slrH[:-1], y=np.diff(p_slrH), mode='lines', name='20 Yr SLR Intermediate High (IH)', line_color='orange', fill='tozeroy')) | |
| fig4.add_trace(go.Scatter(x=P_slrL_50[:-1], y=np.diff(p_slrL_50), mode='lines', name='50 Yr SLR Intermediate Low (IL)', line_color='pink', fill='tozeroy')) | |
| fig4.add_trace(go.Scatter(x=P_slrH_50[:-1], y=np.diff(p_slrH_50), mode='lines', name='50 Yr SLR Intermediate High (IH)', line_color='red', fill='tozeroy')) | |
| fig4.update_layout( | |
| xaxis_title='Water Level (feet)', | |
| yaxis_title='Probability Density', | |
| title='Impact Flooding (Number of Days Impacted)', | |
| hovermode='x unified', | |
| legend=dict(x=0, y=1), | |
| showlegend=True, | |
| xaxis=dict(showgrid=True), | |
| yaxis=dict(showgrid=True) | |
| ) | |
| text_output = ( | |
| f"Number of days impacted by flooding (current): {round(days_impacted_current)}\n" | |
| f"Number of days impacted by flooding (20 Year SLR IL): {round(days_impacted_slrL)}\n" | |
| f"Number of days impacted by flooding (20 Year SLR IH): {round(days_impacted_slrH)}\n" | |
| f"Number of days impacted by flooding (50 Year SLR IL): {round(days_impacted_slrL_50)}\n" | |
| f"Number of days impacted by flooding (50 Year SLR IH): {round(days_impacted_slrH_50)}\n" | |
| ) | |
| return fig1, fig2, fig3, fig4, text_output | |
| st.title("Flooding Impact Calculator") | |
| st.write("Calculate the impact of flooding based on water level data and sea-level rise. Input the threshold value to determine the number of days flooding can occur due to high tide. For more information, determine SLR values from reliable sources such as IPCC, [NOAA](https://coast.noaa.gov/slr/). Upload the water levels in the provided Excel format.") | |
| threshold = st.number_input("Threshold Value (feet)", value=1.0) | |
| slr_interL_20 = st.number_input("20 YR SLR Intermediate Low (feet)", value=0.5) | |
| slr_interH_20 = st.number_input("20 YR SLR Intermediate High (feet)", value=0.7) | |
| slr_interL_50 = st.number_input("50 YR SLR Intermediate Low (feet)", value=0.7) | |
| slr_interH_50 = st.number_input("50 YR SLR Intermediate High (feet)", value=1.5) | |
| uploaded_file = st.file_uploader("Upload water_levels.xlsx", type="xlsx") | |
| if uploaded_file is not None: | |
| fig1, fig2, fig3, fig4, text_output = calculate_flooding_impact(threshold, slr_interL_20, slr_interH_20, slr_interL_50, slr_interH_50, uploaded_file) | |
| st.plotly_chart(fig1) | |
| st.plotly_chart(fig2) | |
| st.pyplot(fig3) | |
| st.plotly_chart(fig4) | |
| st.text(text_output) | |