or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

calculation-functions.mddata-io.mdindex.mdinterpolation.mdphysical-constants.mdplotting.mdxarray-integration.md

xarray-integration.mddocs/

0

# XArray Integration

1

2

MetPy provides seamless integration with xarray through custom accessors that make data arrays and datasets meteorology-aware. The `.metpy` accessor automatically handles coordinate identification, unit management, coordinate reference systems, and meteorological coordinate transformations.

3

4

## Capabilities

5

6

### DataArray Accessor

7

8

The MetPy DataArray accessor provides meteorological functionality directly on xarray DataArrays through the `.metpy` attribute.

9

10

```python { .api }

11

@property

12

def units:

13

"""

14

Get or set units of the DataArray as a pint.Unit.

15

16

Returns:

17

pint.Unit object representing the data units

18

"""

19

20

@property

21

def magnitude:

22

"""

23

Return magnitude of data values without units.

24

25

Returns:

26

Data array values without units attached

27

"""

28

29

@property

30

def unit_array:

31

"""

32

Return data values as a pint.Quantity.

33

34

Returns:

35

pint.Quantity with data and units

36

"""

37

38

def convert_units(units):

39

"""

40

Convert DataArray to different units.

41

42

Parameters:

43

- units: target units for conversion

44

45

Returns:

46

New DataArray with converted units

47

"""

48

49

def convert_to_base_units():

50

"""

51

Convert DataArray to base SI units.

52

53

Returns:

54

New DataArray with base units

55

"""

56

57

def convert_coordinate_units(coord, units):

58

"""

59

Convert coordinate to different units.

60

61

Parameters:

62

- coord: coordinate name to convert

63

- units: target units

64

65

Returns:

66

New DataArray with converted coordinate units

67

"""

68

69

def quantify():

70

"""

71

Convert data to pint.Quantity if not already quantified.

72

73

Returns:

74

DataArray with pint.Quantity data

75

"""

76

77

def dequantify():

78

"""

79

Convert pint.Quantity data to magnitude with units as attribute.

80

81

Returns:

82

DataArray with numeric data and units attribute

83

"""

84

```

85

86

### Coordinate System Properties

87

88

Automatic identification and access to meteorological coordinate axes.

89

90

```python { .api }

91

@property

92

def time:

93

"""

94

Return the time coordinate.

95

96

Returns:

97

Time coordinate DataArray

98

"""

99

100

@property

101

def vertical:

102

"""

103

Return the vertical coordinate (pressure, height, etc.).

104

105

Returns:

106

Vertical coordinate DataArray

107

"""

108

109

@property

110

def y:

111

"""

112

Return the y coordinate (latitude or projected y).

113

114

Returns:

115

Y coordinate DataArray

116

"""

117

118

@property

119

def latitude:

120

"""

121

Return the latitude coordinate.

122

123

Returns:

124

Latitude coordinate DataArray

125

"""

126

127

@property

128

def x:

129

"""

130

Return the x coordinate (longitude or projected x).

131

132

Returns:

133

X coordinate DataArray

134

"""

135

136

@property

137

def longitude:

138

"""

139

Return the longitude coordinate.

140

141

Returns:

142

Longitude coordinate DataArray

143

"""

144

145

def coordinates(*args):

146

"""

147

Return coordinate variables for specified axis types.

148

149

Parameters:

150

- args: axis type strings ('time', 'vertical', 'y', 'latitude', 'x', 'longitude')

151

152

Returns:

153

Generator yielding coordinate DataArrays

154

"""

155

156

def coordinates_identical(other):

157

"""

158

Check if coordinates match another DataArray.

159

160

Parameters:

161

- other: DataArray to compare coordinates with

162

163

Returns:

164

Boolean indicating coordinate match

165

"""

166

```

167

168

### Coordinate Reference System Support

169

170

Handle map projections and coordinate transformations for meteorological data.

171

172

