github-actions[bot] commited on
Commit
faed07e
·
1 Parent(s): 99ccdef

Deploy from GitHub Actions

Browse files
Files changed (5) hide show
  1. app.py +4 -4
  2. pages.py +4 -4
  3. plots/map.py +9 -0
  4. ui/pages/seasonal_maps.py +6 -16
  5. ui/pages/tables.py +99 -0
app.py CHANGED
@@ -10,7 +10,6 @@ from pages import (
10
  home_page,
11
  nutrient_ratios_page,
12
  parameter_correlations_page,
13
- parameter_summary_tables_page,
14
  raw_data_page,
15
  scatter_plots_page,
16
  seasonal_line_charts_page,
@@ -18,6 +17,7 @@ from pages import (
18
  sector_compare_page,
19
  sector_trends_page,
20
  settings_page,
 
21
  trends_by_station_page,
22
  )
23
  from utils.session import ensure_session_initialized
@@ -46,11 +46,11 @@ analytics = st.Page(
46
  page_dict = {}
47
 
48
  page_dict["Annual Report Draft Charts/Tables"] = [
49
- seasonal_line_charts_page,
50
- seasonal_maps_page,
51
  sector_compare_page,
 
 
52
  scatter_plots_page,
53
- parameter_summary_tables_page,
54
  ]
55
 
56
  page_dict["Water Quality Portal"] = [
 
10
  home_page,
11
  nutrient_ratios_page,
12
  parameter_correlations_page,
 
13
  raw_data_page,
14
  scatter_plots_page,
15
  seasonal_line_charts_page,
 
17
  sector_compare_page,
18
  sector_trends_page,
19
  settings_page,
20
+ tables_page,
21
  trends_by_station_page,
22
  )
23
  from utils.session import ensure_session_initialized
 
46
  page_dict = {}
47
 
48
  page_dict["Annual Report Draft Charts/Tables"] = [
 
 
49
  sector_compare_page,
50
+ seasonal_maps_page,
51
+ seasonal_line_charts_page,
52
  scatter_plots_page,
53
+ tables_page,
54
  ]
55
 
56
  page_dict["Water Quality Portal"] = [
pages.py CHANGED
@@ -659,9 +659,9 @@ dissolved_oxygen_page = st.Page(
659
  icon=":material/water_drop:",
660
  )
661
 
662
- parameter_summary_tables_page = st.Page(
663
- "ui/pages/parameter_summary_tables.py",
664
- title="Parameter Summary Tables",
665
  icon=":material/table_chart:",
666
  )
667
  scatter_plots_page = st.Page(
@@ -687,7 +687,7 @@ __all__ = [
687
  "do_temp_relationship_page",
688
  "raw_data_page",
689
  "settings_page",
690
- "parameter_summary_tables_page",
691
  "scatter_plots_page",
692
  "seasonal_line_charts_page",
693
  "sector_compare_page",
 
659
  icon=":material/water_drop:",
660
  )
661
 
662
+ tables_page = st.Page(
663
+ "ui/pages/tables.py",
664
+ title="Tables",
665
  icon=":material/table_chart:",
666
  )
667
  scatter_plots_page = st.Page(
 
687
  "do_temp_relationship_page",
688
  "raw_data_page",
689
  "settings_page",
690
+ "tables_page",
691
  "scatter_plots_page",
692
  "seasonal_line_charts_page",
693
  "sector_compare_page",
plots/map.py CHANGED
@@ -13,6 +13,15 @@ from osgeo import gdal
13
 
14
  from utils.data_loading import timer
15
 
 
 
 
 
 
 
 
 
 
16
 
17
  @timer(include_params=True)
18
  def generate_seasonal_plot(
 
13
 
14
  from utils.data_loading import timer
15
 
16
+ BASEMAP_PROVIDERS = {
17
+ "USGS Topo": ctx.providers.USGS.USTopo, # type: ignore
18
+ "OpenStreetMap": ctx.providers.OpenStreetMap.Mapnik, # type: ignore
19
+ "CartoDB Light": ctx.providers.CartoDB.Positron, # type: ignore
20
+ "CartoDB Voyager": ctx.providers.CartoDB.Voyager, # type: ignore
21
+ "NASAGIBS.ASTER_GDEM_Greyscale_Shaded_Relief": ctx.providers.NASAGIBS.ASTER_GDEM_Greyscale_Shaded_Relief, # type: ignore
22
+ "OpenTopoMap": ctx.providers.OpenTopoMap, # type: ignore
23
+ }
24
+
25
 
26
  @timer(include_params=True)
27
  def generate_seasonal_plot(
ui/pages/seasonal_maps.py CHANGED
@@ -1,12 +1,11 @@
1
  import io
2
 
3
- import contextily as ctx
4
  import pandas as pd
5
  import streamlit as st
6
 
7
  from components import render_filtered_data_preview
8
  from dashboard_analytics import log_visit
9
- from plots.map import generate_seasonal_plot
10
  from utils.data_loading import add_lat_long, get_stations_data
11
  from utils.date_utils import get_reporting_year
12
 
@@ -24,7 +23,7 @@ timeframe = st.sidebar.radio(
24
  # parameter selection
25
  parameters = sorted(raw_df["Org_Analyte_Name"].unique())
26
  selected_parameter = st.sidebar.selectbox(
27
- "Select Parameter:",
28
  parameters,
29
  index=parameters.index("Salinity") if "Salinity" in parameters else 0,
30
  key="seasonal_parameter_select",
@@ -38,7 +37,7 @@ param_years = sorted(
38
  # Show either single year selector or year range based on timeframe
39
  if timeframe == "Single Year":
40
  selected_year = st.sidebar.selectbox(
41
- "Select Year:",
42
  param_years,
43
  index=len(param_years) - 1,
44
  key="seasonal_year_select",
@@ -55,7 +54,7 @@ else:
55
 
56
  # Add reporting year end month selector
57
  reporting_end_month = st.sidebar.selectbox(
58
- "Reporting Year End Month",
59
  options=range(1, 13),
60
  index=10, # Default to November
61
  format_func=lambda x: pd.Timestamp(2000, x, 1).strftime("%B"), # Show month names
@@ -68,18 +67,9 @@ raw_df["Reporting_Year"] = raw_df["Activity_Start_Date_Time"].apply(
68
  lambda x: get_reporting_year(x, reporting_end_month)
69
  )
70
  # Add basemap selector
71
- basemap_options = {
72
- "OpenStreetMap": ctx.providers.OpenStreetMap.Mapnik, # type: ignore
73
- "USGS Topo": ctx.providers.USGS.USTopo, # type: ignore
74
- "CartoDB Light": ctx.providers.CartoDB.Positron, # type: ignore
75
- "CartoDB Voyager": ctx.providers.CartoDB.Voyager, # type: ignore
76
- "NASAGIBS.ASTER_GDEM_Greyscale_Shaded_Relief": ctx.providers.NASAGIBS.ASTER_GDEM_Greyscale_Shaded_Relief, # type: ignore
77
- "OpenTopoMap": ctx.providers.OpenTopoMap, # type: ignore
78
- }
79
-
80
  selected_basemap = st.sidebar.selectbox(
81
  "Basemap Provider:",
82
- options=list(basemap_options.keys()),
83
  index=0,
84
  key="seasonal_basemap_select",
85
  )
@@ -125,7 +115,7 @@ if not raw_df.empty:
125
  areas=sectors,
126
  area_type="sector",
127
  reporting_end_month=reporting_end_month,
128
- basemap_provider=basemap_options[selected_basemap],
129
  )
130
  st.pyplot(fig)
131
 
 
1
  import io
2
 
 
3
  import pandas as pd
4
  import streamlit as st
5
 
6
  from components import render_filtered_data_preview
7
  from dashboard_analytics import log_visit
8
+ from plots.map import BASEMAP_PROVIDERS, generate_seasonal_plot
9
  from utils.data_loading import add_lat_long, get_stations_data
10
  from utils.date_utils import get_reporting_year
11
 
 
23
  # parameter selection
24
  parameters = sorted(raw_df["Org_Analyte_Name"].unique())
25
  selected_parameter = st.sidebar.selectbox(
26
+ "Parameter:",
27
  parameters,
28
  index=parameters.index("Salinity") if "Salinity" in parameters else 0,
29
  key="seasonal_parameter_select",
 
37
  # Show either single year selector or year range based on timeframe
38
  if timeframe == "Single Year":
39
  selected_year = st.sidebar.selectbox(
40
+ "Year:",
41
  param_years,
42
  index=len(param_years) - 1,
43
  key="seasonal_year_select",
 
54
 
55
  # Add reporting year end month selector
56
  reporting_end_month = st.sidebar.selectbox(
57
+ "Reporting Year End-Month",
58
  options=range(1, 13),
59
  index=10, # Default to November
60
  format_func=lambda x: pd.Timestamp(2000, x, 1).strftime("%B"), # Show month names
 
67
  lambda x: get_reporting_year(x, reporting_end_month)
68
  )
69
  # Add basemap selector
 
 
 
 
 
 
 
 
 
70
  selected_basemap = st.sidebar.selectbox(
71
  "Basemap Provider:",
72
+ options=list(BASEMAP_PROVIDERS.keys()),
73
  index=0,
74
  key="seasonal_basemap_select",
75
  )
 
115
  areas=sectors,
116
  area_type="sector",
117
  reporting_end_month=reporting_end_month,
118
+ basemap_provider=BASEMAP_PROVIDERS[selected_basemap],
119
  )
120
  st.pyplot(fig)
121
 
ui/pages/tables.py ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import calendar
2
+
3
+ import pandas as pd
4
+ import streamlit as st
5
+
6
+ from dashboard_analytics import log_visit
7
+ from utils.data_loading import create_summaries
8
+ from utils.summary import create_overall_summary_table
9
+
10
+ st.title("Summary Tables")
11
+ log_visit("Tables")
12
+
13
+ # Create summaries if they don't exist
14
+ if "overall_summary" not in st.session_state.data:
15
+ summary_by_station, overall_summary, multiindex_df = create_summaries(
16
+ st.session_state.data["raw_df"]
17
+ )
18
+ st.session_state.data.update(
19
+ {
20
+ "summary_by_station": summary_by_station,
21
+ "overall_summary": overall_summary,
22
+ "multiindex_df": multiindex_df,
23
+ }
24
+ )
25
+
26
+ # Create tabs for different summary views
27
+ tab1, tab2 = st.tabs(["Overall Summary", "Monthly Means"])
28
+
29
+ with tab1:
30
+ st.html(
31
+ create_overall_summary_table(
32
+ st.session_state.data["overall_summary"]
33
+ ).as_raw_html()
34
+ )
35
+
36
+ with tab2:
37
+ # Get data from session state
38
+ raw_df = st.session_state.data["raw_df"].copy()
39
+
40
+ # Create datetime column if not exists
41
+ raw_df["Date"] = pd.to_datetime(raw_df["Activity_Start_Date_Time"])
42
+
43
+ # Add month and year columns
44
+ raw_df["Month"] = raw_df["Date"].dt.strftime("%b") # 3-letter month names
45
+ raw_df["Year"] = raw_df["Date"].dt.year
46
+
47
+ # Move parameter selection into tab2
48
+ selected_parameter = st.selectbox(
49
+ "Parameter:",
50
+ options=sorted(raw_df["Org_Analyte_Name"].unique()),
51
+ index=0,
52
+ help="Select a parameter to display monthly averages.",
53
+ )
54
+
55
+ # Filter data for selected parameter
56
+ param_df = raw_df[raw_df["Org_Analyte_Name"] == selected_parameter]
57
+
58
+ # Create pivot table
59
+ pivot_table = pd.pivot_table(
60
+ param_df,
61
+ values="Org_Result_Value",
62
+ index="Year",
63
+ columns="Month",
64
+ aggfunc="mean",
65
+ )
66
+
67
+ # Reorder columns to match calendar months
68
+ month_order = [calendar.month_abbr[i] for i in range(1, 13)]
69
+ pivot_table = pivot_table.reindex(columns=month_order)
70
+ pivot_table = pivot_table.round(2)
71
+
72
+ # Add yearly mean column
73
+ pivot_table_with_yearly_mean = pivot_table.copy()
74
+ pivot_table_with_yearly_mean["Annual Mean"] = pivot_table.mean(axis=1)
75
+
76
+ # Add grand mean row
77
+ grand_mean = pivot_table.mean()
78
+ pivot_table_with_yearly_mean.loc["Grand Mean"] = grand_mean
79
+
80
+ # Display the pivot table
81
+ st.markdown(f"### Monthly Means: {selected_parameter}")
82
+ st.dataframe(
83
+ pivot_table_with_yearly_mean.reset_index().style.format(
84
+ na_rep="", precision=2, thousands=""
85
+ ),
86
+ use_container_width=True,
87
+ hide_index=True,
88
+ height=(len(pivot_table_with_yearly_mean) + 1) * 35
89
+ + 2, # 35 pixels per row, +1 for header
90
+ )
91
+
92
+ # Add download button
93
+ csv_buffer = pivot_table_with_yearly_mean.to_csv().encode()
94
+ st.download_button(
95
+ label="Download Table (CSV)",
96
+ data=csv_buffer,
97
+ file_name=f"{selected_parameter}_monthly_means.csv",
98
+ mime="text/csv",
99
+ )