Skip to content

Commit 7306694

Browse files
committed
Plot wind speed
I'm assuming the default colormap is in knots
1 parent ef00ccc commit 7306694

File tree

3 files changed

+30
-18
lines changed

3 files changed

+30
-18
lines changed

src/plotting/colormap_defaults.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ def _fallback():
1515
"sp": {"cmap": plt.get_cmap("coolwarm", 11), "vmin": 800 * 100, "vmax": 1100 * 100},
1616
"2d": load_ncl_colormap("t2m_29lev.ct"),
1717
"2t": load_ncl_colormap("t2m_29lev.ct") | {"units": "degC"},
18-
"10v": load_ncl_colormap("uv_17lev.ct") | {"units": "m/s"},
19-
"10u": load_ncl_colormap("uv_17lev.ct") | {"units": "m/s"},
20-
"uv": load_ncl_colormap("uv_17lev.ct"),
18+
"10v": load_ncl_colormap("uv_17lev.ct") | {"units": "kt"},
19+
"10u": load_ncl_colormap("uv_17lev.ct") | {"units": "kt"},
20+
"10sp": load_ncl_colormap("uv_17lev.ct") | {"units": "kt"},
2121
"10si": {"cmap": plt.get_cmap("GnBu", 11), "vmin": 0, "vmax": 25},
2222
"t_850": {"cmap": plt.get_cmap("inferno", 11), "vmin": 220, "vmax": 310},
2323
"z_850": {"cmap": plt.get_cmap("coolwarm", 11), "vmin": 8000, "vmax": 17000},

workflow/Snakefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ rule showcase_all:
5252
/ "showcases/{run_id}/{init_time}/{init_time}_{param}_{projection}_{region}.gif",
5353
init_time=[t.strftime("%Y%m%d%H%M") for t in REFTIMES],
5454
run_id=collect_all_runs(),
55-
param="2t",
55+
param=["2t", "10sp"],
5656
projection="orthographic",
5757
region=["none", "switzerland"],
5858
),

workflow/scripts/plot_forecast_frame.mo.py

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,13 @@ def _(ArgumentParser, Path):
8080
def _(grib_dir, init_time, lead_time, load_state_from_grib, param):
8181
# load grib file
8282
grib_file = grib_dir / f"{init_time}_{lead_time}.grib"
83-
state = load_state_from_grib(grib_file, paramlist=[param])
83+
if param == "10sp":
84+
paramlist = ["10u", "10v"]
85+
elif param == "sp":
86+
paramlist = ["u", "v"]
87+
else:
88+
paramlist = [param]
89+
state = load_state_from_grib(grib_file, paramlist=paramlist)
8490
return (state,)
8591

8692

@@ -120,17 +126,27 @@ def _k_to_c(arr):
120126
except Exception:
121127
return arr - 273.15
122128

129+
def _ms_to_knots(arr):
130+
# robust conversion with pint, fallback if dtype unsupported
131+
try:
132+
return (_ureg.Quantity(arr, _ureg.meter / _ureg.second).to(_ureg.knot)).magnitude
133+
except Exception:
134+
return arr * 1.943844
135+
123136
except Exception:
124-
LOG.warning("pint not available; falling back to K->C by subtracting 273.15")
137+
LOG.warning("pint not available; falling back hardcoded conversions")
125138

126139
def _k_to_c(arr):
127140
return arr - 273.15
128141

142+
def _ms_to_knots(arr):
143+
return arr * 1.943844
144+
129145
def preprocess_field(param: str, state: dict):
130146
"""
131147
- Temperatures (2t, 2d, t, d): K -> °C
132-
- Wind speed at 10m (10sp): sqrt(10u^2 + 10v^2)
133-
- Wind speed (sp): sqrt(u^2 + v^2)
148+
- Wind speed at 10m (10sp): m/s -> kn, sqrt(10u^2 + 10v^2)
149+
- Wind speed (sp): m/s -> kn, sqrt(u^2 + v^2)
134150
Returns: (field_array, units_override or None)
135151
"""
136152
fields = state["fields"]
@@ -139,18 +155,14 @@ def preprocess_field(param: str, state: dict):
139155
return _k_to_c(fields[param]), "°C"
140156
# 10m wind speed (allow legacy 'uv' alias)
141157
if param == "10sp":
142-
u = fields.get("10u")
143-
v = fields.get("10v")
144-
if u is None or v is None:
145-
raise KeyError("Required components 10u/10v not in state['fields']")
146-
return np.sqrt(u**2 + v**2), "m s$^{-1}$"
158+
u = _ms_to_knots(fields["10u"])
159+
v = _ms_to_knots(fields["10v"])
160+
return np.sqrt(u**2 + v**2), "kn"
147161
# wind speed from standard-level components
148162
if param == "sp":
149-
u = fields.get("u")
150-
v = fields.get("v")
151-
if u is None or v is None:
152-
raise KeyError("Required components u/v not in state['fields']")
153-
return np.sqrt(u**2 + v**2), "m s$^{-1}$"
163+
u = _ms_to_knots(fields["u"])
164+
v = _ms_to_knots(fields["v"])
165+
return np.sqrt(u**2 + v**2), "kn"
154166
# default: passthrough
155167
return fields[param], None
156168
return (preprocess_field,)

0 commit comments

Comments
 (0)