```python { .api }

173

@property

174

def crs:

175

"""

176

Return coordinate reference system as CFProjection object.

177

178

Returns:

179

CFProjection object with CRS information

180

"""

181

182

@property

183

def cartopy_crs:

184

"""

185

Return CRS as cartopy projection object.

186

187

Returns:

188

cartopy CRS object for plotting

189

"""

190

191

@property

192

def cartopy_globe:

193

"""

194

Return globe associated with the CRS.

195

196

Returns:

197

cartopy Globe object

198

"""

199

200

@property

201

def cartopy_geodetic:

202

"""

203

Return cartopy geodetic CRS for the globe.

204

205

Returns:

206

cartopy Geodetic CRS

207

"""

208

209

@property

210

def pyproj_crs:

211

"""

212

Return CRS as pyproj object.

213

214

Returns:

215

pyproj CRS object

216

"""

217

218

@property

219

def pyproj_proj:

220

"""

221

Return Proj object for coordinate transformations.

222

223

Returns:

224

pyproj Proj object

225

"""

226

227

def assign_crs(cf_attributes=None, **kwargs):

228

"""

229

Assign coordinate reference system using CF conventions.

230

231

Parameters:

232

- cf_attributes: dictionary of CF projection attributes

233

- kwargs: CF attributes as keyword arguments

234

235

Returns:

236

New DataArray with CRS coordinate assigned

237

"""

238

239

def assign_latitude_longitude(force=False):

240

"""

241

Assign 2D latitude/longitude coordinates from y/x coordinates.

242

243

Parameters:

244

- force: overwrite existing lat/lon coordinates if True

245

246

Returns:

247

New DataArray with latitude/longitude coordinates

248

"""

249

250

def assign_y_x(force=False, tolerance=None):

251

"""

252

Assign 1D y/x coordinates from 2D latitude/longitude.

253

254

Parameters:

255

- force: overwrite existing y/x coordinates if True

256

- tolerance: maximum range tolerance for 2D to 1D collapse

257

258

Returns:

259

New DataArray with y/x dimension coordinates

260

"""

261

```

262

263

### Grid Analysis Properties

264

265

Meteorological grid analysis utilities for spatial derivatives and coordinate spacing.

266

267

```python { .api }

268

@property

269

def time_deltas:

270

"""

271

Return time differences in seconds.

272

273

Returns:

274

pint.Quantity with time differences

275

"""

276

277

@property

278

def grid_deltas:

279

"""

280

Return horizontal grid spacing for derivatives.

281

282

Returns:

283

Dictionary with 'dx' and 'dy' grid spacing arrays

284

"""

285

286

def find_axis_name(axis):

287

"""

288

Find coordinate name for given axis identifier.

289

290

Parameters:

291

- axis: axis identifier (int, string, or axis type)

292

293

Returns:

294

String name of the coordinate

295

"""

296

297

def find_axis_number(axis):

298

"""

299

Find dimension number for given axis identifier.

300

301

Parameters:

302

- axis: axis identifier (int, string, or axis type)

303

304

Returns:

305

Integer dimension number

306

"""

307

```

308

309

### Coordinate Management

310

311

Assign and manage meteorological coordinate metadata.

312

313

```python { .api }

314

def assign_coordinates(coordinates):

315

"""

316

Assign coordinates to specific MetPy axis types.

317

318

Parameters:

319

- coordinates: dict mapping axis types to coordinates, or None to clear

320

321

Returns:

322

New DataArray with assigned coordinate metadata

323

"""

324

```

325

326

### Advanced Indexing

327

328

Unit-aware and coordinate-type-aware data selection.

329

330

