HydroPlot: rating workshop, dynamic metrics, climate/SPI fixes, mobile UX#2
HydroPlot: rating workshop, dynamic metrics, climate/SPI fixes, mobile UX#2abstractionisms wants to merge 65 commits into
Conversation
…sh, and reduced-motion support - Extended custom CSS with @Keyframes (fadeInUp, cardPop, subtlePulse) and enhanced transitions on .workspace-panel, .action-card, .plot-card, .insight-card, buttons, nav, etc. - Added prefers-reduced-motion guard and stronger interactive feedback. - Lightly wrapped Reach Analysis summary + Baseflow sections and Overview regional conditions using existing render_workspace_panel for consistent motion. - Added apply_hydro_theme() helper (wired into baseflow waterfall) for cohesive Plotly styling. - Extended visual shell test with motion assertions. - References modern animated web UI patterns from https://x.com/twetsfyp/status/2065283731833651709 This elevates the visual frontend while preserving all existing behavior, reach logic, and responsive design. Builds on prior visual UX upgrade and map-centered reach redesign.
…ronger lifts/scales, pulsing primary CTA button (the 'Run Analysis' button now has a repeating subtle teal glow so it's obvious the new animations are active)
…nger scale for more obvious premium motion
Refine Streamlit CSS injection and design system. Prefer Meteostat for SPI precip, skip Daymet without Earthdata credentials, extend SPI climate window, and improve per-site readiness messaging.
Stop forcing a flat log scale. Use linear when discharge spans a moderate range, and clamp log range to the data envelope when multi-order behavior is real.
For sites like 14018500, simple Q=A*H^B fails (negative R2). Prefer Q=A*(H-H0)^B when better, and color stage-discharge points by season.
Nearest Meteostat stations can be historical-only (e.g. Walla Walla ends 1988), leaving sites like 14018500 with no climate. Prefer Open-Meteo archive, then multi-station Meteostat with coverage filtering.
Add plain-language narrative for interactive charts and Guided Plot Builder output: flow duration, seasons, climate, rating curve, with markdown download.
Add Q10/Q50/Q90 metrics with tooltips, expander explaining why each metric matters, and a Metric relevance section in the automated post-plot narrative.
Tooltips, expander table, and post-plot narrative now use compute_hydrologic_profile (regime, Q10/Q50/Q90, seasons, rating, climate) instead of static catalog blurbs. Falls back to catalog when no discharge.
Live Plotly rating curve with A/B/H0 sliders, auto-fit reference, season/year point coloring, residual pane, and live R2/RMSE/NSE/bias. Adds evaluate_rating_params helper and Pi Streamlit restart script.
HTML insight/readiness tiles show i-popups on hover. Q10/Q50/Q90 and mean/peak sit with the flow-duration section instead of the page top; record length stays in the header strip.
Stack Streamlit columns under 768px, open tile tips below cards on narrow screens, support tap/focus for help popups on touch devices, and keep Plotly charts usable on phones.
main added Open-Meteo and dynamic climate metadata; this branch already had Open-Meteo-first + multi-station Meteostat + richer cached results. Keep branch climate implementation; record merge with main.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 253300d807
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| b1, b2 = st.columns(2) | ||
| with b1: | ||
| if st.button("↩ Auto-fit", key=f"{state_key}_reset", use_container_width=True): |
There was a problem hiding this comment.
Replace the stale button width argument
This new button is the only remaining use_container_width use under hydrology, while the commit adds tests/test_streamlit_cloud_compat.py asserting that no hydrology file contains that argument. Any CI run including that test fails even though the app otherwise standardizes on width="stretch"; use the supported width argument here as well.
Useful? React with 👍 / 👎.
| site_ids = config.get("site_ids", []) | ||
| if not site_ids: | ||
| return None | ||
| df = fetch_discharge_data(str(site_ids[0]), config.get("start_date"), config.get("end_date")) |
There was a problem hiding this comment.
Handle reach-case site mappings in the case runner
The new docs/cases/spokane_reach_gain_loss/case.yml defines site_ids as a mapping with upstream and downstream, but this loader unconditionally indexes site_ids[0]. Running the advertised case study with python scripts/run_case_study.py docs/cases/spokane_reach_gain_loss/case.yml therefore raises KeyError: 0 before producing any summary; branch on dict-shaped reach configs or validate them explicitly.
Useful? React with 👍 / 👎.
| if usable < 30: | ||
| return None |
There was a problem hiding this comment.
Allow complete short Meteostat windows
This absolute usable < 30 cutoff rejects valid short Meteostat requests: a complete 7- or 14-day climate window has fewer than 30 daily values, so fetch_climate_data() returns None despite full coverage. That regresses short analysis periods, especially whenever Open-Meteo is unavailable and the app/public API falls back to Meteostat; compare against the requested window length or a coverage ratio instead.
Useful? React with 👍 / 👎.
Summary
Ships a large HydroPlot dashboard upgrade: more reliable climate/SPI, better rating curves, automated plot narrative, site-specific metric relevance, an interactive stage–discharge workshop, and mobile-friendly tile help / layout.
Highlights
Test plan
mainif CI reports themNotes
Deployed/smoked on Pi (
:8501) during development; branch tip253300d.