Skip to content

Commit 06dd1a5

Browse files
authored
Figure.coast/pygmt.select/pygmt.grdlandmask: Use long names ("crude"/"low"/"intermediate"/"high"/"full") for the 'resolution' parameter (#3013)
1 parent 438edce commit 06dd1a5

File tree

6 files changed

+120
-46
lines changed

6 files changed

+120
-46
lines changed

examples/tutorials/basics/coastlines.py

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@
2727
# 3. island-in-lake shore
2828
# 4. lake-in-island-in-lake shore
2929
#
30-
# You can specify which level you want to plot by passing the level number and
31-
# a GMT pen configuration. For example, to plot just the coastlines with 0.5p
32-
# thickness and black lines:
30+
# You can specify which level you want to plot by passing the level number and a GMT
31+
# pen configuration. For example, to plot just the coastlines with 0.5p thickness and
32+
# black lines:
3333

3434
fig = pygmt.Figure()
3535
fig.basemap(region="g", projection="W15c", frame=True)
@@ -50,18 +50,14 @@
5050
# Resolutions
5151
# -----------
5252
#
53-
# The coastline database comes with 5 resolutions. The resolution drops by 80%
54-
# between levels:
55-
#
56-
# 1. ``"c"``: crude
57-
# 2. ``"l"``: low (default)
58-
# 3. ``"i"``: intermediate
59-
# 4. ``"h"``: high
60-
# 5. ``"f"``: full
53+
# The coastline database comes with 5 resolutions: ``"full"``, ``"high"``,
54+
# ``"intermediate"``, ``"low"``, and ``"crude"``. The resolution drops by 80% between
55+
# levels. The ``resolution`` parameter defaults to ``"auto"`` to automatically select
56+
# the best resolution given the chosen map scale.
6157

6258
oahu = [-158.3, -157.6, 21.2, 21.8]
6359
fig = pygmt.Figure()
64-
for res in ["c", "l", "i", "h", "f"]:
60+
for res in ["crude", "low", "intermediate", "high", "full"]:
6561
fig.coast(resolution=res, shorelines="1p", region=oahu, projection="M5c")
6662
fig.shift_origin(xshift="5c")
6763
fig.show()
@@ -71,9 +67,9 @@
7167
# Land and water
7268
# --------------
7369
#
74-
# Use the ``land`` and ``water`` parameters to specify a fill color for land
75-
# and water bodies. The colors can be given by name or hex codes (like the ones
76-
# used in HTML and CSS):
70+
# Use the ``land`` and ``water`` parameters to specify a fill color for land and water
71+
# bodies. The colors can be given by name or hex codes (like the ones used in HTML and
72+
# CSS):
7773

7874
fig = pygmt.Figure()
7975
fig.basemap(region="g", projection="W15c", frame=True)

pygmt/src/_common.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,3 +251,56 @@ def from_params(
251251
f"{', '.join(params)}."
252252
)
253253
raise GMTInvalidInput(msg)
254+
255+
256+
def _parse_coastline_resolution(
257+
resolution: Literal["auto", "full", "high", "intermediate", "low", "crude", None],
258+
) -> Literal["a", "f", "h", "i", "l", "c", None]:
259+
"""
260+
Parse the 'resolution' parameter for coastline-related functions.
261+
262+
Parameters
263+
----------
264+
resolution
265+
The resolution of the coastline dataset to use. The available resolutions from
266+
highest to lowest are: ``"full"``, ``"high"``, ``"intermediate"``, ``"low"``,
267+
and ``"crude"``, which drops by 80% between levels. Alternatively, choose
268+
``"auto"`` to automatically select the most suitable resolution given the chosen
269+
map scale or region. ``None`` means using the default resolution.
270+
271+
Returns
272+
-------
273+
The single-letter resolution code or ``None``.
274+
275+
Raises
276+
------
277+
GMTInvalidInput
278+
If the resolution is invalid.
279+
280+
Examples
281+
--------
282+
>>> _parse_coastline_resolution("full")
283+
'f'
284+
>>> _parse_coastline_resolution("f")
285+
'f'
286+
>>> _parse_coastline_resolution(None)
287+
>>> _parse_coastline_resolution("invalid")
288+
Traceback (most recent call last):
289+
...
290+
pygmt.exceptions.GMTInvalidInput: Invalid resolution: 'invalid'. Valid values ...
291+
"""
292+
if resolution is None:
293+
return None
294+
295+
_valid_res = {"auto", "full", "high", "intermediate", "low", "crude"}
296+
297+
if resolution in _valid_res: # Long-form arguments.
298+
return resolution[0] # type: ignore[return-value]
299+
300+
if resolution in {_res[0] for _res in _valid_res}: # Short-form arguments.
301+
return resolution # type: ignore[return-value]
302+
303+
msg = (
304+
f"Invalid resolution: '{resolution}'. Valid values are {', '.join(_valid_res)}."
305+
)
306+
raise GMTInvalidInput(msg)

pygmt/src/coast.py

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
coast - Plot continents, countries, shorelines, rivers, and borders.
33
"""
44

5+
from typing import Literal
6+
57
from pygmt.clib import Session
68
from pygmt.exceptions import GMTInvalidInput
79
from pygmt.helpers import (
@@ -11,6 +13,7 @@
1113
kwargs_to_strings,
1214
use_alias,
1315
)
16+
from pygmt.src._common import _parse_coastline_resolution
1417

1518
__doctest_skip__ = ["coast"]
1619

@@ -20,7 +23,6 @@
2023
A="area_thresh",
2124
B="frame",
2225
C="lakes",
23-
D="resolution",
2426
E="dcw",
2527
F="box",
2628
G="land",
@@ -37,7 +39,13 @@
3739
t="transparency",
3840
)
3941
@kwargs_to_strings(R="sequence", c="sequence_comma", p="sequence")
40-
def coast(self, **kwargs):
42+
def coast(
43+
self,
44+
resolution: Literal[
45+
"auto", "full", "high", "intermediate", "low", "crude", None
46+
] = None,
47+
**kwargs,
48+
):
4149
r"""
4250
Plot continents, countries, shorelines, rivers, and borders.
4351
@@ -73,10 +81,12 @@ def coast(self, **kwargs):
7381
parameter. Optionally, specify separate fills by appending
7482
**+l** for lakes or **+r** for river-lakes, and passing multiple
7583
strings in a list.
76-
resolution : str
77-
**f**\|\ **h**\|\ **i**\|\ **l**\|\ **c**.
78-
Select the resolution of the data set to: (**f**\ )ull, (**h**\ )igh,
79-
(**i**\ )ntermediate, (**l**\ )ow, and (**c**\ )rude.
84+
resolution
85+
Select the resolution of the coastline dataset to use. The available resolutions
86+
from highest to lowest are: ``"full"``, ``"high"``, ``"intermediate"``,
87+
``"low"``, and ``"crude"``, which drops by 80% between levels. Default is
88+
``"auto"`` to automatically select the most suitable resolution given the chosen
89+
map scale.
8090
land : str
8191
Select filling of "dry" areas.
8292
rivers : int, str, or list
@@ -200,5 +210,8 @@ def coast(self, **kwargs):
200210
"lakes, land, water, rivers, borders, dcw, Q, or shorelines."
201211
)
202212
raise GMTInvalidInput(msg)
213+
214+
kwargs["D"] = kwargs.get("D", _parse_coastline_resolution(resolution))
215+
203216
with Session() as lib:
204217
lib.call_module(module="coast", args=build_arg_list(kwargs))

