Skip to content

Regridding

create_pyramid only coarsens. It needs a uniform 1-D grid, and it keeps that grid. To change the resolution or extent, or to start from a non-uniform grid, regrid first. This example uses xarray-regrid to put one day of air_temperature on a 0.5° grid, then builds the pyramid.

import xarray as xr
import xarray_regrid  # noqa: F401
import xproj  # noqa: F401
from xarray_regrid import Grid

ds = xr.tutorial.open_dataset("air_temperature").drop_encoding().sel(time="2013-01-01")

target = Grid(
    north=75, south=15, west=200, east=330, resolution_lat=0.5, resolution_lon=0.5
).create_regridding_dataset(lat_name="lat", lon_name="lon")
fine = ds.regrid.linear(target).proj.assign_crs(spatial_ref="EPSG:4326")
print(dict(fine.sizes))
{'time': 4, 'lat': 121, 'lon': 261}
from topozarr import create_pyramid

create_pyramid(fine, levels=3, x_dim="lon", y_dim="lat").write("regrid.zarr")
dt = xr.open_datatree("regrid.zarr", engine="zarr", consolidated=False)
print({level: dict(dt[level].sizes) for level in sorted(dt.children)})
{'0': {'time': 4, 'lat': 121, 'lon': 261}, '1': {'time': 4, 'lat': 60, 'lon': 130}, '2': {'time': 4, 'lat': 30, 'lon': 65}}
import matplotlib.pyplot as plt


def plot(mode):
    levels = ["0", str(len(dt.children) - 1)]  # finest and coarsest
    fig, axes = plt.subplots(1, 2, figsize=(10, 3.5), layout="constrained")
    for ax, level in zip(axes, levels):
        im = dt[level].air.isel(time=0).plot(
            ax=ax, vmin=230, vmax=305, cmap=f"warm_{mode}", add_colorbar=False
        )
        ax.set_title(f"level {level}")
    fig.colorbar(im, ax=axes, label="air temperature [K]")
    return fig


show(plot)