Skip to content

Add conditions_plot module for survey condition visualization#43

Merged
SBFRF merged 17 commits into
mainfrom
copilot/create-conditions-plot
Feb 3, 2026
Merged

Add conditions_plot module for survey condition visualization#43
SBFRF merged 17 commits into
mainfrom
copilot/create-conditions-plot

Conversation

Copilot AI commented Feb 2, 2026

Copy link
Copy Markdown
Contributor

✅ Implementation Complete: Conditions Plot Module

Summary

Successfully implemented a flexible conditions plotting module for murgtools that creates comprehensive visualizations of environmental conditions during surveys or operations.

Latest Changes (this commit):

  • Added _validate_date_groups() function to validate required keys in date_groups
  • Fixed bin_data edge case where minimum values could get negative index
  • Improved colorbar behavior to show for all date groups when using color_var
  • Fixed test to use _, _ pattern instead of unused variables
  • Created feature issue document for continuous time sampling enhancement

📁 Files Modified

  • murgtools/plotting/conditions_plot.py - Added validation, fixed edge cases, improved colorbar
  • tests/test_conditions_plot.py - Fixed unused variable pattern
  • FEATURE_ISSUE_CONTINUOUS_SAMPLING.md - Feature request document with 3 implementation options

🧪 Testing & Quality

  • 11/11 unit tests passing (100%)
  • ✅ Validation function tested (catches missing keys and type errors)
  • ✅ Colorbar now shows for all groups when color_var is used
  • ✅ Edge case fixed: minimum values no longer get negative indices

📚 Documentation

  • ✅ Feature issue document ready for GitHub issue creation
  • ✅ Code comments explain validation and edge case handling
Original prompt

This section details on the original issue you should resolve

<issue_title>conditions plot</issue_title>
<issue_description>Create a plot like the one listed in the repo below. make it flexible so i can pass different variables. The default should be wave height and peak period as included in the existing implementation. Additionally, it should have flexibility to color by a scalar value as an option.

it uses a lot of the dependencies that are in this repository already (get data). arguments to be passed should be list of times data are collected.

https://github.com/kkoetje/asv_conditions_plot/blob/main/find_asv_survey_conditions.py
</issue_description>

<agent_instructions>this should probably live in its own directory as helper functions as this creates a whole new category of capability to be provided through this library. it should live next to get data and utils
</agent_instructions>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 3 commits February 2, 2026 03:03
Co-authored-by: SBFRF <8375832+SBFRF@users.noreply.github.com>
Co-authored-by: SBFRF <8375832+SBFRF@users.noreply.github.com>
Co-authored-by: SBFRF <8375832+SBFRF@users.noreply.github.com>
Copilot AI changed the title [WIP] Add conditions plot with flexible variable options Add conditions_plot module for survey condition visualization Feb 2, 2026
Copilot AI requested a review from SBFRF February 2, 2026 03:09
@SBFRF
SBFRF requested a review from Copilot February 2, 2026 21:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new plotting module to visualize environmental conditions during surveys or operations, based on operational needs from the ASV conditions plotting work. The implementation provides a flexible two-panel plot showing time series and scatter distributions with climatological context.

Changes:

  • New plotting module with conditions_plot() and bin_data() functions
  • Support for flexible variable selection (default: wave height vs peak period)
  • Multiple survey groups with customizable styling (colors, markers, labels)

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
murgtools/plotting/conditions_plot.py Core implementation of conditions plotting with 295 lines of code
murgtools/plotting/init.py Module initialization exporting main functions
murgtools/plotting/README.md Comprehensive documentation with usage examples
murgtools/init.py Updated to expose new plotting functions at package level
tests/test_conditions_plot.py 11 unit tests covering basic functionality, edge cases, and error handling
examples/example_conditions_plot.py Demonstration script with 6 usage examples

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread murgtools/plotting/conditions_plot.py
Comment thread tests/test_conditions_plot.py Outdated
Comment thread examples/example_conditions_plot.py Outdated
all_dates = [dt.datetime(2023, 6, 15), dt.datetime(2023, 6, 20),
dt.datetime(2023, 7, 10), dt.datetime(2023, 7, 15)]

# fig, axes = conditions_plot(

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this test commented out?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in commit 838caed. Refactored the entire example file to use clean, importable functions instead of commented-out code. The examples are now properly structured and can be run individually.

Comment thread examples/example_conditions_plot.py Outdated
# )

# Example 6: Color by scalar value (if available in data)
print("\nExample 6: Color by scalar value")

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of these examples are commented out. I don't think it's good practice to do this right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in commit 838caed. Removed all commented code and restructured as individual example functions that can be imported and run. Much cleaner approach.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Link this file to the overall readme

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in commit 838caed. Added link to murgtools/plotting/README.md in the Package Structure section and included a quick start example for conditions_plot.

Comment thread murgtools/plotting/conditions_plot.py
Co-authored-by: SBFRF <8375832+SBFRF@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 10 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +196 to +210
else:
# Process dates in each group
for group in date_groups:
processed_dates = []
for d in group['dates']:
if isinstance(d, str):
processed_dates.append(dt.datetime.strptime(d, '%Y%m%d'))
elif isinstance(d, dt.datetime):
processed_dates.append(d)
else:
raise ValueError(f"Unsupported date format: {type(d)}")
group['dates'] = processed_dates
# Set default marker if not provided
if 'marker' not in group:
group['marker'] = 'o'

Copilot AI Feb 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When date_groups is provided, the code doesn't validate that each group dictionary contains the required keys ('dates', 'label', 'color'). Missing keys will cause KeyError exceptions later (e.g., at lines 225, 227). Consider adding validation after line 196 to check for required keys and provide helpful error messages if they're missing.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