```python { .api }

331

@property

332

def loc:

333

"""

334

Unit-aware .loc indexer for DataArrays.

335

336

Returns:

337

Indexer object supporting units and coordinate types

338

"""

339

340

def sel(indexers=None, method=None, tolerance=None, drop=False, **indexers_kwargs):

341

"""

342

Unit-aware selection method.

343

344

Parameters:

345

- indexers: coordinate indexers (can include units)

346

- method: selection method for inexact matches

347

- tolerance: tolerance for inexact matches

348

- drop: drop scalar coordinates

349

- indexers_kwargs: indexers as keyword arguments

350

351

Returns:

352

Selected DataArray subset

353

"""

354

```

355

356

### Dataset Accessor

357

358

The MetPy Dataset accessor provides meteorological functionality for entire datasets.

359

360

```python { .api }

361

def parse_cf(varname=None, coordinates=None):

362

"""

363

Parse CF conventions for coordinate metadata.

364

365

Parameters:

366

- varname: variable name(s) to parse (default: all)

367

- coordinates: manual coordinate assignments

368

369

Returns:

370

DataArray or Dataset with parsed CF metadata

371

"""

372

373

@property

374

def loc:

375

"""

376

Unit-aware .loc indexer for Datasets.

377

378

Returns:

379

Indexer object supporting units

380

"""

381

382

def sel(indexers=None, method=None, tolerance=None, drop=False, **indexers_kwargs):

383

"""

384

Unit-aware Dataset selection.

385

386

Parameters:

387

- indexers: coordinate indexers

388

- method: selection method

389

- tolerance: selection tolerance

390

- drop: drop scalar coordinates

391

- indexers_kwargs: indexers as keywords

392

393

Returns:

394

Selected Dataset subset

395

"""

396

397

def assign_crs(cf_attributes=None, **kwargs):

398

"""

399

Assign CRS to Dataset variables.

400

401

Parameters:

402

- cf_attributes: CF projection attributes dictionary

403

- kwargs: CF attributes as keywords

404

405

Returns:

406

New Dataset with CRS coordinate

407

"""

408

409

def assign_latitude_longitude(force=False):

410

"""

411

Assign lat/lon coordinates to all applicable variables.

412

413

Parameters:

414

- force: overwrite existing coordinates

415

416

Returns:

417

New Dataset with latitude/longitude coordinates

418

"""

419

420

def assign_y_x(force=False, tolerance=None):

421

"""

422

Assign y/x coordinates to all applicable variables.

423

424

Parameters:

425

- force: overwrite existing coordinates

426

- tolerance: tolerance for coordinate collapse

427

428

Returns:

429

New Dataset with y/x coordinates

430

"""

431

432

def update_attribute(attribute, mapping):

433

"""

434

Update attribute across all Dataset variables.

435

436

Parameters:

437

- attribute: attribute name to update

438

- mapping: dict or callable for new attribute values

439

440

Returns:

441

New Dataset with updated attributes

442

"""

443

444

def quantify():

445

"""

446

Convert all numeric variables to pint.Quantities.

447

448

Returns:

449

New Dataset with quantified variables

450

"""

451

452

def dequantify():

453

"""

454

Convert pint.Quantities to magnitudes with units attributes.

455

456

Returns:

457

New Dataset with dequantified variables

458

"""

459

```

460

461

## Usage Examples

462

463

### Basic XArray Integration

464

465

```python

466

import xarray as xr

467

import metpy.xarray # Enables .metpy accessor

468

from metpy.units import units

469

470

# Load meteorological data

471

ds = xr.open_dataset('temperature_data.nc')

472

473

# Enable MetPy functionality

474

ds = ds.metpy.parse_cf()

475

476

# Access meteorological coordinates automatically

477

print("Time coordinate:", ds['temperature'].metpy.time)

478

print("Pressure levels:", ds['temperature'].metpy.vertical)

479

print("Spatial coordinates:", ds['temperature'].metpy.x, ds['temperature'].metpy.y)

480

481

# Check coordinate reference system

482

if hasattr(ds['temperature'].metpy, 'crs'):

483

print("Projection:", ds['temperature'].metpy.crs)

484

```

