Spatial Selection Operators
In this tutorial, you’ll learn:
Using UXarray to select specific regions from an unstructured grid
Prerequisites
Concepts |
Importance |
Notes |
---|---|---|
Necessary |
Time to learn: 10 minutes
Overview
When working with unstructured grids, a region or zone rather than the entire global grid might be of interest for data analysis and visualization. Such spatial selection of the grid/data might help with not only analyzing/plotting a specific region/zone, but also reducing the data size and increasing the performance as well as allowing the entire plots to be effectively displayed on the screen.
This notebook showcases how to spatially subset a grid and take a cross-section of the grid at a constant latitude and longitude.
Subsetting
UXarray provides functionality for subsetting the grid into a bounding box, bounding circle, or K-nearest neighbors.
Before demonstrating them, let us load some global data first:
Load Data
# Import
import cartopy.crs as ccrs
import geoviews.feature as gf
import uxarray as ux
grid_path = "../../meshfiles/x1.655362.grid.nc"
data_path = "../../meshfiles/x1.655362.data.nc"
# Open dataset and grab a data variable of interest
uxds = ux.open_dataset(grid_path, data_path)
uxda = uxds["relhum_200hPa"][0]
Plot The Global Data
Note!
The visualizations throughout this tutorial are only for demonstrating the results of the subsetting and cross-sections versus the global grid. Since the details of plotting with UXarray will be covered in the next chapter, we will not go over any details of the plots here.
plot_opts = {"width": 700, "height": 350}
features = gf.coastline(
projection=ccrs.PlateCarree(), line_width=0.4, scale="50m"
) * gf.states(projection=ccrs.PlateCarree(), line_width=0.4, scale="50m")
clim = (uxda.values.min(), uxda.values.max())
uxda.plot(
rasterize=True, periodic_elements="exclude", title="Global Grid", **plot_opts
) * features
/home/runner/miniconda3/envs/unstructured-grid-viz-cookbook-dev/lib/python3.10/site-packages/cartopy/io/__init__.py:241: DownloadWarning: Downloading: https://naturalearth.s3.amazonaws.com/110m_cultural/ne_110m_admin_1_states_provinces_lakes.zip
warnings.warn(f'Downloading: {url}', DownloadWarning)
/home/runner/miniconda3/envs/unstructured-grid-viz-cookbook-dev/lib/python3.10/site-packages/cartopy/io/__init__.py:241: DownloadWarning: Downloading: https://naturalearth.s3.amazonaws.com/50m_physical/ne_50m_coastline.zip
warnings.warn(f'Downloading: {url}', DownloadWarning)
/home/runner/miniconda3/envs/unstructured-grid-viz-cookbook-dev/lib/python3.10/site-packages/cartopy/io/__init__.py:241: DownloadWarning: Downloading: https://naturalearth.s3.amazonaws.com/50m_cultural/ne_50m_admin_1_states_provinces_lakes.zip
warnings.warn(f'Downloading: {url}', DownloadWarning)
Generate Various Subsets
# Bounding box around Boulder, CO
ref_lon = -105.2705
ref_lat = 40.0150
ref_offset = 1
lon_bounds = (ref_lon - ref_offset, ref_lon + ref_offset)
lat_bounds = (ref_lat - ref_offset, ref_lat + ref_offset)
# Subset the global data variable and its grid using the bounding box
uxda_bbox = uxda.subset.bounding_box(lon_bounds, lat_bounds, element="nodes")
# Now use a bounding circle subsetting
ref_center = [ref_lon, ref_lat]
uxda_bcircle = uxda.subset.bounding_circle(ref_center, ref_offset)
# Now use a K-nearest neighbor subsetting
k_nn = 60
uxda_nn = uxda.subset.nearest_neighbor(ref_center, k=k_nn, element="nodes")
Plot The Subsets
plot_bbox = (
uxda_bbox.plot(
rasterize=True,
periodic_elements="exclude",
clim=clim,
title="Bounding Box Subset around Boulder, CO (Corner Node Query)",
**plot_opts,
)
* features
)
plot_bcircle = (
uxda_bcircle.plot(
rasterize=True,
periodic_elements="exclude",
clim=clim,
title="Bounding Circle Subset around Boulder, CO (Corner Node Query)",
**plot_opts,
)
* features
)
plot_nn = (
uxda_nn.plot(
rasterize=True,
periodic_elements="exclude",
clim=clim,
title="K-Nearest Neighbor Subset around Boulder, CO (Corner Node Query)",
**plot_opts,
)
* features
)
(plot_bbox + plot_bcircle + plot_nn).cols(1)