Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "cssi_evaluation"
version = "0.1.6"
version = "0.1.7"
description = "Model evaluation functions for the CSSI project"
readme = { file = "README.md", content-type = "text/markdown" }
license = { file = "LICENSE" }
Expand Down
80 changes: 58 additions & 22 deletions src/cssi_evaluation/utils/plot_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,10 @@
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from matplotlib.lines import Line2D
import xarray as xr
import geopandas as gpd
import holoviews as hv
import hvplot.pandas
import hvplot.xarray
import geoviews as gv
import geoviews.tile_sources as gts
import folium
import xyzservices.providers as xyz
import warnings
import numpy as np

gv.extension("bokeh")

SITE_COLORS = {
"stream gauge": "blue",
Expand Down Expand Up @@ -395,7 +386,9 @@ def plot_condon_diagram(metrics_df, variable, output_dir=".", adaptive_xlim=True
os.makedirs(output_dir)

# Keep only rows that can actually be plotted
df_plot = metrics_df.dropna(subset=["abs_rel_bias", "spearman_rho", "condon"]).copy()
df_plot = metrics_df.dropna(
subset=["abs_rel_bias", "spearman_rho", "condon"]
).copy()

# Remove undefined categories
df_plot = df_plot[df_plot["condon"] != "Undefined"].copy()
Expand All @@ -415,10 +408,38 @@ def plot_condon_diagram(metrics_df, variable, output_dir=".", adaptive_xlim=True
)

custom = [
Line2D([], [], marker="o", color=CONDON_COLORS["Low bias, good shape"], linestyle="None", markersize=5),
Line2D([], [], marker="o", color=CONDON_COLORS["High bias, good shape"], linestyle="None", markersize=5),
Line2D([], [], marker="o", color=CONDON_COLORS["Low bias, poor shape"], linestyle="None", markersize=5),
Line2D([], [], marker="o", color=CONDON_COLORS["High bias, poor shape"], linestyle="None", markersize=5),
Line2D(
[],
[],
marker="o",
color=CONDON_COLORS["Low bias, good shape"],
linestyle="None",
markersize=5,
),
Line2D(
[],
[],
marker="o",
color=CONDON_COLORS["High bias, good shape"],
linestyle="None",
markersize=5,
),
Line2D(
[],
[],
marker="o",
color=CONDON_COLORS["Low bias, poor shape"],
linestyle="None",
markersize=5,
),
Line2D(
[],
[],
marker="o",
color=CONDON_COLORS["High bias, poor shape"],
linestyle="None",
markersize=5,
),
]

# Put legend outside the axes
Expand Down Expand Up @@ -506,15 +527,20 @@ def plot_condon_diagram(metrics_df, variable, output_dir=".", adaptive_xlim=True
)

plt.title(f"{variable.capitalize()} Performance Category")
plt.savefig(f"{output_dir}/{variable}_condon_diagram.png", bbox_inches="tight", dpi=300)
plt.savefig(
f"{output_dir}/{variable}_condon_diagram.png", bbox_inches="tight", dpi=300
)

# Leave room at top for outside legend
fig.subplots_adjust(top=0.82)

plt.savefig(f"{output_dir}/{variable}_condon_diagram.png", dpi=300, bbox_inches="tight")
plt.savefig(
f"{output_dir}/{variable}_condon_diagram.png", dpi=300, bbox_inches="tight"
)
plt.show()
plt.close()


# from Irene's nwm_utils.py


Expand All @@ -530,6 +556,9 @@ def map_sites_within_watershed(gdf_sites, domain_gdf, zoom_start=10):
Returns:
- folium.Map object ready to display.
"""
import geopandas as gpd
import folium

# Ensure CRS compatibility
if gdf_sites.crs != domain_gdf.crs:
gdf_sites = gdf_sites.to_crs(domain_gdf.crs)
Expand Down Expand Up @@ -672,6 +701,7 @@ def find_column(columns, candidates):

# return layout


def comparison_plots(df_obs, df_mod, obs_col, mod_col, site_label=None):
"""
Create comparison plots (timeseries + scatter) for a given site
Expand Down Expand Up @@ -830,6 +860,7 @@ def comparison_plots(df_obs, df_mod, obs_col, mod_col, site_label=None):

# return (scatter * one_to_one).opts(legend_position="bottom_right")


def plot_custom_scatter_SWE(
df_obs,
df_mod,
Expand Down Expand Up @@ -921,7 +952,11 @@ def plot_custom_scatter_SWE(


def plot_grid_vector_data(ds_clip, data_var, time_index, shp, sites):
import geoviews as gv
import geoviews.tile_sources as gts

hv.extension("bokeh")

da = ds_clip[data_var]

# Select one timestep
Expand Down Expand Up @@ -970,6 +1005,9 @@ def plot_grid_vector_data(ds_clip, data_var, time_index, shp, sites):


def plot_grid_vector_monthly_data(ds_clip, data_var, shp, sites):
import geoviews as gv
import geoviews.tile_sources as gts

hv.extension("bokeh")

# Create an interactive map plot
Expand Down Expand Up @@ -1037,8 +1075,6 @@ def plot_scatter_melt_metrics(df):
Displays the figure.
"""

import matplotlib.pyplot as plt

fig, axes = plt.subplots(1, 2, figsize=(12, 5))

# -------- Melt Rate --------
Expand All @@ -1048,7 +1084,7 @@ def plot_scatter_melt_metrics(df):
axes[0].scatter(x, y, alpha=0.7)

lims = [min(x.min(), y.min()), max(x.max(), y.max())]
axes[0].plot(lims, lims, 'k--')
axes[0].plot(lims, lims, "k--")

axes[0].set_title("Melt Rate (Obs vs Model): m/day")
axes[0].set_xlabel("Observed")
Expand All @@ -1062,7 +1098,7 @@ def plot_scatter_melt_metrics(df):
axes[1].scatter(x, y, alpha=0.7)

lims = [min(x.min(), y.min()), max(x.max(), y.max())]
axes[1].plot(lims, lims, 'k--')
axes[1].plot(lims, lims, "k--")

axes[1].set_title("Melt Duration (Obs vs Model): days")
axes[1].set_xlabel("Observed")
Expand Down Expand Up @@ -1123,8 +1159,8 @@ def plot_melt_bias_summary(df, col_obs, col_mod, title):
transform=plt.gca().transAxes,
verticalalignment="top",
fontsize=10,
bbox=dict(facecolor="white", alpha=0.8)
bbox=dict(facecolor="white", alpha=0.8),
)

plt.tight_layout()
plt.show()
plt.show()
Loading