ECOv002-calval-tables 1.4.0__py3-none-any.whl → 1.6.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,113 @@
1
+
2
+ import matplotlib.pyplot as plt
3
+ import numpy as np
4
+ import matplotlib.lines as mlines
5
+ import os
6
+ from . import error_funcs
7
+
8
+ import pandas as pd
9
+ from typing import Optional
10
+
11
+ def quick_look_plot_single_model(
12
+ calval_table_df: pd.DataFrame,
13
+ model_output_variable_name: str,
14
+ model_name: str,
15
+ insitu_variable_name: str = 'LEcorr50'
16
+ ) -> plt.Figure:
17
+ """
18
+ Generate a scatter plot comparing model output to flux tower latent energy (LE) measurements, color-coded by vegetation type, with error bars and annotated performance metrics.
19
+
20
+ This function is designed for visual evaluation of model performance against observed data, and is suitable for use in Jupyter notebooks (returns a matplotlib Figure object for direct display).
21
+
22
+ Parameters
23
+ ----------
24
+ calval_table_df : pd.DataFrame
25
+ DataFrame containing all relevant data for plotting and analysis. Must include columns for vegetation type, model output, flux tower LE, and optionally uncertainty/error columns.
26
+ model_output_variable_name : str
27
+ Column name in `calval_table_df` for the model output to be plotted on the y-axis.
28
+ model_name : str
29
+ Display name for the model, used as the plot title.
30
+ insitu_variable_name : str, optional
31
+ Column name for the flux tower LE values to be plotted on the x-axis (default is 'LEcorr50').
32
+
33
+ Returns
34
+ -------
35
+ matplotlib.figure.Figure
36
+ The generated matplotlib Figure object, ready for display in a Jupyter notebook or further customization.
37
+
38
+ Notes
39
+ -----
40
+ - Points are color-coded by vegetation type using a predefined color map.
41
+ - Error bars are included if uncertainty columns are present in the DataFrame.
42
+ - The plot includes a 1:1 reference line, a regression line, and annotations for RMSE, bias, and R².
43
+ - A legend for vegetation types is included below the plot.
44
+
45
+ Example
46
+ -------
47
+ >>> fig = quick_look_plot_single_model(df, 'model_output', 'My Model')
48
+ >>> fig.show()
49
+ """
50
+ # Define colors for each vegetation type for scatter plot visualization
51
+ colors = {
52
+ 'CRO': '#FFEC8B', 'CSH': '#AB82FF', 'CVM': '#8B814C',
53
+ 'DBF': '#98FB98', 'EBF': '#7FFF00', 'ENF': '#006400',
54
+ 'GRA': '#FFA54F', 'MF': '#8FBC8F', 'OSH': '#FFE4E1',
55
+ 'SAV': '#FFD700', 'WAT': '#98F5FF', 'WET': '#4169E1',
56
+ 'WSA': '#CDAA7D'
57
+ }
58
+ # Assign a color to each data point based on its vegetation type
59
+ scatter_colors = [colors.get(veg, 'gray') for veg in calval_table_df['vegetation']]
60
+ # Create a reference 1:1 line for the plot (where model output equals flux tower measurement)
61
+ one2one = np.arange(-250, 1200, 5)
62
+ # Helper function to calculate performance metrics between model and observed data
63
+ def calculate_metrics(x: np.ndarray, y: np.ndarray) -> tuple[float, float, float, float, float]:
64
+ # RMSE: Root Mean Square Error
65
+ rmse = error_funcs.rmse(y, x)
66
+ # R2: Coefficient of Determination
67
+ r2 = error_funcs.R2_fun(y, x)
68
+ # Slope and intercept from linear regression
69
+ slope, intercept = error_funcs.lin_regress(y, x)
70
+ # Bias: Mean difference between model and observed
71
+ bias = error_funcs.BIAS_fun(y,x)
72
+ return rmse, r2, slope, intercept, bias
73
+ # Extract flux tower LE values and model output values from DataFrame
74
+ x = calval_table_df[insitu_variable_name].to_numpy()
75
+ y = calval_table_df[model_output_variable_name].to_numpy()
76
+ # Extract uncertainty in model output if available
77
+ err = calval_table_df['ETinstUncertainty'].to_numpy() if 'ETinstUncertainty' in calval_table_df.columns else None
78
+ # Calculate standard deviation across three LE columns for x error bars if all columns are present
79
+ xerr = calval_table_df[['LE_filt', 'LEcorr50', 'LEcorr_ann']].std(axis=1).to_numpy() if all(col in calval_table_df.columns for col in ['LE_filt', 'LEcorr50', 'LEcorr_ann']) else None
80
+ # Compute performance metrics for the plot annotation
81
+ rmse, r2, slope, intercept, bias = calculate_metrics(x, y)
82
+ # Count number of valid (non-NaN) data points
83
+ number_of_points = np.sum(~np.isnan(y) & ~np.isnan(x))
84
+ # Create the matplotlib figure and axis
85
+ fig, ax = plt.subplots(figsize=(6, 6))
86
+ # Plot error bars if uncertainty data is available
87
+ if err is not None and xerr is not None:
88
+ ax.errorbar(x, y, yerr=err, xerr=xerr, fmt='', ecolor='lightgray')
89
+ # Plot the scatter points, colored by vegetation type
90
+ ax.scatter(x, y, c=scatter_colors, marker='o', s=6, zorder=4)
91
+ # Plot the 1:1 reference line (ideal fit)
92
+ ax.plot(one2one, one2one, '--', c='k')
93
+ # Plot the regression line (actual fit)
94
+ ax.plot(one2one, one2one * slope + intercept, '--', c='gray')
95
+ # Set plot title and axis limits
96
+ ax.set_title(model_name)
97
+ ax.set_xlim([-250, 1200])
98
+ ax.set_ylim([-250, 1200])
99
+ # Set axis labels
100
+ ax.set_ylabel('Model LE Wm$^{-2}$',fontsize=14)
101
+ ax.set_xlabel('Flux Tower LE Wm$^{-2}$',fontsize=14)
102
+ # Add subplot label
103
+ ax.text(-0.1, 1.1, 'a)', transform=ax.transAxes, fontsize=16, fontweight='bold', va='top', ha='right')
104
+ # Annotate plot with regression equation, RMSE, bias, and R2
105
+ ax.text(500, -200, f'y = {slope:.1f}x + {intercept:.1f} \nRMSE: {rmse:.1f} Wm$^-$² \nbias: {bias:.1f} Wm$^-$² \nR$^2$: {r2:.2f}', fontsize=12)
106
+ # Create legend handles for each vegetation type
107
+ scatter_handles = [mlines.Line2D([], [], color=color, marker='o', linestyle='None', markersize=6, label=veg) for veg, color in colors.items()]
108
+ # Add legend to the figure
109
+ fig.legend(handles=scatter_handles, loc='lower center', bbox_to_anchor=(0.5, -0.05), ncol=7, title='Vegetation Type',fontsize=10)
110
+ # Adjust layout for better appearance
111
+ fig.tight_layout()
112
+ # Return the figure object for display in Jupyter notebooks
113
+ return fig
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ECOv002-calval-tables
3
- Version: 1.4.0
3
+ Version: 1.6.0
4
4
  Summary: Priestley-Taylor Jet Propulsion Laboratory Soil Moisutre Evapotranspiration Model
