Assign value by coordinate

How to assign to individual pixels of a xr.DataArray by coordinate. This is detailed for .sel(...) in the xarray documentation, but works similar for .loc[...].

import xarray as xr
import numpy as np

from util import generate_3d_dataset
print(xr.__version__)
print(np.__version__)
2025.3.1
2.2.0

Generate some dummy data. Needs to be loaded for the value assignment/indexing to work.

ds = generate_3d_dataset(lat = 100, lon=200, time=1).load()
ds
<xarray.Dataset> Size: 162kB
Dimensions:  (lat: 100, lon: 200, time: 1)
Coordinates:
  * lat      (lat) int64 800B 0 1 2 3 4 5 6 7 8 9 ... 91 92 93 94 95 96 97 98 99
  * lon      (lon) int64 2kB 0 1 2 3 4 5 6 7 ... 192 193 194 195 196 197 198 199
  * time     (time) datetime64[ns] 8B 2021-01-01
Data variables:
    test     (lat, lon, time) float64 160kB 0.4465 0.2039 ... 0.9729 0.8818

Generate target locations. In the following these will be used for orthogonal and pointwise indexing.

lon_coords = np.array([3, 20, 75])
lat_coords = np.array([0, 32, 99])

Orthogonal indexing

ds.loc[dict(lon=lon_coords, lat=lat_coords)]
<xarray.Dataset> Size: 128B
Dimensions:  (lat: 3, lon: 3, time: 1)
Coordinates:
  * lat      (lat) int64 24B 0 32 99
  * lon      (lon) int64 24B 3 20 75
  * time     (time) datetime64[ns] 8B 2021-01-01
Data variables:
    test     (lat, lon, time) float64 72B 0.3392 0.6619 0.7458 ... 0.5027 0.7492
indexer = xr.Dataset(
    coords={
        "lon": ("queried_points", lon_coords),
        "lat": ("queried_points", lat_coords),
    },
)
indexer
<xarray.Dataset> Size: 48B
Dimensions:  (queried_points: 3)
Coordinates:
    lon      (queried_points) int64 24B 3 20 75
    lat      (queried_points) int64 24B 0 32 99
Dimensions without coordinates: queried_points
Data variables:
    *empty*

Pointwise indexing and value assignment

ds["test"].loc[dict(lon=indexer.lon, lat=indexer.lat)]
<xarray.DataArray 'test' (queried_points: 3, time: 1)> Size: 24B
array([[0.33919176],
       [0.55243292],
       [0.74918222]])
Coordinates:
    lat      (queried_points) int64 24B 0 32 99
    lon      (queried_points) int64 24B 3 20 75
  * time     (time) datetime64[ns] 8B 2021-01-01
Dimensions without coordinates: queried_points
ds["test"].loc[dict(lon=indexer.lon, lat=indexer.lat)] = 1
ds["test"].loc[dict(lon=indexer.lon, lat=indexer.lat)]
<xarray.DataArray 'test' (queried_points: 3, time: 1)> Size: 24B
array([[1.],
       [1.],
       [1.]])
Coordinates:
    lat      (queried_points) int64 24B 0 32 99
    lon      (queried_points) int64 24B 3 20 75
  * time     (time) datetime64[ns] 8B 2021-01-01
Dimensions without coordinates: queried_points