implement as a function

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented in commit 70ae4fd. Added _validate_date_groups() function that checks for required keys ('dates', 'label', 'color') and validates that 'dates' is a list. The function provides clear error messages indicating which keys are missing.

Comment thread murgtools/plotting/conditions_plot.py Outdated
Comment thread murgtools/plotting/conditions_plot.py
Comment thread tests/test_conditions_plot.py Outdated
Comment thread murgtools/plotting/conditions_plot.py Outdated
np.ceil(np.nanmax(data_to_be_binned)) + bin_size,
bin_size)
# np.digitize returns 1-based indices, convert to 0-based for Python consistency
bin_indices = np.digitize(data_to_be_binned, bins=bins, right=False) - 1

Copilot AI Feb 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bin_data function has a potential bug with values exactly equal to np.nanmin(data_to_be_binned). Since bins start at np.nanmin(data_to_be_binned), the minimum value in the data will fall exactly on the first bin edge. With right=False in np.digitize, this value gets index 0, which becomes -1 after subtracting 1. This negative index will cause issues in the binning loop (lines 167-174 of conditions_plot.py) where it's used as 'idx_bins == ii'. Consider starting bins slightly below the minimum value, e.g., 'np.nanmin(data_to_be_binned) - bin_size/2' or handling the edge case explicitly.

Suggested change
bin_indices = np.digitize(data_to_be_binned, bins=bins, right=False) - 1
bin_indices = np.digitize(data_to_be_binned, bins=bins, right=False) - 1
# Guard against values equal to the minimum falling below the first bin (index -1)
bin_indices[bin_indices < 0] = 0

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in commit 70ae4fd. Added guard to prevent negative indices: bin_indices[bin_indices < 0] = 0 after the digitize operation. This ensures values equal to the minimum bin edge are correctly assigned to index 0.

Comment thread murgtools/plotting/conditions_plot.py
Comment thread murgtools/plotting/conditions_plot.py Outdated
Comment thread murgtools/plotting/conditions_plot.py Outdated
Comment on lines +272 to +274
if len(date_groups) == 1: # Only add colorbar if single group
cbar = plt.colorbar(scatter, ax=ax2)
cbar.set_label(color_var)

Copilot AI Feb 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When using color_var with multiple date groups, no colorbar is created (line 272 condition is False). This means users cannot see what the color values represent. Consider either: (1) adding a single colorbar for all groups combined, (2) documenting this limitation in the docstring, or (3) raising a warning when color_var is used with multiple groups.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets do a single colorbar for all groups combined

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented in commit 70ae4fd. Changed the colorbar logic to create a single colorbar for all groups when color_var is used. The colorbar now uses the first scatter collection and displays outside the loop, showing the color scale for all groups combined.

Comment thread tests/test_conditions_plot.py Outdated
start_date = dt.datetime(2023, 6, 1)
end_date = dt.datetime(2023, 6, 30)

fig, axes = conditions_plot(time_list, start_date, end_date, ofname='test_output.png')

Copilot AI Feb 3, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variable fig is not used.

Suggested change
fig, axes = conditions_plot(time_list, start_date, end_date, ofname='test_output.png')
conditions_plot(time_list, start_date, end_date, ofname='test_output.png')

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

write as _, _ = conditions_plot

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in commit 70ae4fd. Changed to _, _ = conditions_plot(...) pattern to explicitly indicate both return values are intentionally unused.

Comment thread tests/test_conditions_plot.py Outdated
SBFRF and others added 5 commits February 2, 2026 21:04
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Comment thread murgtools/plotting/conditions_plot.py
Comment thread murgtools/plotting/conditions_plot.py Outdated
Comment on lines +272 to +274
if len(date_groups) == 1: # Only add colorbar if single group
cbar = plt.colorbar(scatter, ax=ax2)
cbar.set_label(color_var)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets do a single colorbar for all groups combined

Comment thread tests/test_conditions_plot.py Outdated
start_date = dt.datetime(2023, 6, 1)
end_date = dt.datetime(2023, 6, 30)

fig, axes = conditions_plot(time_list, start_date, end_date, ofname='test_output.png')

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

write as _, _ = conditions_plot

…olorbar

Co-authored-by: SBFRF <8375832+SBFRF@users.noreply.github.com>

Copilot AI commented Feb 3, 2026

Copy link
Copy Markdown
Contributor Author

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • chldata.erdc.dren.mil
    • Triggering command: /usr/bin/python python -m pytest tests/test_conditions_plot.py::TestDateGroupsValidation -v (dns block)
    • Triggering command: /usr/bin/python python -m pytest tests/test_conditions_plot.py::TestDateGroupsValidation::test_date_groups_missing_dates_key -v (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI requested a review from SBFRF February 3, 2026 02:19
this was not meant to be part of this PR or branch

@SBFRF SBFRF left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@SBFRF
SBFRF marked this pull request as ready for review February 3, 2026 03:03
SBFRF and others added 5 commits February 2, 2026 22:07
The tests were failing on Python 3.9 and 3.10 due to a naming collision:
the module `conditions_plot.py` exports a function also named
`conditions_plot`, causing mock.patch to find the function instead of
the module when resolving the patch path.

Fix by using sys.modules to get the actual module object for patching,
and add real test implementations for bin_data tests.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Example script demonstrating conditions_plot with real ASV survey dates
from https://github.com/kkoetje/asv_conditions_plot

Includes examples for:
- Individual platform analysis (Jaiabot, Yellowfin)
- Combined platform comparison with different markers/colors
- Coloring by wave direction
- Full multi-year record analysis

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@SBFRF
SBFRF merged commit fc1e2aa into main Feb 3, 2026
4 checks passed
@SBFRF
SBFRF deleted the copilot/create-conditions-plot branch February 3, 2026 03:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

conditions plot

3 participants