pygmt/src/grdlandmask.py

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,21 @@
22
grdlandmask - Create a "wet-dry" mask grid from shoreline database.
33
"""
44

5+
from typing import Literal
6+
57
import xarray as xr
68
from pygmt._typing import PathLike
79
from pygmt.clib import Session
810
from pygmt.exceptions import GMTInvalidInput
911
from pygmt.helpers import build_arg_list, fmt_docstring, kwargs_to_strings, use_alias
12+
from pygmt.src._common import _parse_coastline_resolution
1013

1114
__doctest_skip__ = ["grdlandmask"]
1215

1316

1417
@fmt_docstring
1518
@use_alias(
1619
A="area_thresh",
17-
D="resolution",
1820
E="bordervalues",
1921
I="spacing",
2022
N="maskvalues",
@@ -24,7 +26,13 @@
2426
x="cores",
2527
)
2628
@kwargs_to_strings(I="sequence", R="sequence", N="sequence", E="sequence")
27-
def grdlandmask(outgrid: PathLike | None = None, **kwargs) -> xr.DataArray | None:
29+
def grdlandmask(
30+
outgrid: PathLike | None = None,
31+
resolution: Literal[
32+
"auto", "full", "high", "intermediate", "low", "crude", None
33+
] = None,
34+
**kwargs,
35+
) -> xr.DataArray | None:
2836
r"""
2937
Create a "wet-dry" mask grid from shoreline database.
3038
@@ -44,17 +52,15 @@ def grdlandmask(outgrid: PathLike | None = None, **kwargs) -> xr.DataArray | Non
4452
{spacing}
4553
{region}
4654
{area_thresh}
47-
resolution : str
48-
*res*\[\ **+f**\]. Select the resolution of the data set to use
49-
((**f**)ull, (**h**)igh, (**i**)ntermediate, (**l**)ow, or
50-
(**c**)rude). The resolution drops off by ~80% between data sets.
51-
[Default is **l**]. Append **+f** to automatically select a lower
52-
resolution should the one requested not be available
53-
[abort if not found]. Alternatively, choose (**a**)uto to automatically
54-
select the best resolution given the chosen region. Note that because
55-
the coastlines differ in details a node in a mask file using one
56-
resolution is not guaranteed to remain inside [or outside] when a
57-
different resolution is selected.
55+
resolution
56+
Select the resolution of the coastline dataset to use. The available resolutions
57+
from highest to lowest are: ``"full"``, ``"high"``, ``"intermediate"``,
58+
``"low"``, and ``"crude"``, which drops by 80% between levels. Alternatively,
59+
choose ``"auto"`` to automatically select the most suitable resolution given the
60+
chosen region. Note that because the coastlines differ in details, a node in a
61+
mask file using one resolution is not guaranteed to remain inside [or outside]
62+
when a different resolution is selected. If ``None``, the low resolution is used
63+
by default.
5864
maskvalues : list
5965
Set the values that will be assigned to nodes, in the form of [*wet*, *dry*], or
6066
[*ocean*, *land*, *lake*, *island*, *pond*]. Default is ``[0, 1, 0, 1, 0]``
@@ -102,6 +108,8 @@ def grdlandmask(outgrid: PathLike | None = None, **kwargs) -> xr.DataArray | Non
102108
msg = "Both 'region' and 'spacing' must be specified."
103109
raise GMTInvalidInput(msg)
104110