5
5
  Author-email: Gregory Halverson <gregory.h.halverson@jpl.nasa.gov>, Zoe Pierrat <zoe.a.pierrat@jpl.nasa.gov>
6
6
  Project-URL: Homepage, https://github.com/gregory-halverson/ECOv002-calval-tables
@@ -11,6 +11,12 @@ Description-Content-Type: text/markdown
11
11
  License-File: LICENSE
12
12
  Requires-Dist: pandas
13
13
  Requires-Dist: geopandas
14
+ Requires-Dist: numpy
15
+ Requires-Dist: tables
16
+ Requires-Dist: scikit-learn
17
+ Requires-Dist: scipy
18
+ Requires-Dist: matplotlib
19
+ Requires-Dist: shapely
14
20
  Provides-Extra: dev
15
21
  Requires-Dist: build; extra == "dev"
16
22
  Requires-Dist: pytest>=6.0; extra == "dev"
@@ -0,0 +1,15 @@
1
+ ECOv002_calval_tables/ECOv002_calval_tables.py,sha256=k8y7TEevSX3Y6NhEU1qg_CySd-f_T4omNNJFc7ZxXcY,135
2
+ ECOv002_calval_tables/__init__.py,sha256=oO0pVascuJs247UwpXq2o23wQPThM1bWEwUhSYiNzMY,60
3
+ ECOv002_calval_tables/combined_eco_flux_EC_filtered.csv,sha256=uSRv1CBMJKUWBgtMlRHB1359kiUFUL1ez2c4m7C4DxU,745225
4
+ ECOv002_calval_tables/ec_lib.py,sha256=0k7CldHMFrcq77OqsXdreJQNEVUHVMCAHmUWNo-63fA,24676
5
+ ECOv002_calval_tables/error_funcs.py,sha256=WFsoYvZyJVF-ppBn0BV2JJADPZN48OJBG2QZ6Lt3uCk,11275
6
+ ECOv002_calval_tables/load_tables.py,sha256=m9UEz07yIrM-m2PaYv2g_TnBLN5Wjg7yUuMzs-T25Gk,2685
7
+ ECOv002_calval_tables/metadata_ebc_filt.csv,sha256=74AeCH5DG2Zu8ZFBXUZAW95hlsCjK9K3t6BWRRReR3s,13975
8
+ ECOv002_calval_tables/plot_funcs.py,sha256=asu43YEtWhNehBRKx5ujIiqNn6iePbXW6fC_8Tl8yzI,23988
9
+ ECOv002_calval_tables/plot_single_model.py,sha256=1McpBLyLm8oM-7wA0sDEgEQY_AM_8aisxcDUuKPBrDM,5853
10
+ ECOv002_calval_tables/version.py,sha256=DOnf2BIAf7HAp9SIUIetrDgRoZDL0o7JuKSiC7_ZT_I,87
11
+ ecov002_calval_tables-1.6.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
12
+ ecov002_calval_tables-1.6.0.dist-info/METADATA,sha256=_bQvh2W1unTzjawE2rtBYJX1Vb252MVH4pa6AxSOWNg,3312
13
+ ecov002_calval_tables-1.6.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
14
+ ecov002_calval_tables-1.6.0.dist-info/top_level.txt,sha256=ePbA84g_XQHWQUAQEVo6gmyuW0WLUzPg2IfHyoGqUqg,22
15
+ ecov002_calval_tables-1.6.0.dist-info/RECORD,,
@@ -1,10 +0,0 @@
1
- ECOv002_calval_tables/ECOv002_calval_tables.py,sha256=m9UEz07yIrM-m2PaYv2g_TnBLN5Wjg7yUuMzs-T25Gk,2685
2
- ECOv002_calval_tables/__init__.py,sha256=oO0pVascuJs247UwpXq2o23wQPThM1bWEwUhSYiNzMY,60
3
- ECOv002_calval_tables/combined_eco_flux_EC_filtered.csv,sha256=uSRv1CBMJKUWBgtMlRHB1359kiUFUL1ez2c4m7C4DxU,745225
4
- ECOv002_calval_tables/metadata_ebc_filt.csv,sha256=74AeCH5DG2Zu8ZFBXUZAW95hlsCjK9K3t6BWRRReR3s,13975
5
- ECOv002_calval_tables/version.py,sha256=DOnf2BIAf7HAp9SIUIetrDgRoZDL0o7JuKSiC7_ZT_I,87
6
- ecov002_calval_tables-1.4.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
7
- ecov002_calval_tables-1.4.0.dist-info/METADATA,sha256=ryh_AXt-OEHshWsMhSnM3J4bVcChyp52ArR33wxGF3Y,3171
8
- ecov002_calval_tables-1.4.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
9
- ecov002_calval_tables-1.4.0.dist-info/top_level.txt,sha256=ePbA84g_XQHWQUAQEVo6gmyuW0WLUzPg2IfHyoGqUqg,22
10
- ecov002_calval_tables-1.4.0.dist-info/RECORD,,