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))
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)