Skip to content

Commit 5165727

Browse files
committed
Refactor with the _parse_position function
1 parent 698cb64 commit 5165727

File tree

1 file changed

+31
-30
lines changed

1 file changed

+31
-30
lines changed

pygmt/src/legend.py

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,20 @@
66
from collections.abc import Sequence
77
from typing import Literal
88

9-
from pygmt._typing import PathLike
9+
from pygmt._typing import AnchorCode, PathLike
1010
from pygmt.alias import Alias, AliasSystem
1111
from pygmt.clib import Session
12-
from pygmt.exceptions import GMTInvalidInput, GMTTypeError
12+
from pygmt.exceptions import GMTTypeError
1313
from pygmt.helpers import build_arg_list, data_kind, fmt_docstring, is_nonstr_iter
1414
from pygmt.params import Box, Position
15+
from pygmt.src._common import _parse_position
1516

1617

1718
@fmt_docstring
1819
def legend( # noqa: PLR0913
1920
self,
2021
spec: PathLike | io.StringIO | None = None,
21-
position: Position | None = None,
22+
position: Position | Sequence[float | str] | AnchorCode | None = None,
2223
width: float | str | None = None,
2324
height: float | str | None = None,
2425
line_spacing: float | None = None,
@@ -30,8 +31,8 @@ def legend( # noqa: PLR0913
3031
verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"]
3132
| bool = False,
3233
panel: int | Sequence[int] | bool = False,
33-
transparency: float | None = None,
3434
perspective: float | Sequence[float] | str | bool = False,
35+
transparency: float | None = None,
3536
**kwargs,
3637
):
3738
"""
@@ -73,25 +74,31 @@ def legend( # noqa: PLR0913
7374
7475
See :gmt-docs:`legend.html` for the definition of the legend specification.
7576
position
76-
Specify the position of the legend on the plot. If not specified, defaults to
77-
the top right corner inside the plot with a 0.2-cm offset. See
78-
:class:`pygmt.params.Position` for details.
77+
Position of the legend on the plot. It can be specified in multiple ways:
78+
79+
- A :class:`pygmt.params.Position` object to fully control the reference point,
80+
anchor point, and offset.
81+
- A sequence of two values representing the x and y coordinates in plot
82+
coordinates, e.g., ``(1, 2)`` or ``("1c", "2c")``.
83+
- A :doc:`2-character justification code </techref/justification_codes>` for a
84+
position inside the plot, e.g., ``"TL"`` for Top Left corner inside the plot.
85+
86+
If not specified, defaults to the top right corner inside the plot with a 0.2-cm
87+
offset.
7988
width
8089
height
81-
Specify the width and height of the legend box in plot coordinates (inches, cm,
82-
etc.). If not given, the width and height are computed automatically based on
83-
the contents of the legend specification.
84-
85-
If unit is ``%`` (percentage) then width is computed as that fraction of the
86-
plot width. If height is given as percentage then height is recomputed as that
90+
Width and height of the legend box. If not given, the width and height are
91+
computed automatically based on the contents of the legend specification. If
92+
unit is ``%`` (percentage) then width is computed as that fraction of the plot
93+
width. If height is given as percentage then height is recomputed as that
8794
fraction of the legend width (not plot height).
8895
8996
**Note:** Currently, the automatic height calculation only works when legend
9097
codes **D**, **H**, **L**, **S**, or **V** are used and that the number of
9198
symbol columns (**N**) is 1.
9299
line_spacing
93-
Specify the line-spacing factor between legend entries in units of the current
94-
font size [Default is 1.1].
100+
The line-spacing factor between legend entries in units of the current font size
101+
[Default is 1.1].
95102
box
96103
Draw a background box behind the legend. If set to ``True``, a simple
97104
rectangular box is drawn using :gmt-term:`MAP_FRAME_PEN`. To customize the box
@@ -109,22 +116,16 @@ def legend( # noqa: PLR0913
109116
"""
110117
self._activate_figure()
111118

112-
# Prior PyGMT v0.17.0, 'position' can accept a raw GMT CLI string. Check for
113-
# conflicts with other parameters.
114-
if isinstance(position, str) and any(
115-
v is not None for v in (width, height, line_spacing)
116-
):
117-
msg = (
118-
"Parameter 'position' is given with a raw GMT command string, and conflicts "
119-
"with parameters 'width', 'height', and 'line_spacing'."
120-
)
121-
raise GMTInvalidInput(msg)
119+
# Set default box if both position and box are not given.
120+
# The default position will be set later in _parse_position().
121+
if kwargs.get("D", position) is None and kwargs.get("F", box) is False:
122+
box = Box(pen="1p", fill="white")
122123

123-
# Set default position if not specified.
124-
if kwargs.get("D", position) is None:
125-
position = Position("TR", anchor="TR", offset=0.2)
126-
if kwargs.get("F", box) is False:
127-
box = Box(pen="1p", fill="white") # Default box
124+
position = _parse_position(
125+
position,
126+
kwdict={"width": width, "height": height, "line_spacing": line_spacing},
127+
default=Position("TR", offset=0.2), # Default to TR.
128+
)
128129

129130
# Set default width to 0 if height is given but width is not.
130131
if height is not None and width is None:

0 commit comments

Comments
 (0)