485

486

### Units and Conversions

487

488

```python

489

# Work with units automatically

490

temp = ds['temperature']

491

print("Original units:", temp.metpy.units)

492

493

# Convert units seamlessly

494

temp_celsius = temp.metpy.convert_units('celsius')

495

temp_kelvin = temp.metpy.convert_units('kelvin')

496

497

print(f"Temperature range: {temp_celsius.min().values:.1f} to {temp_celsius.max().values:.1f} °C")

498

499

# Convert coordinates

500

if 'height' in ds.coords:

501

# Convert height from meters to kilometers

502

ds_km = ds.metpy.convert_coordinate_units('height', 'km')

503

print("Height now in km:", ds_km.height.metpy.units)

504

```

505

506

### Coordinate System Operations

507

508

```python

509

# Assign coordinate reference system

510

import metpy.plots.mapping as mp

511

512

# For Lambert Conformal Conic projection

513

lcc_attrs = {

514

'grid_mapping_name': 'lambert_conformal_conic',

515

'standard_parallel': [25.0, 60.0],

516

'longitude_of_central_meridian': -100.0,

517

'latitude_of_projection_origin': 50.0

518

}

519

520

# Assign CRS to data

521

ds_proj = ds.metpy.assign_crs(lcc_attrs)

522

print("CRS assigned:", ds_proj.metpy.crs)

523

524

# Generate latitude/longitude coordinates from projection

525

ds_with_latlon = ds_proj.metpy.assign_latitude_longitude()

526

print("Latitude range:", ds_with_latlon.latitude.min().values, "to", ds_with_latlon.latitude.max().values)

527

```

528

529

### Advanced Selection and Indexing

530

531

```python

532

from metpy.units import units

533

534

# Unit-aware selection

535

temp_500mb = ds.sel(pressure=500 * units.hPa)

536

temp_region = ds.sel(

537

latitude=slice(30 * units.degrees_north, 50 * units.degrees_north),

538

longitude=slice(-120 * units.degrees_east, -90 * units.degrees_east)

539

)

540

541

# Select using coordinate types instead of names

542

temp_surface = ds.isel(vertical=0) # Surface level

543

temp_recent = ds.isel(time=-1) # Most recent time

544

545

# Advanced indexing with .loc

546

temp_point = ds.metpy.loc[{

547

'y': 40.0 * units.degrees_north,

548

'x': -105.0 * units.degrees_east,

549

'vertical': 850 * units.hPa

550

}]

551

```

552

553

### Grid Analysis

554

555

```python

556

# Calculate grid spacing for derivatives

557

temp = ds['temperature']

558

grid_info = temp.metpy.grid_deltas

559

560

print("Grid spacing dx:", grid_info['dx'])

561

print("Grid spacing dy:", grid_info['dy'])

562

563

# Use with MetPy calculation functions

564

import metpy.calc as mpcalc

565

566

# Calculate temperature advection

567

u_wind = ds['u_wind']

568

v_wind = ds['v_wind']

569

570

# Grid deltas automatically used by calculation functions

571

temp_advection = mpcalc.advection(temp, u_wind, v_wind)

572

print("Temperature advection calculated with automatic grid spacing")

573

```

574

575

### Working with Different Data Sources

576

577

```python

578

# GRIB data with CF conventions

579

grib_ds = xr.open_dataset('forecast.grib2', engine='cfgrib')

580

grib_ds = grib_ds.metpy.parse_cf()

581

582

# NetCDF data from THREDDS

583

netcdf_ds = xr.open_dataset('http://thredds.server.edu/data.nc')

584

netcdf_ds = netcdf_ds.metpy.parse_cf()

585

586

# Manual coordinate assignment when automatic parsing fails

587

coords_manual = {

588

'time': 'time',

589

'vertical': 'pressure',

590

'y': 'lat',

591

'x': 'lon'

592

}

593

ds_manual = ds.metpy.assign_coordinates(coords_manual)

594

```

