Subsetting#

When working with large unstructured grids, it’s often more efficient to focus on a smaller, region-specific subset rather than the entire global grid. UXarray offers a suite of grid-aware subsetting operations to help you isolate exactly the area you need for your analysis.

  1. Nearest Neighbor

  2. Bounding Box

  3. Bounding Circle

  4. Constant Latitude/Longitude

  5. Interval Latitude/Longitude

import warnings

import cartopy.crs as ccrs
import geocat.datafiles as geodf
import geoviews.feature as gf
import holoviews as hv

import uxarray as ux

plot_opts = {"width": 700, "height": 350}
hv.extension("bokeh")
warnings.filterwarnings("ignore")
/home/docs/checkouts/readthedocs.org/user_builds/uxarray/conda/latest/lib/python3.14/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
  from .autonotebook import tqdm as notebook_tqdm

Data#

In this example, we will be using the geocat-datafiles package to obtain our grid and data files. The dataset used in this example is a 30km global MPAS meshes. We will be investigating the relative humidity vertically interpolated to 200hPa (relhum200hPa) data variable.

datafiles = (
    geodf.get(
        "netcdf_files/MPAS/FalkoJudt/dyamond_1/30km/diag.2016-08-20_00.00.00_subset.nc"
    ),
    geodf.get("netcdf_files/MPAS/FalkoJudt/dyamond_1/30km/x1.655362.grid_subset.nc"),
)
uxds = ux.open_dataset(datafiles[1], datafiles[0])
clim = (uxds["relhum_200hPa"][0].values.min(), uxds["relhum_200hPa"][0].values.max())
features = gf.coastline(
    projection=ccrs.PlateCarree(), line_width=1, scale="50m"
) * gf.states(projection=ccrs.PlateCarree(), line_width=1, scale="50m")

Global Grid#

Many unstructured grids, such as those from global climate models, span the entire surface of a sphere. UXarray supports working with these global grids, handling cases that arise with the spherical geometry of the earth (wrap around at the antimeridian, pole points, etc.)

uxds["relhum_200hPa"][0].plot(
    rasterize=True, periodic_elements="exclude", title="Global Grid", **plot_opts
) * features

In addition to plotting global grids, we can perform analysis operations on the entire grid.

uxds["relhum_200hPa"][0].values.mean()
np.float32(46.81902)

Regional Subsets#

UXarray supports taking subsets of a grid, which allows us to select a region and perform analysis directly on that area, as opposed to the global grid.

There are currently three supported subsetting methods, both for the Grid and UxDataArray data structures.

uxds["relhum_200hPa"].subset
<uxarray.UxDataArray.subset>
Supported Methods:
  * nearest_neighbor(center_coord, k, element)
  * bounding_circle(center_coord, r, element)
  * bounding_box(lon_bounds, lat_bounds)
  * constant_latitude(lat, lon_range)
  * constant_longitude(lon, lat_range)
  * constant_latitude_interval(lats)
  * constant_longitude_interval(lons)
uxds["relhum_200hPa"].uxgrid.subset
<uxarray.Grid.subset>
Supported Methods:
  * nearest_neighbor(center_coord, k, element)
  * bounding_circle(center_coord, r, element)
  * bounding_box(lon_bounds, lat_bounds)
  * constant_latitude(lat, lon_range)
  * constant_longitude(lon, lat_range)
  * constant_latitude_interval(lats)
  * constant_longitude_interval(lons)

Bounding Box#

We can declare a bounding box centered about the Chicago area by specifying the minimum and maximum longitude and latitude bounds.

lon_bounds = (-87.6298 - 2, -87.6298 + 2)
lat_bounds = (41.8781 - 2, 41.8781 + 2)
bbox_subset_nodes = uxds["relhum_200hPa"][0].subset.bounding_box(
    lon_bounds,
    lat_bounds,
)

bbox_subset_nodes.plot(
    rasterize=True,
    periodic_elements="exclude",
    clim=clim,
    title="Bounding Box Subset (Corner Node Query)",
    **plot_opts,
) * features