Skip to content

Conversation

@LydiaFrance
Copy link
Contributor

New callback and CLI for visualising raw input variables.

Static Images (a selection)

image

Animation (e.g. temp)

era5__2t

Running

uv run zebra visualisations plot-raw-inputs --config-name <your local config>.yaml 
uv run zebra visualisations animate-raw-inputs --config-name <your local config>.yaml 

Or as part of the evaluate command:

uv run zebra evaluate --checkpoint <your checkpoint>.ckpt --config-name <your local config>.yaml 

If you have options like this in your local yaml file:

evaluate:
  callbacks:
    raw_inputs:
      frequency: null            # Plot a single example by default
      save_dir: ./data/raw_input_plots

      # Enable animations for raw inputs
      make_video_plots: true     # Set to false to disable animations
      video_fps: 2               # Faster playback for quicker review
      video_format: gif          # or "mp4"
      video_save_dir: ./data/raw_input_animations

      plot_spec:
        colourbar_location: vertical

Also improves plotting and metadata handling, and enhances configuration options for evaluation and visualisation.

Copilot's Summary

Visualisation Features

  • Added a new RawInputsCallback for plotting and animating raw input variables during evaluation, with detailed configuration for styling and output. This includes a new YAML config (raw_inputs.yaml), updates to the default callbacks, and CLI integration for visualisation commands. [1] [2] [3] [4] [5] [6] [7] [8]
  • Introduced input_variable_names and variable_names properties to dataset classes for robust variable handling and naming in visualisations. [1] [2]

Plotting and Metadata Improvements

  • Improved PlotSpec and plotting callbacks to support hemisphere and metadata subtitle detection, auto-titling, and enhanced footer metadata control. [1] [2] [3] [4] [5] [6] [7]
  • Added robust error handling for static plot logging and ensured matplotlib backend is set to "Agg" early to avoid interactive backend issues. [1] [2] [3]

Animation and Plotting Infrastructure

  • Added animation_helper.py to manage matplotlib animation lifecycle and prevent garbage collection issues during video saving.

Configuration and Linting

  • Updated .pre-commit-config.yaml to ensure filenames are passed to Ruff linter and formatter for correct operation.

Documentation

  • Extended the README.md with clear instructions for new visualisation features, including plotting and animating raw inputs.

@LydiaFrance LydiaFrance linked an issue Nov 22, 2025 that may be closed by this pull request
1 task
@LydiaFrance LydiaFrance requested a review from IFenton November 22, 2025 16:26
@IFenton
Copy link
Contributor

IFenton commented Nov 24, 2025

Reviewing this

@IFenton
Copy link
Contributor

IFenton commented Nov 24, 2025

I'm currently getting an error when I try to run this - the environment won't load:

