Skip to content

Add visualize sos CLI command and heatmap --vmin/--vmax#228

Open
Hackshaven wants to merge 4 commits into
mirror/stagingfrom
claude/github-issue-access-w3t2pd
Open

Add visualize sos CLI command and heatmap --vmin/--vmax#228
Hackshaven wants to merge 4 commits into
mirror/stagingfrom
claude/github-issue-access-w3t2pd

Conversation

@Hackshaven

Copy link
Copy Markdown
Member

Summary

Wires the existing PlotManager Science On a Sphere (SOS) renderer to the CLI and adds fixed color scaling — closing the gap the issue identified between "frames render" and "production-quality SOS animation." The library already did full-globe / PlateCarree / 2:1 / edge-to-edge rendering via PlotManager; it just wasn't reachable from the CLI or zyra run YAML.

Addresses NOAA-GSL/zyra#284.

Changes

New command

  • zyra visualize sos (alias render sos), backed by PlotManager (src/zyra/visualization/cli_sos.py). Renders gridded data as SOS frames (full-globe, PlateCarree, 2:1, edge-to-edge). Supports single (--input/--output) and batch (--inputs/--output-dir) modes with a fixed --vmin/--vmax color range for flicker-free sequences. Defaults to 4096×2048; NaN/inf masked transparent.

    zyra visualize sos --inputs ./nc/*.nc --output-dir ./frames \
      --var <VAR> --cmap YlOrBr --width 4096 --height 2048 --vmin 0 --vmax 50
    

Heatmap (the "additionally" option in the issue)

  • Added --vmin/--vmax to visualize heatmap so frame sequences share a fixed color scale instead of self-scaling per frame.

Supporting changes

  • Shared load_data_array helper (.nc/.nc4/.npy) in cli_utils.py, validating --var before the heavy xarray import.
  • PlotManager.sos_plot_data now returns the saved output path.
  • pipeline_runner expands list/tuple arg values into multi-token flags so nargs options (inputs, extent) work from zyra run YAML/JSON.
  • Registered sos in both the CLI (cli_register.py) and API manifest (__init__.py) registration paths; regenerated both wizard capability manifests (only the new sos entries and heatmap --vmin/--vmax differ).

Tests & samples

  • tests/visualization/test_sos.py: single + batch render, 2:1 edge-to-edge assertion, and identical color scaling across frames. Render tests are gated behind DATAVIZHUB_RUN_CARTOPY_TESTS=1 (repo convention); lightweight CLI/helper tests always run.
  • Pipeline-runner list-expansion test in tests/misc/test_pipeline_runner.py.
  • Sample pipeline samples/pipelines/sos_fv3chem_frames.yaml (FV3-Chem SOS frames → MP4), dry-run verified.

Notes

  • OpenAPI snapshot not regenerated: the update script is gated on changes to api/{routers,server,models,schemas}, none of which were touched. The CLI command list is a runtime discovery endpoint, not baked into the OpenAPI schema, so the hash is unaffected.
  • Pre-existing (not introduced here): test_cli_heatmap_smoke invokes python -m zyra.visualization.cli heatmap without the visualize prefix the compat wrapper now requires. It fails on the untouched baseline and is normally skipped in CI — left as-is, out of scope.

🤖 Generated with Claude Code


Generated by Claude Code

Wire the existing PlotManager Science On a Sphere renderer to the CLI so
gridded data can be rendered as SOS frames (full-globe, PlateCarree, 2:1,
edge-to-edge) directly from `zyra visualize sos` and from `zyra run` YAML.

- Add `zyra visualize sos` (alias `render sos`) backed by PlotManager, with
  single (--input/--output) and batch (--inputs/--output-dir) modes and a
  fixed --vmin/--vmax color range for flicker-free frame sequences.
- Add --vmin/--vmax to `visualize heatmap` so frame sequences can share a
  fixed color scale instead of self-scaling per frame.
- Add a shared `load_data_array` helper (.nc/.nc4/.npy) in cli_utils.
- PlotManager.sos_plot_data now returns the saved output path.
- pipeline_runner: expand list/tuple arg values to multi-token flags so
  nargs options (e.g. inputs, extent) work from YAML/JSON pipelines.
- Register sos in both the CLI and API manifest registration paths and
  regenerate the wizard capabilities manifests.
- Add tests (single + batch render, 2:1 edge-to-edge, consistent color
  scaling across frames) and a sample FV3-Chem SOS pipeline.

Signed-off-by: Claude <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

🔁 Relay created/updated upstream PR: NOAA-GSL/zyra#287

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

Adds a new visualization entry point for Science On a Sphere (SOS) frame rendering and introduces fixed color scaling (--vmin/--vmax) to avoid per-frame autoscaling “flicker” in sequences. It also improves zyra run pipeline argument handling to support argparse nargs options from YAML/JSON.

Changes:

  • Added zyra visualize sos (and render sos alias) wired to PlotManager, supporting single and batch frame rendering with optional fixed --vmin/--vmax.
  • Added --vmin/--vmax to visualize heatmap CLI plumbing.
  • Updated pipeline runner argv building to expand list/tuple args into multi-token flags; updated wizard capability manifests and added tests/samples.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/zyra/visualization/cli_sos.py New SOS CLI handler + parser registration.
src/zyra/visualization/cli_utils.py Adds load_data_array helper for .nc/.nc4/.npy inputs.
src/zyra/visualization/plot_manager.py sos_plot_data now returns the saved output path (or None).
src/zyra/visualization/cli_register.py Registers sos subcommand; adds --vmin/--vmax to heatmap parser.
src/zyra/visualization/__init__.py Mirrors CLI registration changes for the alternate registration path.
src/zyra/visualization/cli_heatmap.py Passes through vmin/vmax to HeatmapManager.render.
src/zyra/pipeline_runner.py Expands list/tuple stage args into multi-token argv entries.
tests/visualization/test_sos.py New SOS CLI + helper tests; includes Cartopy-gated render assertions.
tests/visualization/test_cli_commands.py Includes visualize sos --help in subcommand help smoke test.
tests/misc/test_pipeline_runner.py Adds regression test for list expansion in _build_argv_for_stage.
src/zyra/wizard/zyra_capabilities/visualize.json Updates wizard capabilities for SOS + heatmap --vmin/--vmax.
src/zyra/wizard/zyra_capabilities.json Updates aggregated wizard capabilities for SOS + heatmap --vmin/--vmax.
samples/pipelines/sos_fv3chem_frames.yaml Adds sample pipeline rendering SOS frames and composing them into MP4.

Comment on lines +268 to +273
elif isinstance(v, (list, tuple)):
# Expand to a multi-valued flag (argparse nargs), e.g.
# ``inputs: [a, b]`` -> ``--inputs a b`` and
# ``extent: [-180, 180, -90, 90]`` -> ``--extent -180 180 -90 90``.
argv.append(to_flag(k))
argv.extend(str(item) for item in v)
Comment on lines +93 to +104
outputs: list[str] = []
for src in ns.inputs:
dest = outdir_p / f"{Path(str(src)).stem}.png"
out = _render_one(ns, src, str(dest))
if out:
logging.info(out)
outputs.append(out)
try:
print(json.dumps({"outputs": outputs}))
except Exception:
pass
return 0
Comment on lines +111 to +114
out = _render_one(ns, ns.input, ns.output)
if out:
logging.info(out)
return 0
Comment thread tests/visualization/test_sos.py Outdated
Comment on lines +175 to +199
frame_a = np.full((32, 64), 25.0)
frame_b = np.full((32, 64), 25.0)

out_a = tmp_path / "a.png"
out_b = tmp_path / "b.png"

for arr, out in ((frame_a, out_a), (frame_b, out_b)):
pm = PlotManager(image_extent=[-180, 180, -90, 90])
pm.sos_plot_data(
arr,
custom_cmap="YlOrBr",
output_path=str(out),
width=256,
height=128,
vmin=0.0,
vmax=50.0,
)

from PIL import Image

a = np.asarray(Image.open(out_a).convert("RGB"))
b = np.asarray(Image.open(out_b).convert("RGB"))
assert a.shape == b.shape
# Identical inputs + identical fixed scale -> pixel-identical output.
assert np.array_equal(a, b)
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 22, 2026

Copy link
Copy Markdown

Deploying zyra with  Cloudflare Pages  Cloudflare Pages

Latest commit: 34da338
Status: ✅  Deploy successful!
Preview URL: https://b0ca9474.zyra.pages.dev
Branch Preview URL: https://claude-github-issue-access-w.zyra.pages.dev

View logs

@github-actions

Copy link
Copy Markdown

🔁 Relay created/updated upstream PR: NOAA-GSL/zyra#287

@Hackshaven Hackshaven force-pushed the claude/github-issue-access-w3t2pd branch from a7a29f5 to 53fc45b Compare June 22, 2026 01:06
@github-actions

Copy link
Copy Markdown

🔁 Relay created/updated upstream PR: NOAA-GSL/zyra#287

…e test

- cli_sos: exit non-zero when a frame fails to render (single and batch
  modes) instead of silently returning 0, so `zyra run` pipelines see
  failures.
- test_sos: rewrite the fixed-scale test to use two frames with different
  ranges sharing a mid-value, comparing the center pixel block; add a
  "teeth" assertion that self-scaling differs. Add failure-exit regression
  tests.

Signed-off-by: Eric Hackathorn <62408375+Hackshaven@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown

🔁 Relay created/updated upstream PR: NOAA-GSL/zyra#287

Skip empty list/tuple stage args rather than emitting a bare `--flag`,
which is a hard parse error for argparse nargs='+' options.

Signed-off-by: Eric Hackathorn <62408375+Hackshaven@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown

🔁 Relay created/updated upstream PR: NOAA-GSL/zyra#287

Signed-off-by: Eric Hackathorn <62408375+Hackshaven@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown

🔁 Relay created/updated upstream PR: NOAA-GSL/zyra#287

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.

3 participants