From 73cec87578492b940bc78c1199377d646fe3e98f Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Tue, 9 Dec 2025 14:46:15 +0800 Subject: [PATCH 1/4] Figure.coast: Improve parameters lakes/river_lakes for setting fill of lakes/river-lakes --- pygmt/src/coast.py | 76 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 65 insertions(+), 11 deletions(-) diff --git a/pygmt/src/coast.py b/pygmt/src/coast.py index db4fa4050e8..2787bf47c92 100644 --- a/pygmt/src/coast.py +++ b/pygmt/src/coast.py @@ -7,15 +7,65 @@ from pygmt.alias import Alias, AliasSystem from pygmt.clib import Session -from pygmt.exceptions import GMTParameterError -from pygmt.helpers import args_in_kwargs, build_arg_list, fmt_docstring, use_alias +from pygmt.exceptions import GMTInvalidInput, GMTParameterError +from pygmt.helpers import ( + args_in_kwargs, + build_arg_list, + fmt_docstring, + is_nonstr_iter, + use_alias, +) from pygmt.params import Box __doctest_skip__ = ["coast"] +def _alias_option_C(lakes=None, river_lakes=None): # noqa: N802 + """ + Helper function to create the alias list for the -C option. + + Example + ------- + >>> def parse(**kwargs): + ... return AliasSystem(C=_alias_option_C(**kwargs)).get("C") + >>> parse() + >>> parse(lakes="blue") + 'blue' + >>> parse(river_lakes="cyan") + 'cyan+r' + >>> parse(lakes="blue", river_lakes="cyan") + ['blue+l', 'cyan+r'] + + >>> # Check for backward compatibility + >>> parse(lakes="blue+l") + 'blue+l' + >>> parse(lakes="cyan+r") + 'cyan+r' + >>> parse(lakes=["blue+l", "cyan+r"]) + ['blue+l', 'cyan+r'] + + >>> # Check for mixed usage error + >>> parse(lakes=["blue+l", "cyan+r"], river_lakes="cyan") + Traceback (most recent call last): + ... + pygmt.exceptions.GMTInvalidInput: Parameter 'lakes' is given with a list; ... + """ + # Check for backward compatibility. + if is_nonstr_iter(lakes): # Old syntax: lakes is a list of strings. + if river_lakes is not None: + msg = "Parameter 'lakes' is given with a list; 'river_lakes' must be None." + raise GMTInvalidInput(msg) + return Alias(lakes, name="lakes") # Return as is. + + # If only 'lakes' is specified, no suffix is needed. + return [ + Alias(lakes, name="lakes", suffix="+l" if river_lakes is not None else ""), + Alias(river_lakes, name="river_lakes", suffix="+r"), + ] + + @fmt_docstring -@use_alias(A="area_thresh", C="lakes", E="dcw") +@use_alias(A="area_thresh", E="dcw") def coast( # noqa: PLR0913 self, resolution: Literal[ @@ -26,6 +76,8 @@ def coast( # noqa: PLR0913 rivers: int | str | Sequence[int | str] | None = None, borders: int | str | Sequence[int | str] | None = None, shorelines: bool | str | Sequence[int | str] = False, + lakes: str | None = None, + river_lakes: str | None = None, map_scale: str | None = None, box: Box | bool = False, projection: str | None = None, @@ -59,6 +111,7 @@ def coast( # noqa: PLR0913 $aliases - B = frame + - C = lakes, river_lakes - D = resolution - F = box - G = land @@ -75,13 +128,6 @@ def coast( # noqa: PLR0913 Parameters ---------- $area_thresh - lakes : str or list - *fill*\ [**+l**\|\ **+r**]. - Set the shade, color, or pattern for lakes and river-lakes. The - default is the fill chosen for "wet" areas set by the ``water`` - parameter. Optionally, specify separate fills by appending - **+l** for lakes or **+r** for river-lakes, and passing multiple - strings in a list. resolution Select the resolution of the coastline dataset to use. The available resolutions from highest to lowest are: ``"full"``, ``"high"``, ``"intermediate"``, @@ -92,6 +138,11 @@ def coast( # noqa: PLR0913 Select filling of "dry" areas. water Select filling of "wet" areas. + lakes + river_lakes + Select filling of lakes and river-lakes. If not specified, will use the fill for + "wet" areas set by the ``water`` parameter. If ``lakes`` is specified but + ``river_lakes`` isn't, ``river_lakes`` will use the same fill as ``lakes``. rivers Draw rivers. Specify the type of rivers to draw, and optionally append a pen attribute, in the format *river*\ /*pen* [Default pen is @@ -239,7 +290,8 @@ def coast( # noqa: PLR0913 and kwargs.get("I", rivers) is None and kwargs.get("N", borders) is None and kwargs.get("W", shorelines) is False - and not args_in_kwargs(args=["C", "E", "Q"], kwargs=kwargs) + and kwargs.get("C", lakes or river_lakes) is None + and not args_in_kwargs(args=["E", "Q"], kwargs=kwargs) ): raise GMTParameterError( at_least_one=[ @@ -249,12 +301,14 @@ def coast( # noqa: PLR0913 "borders", "shorelines", "lakes", + "river_lakes", "dcw", "Q", ] ) aliasdict = AliasSystem( + C=_alias_option_C(lakes=lakes, river_lakes=river_lakes), D=Alias( resolution, name="resolution", From 7a675de780baff9f6a84bc206d262028afeb95d6 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sun, 17 May 2026 18:50:30 +0800 Subject: [PATCH 2/4] Let lakes='blue' set lake fill only --- pygmt/src/coast.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pygmt/src/coast.py b/pygmt/src/coast.py index 397de6d8782..cfeeed4bfe2 100644 --- a/pygmt/src/coast.py +++ b/pygmt/src/coast.py @@ -30,7 +30,7 @@ def _alias_option_C(lakes=None, river_lakes=None): # noqa: N802 ... return AliasSystem(C=_alias_option_C(**kwargs)).get("C") >>> parse() >>> parse(lakes="blue") - 'blue' + 'blue+l' >>> parse(river_lakes="cyan") 'cyan+r' >>> parse(lakes="blue", river_lakes="cyan") @@ -57,9 +57,8 @@ def _alias_option_C(lakes=None, river_lakes=None): # noqa: N802 raise GMTInvalidInput(msg) return Alias(lakes, name="lakes") # Return as is. - # If only 'lakes' is specified, no suffix is needed. return [ - Alias(lakes, name="lakes", suffix="+l" if river_lakes is not None else ""), + Alias(lakes, name="lakes", suffix="+l"), Alias(river_lakes, name="river_lakes", suffix="+r"), ] From 70d7f2f26c8eab7d80c5ff4c07db6711ab54402d Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sun, 17 May 2026 18:54:59 +0800 Subject: [PATCH 3/4] Fix the docstrings --- pygmt/src/coast.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pygmt/src/coast.py b/pygmt/src/coast.py index cfeeed4bfe2..930db7c37dc 100644 --- a/pygmt/src/coast.py +++ b/pygmt/src/coast.py @@ -139,9 +139,9 @@ def coast( # noqa: PLR0913 Select filling of "wet" areas. lakes river_lakes - Select filling of lakes and river-lakes. If not specified, will use the fill for - "wet" areas set by the ``water`` parameter. If ``lakes`` is specified but - ``river_lakes`` isn't, ``river_lakes`` will use the same fill as ``lakes``. + Select filling of lakes or river-lakes, respectively. If not specified, will use + the fill for "wet" areas set by the ``water`` parameter. If only one of the two + parameters is specified, the other will be set to unfilled (transparent). rivers Draw rivers. Specify the type of rivers to draw, and optionally append a pen attribute, in the format *river*\ /*pen* [Default pen is From e7f22f9c280152d4039f0d284a93bf457cb283fc Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sun, 17 May 2026 19:02:25 +0800 Subject: [PATCH 4/4] Fix backward compatibility --- pygmt/src/coast.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pygmt/src/coast.py b/pygmt/src/coast.py index 930db7c37dc..bbde2931efe 100644 --- a/pygmt/src/coast.py +++ b/pygmt/src/coast.py @@ -58,7 +58,7 @@ def _alias_option_C(lakes=None, river_lakes=None): # noqa: N802 return Alias(lakes, name="lakes") # Return as is. return [ - Alias(lakes, name="lakes", suffix="+l"), + Alias(lakes, name="lakes", suffix="+l" if "+" not in str(lakes) else ""), Alias(river_lakes, name="river_lakes", suffix="+r"), ]