Skip to content

Commit

Permalink
Allow text placement using position argument instead of x/y pairs
Browse files Browse the repository at this point in the history
Equivalent to using `-F+c` in GMT.
  • Loading branch information
weiji14 committed Jun 20, 2020
1 parent 46e98d7 commit 9e7a353
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 6 deletions.
44 changes: 38 additions & 6 deletions pygmt/base_plotting.py
Expand Up @@ -826,20 +826,24 @@ def text(
textfiles=None,
x=None,
y=None,
position=None,
text=None,
angle=None,
font=None,
justify=None,
**kwargs,
):
"""
Plot or typeset text on maps
Plot or typeset text strings of variable size, font type, and
orientation.
Used to be pstext.
Takes in textfile(s) or (x,y,text) triples as input.
Must provide at least one of the following combinations as input:
Must provide at least *textfiles* or *x*, *y*, and *text*.
- *textfiles*
- *x*, *y*, and *text*
- *position* and *text*
Full option list at :gmt-docs:`text.html`
Expand All @@ -853,6 +857,17 @@ def text(
x/y : float or 1d arrays
The x and y coordinates, or an array of x and y coordinates to plot
the text
position : str
Sets reference point on the map for the text by using x,y
coordinates extracted from *region* instead of providing them
through *x* and *y*. Specify with a two letter (order independent)
code, chosen from:
* Horizontal: L(eft), C(entre), R(ight)
* Vertical: T(op), M(iddle), B(ottom)
For example, position="TL" plots the text at the Upper Left corner
of the map.
text : str or 1d array
The text string, or an array of strings to plot on the figure
angle: int, float, str or bool
Expand Down Expand Up @@ -899,17 +914,34 @@ def text(
"""
kwargs = self._preprocess(**kwargs)

kind = data_kind(textfiles, x, y, text)
# Ensure inputs are either textfiles, x/y/text, or position/text
if position is None:
kind = data_kind(textfiles, x, y, text)
elif position is not None:
if x is not None or y is not None:
raise GMTInvalidInput(
"Provide either position only, or x/y pairs, not both"
)
kind = "vectors"

if kind == "vectors" and text is None:
raise GMTInvalidInput("Must provide text with x and y.")
raise GMTInvalidInput("Must provide text with x/y pairs or position")
if kind == "file":
for textfile in textfiles.split(" "): # ensure that textfile(s) exist
if not os.path.exists(textfile):
raise GMTInvalidInput(f"Cannot find the file: {textfile}")

if angle is not None or font is not None or justify is not None:
# Build the `-F` argument in gmt text.
if (
position is not None
or angle is not None
or font is not None
or justify is not None
):
if "F" not in kwargs.keys():
kwargs.update({"F": ""})
if position is not None and isinstance(position, str):
kwargs["F"] += f"+c{position}"
if angle is not None and isinstance(angle, (int, float, str)):
kwargs["F"] += f"+a{str(angle)}"
if font is not None and isinstance(font, str):
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions pygmt/tests/test_text.py
Expand Up @@ -97,6 +97,30 @@ def test_text_nonexistent_filename():
fig.text(region=[10, 70, -5, 10], textfiles=[POINTS_DATA, "notexist.txt"])


@pytest.mark.mpl_image_compare
def test_text_position_four_corners(region):
"""
Print text at four corners (top left/right, bottom left/right) of map.
"""
fig = Figure()
for position in ("TL", "TR", "BL", "BR"):
fig.text(
region=region, projection="x1c", frame="a", position=position, text=position
)
return fig


def test_text_xy_with_position_fails(region, projection):
"""
Run text by providing both x/y pairs and position arguments.
"""
fig = Figure()
with pytest.raises(GMTInvalidInput):
fig.text(
region=region, projection="x1c", x=1.2, y=2.4, position="MC", text="text"
)


@pytest.mark.mpl_image_compare
def test_text_angle_30(region, projection):
"""
Expand Down

0 comments on commit 9e7a353

Please sign in to comment.