Clip Data to a Spatial Region
Subset your data to a specific geographic area using boundaries, points, or bounding boxes.
The boundary catalog also includes an optional Tribal Areas category for named BIA
areas in the western United States. These are illustrative geographic representations,
not legal or ownership boundaries.
By Named Region (County, Watershed, etc.)
from climakitae.new_core.user_interface import ClimateData
cd = ClimateData()
# Single county
data = (cd
.catalog("cadcat")
.activity_id("LOCA2")
.variable_id("tasmax")
.table_id("mon")
.grid_label("d03")
.processes({"clip": "Los Angeles County"})
.get())
# Multiple counties (union)
data = (cd
.catalog("cadcat")
.activity_id("LOCA2")
.variable_id("tasmax")
.table_id("mon")
.grid_label("d03")
.processes({"clip": ["Alameda County", "Contra Costa County", "Santa Clara County"]})
.get())
# Discover available regions
cd.show_boundary_options() # All boundary types
cd.show_boundary_options("ca_counties") # All California counties
cd.show_boundary_options("Tribal Areas") # Western US BIA tribal areas
Available boundary types:
| Boundary Type | Description |
|---|---|
ca_counties |
California counties (58 total) |
ca_watersheds |
Hydrologic units (HUC8) |
ca_census_tracts |
Census geography |
states |
Western US states (11 states) |
ious_pous |
California investor-owned and public utilities |
forecast_zones |
NOAA forecast zones |
electric_balancing_areas |
Electric grid authorities |
Tribal Areas |
BIA land-area representations and Tribal statistical areas in the western US |
Tribal selections use qualified names so they do not collide with counties or watersheds. For example, to select the Shingle Springs area:
data = (cd
.catalog("cadcat")
.activity_id("LOCA2")
.variable_id("tasmax")
.table_id("mon")
.grid_label("d03")
.processes({"clip": "Tribal Area: Shingle Springs"})
.get())
Use cd.show_boundary_options("Tribal Areas", show_n=None) to see the exact
selectors available in the current catalog. The category is available only when
the optional tribalareas entry is present in the boundary Intake catalog.
By Single Point (Lat/Lon)
# Query closest grid cell to a point
data = (cd
.catalog("cadcat")
.activity_id("LOCA2")
.variable_id("tasmax")
.table_id("day")
.grid_label("d03")
.processes({"clip": (37.7749, -122.4194)}) # San Francisco
.get())
# Inspect the closest location
print(f"Lat: {data.lat.values}, Lon: {data.lon.values}")
By Multiple Points
# Query nearest grid cell for each point
locations = [
(34.05, -118.25), # Los Angeles
(37.77, -122.42), # San Francisco
(32.72, -117.16), # San Diego
]
data = (cd
.catalog("cadcat")
.activity_id("LOCA2")
.variable_id("tasmax")
.table_id("day")
.grid_label("d03")
.processes({"clip": locations})
.get())
# Data has 'closest_cell' dimension
print(f"Shape: {data['tasmax'].shape}") # (time, closest_cell, ...)
la_data = data.isel(closest_cell=0)
sf_data = data.isel(closest_cell=1)
sd_data = data.isel(closest_cell=2)
By Bounding Box
# Rectangular region: (lat_range, lon_range)
data = (cd
.catalog("cadcat")
.activity_id("LOCA2")
.variable_id("tasmax")
.table_id("mon")
.grid_label("d03")
.processes({
"clip": ((34.0, 36.0), (-121.0, -119.0)) # LA area
})
.get())
# Extract subset
data_subset = data.sel(lat=slice(34.5, 35.5), lon=slice(-120.5, -119.5))
Best Practice: Combine with Time Slice
# Always clip FIRST, then aggregate
# ✅ EFFICIENT
data = (cd
.catalog("cadcat")
.activity_id("LOCA2")
.variable_id("tasmax")
.table_id("mon")
.grid_label("d03")
.processes({
"clip": "Los Angeles County",
"time_slice": ("2015-01-01", "2015-12-31")
})
.get())
spatial_mean = data["tasmax"].mean(dim=["lat", "lon"]).compute()
# ❌ INEFFICIENT (loads all data first)
data_full = (cd
.catalog("cadcat")
.activity_id("LOCA2")
.variable_id("tasmax")
.table_id("mon")
.grid_label("d03")
.get())
la_data = data_full.sel(lat=slice(33.5, 35.5), lon=slice(-119, -117))
spatial_mean = la_data["tasmax"].mean().compute()