595

596

### Integration with Calculations

597

598

```python

599

import metpy.calc as mpcalc

600

601

# Load upper-air data

602

sounding = xr.open_dataset('sounding.nc').metpy.parse_cf()

603

604

# Extract profiles - coordinates automatically identified

605

pressure = sounding['pressure'].metpy.vertical

606

temperature = sounding['temperature']

607

dewpoint = sounding['dewpoint']

608

609

# Calculations work seamlessly with xarray data

610

theta = mpcalc.potential_temperature(pressure, temperature)

611

rh = mpcalc.relative_humidity_from_dewpoint(temperature, dewpoint)

612

613

# Results maintain coordinate information

614

print("Potential temperature coordinates:", theta.coords)

615

print("Relative humidity range:", rh.min().values, "to", rh.max().values)

616

```

617

618

### Quantification and Dequantification

619

620

```python

621

# Convert to pint quantities for advanced unit operations

622

temp_quantity = ds['temperature'].metpy.quantify()

623

print("Temperature as quantity:", type(temp_quantity.data))

624

625

# Perform complex unit operations

626

temp_rankine = temp_quantity.metpy.convert_units('rankine')

627

temp_difference = temp_quantity - temp_quantity.mean()

628

629

# Convert back to normal xarray with units as attributes

630

temp_dequant = temp_quantity.metpy.dequantify()

631

print("Units attribute:", temp_dequant.attrs['units'])

632

```

633

634

## Coordinate Identification Criteria

635

636

MetPy uses multiple criteria to automatically identify coordinate types:

637

638

```python { .api }

639

# Coordinate axis types recognized by MetPy

640

metpy_axes = ['time', 'vertical', 'y', 'latitude', 'x', 'longitude']

641

642

# Identification criteria (examples)

643

coordinate_criteria = {

644

'standard_name': {

645

'time': 'time',

646

'vertical': {'air_pressure', 'height', 'geopotential_height'},

647

'latitude': 'latitude',

648

'longitude': 'longitude'

649

},

650

'axis': {

651

'time': 'T',

652

'vertical': 'Z',

653

'y': 'Y',

654

'x': 'X'

655

},

656

'units': {

657

'vertical': {'match': 'dimensionality', 'units': 'Pa'},

658

'latitude': {'match': 'name', 'units': {'degree_north', 'degrees_north'}},

659

'longitude': {'match': 'name', 'units': {'degree_east', 'degrees_east'}}

660

}

661

}

662

```

663

664

## Error Handling

665

666

```python

667

try:

668

# Attempt to access coordinate

669

time_coord = ds['temperature'].metpy.time

670

except AttributeError:

671

print("Time coordinate not found or not identifiable")

672

673

try:

674

# Attempt coordinate conversion

675

temp_kelvin = ds['temperature'].metpy.convert_units('kelvin')

676

except DimensionalityError:

677

print("Units are not compatible with temperature")

678

679

# Check for CRS before using projection methods

680

if hasattr(ds['temperature'].metpy, 'crs'):

681

cartopy_crs = ds['temperature'].metpy.cartopy_crs

682

else:

683

print("No CRS information available")

684

```

685

686

## Types

687

688

```python { .api }

689

from typing import Optional, Dict, Generator, Union

690

import xarray as xr

691

from pint import Quantity

692

693

# Accessor types

694

MetPyDataArrayAccessor = object

695

MetPyDatasetAccessor = object

696

697

# Coordinate types

698

CoordinateArray = xr.DataArray

699

CoordinateMapping = Dict[str, str]

700

701

# CRS types

702

CRS = object # CFProjection object

703

CartopyCRS = object

704

PyProjCRS = object

705

706

# Selection types

707

IndexerDict = Dict[str, Union[slice, Quantity, float, int]]

708

SelectionResult = Union[xr.DataArray, xr.Dataset]

709

```