github-actions[bot] commited on
Commit
3a1dc7d
·
1 Parent(s): d055b25

Add all files with LFS support

Browse files
Files changed (3) hide show
  1. analysis.py +69 -20
  2. app.py +17 -14
  3. main.py +3 -0
analysis.py CHANGED
@@ -922,13 +922,16 @@ def plot_seasonal_salinity(
922
  basemap_provider,
923
  alpha=0.5,
924
  shapefile_path="data/SAB/SAB.shp",
 
925
  ):
926
  """
927
  Create seasonal plots of mean salinity values by WBID with basemap.
 
928
 
929
  Args:
930
  salinity_data: DataFrame containing salinity measurements
931
- year: Year to filter data for (str)
 
932
  """
933
  # Read and filter WBIDs
934
  wbids = gpd.read_file(shapefile_path)
@@ -937,20 +940,29 @@ def plot_seasonal_salinity(
937
  wbids = wbids.to_crs(epsg=3857)
938
 
939
  # Process data - create a copy to avoid SettingWithCopyWarning
940
- year_data = salinity_data[
941
- salinity_data["Activity_Start_Date_Time"].dt.year == int(year)
942
- ].copy()
943
-
944
- # Add season column using loc
945
- year_data.loc[:, "season"] = pd.cut(
946
- year_data["Activity_Start_Date_Time"].dt.month,
947
- bins=[0, 3, 6, 9, 12],
948
- labels=["Winter", "Spring", "Summer", "Fall"],
 
 
 
 
 
 
 
 
 
949
  )
950
 
951
- # Calculate seasonal means with observed=True
952
  seasonal_means = (
953
- year_data.groupby(["WBID", "season"], observed=True)["Salinity"]
954
  .mean()
955
  .reset_index()
956
  )
@@ -989,11 +1001,38 @@ def plot_seasonal_salinity(
989
  bottom=0.05, # Slightly increased bottom margin to give more space
990
  )
991
 
992
- for idx, season in enumerate(["Winter", "Spring", "Summer", "Fall"]):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
993
  ax = fig.add_subplot(gs[idx // 2, idx % 2])
994
 
995
- season_data = seasonal_means[seasonal_means["season"] == season]
996
- merged = wbids.merge(season_data, on="WBID", how="left")
997
 
998
  # Plot WBIDs
999
  merged.plot(
@@ -1010,15 +1049,23 @@ def plot_seasonal_salinity(
1010
 
1011
  ax.set_xlim(extent[0], extent[1])
1012
  ax.set_ylim(extent[2], extent[3])
1013
- # Adjust title position
 
 
 
 
1014
  if idx < 2: # Top row
1015
  ax.set_title(
1016
- f"{season} {year} Mean Salinity", pad=15
1017
- ) # More padding for top row
 
 
1018
  else: # Bottom row
1019
  ax.set_title(
1020
- f"{season} {year} Mean Salinity", pad=5
1021
- ) # Less padding for bottom row
 
 
1022
  ax.set_axis_off()
1023
 
1024
  # Add colorbar
@@ -1045,6 +1092,7 @@ def plot_seasonal_salinity_for_bays(
1045
  alpha=0.5,
1046
  shapefile_path="data/SAB/SAB.shp",
1047
  wbids=None,
 
1048
  ):
1049
  """
1050
  Create seasonal plots of mean salinity values by WBID for N, E, W, SAB, GL and Lake Powell.
@@ -1062,6 +1110,7 @@ def plot_seasonal_salinity_for_bays(
1062
  basemap_provider=basemap_provider,
1063
  alpha=alpha,
1064
  shapefile_path=shapefile_path,
 
1065
  )
1066
  return fig
1067
 
 
922
  basemap_provider,
923
  alpha=0.5,
924
  shapefile_path="data/SAB/SAB.shp",
925
+ reporting_end_month: int = 10,
926
  ):
927
  """
928
  Create seasonal plots of mean salinity values by WBID with basemap.
929
+ Uses configurable Reporting Year with meteorological seasons.
930
 
931
  Args:
932
  salinity_data: DataFrame containing salinity measurements
933
+ year: Reporting Year to filter data for (str)
934
+ reporting_end_month: Last month of the reporting year (1-12, default=10 for October)
935
  """
936
  # Read and filter WBIDs
937
  wbids = gpd.read_file(shapefile_path)
 
940
  wbids = wbids.to_crs(epsg=3857)
941
 
942
  # Process data - create a copy to avoid SettingWithCopyWarning
943
+ year_data = salinity_data[salinity_data["Reporting_Year"] == int(year)].copy()
944
+
945
+ # Function to determine quarter based on date and reporting year end
946
+ def get_quarter(date, reporting_end_month):
947
+ month = date.month
948
+
949
+ # Calculate month offset to align with reporting year
950
+ month_offset = (12 - reporting_end_month) % 12
951
+
952
+ # Adjust month to align with reporting year
953
+ adjusted_month = ((month + month_offset) % 12) or 12
954
+
955
+ # Determine quarter (1-4)
956
+ return f"Q{((adjusted_month - 1) // 3) + 1}"
957
+
958
+ # Add quarter column
959
+ year_data.loc[:, "quarter"] = year_data["Activity_Start_Date_Time"].apply(
960
+ lambda x: get_quarter(x, reporting_end_month)
961
  )
962
 
963
+ # Calculate quarterly means
964
  seasonal_means = (
965
+ year_data.groupby(["WBID", "quarter"], observed=True)["Salinity"]
966
  .mean()
967
  .reset_index()
968
  )
 
1001
  bottom=0.05, # Slightly increased bottom margin to give more space
1002
  )
1003
 
1004
+ # Function to get quarter date range
1005
+ def get_quarter_dates(quarter: str, year: int, reporting_end_month: int) -> str:
1006
+ # Calculate first month of reporting year
1007
+ first_month = (reporting_end_month % 12) + 1
1008
+
1009
+ # Calculate start month for each quarter
1010
+ quarter_num = int(quarter[1])
1011
+ start_month = ((first_month - 1 + ((quarter_num - 1) * 3)) % 12) + 1
1012
+ end_month = ((start_month + 2) % 12) or 12
1013
+
1014
+ # For Reporting Year X, the start date is actually in year X-1 if the month
1015
+ # is after the reporting end month
1016
+ start_year = int(year) - 1 if start_month > reporting_end_month else int(year)
1017
+ end_year = start_year
1018
+ if end_month < start_month:
1019
+ end_year += 1
1020
+
1021
+ start_date = pd.Timestamp(f"{start_year}-{start_month:02d}-01")
1022
+ end_date = pd.Timestamp(
1023
+ f"{end_year}-{end_month:02d}-{pd.Timestamp(f'{end_year}-{end_month:02d}').days_in_month}"
1024
+ )
1025
+
1026
+ return f"{start_date.strftime('%b %d, %Y')} - {end_date.strftime('%b %d, %Y')}"
1027
+
1028
+ # Use quarters instead of seasons
1029
+ quarters = ["Q1", "Q2", "Q3", "Q4"]
1030
+
1031
+ for idx, quarter in enumerate(quarters):
1032
  ax = fig.add_subplot(gs[idx // 2, idx % 2])
1033
 
1034
+ quarter_data = seasonal_means[seasonal_means["quarter"] == quarter]
1035
+ merged = wbids.merge(quarter_data, on="WBID", how="left")
1036
 
1037
  # Plot WBIDs
1038
  merged.plot(
 
1049
 
1050
  ax.set_xlim(extent[0], extent[1])
1051
  ax.set_ylim(extent[2], extent[3])
1052
+
1053
+ # Get date range for this quarter
1054
+ date_range = get_quarter_dates(quarter, int(year), reporting_end_month)
1055
+
1056
+ # Create title with two lines
1057
  if idx < 2: # Top row
1058
  ax.set_title(
1059
+ f"Quarter {quarter[1]} Mean Salinity\n{date_range}",
1060
+ pad=15,
1061
+ fontsize=10,
1062
+ )
1063
  else: # Bottom row
1064
  ax.set_title(
1065
+ f"Quarter {quarter[1]} Mean Salinity\n{date_range}",
1066
+ pad=5,
1067
+ fontsize=10,
1068
+ )
1069
  ax.set_axis_off()
1070
 
1071
  # Add colorbar
 
1092
  alpha=0.5,
1093
  shapefile_path="data/SAB/SAB.shp",
1094
  wbids=None,
1095
+ reporting_end_month: int = 10,
1096
  ):
1097
  """
1098
  Create seasonal plots of mean salinity values by WBID for N, E, W, SAB, GL and Lake Powell.
 
1110
  basemap_provider=basemap_provider,
1111
  alpha=alpha,
1112
  shapefile_path=shapefile_path,
1113
+ reporting_end_month=reporting_end_month,
1114
  )
1115
  return fig
1116
 
app.py CHANGED
@@ -480,7 +480,11 @@ def generate_seasonal_plot(data, year, shapefile_path):
480
  )
481
 
482
  return plot_seasonal_salinity_for_bays(
483
- data, year, shapefile_path=shapefile_path, wbids=wbids
 
 
 
 
484
  )
485
 
486
 
@@ -1158,19 +1162,18 @@ elif section == "Calendar Heatmaps":
1158
  elif section == "Seasonal Trends":
1159
  st.title("Seasonal Trends")
1160
  raw_df = data["raw_df"]
1161
- years = sorted(pd.to_datetime(raw_df["Activity_Start_Date_Time"]).dt.year.unique())
1162
- col1, col2 = st.columns(2)
1163
- with col1:
1164
- analyte = st.selectbox(
1165
- "Select Analyte:", ["Salinity"], index=0, key="seasonal_analyte_select"
1166
- )
1167
- with col2:
1168
- selected_year = st.selectbox(
1169
- "Select Year:",
1170
- sorted(years, reverse=True),
1171
- index=0,
1172
- key="seasonal_year_select",
1173
- )
1174
  if not raw_df.empty:
1175
  seasonal_data = load_seasonal_data(raw_df, analyte)
1176
  fig = generate_seasonal_plot(
 
480
  )
481
 
482
  return plot_seasonal_salinity_for_bays(
483
+ data,
484
+ year,
485
+ shapefile_path=shapefile_path,
486
+ wbids=wbids,
487
+ reporting_end_month=st.session_state.dataset_reporting_month,
488
  )
489
 
490
 
 
1162
  elif section == "Seasonal Trends":
1163
  st.title("Seasonal Trends")
1164
  raw_df = data["raw_df"]
1165
+ # Use Reporting_Year instead of calendar year
1166
+ years = sorted(raw_df["Reporting_Year"].unique())
1167
+
1168
+ # Move filters to sidebar
1169
+ st.sidebar.markdown("### Filter Options")
1170
+ analyte = st.sidebar.selectbox(
1171
+ "Select Analyte:", ["Salinity"], index=0, key="seasonal_analyte_select"
1172
+ )
1173
+ selected_year = st.sidebar.selectbox(
1174
+ "Select Year:", sorted(years, reverse=True), index=0, key="seasonal_year_select"
1175
+ )
1176
+
 
1177
  if not raw_df.empty:
1178
  seasonal_data = load_seasonal_data(raw_df, analyte)
1179
  fig = generate_seasonal_plot(
main.py CHANGED
@@ -73,6 +73,7 @@ def get_analyte_data_with_lat_long(df: pd.DataFrame, analyte: str) -> pd.DataFra
73
  - Station_Number
74
  - Org_Analyte_Name
75
  - Org_Result_Value
 
76
  analyte (str): Name of the analyte to filter for (e.g., "Temperature, Water")
77
 
78
  Returns:
@@ -85,6 +86,7 @@ def get_analyte_data_with_lat_long(df: pd.DataFrame, analyte: str) -> pd.DataFra
85
  - Activity_Depth: Depth of measurement
86
  - Latitude: Station latitude
87
  - Longitude: Station longitude
 
88
  - {analyte}: Measured value for the specified analyte
89
 
90
  Note:
@@ -104,6 +106,7 @@ def get_analyte_data_with_lat_long(df: pd.DataFrame, analyte: str) -> pd.DataFra
104
  "Activity_Depth",
105
  "Latitude",
106
  "Longitude",
 
107
  ],
108
  values="Org_Result_Value",
109
  aggfunc="mean",
 
73
  - Station_Number
74
  - Org_Analyte_Name
75
  - Org_Result_Value
76
+ - Reporting_Year
77
  analyte (str): Name of the analyte to filter for (e.g., "Temperature, Water")
78
 
79
  Returns:
 
86
  - Activity_Depth: Depth of measurement
87
  - Latitude: Station latitude
88
  - Longitude: Station longitude
89
+ - Reporting_Year: Reporting year
90
  - {analyte}: Measured value for the specified analyte
91
 
92
  Note:
 
106
  "Activity_Depth",
107
  "Latitude",
108
  "Longitude",
109
+ "Reporting_Year",
110
  ],
111
  values="Org_Result_Value",
112
  aggfunc="mean",