How to Visualize xarray Outputs with Temperature, Wind, and Geopotential Fields in WeatherNext
WeatherNext stores atmospheric forecasts as nested xarray.Dataset structures that you can visualize using standard xarray plotting methods combined with Matplotlib.
The WeatherNext repository from Google DeepMind outputs weather predictions as xarray datasets containing standard meteorological variables. This guide shows you how to extract and plot temperature, wind, and geopotential fields using the repository's built-in utilities and the standard scientific Python stack.
Understanding WeatherNext's xarray Output Structure
WeatherNext packages its model forecasts as xarray.Dataset objects. Each dataset contains atmospheric variables as separate xarray.DataArray objects:
t— Temperature in Kelvinu— Zonal wind component in m/sv— Meridional wind component in m/sz— Geopotential height in m²/s²
The repository provides a specialized wrapper in weathernext/utils/xarray_tree.py that treats every leaf node of a dataset as an independent DataArray while preserving the ability to reconstruct the original Dataset after processing. This utility is essential when working with WeatherNext's potentially non-uniform coordinate structures.
Loading and Extracting WeatherNext Forecast Data
Start by loading your NetCDF output and extracting the three fields you need to visualize.
import xarray as xr
# Load WeatherNext forecast output
ds = xr.open_dataset("forecast_output.nc")
# Extract individual DataArrays
temp = ds["t"] # Temperature
u_wind = ds["u"] # Zonal wind
v_wind = ds["v"] # Meridional wind
geopot = ds["z"] # Geopotential height
WeatherNext follows CF conventions, so coordinate variables (latitude, longitude, pressure level, time) attach automatically to each field.
Visualizing Temperature with xarray pcolormesh
Temperature fields display effectively as filled color maps. The xarray plot.pcolormesh method provides automatic coordinate handling and color bar generation.
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(10, 6))
temp.plot.pcolormesh(
ax=ax,
cmap="coolwarm",
add_colorbar=True,
cbar_kwargs={"label": "Temperature (K)"},
)
ax.set_title("Temperature Field")
ax.set_xlabel("Longitude")
ax.set_ylabel("Latitude")
The coolwarm colormap emphasizes both warm and cold anomalies symmetrically around neutral tones.
Plotting Wind Vectors with quiver
Wind requires combining both components into vector arrows. Subsampling prevents overcrowding in high-resolution WeatherNext outputs.
fig, ax = plt.subplots(figsize=(10, 6))
# Subsample every 5th grid point for clarity
step = 5
u_sub = u_wind[::step, ::step]
v_sub = v_wind[::step, ::step]
# Optional: background shading for context
temp[::step, ::step].plot.pcolormesh(ax=ax, cmap="Greys", alpha=0.3)
ax.quiver(
u_sub["lon"], u_sub["lat"],
u_sub.values, v_sub.values,
scale=700,
width=0.002,
color="k"
)
ax.set_title("Wind Vectors")
ax.set_xlabel("Longitude")
ax.set_ylabel("Latitude")
Adjust the scale parameter to control arrow length. Larger values produce shorter arrows.
Displaying Geopotential Height with contour
Geopotential height fields work best as contour lines, emphasizing pressure-level topology and wave patterns.
fig, ax = plt.subplots(figsize=(10, 6))
geopot.plot.contour(
ax=ax,
colors="black",
linewidths=0.8,
add_colorbar=False,
levels=12,
)
ax.set_title("Geopotential Height")
ax.set_xlabel("Longitude")
ax.set_ylabel("Latitude")
Specify levels to control contour density. Twelve levels typically resolve synoptic-scale features without excessive clutter.
Combining All Three Fields in a Multi-Panel Figure
For comparative analysis, arrange temperature, wind, and geopotential plots side by side using Matplotlib subplots.
import xarray as xr
import matplotlib.pyplot as plt
# Load WeatherNext dataset
ds = xr.open_dataset("forecast_output.nc")
temp = ds["t"]
u_wind, v_wind = ds["u"], ds["v"]
geopot = ds["z"]
# Create figure with three panels
fig, axs = plt.subplots(1, 3, figsize=(18, 5))
# Panel 1: Temperature pcolormesh
temp.plot.pcolormesh(
ax=axs[0],
cmap="coolwarm",
cbar_kwargs={"label": "Temperature (K)"},
)
axs[0].set_title("Temperature")
# Panel 2: Wind quiver with temperature background
step = 5
axs[1].pcolormesh(
temp["lon"][::step], temp["lat"][::step],
temp[::step, ::step],
cmap="Greys", alpha=0.3
)
axs[1].quiver(
u_wind["lon"][::step], u_wind["lat"][::step],
u_wind[::step, ::step], v_wind[::step, ::step],
scale=700, width=0.002, color="k"
)
axs[1].set_title("Wind Vectors")
# Panel 3: Geopotential contours
geopot.plot.contour(
ax=axs[2],
colors="black",
linewidths=0.8,
levels=12,
)
axs[2].set_title("Geopotential Height")
plt.tight_layout()
plt.show()
This layout enables direct visual comparison of thermal structure, flow patterns, and geopotential topography.
Pre-Processing with xarray_tree.map_structure
Before visualization, you may need to apply transformations uniformly across all variables. The xarray_tree.map_structure function in weathernext/utils/xarray_tree.py safely applies functions to every DataArray leaf while preserving dataset structure.
from weathernext.utils import xarray_tree
# Convert temperature from Kelvin to Celsius
def kelvin_to_celsius(arr):
if arr.name == "t":
return arr - 273.15
return arr
processed_ds = xarray_tree.map_structure(kelvin_to_celsius, ds)
If coordinates mismatch across variables—a possibility in WeatherNext outputs—map_structure automatically falls back to a plain dictionary representation rather than failing. This behavior is implemented in lines 54-65 of xarray_tree.py.
Dependencies and Repository Structure
WeatherNext declares Matplotlib as a dependency in [setup.py](https://github.com/google-deepmind/weathernext/blob/main/setup.py), ensuring visualization tools install automatically with the package.
| File | Purpose |
|---|---|
weathernext/utils/xarray_tree.py |
Dataset traversal and transformation utilities |
weathernext/utils/data_modalities.py |
Canonical variable names (t, u, v, z) |
setup.py |
Matplotlib dependency declaration |
The canonical variable naming scheme in data_modalities.py ensures consistency across WeatherNext's data loading, processing, and visualization pipelines.
Summary
- WeatherNext outputs standard xarray.Dataset objects containing temperature, wind components, and geopotential height as separate DataArrays.
- Extract fields by name (
ds["t"],ds["u"],ds["v"],ds["z"]) for individual visualization. - Use xarray's built-in plotting:
pcolormeshfor temperature,quiverfor wind vectors, andcontourfor geopotential height. - Apply
xarray_tree.map_structurefromweathernext/utils/xarray_tree.pyfor uniform pre-processing across all dataset variables. - Subsample wind fields to prevent visual clutter in high-resolution outputs.
Frequently Asked Questions
What coordinate system does WeatherNext use for its xarray outputs?
WeatherNext follows CF (Climate and Forecast) conventions, attaching latitude, longitude, pressure level, and time coordinates to all output variables. These coordinates propagate automatically through xarray selection and plotting operations.
Can I visualize multiple forecast timesteps simultaneously?
Yes. WeatherNext datasets include a time dimension. Use xarray's .isel(time=...) or .sel(time=...) to select specific lead times, or create animation loops iterating over the time coordinate with matplotlib.animation.FuncAnimation.
How do I handle missing or masked values in WeatherNext outputs?
Apply xarray_tree.map_structure with a masking function before visualization. The utility preserves NaN values in xarray's standard representation, which Matplotlib automatically excludes from plots.
Why does my wind quiver plot appear as solid black?
Your grid resolution exceeds the visualization capacity. Apply subsampling with slice notation ([::5, ::5]) or increase the scale parameter in quiver() to shorten arrow lengths.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →