Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
39111f1
move some vector plotting functionality into vector_utils.py (#2321)
megannissel Feb 18, 2026
a92d069
groundwork for a swy report (#2321)
megannissel Feb 18, 2026
a257cba
Merge branch 'release/3.18.0' into feature/2321-swy-report
megannissel Feb 20, 2026
03ef51f
second iteration of swy report (#2321)
megannissel Mar 3, 2026
e3eefbc
Merge branch 'main' into feature/2321-swy-report
megannissel Mar 3, 2026
eb61c0d
interactive baseflow and quickflow plots, now in m3/s (#2321)
megannissel Mar 5, 2026
6e1bd1d
adjust raster_utils.raster_inputs_summary to check input csvs for ras…
megannissel Mar 6, 2026
4afb5e1
reorganize report sections; include monthly qf rasters alongside annu…
megannissel Mar 6, 2026
fc6b23b
fix qf+b graph to show sums when multiple features are selected (#2321)
megannissel Mar 9, 2026
a56e945
move chart_landmass back into CV reporter (not used elsewhere) (#2321)
megannissel Mar 11, 2026
d779405
fix alignment of monthly tickmarks; add FID to aggregate_vector.shp r…
megannissel Mar 11, 2026
aa4dfb4
move construction of monthly qf & b csv into execute (#2321)
megannissel Mar 12, 2026
70b252e
update SWY created_if conditions; update reporter conditional logic t…
megannissel Mar 12, 2026
f90e7d5
mask qf rasters by stream network for improved contrast (#2321)
megannissel Mar 13, 2026
faa6ed0
fix quotes in f-string (#2321)
megannissel Mar 13, 2026
b7e061c
Revert "mask qf rasters by stream network for improved contrast (#2321)"
megannissel Mar 13, 2026
cbfe933
log-transform qf plots for increased contrast; add small plots and cu…
megannissel Mar 16, 2026
169be1e
summarize output raster stats for nested paths; expand utils.fake_exe…
megannissel Mar 18, 2026
18047bc
minor edits to swy reporter, including supertitle for raster facet gr…
megannissel Mar 18, 2026
3b3b0f5
update SWY outputs units in model_spec (#2321)
megannissel Mar 18, 2026
d096609
basic testing for swy reporter template (#2321)
megannissel Mar 18, 2026
26753e3
always pass model spec to `raster_inputs_summary` (#2321)
megannissel Mar 18, 2026
cecba2e
swy report template testing (#2321)
megannissel Mar 19, 2026
375e96c
accept either str or colormap object for RasterPlotConfig.colormap; u…
megannissel Mar 19, 2026
7e51bdd
improvements to SWY reporter, including better axis and legend config…
megannissel Mar 19, 2026
93f9c73
document geom_id in aggregate vector output spec; adjust gemon_id des…
megannissel Mar 19, 2026
8c45a1a
update SWY model to index all monthly outputs consistently by month, …
megannissel Mar 19, 2026
4c4a789
reduce tests checking quickflow/baseflow CSV values to the base regre…
megannissel Mar 19, 2026
5e78639
snapshot tests for plot_raster_facets small plots (#2321)
megannissel Mar 20, 2026
68f4641
raster_workspace_summary: recursively handle nested file_registry (#2…
megannissel Mar 20, 2026
3903ad4
provide quickflow, baseflow, and precip CSV values in m3/month (#2321)
megannissel Mar 20, 2026
47b69cb
update qf+b+precip chart axis labels to reflect m3/month (#2321)
megannissel Mar 20, 2026
6645ee4
update MONTH_ID_TO_LABEL so that it is indexed in line with month num…
megannissel Mar 20, 2026
7150fca
add regression test for user_defined_climate_zones base case (#2321)
megannissel Mar 20, 2026
24b9f96
fix test docstring (#2321)
megannissel Mar 20, 2026
779f84f
fixes and improvements to utils; different color scheme for qb, vri_s…
megannissel Mar 20, 2026
c3a7f95
custom matplotlib colormap for local recharge raster that matches the…
megannissel Mar 20, 2026
30c8535
use built-in matplotlib BrBG instead of custom version (#2321)
megannissel Mar 23, 2026
b86deab
update HISTORY.rst to reflect updates to the SWY model and report (#2…
megannissel Mar 23, 2026
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
24 changes: 21 additions & 3 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,28 @@
7. InVEST model Z (model names should be sorted A-Z)


Unreleased Changes
------------------

Seasonal Water Yield
====================
* The model now generates a report, a visual summary of results, available in
the output workspace and also viewable from the Workbench after the model run
completes. (`#2321 <https://github.com/natcap/invest/issues/2321>`_)
* The model now generates an additional output, a CSV containing average monthly
quickflow, baseflow, and precipitation values, in cubic meters per month, for
each feature in the AOI. This output is used by the report to generate some
plots. Note that this CSV is only created when the model is run without
inputting a Local Recharge raster.
(`#2321 <https://github.com/natcap/invest/issues/2321>`_)
* Various updates to model output data metadata, including correcting the
units of some outputs.
(`#2450 <https://github.com/natcap/invest/issues/2450>`_)
* Updated the naming convention of several monthly intermediate outputs to be
1-indexed rather than 0-indexed. This makes filenames consistent throughout
the model, where 1=January and 12=December.
(`#2451 <https://github.com/natcap/invest/issues/2451>`_)

..
Unreleased Changes
------------------

3.18.0 (2026-02-25)
-------------------
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ GIT_SAMPLE_DATA_REPO_REV := cfd1f07673e66823fd22989a2b87afb017aac447

GIT_TEST_DATA_REPO := https://bitbucket.org/natcap/invest-test-data.git
GIT_TEST_DATA_REPO_PATH := $(DATA_DIR)/invest-test-data
GIT_TEST_DATA_REPO_REV := c791f2b50e67680832054536899efacbc72e9e0b
GIT_TEST_DATA_REPO_REV := 94c4bc9f0f22082d2251b6b14063eb0ff4094451

GIT_UG_REPO := https://github.com/natcap/invest.users-guide
GIT_UG_REPO_PATH := doc/users-guide
Expand Down
2 changes: 1 addition & 1 deletion src/natcap/invest/carbon/reporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ def report(file_registry: dict, args_dict: dict, model_spec: ModelSpec,
]

input_raster_stats_table = raster_utils.raster_inputs_summary(
args_dict).to_html(na_rep='')
args_dict, model_spec).to_html(na_rep='')

output_raster_stats_table = raster_utils.raster_workspace_summary(
file_registry).to_html(na_rep='')
Expand Down
63 changes: 11 additions & 52 deletions src/natcap/invest/coastal_vulnerability/reporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from natcap.invest import __version__
from natcap.invest import gettext
import natcap.invest.spec
from natcap.invest.reports import jinja_env
from natcap.invest.reports import jinja_env, vector_utils


LOGGER = logging.getLogger(__name__)
Expand All @@ -28,49 +28,6 @@
POINT_SIZE = 20
MAP_WIDTH = 450 # pixels

LEGEND_CONFIG = {
'labelFontSize': 14,
'titleFontSize': 14,
'orient': 'left',
'gradientLength': 120
}
AXIS_CONFIG = {
'labelFontSize': 12,
'titleFontSize': 12,
}


def _get_geojson_bbox(geodataframe):
"""Get the bounding box of a GeoDataFrame as a GeoJSON feature.

Also calculate its aspect ratio. These are useful for cropping
other layers in altair plots.

Args:
geodataframe (geopandas.GeoDataFrame):
Returns:
tuple: A 2-tuple containing:
- extent_feature (dict): A GeoJSON feature representing the bounding
box of the input GeoDataFrame.
- xy_ratio (float): The aspect ratio of the bounding box
(width/height).

"""
xmin, ymin, xmax, ymax = geodataframe.total_bounds
xy_ratio = (xmax - xmin) / (ymax - ymin)
extent_feature = {
"type": "Feature",
"geometry": {"type": "Polygon",
"coordinates": [[
[xmax, ymax],
[xmax, ymin],
[xmin, ymin],
[xmin, ymax],
[xmax, ymax]]]},
"properties": {}
}
return extent_feature, xy_ratio


def _chart_landmass(geodataframe, clip=False, extent_feature=None):
landmass = altair.Chart(geodataframe).mark_geoshape(
Expand Down Expand Up @@ -134,13 +91,15 @@ def concat_habitats(row):
]
)

_, xy_ratio = _get_geojson_bbox(exposure_geodf)
_, xy_ratio = vector_utils.get_geojson_bbox(exposure_geodf)
habitat_map = landmass_chart + habitat_points
habitat_map = habitat_map.properties(
width=MAP_WIDTH,
height=MAP_WIDTH / xy_ratio,
title=gettext('The role of habitat in reducing coastal exposure')
).configure_legend(**LEGEND_CONFIG).configure_axis(**AXIS_CONFIG)
).configure_legend(
**vector_utils.LEGEND_CONFIG
).configure_axis(**vector_utils.AXIS_CONFIG)
return habitat_map


Expand Down Expand Up @@ -172,7 +131,7 @@ def report(file_registry, args_dict, model_spec, target_html_filepath):

landmass_geo = geopandas.read_file(
file_registry['clipped_projected_landmass'])
extent_feature, xy_ratio = _get_geojson_bbox(exposure_geo)
extent_feature, xy_ratio = vector_utils.get_geojson_bbox(exposure_geo)
landmass_chart = _chart_landmass(
landmass_geo, clip=True, extent_feature=extent_feature)
base_points = _chart_base_points(exposure_geo)
Expand Down Expand Up @@ -247,7 +206,7 @@ def report(file_registry, args_dict, model_spec, target_html_filepath):
width=MAP_WIDTH,
height=MAP_WIDTH / xy_ratio,
title='coastal exposure'
).configure_legend(**LEGEND_CONFIG)
).configure_legend(**vector_utils.LEGEND_CONFIG)
exposure_map_json = exposure_map.to_json()
exposure_map_caption = [model_spec.get_output(
'coastal_exposure').get_field('exposure').about]
Expand Down Expand Up @@ -284,7 +243,7 @@ def report(file_registry, args_dict, model_spec, target_html_filepath):
).properties(
width=MAP_WIDTH,
height=200
).configure_axis(**AXIS_CONFIG)
).configure_axis(**vector_utils.AXIS_CONFIG)
exposure_histogram_json = exposure_histogram.to_json()

base_rank_vars_chart = base_points.mark_circle(
Expand All @@ -308,7 +267,7 @@ def report(file_registry, args_dict, model_spec, target_html_filepath):
rank_vars_figure = altair.vconcat(
altair.hconcat(*rank_vars_chart_list[:n_cols]),
altair.hconcat(*rank_vars_chart_list[n_cols:])
).configure_axis(**AXIS_CONFIG)
).configure_axis(**vector_utils.AXIS_CONFIG)
rank_vars_figure_json = rank_vars_figure.to_json()
rank_vars_figure_caption = gettext(
"""
Expand Down Expand Up @@ -345,7 +304,7 @@ def report(file_registry, args_dict, model_spec, target_html_filepath):
)
histograms.append(hist)
facetted_histograms = altair.hconcat(
*histograms).configure_axis(**AXIS_CONFIG)
*histograms).configure_axis(**vector_utils.AXIS_CONFIG)
facetted_histograms_json = facetted_histograms.to_json()
facetted_histograms_caption = model_spec.get_output(
'intermediate_exposure').about
Expand Down Expand Up @@ -380,7 +339,7 @@ def report(file_registry, args_dict, model_spec, target_html_filepath):
width=MAP_WIDTH + 30, # extra space for legend
height=MAP_WIDTH / xy_ratio,
title=gettext('local wind-driven waves vs. open ocean waves')
).configure_legend(**LEGEND_CONFIG)
).configure_legend(**vector_utils.LEGEND_CONFIG)
wave_energy_map_json = wave_energy_map.to_json()

wave_energy_map_caption = [model_spec.get_output(
Expand Down
Loading
Loading