Py.Cafe

Sindhup24/

river-flow-forecast-visualizer

River Flow Forecast Visualizer

DocsPricing
  • app.py
  • filtered_output.csv
  • merged_output.csv
  • requirements.txt
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import pandas as pd
import solara
import altair as alt
import folium
import folium.plugins

# Load the uploaded CSV file
file_path = 'filtered_output.csv'
df_forecast = pd.read_csv(file_path)

df_forecast['Date'] = df_forecast['Date'].astype(str)

# Function to filter data based on RiverNumber and Date
def forecast_filter(df, river_values, date_values):
    df_river = df.loc[df['RiverNumber'].isin(river_values)]
    df_date = df_river.loc[df_river['Date'].isin(date_values)]
    return df_date

# Function to plot charts using Altair
def forecast_charts(df):
    ensemble_means = df.iloc[:, :52].mean().reset_index()
    ensemble_means.columns = ['ensemble', 'mean']

    chart = alt.Chart(ensemble_means).mark_bar().encode(
        x='ensemble',
        y='mean'
    ).properties(
        title='Ensemble Forecast Means'
    )
    return chart

# Function to create map
def forecast_map(df):
    if len(df) == 0:
        return None

    forecast_map = folium.Map()

    incidents = folium.plugins.MarkerCluster().add_to(forecast_map)

    for lat, lng, label in zip(df.YCoordinate, df.XCoordinate, df.Date):
        folium.Marker(
            location=[lat, lng],
            icon=None,
            popup=label,
        ).add_to(incidents)

    # Fit the map to the bounds of the selected points
    sw = df[['YCoordinate', 'XCoordinate']].min().values.tolist()
    ne = df[['YCoordinate', 'XCoordinate']].max().values.tolist()
    forecast_map.fit_bounds([sw, ne])

    return forecast_map

river_numbers = solara.reactive([110123714],)
dates = solara.reactive(['2024040100'])

@solara.component
def View():
    dff = forecast_filter(df_forecast, river_numbers.value, dates.value)
    row_count = len(dff)
    
    map_display = forecast_map(dff)
    if map_display:
        with solara.VBox() as main:
            solara.HTML(tag="div", unsafe_innerHTML=map_display._repr_html_())
        solara.Info("Map has been updated.")
    else:
        solara.Warning("No data available for the selected filters")

    if row_count > 0:
        chart = forecast_charts(dff)
        with solara.VBox() as main:
            solara.FigureAltair(chart)
        solara.Info("Chart has been updated.")
    else:
        solara.Warning("You filtered out all the data, no charts shown")

@solara.component
def Controls():
    solara.SelectMultiple('RiverNumber', all_values=[str(k) for k in df_forecast['RiverNumber'].unique().tolist()], values=river_numbers)
    solara.SelectMultiple('Date', all_values=[str(k) for k in df_forecast['Date'].unique().tolist()], values=dates)

@solara.component
def Page():
    with solara.Sidebar():
        Controls()
    View()

Page()