-
Notifications
You must be signed in to change notification settings - Fork 234
Figure.legend: Add parameters position/width/height/line_spacing to specify legend position and properties #4046
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
Open
seisman
wants to merge
75
commits into
main
Choose a base branch
from
refactor/legend
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
75 commits
Select commit
Hold shift + click to select a range
eec0fb7
Initial implemention of the Position class
seisman 69d4d42
Merge branch 'main' into params/position
seisman 539f66f
Fix styling
seisman 97f015f
Add tests and improve docstrings
seisman 854804e
Add to API doc
seisman 6b55dde
Add an inline doctest
seisman 3d629cb
position is not required
seisman 576b822
Default to plotcoords
seisman f54bec9
Updates
seisman 5a2e20b
Merge branch 'main' into params/position
seisman 2c59b7f
Improve the checking in Figure.logo
seisman d0b62ec
Merge branch 'main' into params/position
seisman fe18c87
Improve docstrings
seisman 038161b
Improve docstrings
seisman a6e75bc
Improve docstrings
seisman 3ec8c06
Improve docstrings
seisman 339ce00
Improve docstrings
seisman 4d616de
Revert changes in logo.py
seisman ad9e0aa
Simplify tests
seisman b084e5f
Validate values
seisman d4ad6e0
type will be validated in the Alias System
seisman 7dc37bd
Use the image from the GMT docs
seisman bfecb2d
Fix width and alignment
seisman 18b90b3
Improve docstrings
seisman 6b1b5bc
Remove unneeded blank lines
seisman 1eae742
Improve docstrings
seisman 721b46f
Validate anchor code
seisman 669b16d
Merge branch 'main' into params/position
seisman 2a38111
Merge branch 'main' into params/position
seisman 0f9ed6c
offset can be a single value
seisman 7d1b076
Merge branch 'main' into params/position
seisman a779431
Merge branch 'main' into params/position
seisman 2a9cc92
Merge branch 'main' into params/position
seisman 10a0dfb
Use is_nonstr_iter to check the location parameter
seisman 6f1c2c4
Merge remote-tracking branch 'origin/params/position' into params/pos…
seisman c27213f
Fix a typo [skip ci]
seisman d47aaeb
Fix a typo [skip ci]
seisman 7fc6ffc
Fix the wrong logic in checking location
seisman d82f4ba
Add a tests for passing a single value to offset
seisman 5d29e66
Merge branch 'main' into params/position
seisman 563b5a1
Merge branch 'main' into params/position
seisman 0ec021b
Merge branch 'main' into params/position
seisman ff23ac8
Merge branch 'main' into params/position
seisman 620da52
Figure.legend: Refactor using the new alias system
seisman c9c4222
Rename position to refpoint
seisman 0064cde
Fix formatting
seisman d702ce6
Improve Figure.legend and tests
seisman ceb345e
Improve docstrings of width/height
seisman 9922da8
Add one test for width/height
seisman c917192
Fix checking of box
seisman cf11c13
Update the position argument in gallery examples
seisman 816d8b9
Rename spacing to line_spacing
seisman 7ff9f6a
Fix one more spacing to line_spacing
seisman 82426cd
Improve docstrings
seisman cdf6377
Fix typos
seisman 0c276dd
Remove the test_legend_position test because it's already covered in …
seisman 5bc0bb1
Check compatibility with old syntax
seisman 90c7ea2
Merge branch 'main' into params/position
seisman 9a19c1a
Merge branch 'main' into params/position
seisman ff6392d
Update pygmt/params/position.py
seisman 2310b22
Update pygmt/params/position.py [skip ci]
seisman a3185e8
Fix styling
seisman e153ebf
Rename type to cstype
seisman ed31e0f
Merge branch 'main' into params/position
seisman be36403
Merge branch 'params/position' into refactor/legend
seisman 5bf51be
Fix typos
seisman b45fa78
Fix CM to MC
seisman 3480fd1
Merge branch 'main' into params/position
seisman e0b2071
Merge branch 'params/position' into refactor/legend
seisman 36f2519
Fix typos
seisman b58c7ff
Merge branch 'main' into refactor/legend
seisman 19e00c4
Update pygmt/tests/test_legend.py [skip ci]
seisman 2f58300
Update pygmt/tests/test_legend.py [skip ci]
seisman ebe510e
Merge branch 'main' into refactor/legend
seisman 1b4b78d
Merge branch 'main' into refactor/legend
seisman File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,25 +9,21 @@ | |
| from pygmt._typing import PathLike | ||
| from pygmt.alias import Alias, AliasSystem | ||
| from pygmt.clib import Session | ||
| from pygmt.exceptions import GMTTypeError | ||
| from pygmt.helpers import ( | ||
| build_arg_list, | ||
| data_kind, | ||
| fmt_docstring, | ||
| is_nonstr_iter, | ||
| use_alias, | ||
| ) | ||
| from pygmt.params import Box | ||
| from pygmt.exceptions import GMTInvalidInput, GMTTypeError | ||
| from pygmt.helpers import build_arg_list, data_kind, fmt_docstring, is_nonstr_iter | ||
| from pygmt.params import Box, Position | ||
|
|
||
|
|
||
| @fmt_docstring | ||
| @use_alias(D="position") | ||
| def legend( # noqa: PLR0913 | ||
| self, | ||
| spec: PathLike | io.StringIO | None = None, | ||
| scale: float | None = None, | ||
| position="JTR+jTR+o0.2c", | ||
| position: Position | None = None, | ||
| width: float | str | None = None, | ||
| height: float | str | None = None, | ||
| line_spacing: float | None = None, | ||
| box: Box | bool = False, | ||
| scale: float | None = None, | ||
| projection: str | None = None, | ||
| region: Sequence[float | str] | str | None = None, | ||
| frame: str | Sequence[str] | bool = False, | ||
|
|
@@ -38,18 +34,23 @@ def legend( # noqa: PLR0913 | |
| perspective: float | Sequence[float] | str | bool = False, | ||
| **kwargs, | ||
| ): | ||
| r""" | ||
| """ | ||
| Plot a legend. | ||
|
|
||
| Makes legends that can be overlaid on maps. Reads specific | ||
| legend-related information from an input file, or automatically creates | ||
| legend entries from plotted symbols that have labels. Unless otherwise | ||
| noted, annotations will be made using the primary annotation font and | ||
| size in effect (i.e., :gmt-term:`FONT_ANNOT_PRIMARY`). | ||
| Makes legends that can be overlaid on plots. It reads specific legend-related | ||
| information from an input file, a :class:`io.StringIO` object, or automatically | ||
| creates legend entries from plotted symbols that have labels. Unless otherwise | ||
| noted, annotations will be made using the primary annotation font and size in effect | ||
| (i.e., :gmt-term:`FONT_ANNOT_PRIMARY`). | ||
|
|
||
| Full GMT docs at :gmt-docs:`legend.html`. | ||
|
|
||
| $aliases | ||
| **Aliases:** | ||
|
|
||
| .. hlist:: | ||
| :columns: 3 | ||
|
|
||
| - D = position, **+w**: width/height, **+l**: line_spacing | ||
| - B = frame | ||
| - F = box | ||
| - J = projection | ||
|
|
@@ -71,13 +72,26 @@ def legend( # noqa: PLR0913 | |
| - A :class:`io.StringIO` object containing the legend specification | ||
|
|
||
| See :gmt-docs:`legend.html` for the definition of the legend specification. | ||
| position : str | ||
| [**g**\|\ **j**\|\ **J**\|\ **n**\|\ **x**]\ *refpoint*\ | ||
| **+w**\ *width*\ [/*height*]\ [**+j**\ *justify*]\ [**+l**\ *spacing*]\ | ||
| [**+o**\ *dx*\ [/*dy*]]. | ||
| Define the reference point on the map for the legend. By default, uses | ||
| **JTR**\ **+jTR**\ **+o**\ 0.2c which places the legend at the Top Right corner | ||
| inside the map frame, with a 0.2 cm offset. | ||
| position | ||
| Specify the position of the legend on the plot. If not specified, defaults to | ||
| the top right corner inside the plot with a 0.2-cm offset. See | ||
| :class:`pygmt.params.Position` for details. | ||
| width | ||
| height | ||
| Specify the width and height of the legend box in plot coordinates (inches, cm, | ||
| etc.). If not given, the width and height are computed automatically based on | ||
| the contents of the legend specification. | ||
|
|
||
| If unit is ``%`` (percentage) then width is computed as that fraction of the | ||
| plot width. If height is given as percentage then height is recomputed as that | ||
| fraction of the legend width (not plot height). | ||
|
|
||
| **Note:** Currently, the automatic height calculation only works when legend | ||
| codes **D**, **H**, **L**, **S**, or **V** are used and that the number of | ||
| symbol columns (**N**) is 1. | ||
| line_spacing | ||
| Specify the line-spacing factor between legend entries in units of the current | ||
| font size [Default is 1.1]. | ||
| box | ||
| Draw a background box behind the legend. If set to ``True``, a simple | ||
| rectangular box is drawn using :gmt-term:`MAP_FRAME_PEN`. To customize the box | ||
|
|
@@ -95,12 +109,27 @@ def legend( # noqa: PLR0913 | |
| """ | ||
| self._activate_figure() | ||
|
|
||
| # Default position and box when not specified. | ||
| if kwargs.get("D") is None: | ||
| kwargs["D"] = position | ||
| if box is False and kwargs.get("F") is None: | ||
| # Prior PyGMT v0.17.0, 'position' can accept a raw GMT CLI string. Check for | ||
| # conflicts with other parameters. | ||
| if isinstance(position, str) and any( | ||
| v is not None for v in (width, height, line_spacing) | ||
| ): | ||
| msg = ( | ||
| "Parameter 'position' is given with a raw GMT command string, and conflicts " | ||
| "with parameters 'width', 'height', and 'line_spacing'." | ||
| ) | ||
| raise GMTInvalidInput(msg) | ||
|
|
||
| # Set default position if not specified. | ||
| if kwargs.get("D", position) is None: | ||
| position = Position("TR", anchor="TR", offset=0.2) | ||
| if kwargs.get("F", box) is False: | ||
| box = Box(pen="1p", fill="white") # Default box | ||
|
|
||
| # Set default width to 0 if height is given but width is not. | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The syntax is |
||
| if height is not None and width is None: | ||
| width = 0 | ||
|
|
||
| kind = data_kind(spec) | ||
| if kind not in {"empty", "file", "stringio"}: | ||
| raise GMTTypeError(type(spec)) | ||
|
|
@@ -110,6 +139,12 @@ def legend( # noqa: PLR0913 | |
| ) | ||
|
|
||
| aliasdict = AliasSystem( | ||
| D=[ | ||
| Alias(position, name="position"), | ||
| Alias(width, name="width", prefix="+w"), # +wwidth/height | ||
| Alias(height, name="height", prefix="/"), | ||
| Alias(line_spacing, name="line_spacing", prefix="+l"), | ||
| ], | ||
| F=Alias(box, name="box"), | ||
| S=Alias(scale, name="scale"), | ||
| ).add_common( | ||
|
|
||
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| outs: | ||
| - md5: 88cdea7af99c1edd19ade5b4c9b6c09e | ||
| size: 115141 | ||
| hash: md5 | ||
| path: test_legend_width_height.png |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
JTR+jTR+0.2cis equivalent tojTR+0.2(j means inside, J means outside), so I have change it toPosition("TR", offset=0.2).