A minimal TethysDash plugin that renders a 15-day ensemble streamflow forecast from the public GEOGloWS REST API as a Plotly figure. Designed as a workshop example showing how to build a tethysdash plugin from a Jupyter-notebook hydrology workflow without pulling in the full geoglows / geopandas / statsmodels stack.
For a given GEOGloWS 9-digit river_id, the plugin renders:
- High-resolution deterministic forecast (orange line)
- Ensemble median and mean (blue lines)
- 25-75th percentile band (blue shaded area)
- Min-max envelope (light blue shaded area)
Data source: https://geoglows.ecmwf.int/api/v2/forecaststats/<river_id>/?format=json.
| Argument | Type | Description |
|---|---|---|
river_id |
text | The 9-digit GEOGloWS river identifier (e.g. 610217883). |
In a fresh venv:
python3 -m venv .venv
source .venv/bin/activate
pip install -e .This registers the plugin under intake.drivers as
geoglows_forecast_viewer.
import intake
src = intake.open_geoglows_forecast_viewer(river_id="610217883")
figure = src.read()
print("traces:", len(figure["data"]))
print("title :", figure["layout"]["title"])Expected output:
traces: 7
title : GEOGloWS Forecast - River 610217883
TethysDash uses Intake's intake.source.registry. After pip install,
the entry-point declared in pyproject.toml makes the plugin discoverable:
[project.entry-points."intake.drivers"]
geoglows_forecast_viewer = "geoglows_summit_example.forecast_viewer:GeoglowsForecastViewer"The plugin subclasses intake.source.base.DataSource and exposes the
visualization_* class attributes that tethysdash reads to populate its UI
(matches the convention used by the bundled RFC streamflow plugin in
plugins/RFC_plugins/rfc_plugins/river/river_streamflow.py). The read()
method returns the figure dict tethysdash hands to its Plotly renderer:
{"data": [...plotly traces...], "layout": {...plotly layout...}}This plugin is a tightly-scoped slice of the workflow in
lib/tethys-agents/examples/initial_conditions_adjustment_q.py - specifically
the fetch_geoglows_data → plot_forecast_with_context path, without the
bias-correction, AR(1) initialization adjustment, or observed-discharge
fetching. Adding those is an exercise: each new statistic becomes another
trace on the same figure, or a sibling plugin in the same package.