6
6
from pathlib import Path
7
7
8
8
import xarray as xr
9
+ from pygmt .enums import GridRegistration , GridType
9
10
from pygmt .exceptions import GMTInvalidInput
10
11
from pygmt .src .grdinfo import grdinfo
11
12
@@ -15,110 +16,122 @@ class GMTDataArrayAccessor:
15
16
"""
16
17
GMT accessor for :class:`xarray.DataArray`.
17
18
18
- The accessor extends :class:`xarray.DataArray` to store GMT-specific
19
- properties about grids, which are important for PyGMT to correctly process
20
- and plot the grids.
19
+ The *gmt* accessor extends :class:`xarray.DataArray` to store GMT-specific
20
+ properties for grids, which are important for PyGMT to correctly process and plot
21
+ the grids. The *gmt* accessor contains the following properties:
21
22
22
- Notes
23
- -----
24
-
25
- Due to the limitations of xarray accessors, the GMT accessors are created
26
- once per :class:`xarray.DataArray` instance. You may lose these
27
- GMT-specific properties when manipulating grids (e.g., arithmetic and slice
28
- operations) or when accessing a :class:`xarray.DataArray` from a
29
- :class:`xarray.Dataset`. In these cases, you need to manually set these
30
- properties before passing the grid to PyGMT.
23
+ - ``registration``: Grid registration type :class:`pygmt.enums.GridRegistration`.
24
+ - ``gtype``: Grid coordinate system type :class:`pygmt.enums.GridType`.
31
25
32
26
Examples
33
27
--------
34
-
35
- For GMT's built-in remote datasets, these GMT-specific properties are
36
- automatically determined and you can access them as follows:
28
+ For GMT's built-in remote datasets, these GMT-specific properties are automatically
29
+ determined and you can access them as follows:
37
30
38
31
>>> from pygmt.datasets import load_earth_relief
39
32
>>> # Use the global Earth relief grid with 1 degree spacing
40
33
>>> grid = load_earth_relief(resolution="01d", registration="pixel")
41
- >>> # See if grid uses Gridline (0) or Pixel (1) registration
34
+ >>> # See if grid uses Gridline or Pixel registration
42
35
>>> grid.gmt.registration
43
- 1
44
- >>> # See if grid uses Cartesian (0) or Geographic (1) coordinate system
36
+ <GridRegistration.PIXEL: 1>
37
+ >>> # See if grid is in Cartesian or Geographic coordinate system
45
38
>>> grid.gmt.gtype
46
- 1
39
+ <GridType.GEOGRAPHIC: 1>
47
40
48
- For :class:`xarray.DataArray` grids created by yourself, grid properties
49
- ``registration `` and ``gtype `` default to 0 (i.e., a gridline-registered ,
50
- Cartesian grid). You need to set the correct properties before
51
- passing it to PyGMT functions:
41
+ For :class:`xarray.DataArray` grids created by yourself, ``registration`` and
42
+ ``gtype `` default to ``GridRegistration.GRIDLINE `` and ``GridType.CARTESIAN`` (i.e.,
43
+ a gridline-registered, Cartesian grid). You need to set the correct properties
44
+ before passing it to PyGMT functions:
52
45
53
46
>>> import numpy as np
54
- >>> import pygmt
55
47
>>> import xarray as xr
56
- >>> # create a DataArray in gridline coordinates of sin(lon) * cos(lat)
48
+ >>> import pygmt
49
+ >>> from pygmt.enums import GridRegistration, GridType
50
+ >>> # Create a DataArray in gridline coordinates of sin(lon) * cos(lat)
57
51
>>> interval = 2.5
58
52
>>> lat = np.arange(90, -90 - interval, -interval)
59
53
>>> lon = np.arange(0, 360 + interval, interval)
60
54
>>> longrid, latgrid = np.meshgrid(lon, lat)
61
55
>>> data = np.sin(np.deg2rad(longrid)) * np.cos(np.deg2rad(latgrid))
62
56
>>> grid = xr.DataArray(data, coords=[("latitude", lat), ("longitude", lon)])
63
- >>> # default to a gridline-registered Cartesian grid
64
- >>> grid.gmt.registration, grid.gmt.gtype
65
- (0, 0)
66
- >>> # set it to a gridline-registered geographic grid
67
- >>> grid.gmt.registration = 0
68
- >>> grid.gmt.gtype = 1
69
- >>> grid.gmt.registration, grid.gmt.gtype
70
- (0, 1)
71
-
72
- Note that the accessors are created once per :class:`xarray.DataArray`
73
- instance, so you may lose these GMT-specific properties after manipulating
74
- your grid.
57
+ >>> # Default to a gridline-registered Cartesian grid
58
+ >>> grid.gmt.registration
59
+ <GridRegistration.GRIDLINE: 0>
60
+ >>> grid.gmt.gtype
61
+ <GridType.CARTESIAN: 0>
62
+ >>> # Manually set it to a gridline-registered geographic grid
63
+ >>> grid.gmt.registration = GridRegistration.GRIDLINE
64
+ >>> grid.gmt.gtype = GridType.GEOGRAPHIC
65
+ >>> grid.gmt.registration
66
+ <GridRegistration.GRIDLINE: 0>
67
+ >>> grid.gmt.gtype
68
+ <GridType.GEOGRAPHIC: 1>
69
+
70
+ Notes
71
+ -----
72
+ Due to the limitations of xarray accessors, the GMT accessors are created once per
73
+ :class:`xarray.DataArray` instance. You may lose these GMT-specific properties when
74
+ manipulating grids (e.g., arithmetic and slice operations) or when accessing a
75
+ :class:`xarray.DataArray` from a :class:`xarray.Dataset`. In these cases, you need
76
+ to manually set these properties before passing the grid to PyGMT.
75
77
76
78
Inplace assignment operators like ``*=`` don't create new instances, so the
77
79
properties are still kept:
78
80
79
81
>>> grid *= 2.0
80
- >>> grid.gmt.registration, grid.gmt.gtype
81
- (0, 1)
82
+ >>> grid.gmt.registration
83
+ <GridRegistration.GRIDLINE: 0>
84
+ >>> grid.gmt.gtype
85
+ <GridType.GEOGRAPHIC: 1>
82
86
83
- Other grid operations (e.g., arithmetic or slice operations) create new
84
- instances, so the properties will be lost:
87
+ Other grid operations (e.g., arithmetic or slice operations) create new instances,
88
+ so the properties will be lost:
85
89
86
90
>>> # grid2 is a slice of the original grid
87
91
>>> grid2 = grid[0:30, 50:80]
88
- >>> # properties are reset to the default values for new instance
89
- >>> grid2.gmt.registration, grid2.gmt.gtype
90
- (0, 0)
91
- >>> # need to set these properties before passing the grid to PyGMT
92
+ >>> # Properties are reset to the default values for new instance
93
+ >>> grid2.gmt.registration
94
+ <GridRegistration.GRIDLINE: 0>
95
+ >>> grid2.gmt.gtype
96
+ <GridType.CARTESIAN: 0>
97
+ >>> # Need to set these properties before passing the grid to PyGMT
92
98
>>> grid2.gmt.registration = grid.gmt.registration
93
99
>>> grid2.gmt.gtype = grid.gmt.gtype
94
- >>> grid2.gmt.registration, grid2.gmt.gtype
95
- (0, 1)
100
+ >>> grid2.gmt.registration
101
+ <GridRegistration.GRIDLINE: 0>
102
+ >>> grid2.gmt.gtype
103
+ <GridType.GEOGRAPHIC: 1>
96
104
97
- Accessing a :class:`xarray.DataArray` from a :class:`xarray.Dataset` always
98
- creates new instances, so these properties are always lost. The workaround
99
- is to assign the :class:`xarray.DataArray` into a variable:
105
+ Accessing a :class:`xarray.DataArray` from a :class:`xarray.Dataset` always creates
106
+ new instances, so these properties are always lost. The workaround is to assign the
107
+ :class:`xarray.DataArray` into a variable:
100
108
101
109
>>> ds = xr.Dataset({"zval": grid})
110
+ >>> ds.zval.gmt.registration
111
+ <GridRegistration.GRIDLINE: 0>
112
+ >>> ds.zval.gmt.gtype
113
+ <GridType.CARTESIAN: 0>
114
+ >>> # Manually set these properties won't work as expected
115
+ >>> ds.zval.gmt.registration = GridRegistration.GRIDLINE
116
+ >>> ds.zval.gmt.gtype = GridType.GEOGRAPHIC
102
117
>>> ds.zval.gmt.registration, ds.zval.gmt.gtype
103
- (0, 0)
104
- >>> # manually set these properties won't work as expected
105
- >>> ds.zval.gmt.registration, ds.zval.gmt.gtype = 0, 1
106
- >>> ds.zval.gmt.registration, ds.zval.gmt.gtype
107
- (0, 0)
118
+ (<GridRegistration.GRIDLINE: 0>, <GridType.CARTESIAN: 0>)
108
119
>>> # workaround: assign the DataArray into a variable
109
120
>>> zval = ds.zval
110
121
>>> zval.gmt.registration, zval.gmt.gtype
111
- (0, 0)
112
- >>> zval.gmt.registration, zval.gmt.gtype = 0, 1
122
+ (<GridRegistration.GRIDLINE: 0>, <GridType.CARTESIAN: 0>)
123
+ >>> zval.gmt.registration = GridRegistration.GRIDLINE
124
+ >>> zval.gmt.gtype = GridType.GEOGRAPHIC
113
125
>>> zval.gmt.registration, zval.gmt.gtype
114
- (0, 1 )
126
+ (<GridRegistration.GRIDLINE: 0>, <GridType.GEOGRAPHIC: 1> )
115
127
"""
116
128
117
129
def __init__ (self , xarray_obj ):
118
130
self ._obj = xarray_obj
131
+
119
132
# Default to Gridline registration and Cartesian grid type
120
- self ._registration = 0
121
- self ._gtype = 0
133
+ self ._registration = GridRegistration . GRIDLINE
134
+ self ._gtype = GridType . CARTESIAN
122
135
123
136
# If the source file exists, get grid registration and grid type from the last
124
137
# two columns of the shortened summary information of grdinfo.
@@ -131,33 +144,35 @@ def __init__(self, xarray_obj):
131
144
@property
132
145
def registration (self ):
133
146
"""
134
- Registration type of the grid, either 0 (Gridline) or 1 (Pixel) .
147
+ Grid registration type :class:`pygmt.enums.GridRegistration` .
135
148
"""
136
149
return self ._registration
137
150
138
151
@registration .setter
139
152
def registration (self , value ):
140
- if value not in {0 , 1 }:
153
+ # TODO(Python>=3.12): Simplify to `if value not in GridRegistration`.
154
+ if value not in GridRegistration .__members__ .values ():
141
155
msg = (
142
- f"Invalid grid registration value: { value } , should be either "
143
- "0 for Gridline registration or 1 for Pixel registration ."
156
+ f"Invalid grid registration: ' { value } '. Should be either "
157
+ "GridRegistration.GRIDLINE (0) or GridRegistration.PIXEL (1) ."
144
158
)
145
159
raise GMTInvalidInput (msg )
146
- self ._registration = value
160
+ self ._registration = GridRegistration ( value )
147
161
148
162
@property
149
163
def gtype (self ):
150
164
"""
151
- Coordinate system type of the grid, either 0 (Cartesian) or 1 (Geographic) .
165
+ Grid coordinate system type :class:`pygmt.enums.GridType` .
152
166
"""
153
167
return self ._gtype
154
168
155
169
@gtype .setter
156
170
def gtype (self , value ):
157
- if value not in {0 , 1 }:
171
+ # TODO(Python>=3.12): Simplify to `if value not in GridType`.
172
+ if value not in GridType .__members__ .values ():
158
173
msg = (
159
- f"Invalid coordinate system type: { value } , should be "
160
- "either 0 for Cartesian or 1 for Geographic ."
174
+ f"Invalid grid coordinate system type: ' { value } '. "
175
+ "Should be either GridType.CARTESIAN (0) or GridType.GEOGRAPHIC (1) ."
161
176
)
162
177
raise GMTInvalidInput (msg )
163
- self ._gtype = value
178
+ self ._gtype = GridType ( value )
0 commit comments