111+
kwargs["D"] = kwargs.get("D", _parse_coastline_resolution(resolution))
112+
105113
with Session() as lib:
106114
with lib.virtualfile_out(kind="grid", fname=outgrid) as voutgrd:
107115
kwargs["G"] = voutgrd

pygmt/src/select.py

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use_alias,
1616
validate_output_table_type,
1717
)
18+
from pygmt.src._common import _parse_coastline_resolution
1819

1920
__doctest_skip__ = ["select"]
2021

@@ -23,7 +24,6 @@
2324
@use_alias(
2425
A="area_thresh",
2526
C="dist2pt",
26-
D="resolution",
2727
F="polygon",
2828
G="gridmask",
2929
I="reverse",
@@ -49,6 +49,9 @@ def select(
4949
data: PathLike | TableLike | None = None,
5050
output_type: Literal["pandas", "numpy", "file"] = "pandas",
5151
outfile: PathLike | None = None,
52+
resolution: Literal[
53+
"auto", "full", "high", "intermediate", "low", "crude", None
54+
] = None,
5255
**kwargs,
5356
) -> pd.DataFrame | np.ndarray | None:
5457
r"""
@@ -117,16 +120,6 @@ def select(
117120
<reference/file-formats.html#optional-segment-header-records>`
118121
*polygonfile*. For spherical polygons (lon, lat), make sure no
119122
consecutive points are separated by 180 degrees or more in longitude.
120-
resolution : str
121-
*resolution*\ [**+f**].
122-
Ignored unless ``mask`` is set. Selects the resolution of the coastline
123-
data set to use ((**f**)ull, (**h**)igh, (**i**)ntermediate, (**l**)ow,
124-
or (**c**)rude). The resolution drops off by ~80% between data sets.
125-
[Default is **l**]. Append (**+f**) to automatically select a lower
126-
resolution should the one requested not be available [Default is abort
127-
if not found]. Note that because the coastlines differ in details
128-
it is not guaranteed that a point will remain inside [or outside] when
129-
a different resolution is selected.
130123
gridmask : str
131124
Pass all locations that are inside the valid data area of the grid
132125
*gridmask*. Nodes that are outside are either NaN or zero.
@@ -155,6 +148,15 @@ def select(
155148
156149
[Default is s/k/s/k/s (i.e., s/k), which passes all points on dry
157150
land].
151+
resolution
152+
Ignored unless ``mask`` is set. Select the resolution of the coastline dataset
153+
to use. The available resolutions from highest to lowest are: ``"full"``,
154+
``"high"``, ``"intermediate"``, ``"low"``, and ``"crude"``, which drops by 80%
155+
between levels. Alternatively, choose ``"auto"`` to automatically select the
156+
most suitable resolution given the chosen region. Note that because the
157+
coastlines differ in details, a node in a mask file using one resolution is not
158+
guaranteed to remain inside [or outside] when a different resolution is
159+
selected. If ``None``, the low resolution is used by default.
158160
{region}
159161
{verbose}
160162
z_subregion : str or list
@@ -206,6 +208,8 @@ def select(
206208
>>> # longitudes 246 and 247 and latitudes 20 and 21
207209
>>> out = pygmt.select(data=ship_data, region=[246, 247, 20, 21])
208210
"""
211+
kwargs["D"] = kwargs.get("D", _parse_coastline_resolution(resolution))
212+
209213
output_type = validate_output_table_type(output_type, outfile=outfile)
210214

211215
column_names = None

pygmt/tests/test_coast.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def test_coast_world_mercator():
2929
projection="M15c",
3030
frame="af",
3131
land="#aaaaaa",
32-
resolution="c",
32+
resolution="crude",
3333
water="white",
3434
)
3535
return fig

0 commit comments

Comments
 (0)