-
Notifications
You must be signed in to change notification settings - Fork 235
Figure.coast: Improve parameters lakes/river_lakes for setting fill of lakes/river-lakes #4376
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -8,14 +8,64 @@ | |||||||||||
| from pygmt.alias import Alias, AliasSystem | ||||||||||||
| from pygmt.clib import Session | ||||||||||||
| from pygmt.exceptions import GMTInvalidInput | ||||||||||||
| from pygmt.helpers import args_in_kwargs, build_arg_list, fmt_docstring, use_alias | ||||||||||||
| 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 | ||||||||||||
|
|
@@ -74,18 +127,7 @@ def coast( # noqa: PLR0913 | |||||||||||
|
|
||||||||||||
| Parameters | ||||||||||||
| ---------- | ||||||||||||
| $projection | ||||||||||||
| $region | ||||||||||||
| *Required if this is the first plot command.* | ||||||||||||
| $area_thresh | ||||||||||||
| $frame | ||||||||||||
| 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"``, | ||||||||||||
|
|
@@ -96,6 +138,11 @@ def coast( # noqa: PLR0913 | |||||||||||
| Select filling of "dry" areas. | ||||||||||||
| water | ||||||||||||
| Select filling of "wet" areas. | ||||||||||||
| lakes | ||||||||||||
| river_lakes | ||||||||||||
|
Comment on lines
+141
to
+142
|
||||||||||||
| lakes | |
| river_lakes | |
| lakes, river_lakes : str |
Copilot
AI
Jan 29, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docstring says “If lakes is specified but river_lakes isn’t, river_lakes will use the same fill as lakes.” This is true for the new API when lakes is a plain fill (emits -C<fill>), but it’s not true for the documented backward-compatible modifier forms like lakes="blue+l" (which intentionally affects lakes only). Consider clarifying that the inheritance behavior applies when lakes is given without an explicit +l/+r modifier.
| "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``. | |
| "wet" areas set by the ``water`` parameter. If ``lakes`` is specified as a plain | |
| fill (without an explicit ``+l``/``+r`` modifier) but ``river_lakes`` isn't, | |
| ``river_lakes`` will use the same fill as ``lakes``. |
Copilot
AI
Jan 29, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The “required args” validation uses kwargs.get("C", lakes or river_lakes) is None. Using or means a falsy but explicitly provided lakes value (e.g., "") would be treated as not provided. Using an explicit None check (e.g., prefer lakes if lakes is not None else river_lakes) avoids truthiness pitfalls and matches how the other checks treat values.
| and kwargs.get("C", lakes or river_lakes) is None | |
| and kwargs.get("C", lakes if lakes is not None else river_lakes) is None |
Copilot
AI
Jan 29, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New behavior for lakes/river_lakes (including suffix selection and the backward-compatible lakes=["...+l", "...+r"] form and the mixed-usage error) isn’t covered by tests. pygmt/tests/test_coast.py currently tests required-args and dcw/resolution conflicts but has no assertions around -C argument building. Please add tests that exercise: (1) lakes="blue" emits -Cblue, (2) river_lakes="cyan" emits -Ccyan+r, (3) both emit two -C... entries with +l/+r, and (4) mixed list + river_lakes raises GMTInvalidInput.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_alias_option_Creturns a list ofAliasobjects where both entries have noprefix(onlysuffix). When users pass short-formC=...viakwargs,AliasSystem.mergewill build a warning/error message for a “sequence of aliases” that includes an empty “with optional parameters …” clause (seepygmt/alias.pyaround the_modifiersjoin). To avoid degraded/confusing messages forC, consider returning a singleAlias(with its value computed as a string or list like["blue+l", "cyan+r"]) instead of a list ofAliasobjects, or otherwise ensuring the merge message has meaningful content for this option.