github-actions[bot] commited on
Commit ·
e703fdd
1
Parent(s): f06f541
Deploy from GitHub Actions
Browse files- analysis.py +38 -12
- ui/pages/seasonal_line_charts.py +8 -1
analysis.py
CHANGED
|
@@ -2411,6 +2411,7 @@ def plot_seasonal_line(
|
|
| 2411 |
parameter: str,
|
| 2412 |
period: str = "quarterly",
|
| 2413 |
thresh: float | None = None,
|
|
|
|
| 2414 |
) -> tuple[Figure, pd.DataFrame, pd.DataFrame]:
|
| 2415 |
"""
|
| 2416 |
Create a line chart showing seasonal trends for a parameter across all years.
|
|
@@ -2425,7 +2426,8 @@ def plot_seasonal_line(
|
|
| 2425 |
'monthly' or 'quarterly' aggregation period
|
| 2426 |
thresh : float | None
|
| 2427 |
Optional threshold value to display on plot
|
| 2428 |
-
|
|
|
|
| 2429 |
Returns:
|
| 2430 |
--------
|
| 2431 |
tuple[Figure, pd.DataFrame]
|
|
@@ -2463,12 +2465,23 @@ def plot_seasonal_line(
|
|
| 2463 |
# Calculate overall average for dotted line
|
| 2464 |
stats_df["overall_avg"] = param_data["Org_Result_Value"].mean()
|
| 2465 |
|
| 2466 |
-
# Create figure
|
| 2467 |
fig, ax = plt.subplots(figsize=(10, 6))
|
| 2468 |
|
| 2469 |
# Get the unit
|
| 2470 |
unit = param_data["Org_Result_Unit"].iloc[0]
|
| 2471 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2472 |
# Plot mean line
|
| 2473 |
mean_line = ax.plot(
|
| 2474 |
stats_df[group_col],
|
|
@@ -2483,9 +2496,9 @@ def plot_seasonal_line(
|
|
| 2483 |
ax.annotate(
|
| 2484 |
"Mean",
|
| 2485 |
xy=(stats_df[group_col].iloc[0], stats_df["mean"].iloc[0]),
|
| 2486 |
-
xytext=(-5, 0),
|
| 2487 |
textcoords="offset points",
|
| 2488 |
-
ha="right",
|
| 2489 |
va="center",
|
| 2490 |
color=mean_line.get_color(),
|
| 2491 |
fontsize=9,
|
|
@@ -2573,6 +2586,19 @@ def plot_seasonal_line(
|
|
| 2573 |
label=f"Threshold: {thresh} {unit}",
|
| 2574 |
zorder=1,
|
| 2575 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2576 |
|
| 2577 |
# Customize plot
|
| 2578 |
ax.set_xticks(x_ticks)
|
|
@@ -2631,7 +2657,7 @@ def plot_seasonal_line(
|
|
| 2631 |
# Remove tick marks but keep labels
|
| 2632 |
ax2.tick_params(axis="y", which="both", length=0)
|
| 2633 |
else:
|
| 2634 |
-
ax.set_ylabel(f"{
|
| 2635 |
|
| 2636 |
# Get year range for title
|
| 2637 |
start_year = param_data["Activity_Start_Date_Time"].dt.year.min()
|
|
@@ -2639,7 +2665,11 @@ def plot_seasonal_line(
|
|
| 2639 |
year_range = (
|
| 2640 |
f" ({start_year}-{end_year})" if start_year != end_year else f" ({start_year})"
|
| 2641 |
)
|
| 2642 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2643 |
ax.grid(True, axis="y", alpha=0.15, linestyle="-", color="gray")
|
| 2644 |
|
| 2645 |
# Customize spines
|
|
@@ -2648,15 +2678,11 @@ def plot_seasonal_line(
|
|
| 2648 |
ax.spines["left"].set_visible(False)
|
| 2649 |
|
| 2650 |
# Remove tick marks but keep labels
|
| 2651 |
-
ax.tick_params(
|
| 2652 |
-
axis="y", which="both", length=0
|
| 2653 |
-
) # Add this line to remove tick marks
|
| 2654 |
|
| 2655 |
# Adjust layout based on unit type
|
| 2656 |
if unit == "deg C":
|
| 2657 |
-
plt.tight_layout(
|
| 2658 |
-
rect=(0, 0, 0.95, 1)
|
| 2659 |
-
) # Less right margin for temperature plots
|
| 2660 |
else:
|
| 2661 |
plt.tight_layout(rect=(0, 0, 0.9, 1))
|
| 2662 |
stats_df.insert(0, "parameter", parameter)
|
|
|
|
| 2411 |
parameter: str,
|
| 2412 |
period: str = "quarterly",
|
| 2413 |
thresh: float | None = None,
|
| 2414 |
+
sector: str | None = None,
|
| 2415 |
) -> tuple[Figure, pd.DataFrame, pd.DataFrame]:
|
| 2416 |
"""
|
| 2417 |
Create a line chart showing seasonal trends for a parameter across all years.
|
|
|
|
| 2426 |
'monthly' or 'quarterly' aggregation period
|
| 2427 |
thresh : float | None
|
| 2428 |
Optional threshold value to display on plot
|
| 2429 |
+
sector : str | None
|
| 2430 |
+
Optional sector name to include in title
|
| 2431 |
Returns:
|
| 2432 |
--------
|
| 2433 |
tuple[Figure, pd.DataFrame]
|
|
|
|
| 2465 |
# Calculate overall average for dotted line
|
| 2466 |
stats_df["overall_avg"] = param_data["Org_Result_Value"].mean()
|
| 2467 |
|
|
|
|
| 2468 |
fig, ax = plt.subplots(figsize=(10, 6))
|
| 2469 |
|
| 2470 |
# Get the unit
|
| 2471 |
unit = param_data["Org_Result_Unit"].iloc[0]
|
| 2472 |
|
| 2473 |
+
# Set log scale for specific parameters
|
| 2474 |
+
if parameter in [
|
| 2475 |
+
"Turbidity",
|
| 2476 |
+
"Fecal Coliform (MPN)",
|
| 2477 |
+
"Total Nitrogen",
|
| 2478 |
+
"Total Phosphorus",
|
| 2479 |
+
]:
|
| 2480 |
+
ax.set_yscale("log")
|
| 2481 |
+
ax.yaxis.set_major_formatter(
|
| 2482 |
+
plt.ScalarFormatter() # type: ignore
|
| 2483 |
+
)
|
| 2484 |
+
|
| 2485 |
# Plot mean line
|
| 2486 |
mean_line = ax.plot(
|
| 2487 |
stats_df[group_col],
|
|
|
|
| 2496 |
ax.annotate(
|
| 2497 |
"Mean",
|
| 2498 |
xy=(stats_df[group_col].iloc[0], stats_df["mean"].iloc[0]),
|
| 2499 |
+
xytext=(-5, 0),
|
| 2500 |
textcoords="offset points",
|
| 2501 |
+
ha="right",
|
| 2502 |
va="center",
|
| 2503 |
color=mean_line.get_color(),
|
| 2504 |
fontsize=9,
|
|
|
|
| 2586 |
label=f"Threshold: {thresh} {unit}",
|
| 2587 |
zorder=1,
|
| 2588 |
)
|
| 2589 |
+
# Add legend for threshold only
|
| 2590 |
+
ax.legend(
|
| 2591 |
+
[
|
| 2592 |
+
ax.axhline(
|
| 2593 |
+
y=thresh, color="red", linestyle=":", alpha=0.9, linewidth=1.5
|
| 2594 |
+
)
|
| 2595 |
+
],
|
| 2596 |
+
[f"Threshold: {thresh} {unit}"],
|
| 2597 |
+
loc="upper right",
|
| 2598 |
+
frameon=False,
|
| 2599 |
+
handletextpad=0.5,
|
| 2600 |
+
fontsize=9,
|
| 2601 |
+
)
|
| 2602 |
|
| 2603 |
# Customize plot
|
| 2604 |
ax.set_xticks(x_ticks)
|
|
|
|
| 2657 |
# Remove tick marks but keep labels
|
| 2658 |
ax2.tick_params(axis="y", which="both", length=0)
|
| 2659 |
else:
|
| 2660 |
+
ax.set_ylabel(f"{unit}")
|
| 2661 |
|
| 2662 |
# Get year range for title
|
| 2663 |
start_year = param_data["Activity_Start_Date_Time"].dt.year.min()
|
|
|
|
| 2665 |
year_range = (
|
| 2666 |
f" ({start_year}-{end_year})" if start_year != end_year else f" ({start_year})"
|
| 2667 |
)
|
| 2668 |
+
title = f"Seasonal {parameter} Trends{year_range}"
|
| 2669 |
+
if sector:
|
| 2670 |
+
title = f"{title} - {sector}"
|
| 2671 |
+
ax.set_title(title)
|
| 2672 |
+
|
| 2673 |
ax.grid(True, axis="y", alpha=0.15, linestyle="-", color="gray")
|
| 2674 |
|
| 2675 |
# Customize spines
|
|
|
|
| 2678 |
ax.spines["left"].set_visible(False)
|
| 2679 |
|
| 2680 |
# Remove tick marks but keep labels
|
| 2681 |
+
ax.tick_params(axis="y", which="both", length=0)
|
|
|
|
|
|
|
| 2682 |
|
| 2683 |
# Adjust layout based on unit type
|
| 2684 |
if unit == "deg C":
|
| 2685 |
+
plt.tight_layout(rect=(0, 0, 0.95, 1))
|
|
|
|
|
|
|
| 2686 |
else:
|
| 2687 |
plt.tight_layout(rect=(0, 0, 0.9, 1))
|
| 2688 |
stats_df.insert(0, "parameter", parameter)
|
ui/pages/seasonal_line_charts.py
CHANGED
|
@@ -67,6 +67,9 @@ plot_df = plot_df[
|
|
| 67 |
# Apply sector filter
|
| 68 |
if sector_filter != "All":
|
| 69 |
plot_df = plot_df[plot_df["Sector"] == sector_filter]
|
|
|
|
|
|
|
|
|
|
| 70 |
|
| 71 |
if not plot_df.empty:
|
| 72 |
# Create plot for the selected parameter
|
|
@@ -84,7 +87,11 @@ if not plot_df.empty:
|
|
| 84 |
thresh = None
|
| 85 |
|
| 86 |
fig, param_data, stats_df = plot_seasonal_line(
|
| 87 |
-
plot_df,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 88 |
)
|
| 89 |
st.pyplot(fig)
|
| 90 |
|
|
|
|
| 67 |
# Apply sector filter
|
| 68 |
if sector_filter != "All":
|
| 69 |
plot_df = plot_df[plot_df["Sector"] == sector_filter]
|
| 70 |
+
sector = sector_filter
|
| 71 |
+
else:
|
| 72 |
+
sector = None
|
| 73 |
|
| 74 |
if not plot_df.empty:
|
| 75 |
# Create plot for the selected parameter
|
|
|
|
| 87 |
thresh = None
|
| 88 |
|
| 89 |
fig, param_data, stats_df = plot_seasonal_line(
|
| 90 |
+
plot_df,
|
| 91 |
+
selected_parameter,
|
| 92 |
+
period=period.lower(),
|
| 93 |
+
thresh=thresh,
|
| 94 |
+
sector=sector,
|
| 95 |
)
|
| 96 |
st.pyplot(fig)
|
| 97 |
|