File "/Users/ifenton/Documents/Projects/SeaIce/ice-station-zebra/.venv/bin/zebra", line 4, in <module>
    from ice_station_zebra.cli import app
  File "/Users/ifenton/Documents/Projects/SeaIce/ice-station-zebra/ice_station_zebra/cli/__init__.py", line 2, in <module>
    from .main import app
  File "/Users/ifenton/Documents/Projects/SeaIce/ice-station-zebra/ice_station_zebra/cli/main.py", line 6, in <module>
    from ice_station_zebra.training import training_cli
  File "/Users/ifenton/Documents/Projects/SeaIce/ice-station-zebra/ice_station_zebra/training/__init__.py", line 1, in <module>
    from .cli import training_cli
  File "/Users/ifenton/Documents/Projects/SeaIce/ice-station-zebra/ice_station_zebra/training/cli.py", line 8, in <module>
    from .trainer import ZebraTrainer
  File "/Users/ifenton/Documents/Projects/SeaIce/ice-station-zebra/ice_station_zebra/training/trainer.py", line 10, in <module>
    from ice_station_zebra.callbacks import UnconditionalCheckpoint
  File "/Users/ifenton/Documents/Projects/SeaIce/ice-station-zebra/ice_station_zebra/callbacks/__init__.py", line 3, in <module>
    from .plotting_callback import PlottingCallback
  File "/Users/ifenton/Documents/Projects/SeaIce/ice-station-zebra/ice_station_zebra/callbacks/plotting_callback.py", line 25, in <module>
    from ice_station_zebra.visualisations import (
  File "/Users/ifenton/Documents/Projects/SeaIce/ice-station-zebra/ice_station_zebra/visualisations/__init__.py", line 9, in <module>
    from .cli import visualisations_cli
  File "/Users/ifenton/Documents/Projects/SeaIce/ice-station-zebra/ice_station_zebra/visualisations/cli.py", line 12, in <module>
    from ice_station_zebra.callbacks.raw_inputs_callback import RawInputsCallback
  File "/Users/ifenton/Documents/Projects/SeaIce/ice-station-zebra/ice_station_zebra/callbacks/raw_inputs_callback.py", line 24, in <module>
    from ice_station_zebra.visualisations import DEFAULT_SIC_SPEC, detect_land_mask_path
ImportError: cannot import name 'DEFAULT_SIC_SPEC' from partially initialized module 'ice_station_zebra.visualisations' (most likely due to a circular import) (/Users/ifenton/Documents/Projects/SeaIce/ice-station-zebra/ice_station_zebra/visualisations/__init__.py)

It looks like it relates to the fact that DEFAULT_SIC_SPEC and detect_land_mask_path are imported in both raw_inputs_callback.py and visualisations/__init__.py.

Do you get the same error @LydiaFrance?

@github-actions
Copy link

github-actions bot commented Nov 27, 2025

Coverage report

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  ice_station_zebra/callbacks
  __init__.py
  plotting_callback.py 213-216
  raw_inputs_callback.py 83-179, 183, 190-241, 253-330, 348-387, 399-453, 470-482, 490-506, 510-588
  ice_station_zebra/cli
  main.py
  ice_station_zebra/data_loaders
  combined_dataset.py 117-119, 132
  zebra_dataset.py 105-109
  ice_station_zebra/evaluation
  evaluator.py
  ice_station_zebra/visualisations
  __init__.py
  animation_helper.py
  cli.py 40-50, 67-101, 139-204, 265-346, 355
  convert.py 49-55, 96-98, 102-103
  layout.py 221-222, 263-267, 307-308, 436, 787-788, 790, 849-852, 862-865, 924-932, 1027, 1031, 1051
  plotting_core.py 72, 78-80, 100, 117, 140, 149-150, 160-162, 174, 182-193, 330-331, 350, 569, 605, 610, 617, 641, 654, 695
  plotting_maps.py 83, 85, 88-89, 137, 157, 164, 168-170, 252-254, 325, 389-391, 399-400, 541-556, 666-667, 690-698
  plotting_raw_inputs.py 113-124, 132, 220-221, 293, 380-381, 469-473, 504-508
Project Total  

This report was generated by python-coverage-comment-action

@LydiaFrance
Copy link
Contributor Author

Okay, conflicts with main now resolved and tests are now passing on Github actions. Good to go for checking on Baskerville @IFenton 🎉 🎈

@IFenton
Copy link
Contributor

IFenton commented Nov 27, 2025

Excellent. I'll test it out. In the meantime, my initial comments were:

  • Would be good to use base path as the root folder
  • Era5: q_10 seems to have a colour scale of 0-0 (although the values change - presumably a resolution error)

@IFenton
Copy link
Contributor

IFenton commented Nov 27, 2025

Seems to be running fine for me locally, though I still need to test it on Baskerville (I'll do that tomorrow).

It does occur to me thought that currently it will overwrite plots with the same name. Do we want to add a date stamp to the name? Or save them to a particular folder for that run?

@LydiaFrance
Copy link
Contributor Author

LydiaFrance commented Nov 27, 2025

Seems to be running fine for me locally, though I still need to test it on Baskerville (I'll do that tomorrow).

Yay!

It does occur to me thought that currently it will overwrite plots with the same name. Do we want to add a date stamp to the name? Or save them to a particular folder for that run?

I think if you're plotting related to a run, you should use the wandb workflow as part of evaluate and plot it that way. You can find them inside media>images>raw_plots or media>videos>raw_plots with unique identifiers. The local saving should really just be for "I want some pretty pictures for my presentation and just want it locally right now without trying to evaluate the model".

@IFenton
Copy link
Contributor

IFenton commented Nov 27, 2025

I think if you're plotting related to a run, you should use the wandb workflow as part of evaluate and plot it that way. You can find them inside media>images>raw_plots or media>videos>raw_plots with unique identifiers. The local saving should really just be for "I want some pretty pictures for my presentation and just want it locally right now without trying to evaluate the model".

I hadn't noticed it also saved in the wandb run. I wonder if you should set the save_dir to null then in the config as it seems unnecessary to save to two places at once. Though in that case, I guess you'd need to set the save_dir if you are running the code outside the evaluate function? I'll have a think about it

@LydiaFrance
Copy link
Contributor Author

I think if you're plotting related to a run, you should use the wandb workflow as part of evaluate and plot it that way. You can find them inside media>images>raw_plots or media>videos>raw_plots with unique identifiers. The local saving should really just be for "I want some pretty pictures for my presentation and just want it locally right now without trying to evaluate the model".

I hadn't noticed it also saved in the wandb run. I wonder if you should set the save_dir to null then in the config as it seems unnecessary to save to two places at once. Though in that case, I guess you'd need to set the save_dir if you are running the code outside the evaluate function? I'll have a think about it

Yes, that's up to the user about where they want their files/if it is saved locally.

@LydiaFrance
Copy link
Contributor Author

LydiaFrance commented Nov 27, 2025

  • Would be good to use base path as the root folder

  • Era5: q_10 seems to have a colour scale of 0-0 (although the values change - presumably a resolution error)

Thanks for spotting these @IFenton, I have fixed both now. You can have scientific notation on your colour bars now if you like, I personally don't like that so I have also provided suitable decimal places for the q_ humidity plots (commented out). Check out ice_station_zebra/config/evaluate/callbacks/raw_inputs.yaml

Copy link
Contributor

@IFenton IFenton left a comment

Choose a reason for hiding this comment

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

I've tested this both locally and on Baskerville and it works fine.

However, not all the config options work as I expected (I don't know if that is because I misinterpreted them, or because they aren't working properly). I've added notes to the yaml with my queries.

Plot raw input variables from the test dataset:

```bash
uv run zebra visualisations plot-raw-inputs --config-name <your local config>.yaml --sample-idx 0
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe explain what the sample-idx argument is doing? Is it the same as the timestep_index?

raw_inputs:
# Callback to plot raw input variables (ERA5 data, etc.)
_target_: ice_station_zebra.callbacks.RawInputsCallback
frequency: null # Plot once; set N to repeat every N batches
Copy link
Contributor

Choose a reason for hiding this comment

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

When running through evaluate, the files are to be overwritten, so you end up with only the final batch in the folder / on wandb. It doesn't seem to do anything when I run it with the visualisation command

# Callback to plot raw input variables (ERA5 data, etc.)
_target_: ice_station_zebra.callbacks.RawInputsCallback
frequency: null # Plot once; set N to repeat every N batches
timestep_index: 0 # Which history timestep to plot (0 = most recent)
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems to be working as I would expect with evaluate, but the plotting date in the title isn't changing, so it's a bit hard to be certain. It doesn't seem to do anything when run through visualisation

video_fps: 2 # Frames per second for animations
video_format: gif # mp4 or gif
video_save_dir: ./raw_input_animations # Directory to save animations (null to skip disk save)
max_animation_frames: null # Limit frames (null = unlimited; 30 ≈ 1 month daily data)
Copy link
Contributor

Choose a reason for hiding this comment

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

This works as expected, by for some reason, if I create the videos using visualisation it seems to default to 27 days, whereas using evaluate it defaults to 14 days

# Plot specification (colourmap, hemisphere, etc.)
plot_spec:
_target_: ice_station_zebra.types.PlotSpec
variable: "raw_inputs"
Copy link
Contributor

Choose a reason for hiding this comment

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

I couldn't work out how to use this (maybe because I had the wrong format of the variable name)? Or is it just that this is in contrast to predictions? Maybe add a comment explaining

plot_spec:
_target_: ice_station_zebra.types.PlotSpec
variable: "raw_inputs"
colourmap: "viridis"
Copy link
Contributor

Choose a reason for hiding this comment

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

Changing this didn't seem to do anything, maybe because all the colour maps are already specified below?

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.

Add raw data plots

3 participants