-
Notifications
You must be signed in to change notification settings - Fork 244
Expand file tree
/
Copy pathtext.py
More file actions
221 lines (201 loc) · 7.4 KB
/
text.py
File metadata and controls
221 lines (201 loc) · 7.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
"""
text - Plot text on a figure.
"""
import numpy as np
from pygmt.clib import Session
from pygmt.exceptions import GMTInvalidInput
from pygmt.helpers import (
build_arg_string,
data_kind,
dummy_context,
fmt_docstring,
is_nonstr_iter,
kwargs_to_strings,
use_alias,
)
@fmt_docstring
@use_alias(
R="region",
J="projection",
B="frame",
C="clearance",
D="offset",
G="fill",
N="no_clip",
V="verbose",
W="pen",
X="xshift",
Y="yshift",
c="panel",
f="coltypes",
p="perspective",
t="transparency",
)
@kwargs_to_strings(
R="sequence",
textfiles="sequence_space",
angle="sequence_comma",
font="sequence_comma",
justify="sequence_comma",
c="sequence_comma",
p="sequence",
)
def text_(
self,
textfiles=None,
x=None,
y=None,
position=None,
text=None,
angle=None,
font=None,
justify=None,
**kwargs,
):
r"""
Plot or typeset text strings of variable size, font type, and orientation.
Must provide at least one of the following combinations as input:
- ``textfiles``
- ``x``/``y``, and ``text``
- ``position`` and ``text``
Full parameter list at :gmt-docs:`text.html`
{aliases}
Parameters
----------
textfiles : str or list
A text data file name, or a list of filenames containing 1 or more
records with (x, y[, angle, font, justify], 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``/``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
Set the angle measured in degrees counter-clockwise from
horizontal (e.g. 30 sets the text at 30 degrees). If no angle is
explicitly given (i.e. ``angle=True``) then the input to ``textfiles``
must have this as a column.
font : str or bool
Set the font specification with format *size*\ ,\ *font*\ ,\ *color*
where *size* is text size in points, *font* is the font to use, and
*color* sets the font color. For example,
``font="12p,Helvetica-Bold,red"`` selects a 12p, red, Helvetica-Bold
font. If no font info is explicitly given (i.e. ``font=True``), then
the input to ``textfiles`` must have this information in one of its
columns.
justify : str or bool
Set the alignment which refers to the part of the text string that
will be mapped onto the (x,y) point. Choose a 2 character
combination of **L**, **C**, **R** (for left, center, or right) and
**T**, **M**, **B** for top, middle, or bottom. E.g., **BL** for lower
left. If no justification is explicitly given (i.e. ``justify=True``),
then the input to ``textfiles`` must have this as a column.
{J}
{R}
clearance : str
[*dx/dy*][**+to**\|\ **O**\|\ **c**\|\ **C**].
Adjust the clearance between the text and the surrounding box
[Default is 15% of the font size]. Only used if ``pen`` or ``fill`` are
specified. Append the unit you want (*c* for cm, *i* for inch, or *p*
for point; if not given we consult **PROJ_LENGTH_UNIT**) or *%* for a
percentage of the font size. Optionally, use modifier **+t** to set
the shape of the textbox when using ``fill`` and/or ``pen``. Append
lower case **o** to get a straight rectangle [Default is **o**]. Append
upper case **O** to get a rounded rectangle. In paragraph mode
(*paragraph*) you can also append lower case **c** to get a concave
rectangle or append upper case **C** to get a convex rectangle.
fill : str
Sets the shade or color used for filling the text box [Default is
no fill].
offset : str
[**j**\|\ **J**]\ *dx*\[/*dy*][**+v**\[*pen*]].
Offsets the text from the projected (x,y) point by *dx*,\ *dy* [0/0].
If *dy* is not specified then it is set equal to *dx*. Use **j** to
offset the text away from the point instead (i.e., the text
justification will determine the direction of the shift). Using
**J** will shorten diagonal offsets at corners by sqrt(2).
Optionally, append **+v** which will draw a line from the original
point to the shifted point; append a pen to change the attributes
for this line.
pen : str
Sets the pen used to draw a rectangle around the text string
(see ``clearance``) [Default is width = default, color = black,
style = solid].
no_clip : bool
Do NOT clip text at map boundaries [Default is will clip].
{V}
{XY}
{c}
{f}
{p}
{t}
"""
# pylint: disable=too-many-locals
# pylint: disable=too-many-branches
kwargs = self._preprocess(**kwargs) # pylint: disable=protected-access
# Ensure inputs are either textfiles, x/y/text, or position/text
if position is None:
kind = data_kind(textfiles, x, y, text)
else:
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/y pairs or position")
# Build the -F option in gmt text.
if "F" not in kwargs.keys() and (
(
position is not None
or angle is not None
or font is not None
or justify is not None
)
):
kwargs.update({"F": ""})
if angle is True:
kwargs["F"] += "+a"
elif isinstance(angle, (int, float, str)):
kwargs["F"] += f"+a{str(angle)}"
if font is True:
kwargs["F"] += "+f"
elif isinstance(font, str):
kwargs["F"] += f"+f{font}"
if justify is True:
kwargs["F"] += "+j"
elif isinstance(justify, str):
kwargs["F"] += f"+j{justify}"
if isinstance(position, str):
kwargs["F"] += f'+c{position}+t"{text}"'
extra_arrays = []
# If an array of transparency is given, GMT will read it from
# the last numerical column per data record.
if "t" in kwargs and is_nonstr_iter(kwargs["t"]):
extra_arrays.append(kwargs["t"])
kwargs["t"] = ""
with Session() as lib:
file_context = dummy_context(textfiles) if kind == "file" else ""
if kind == "vectors":
if position is not None:
file_context = dummy_context("")
else:
file_context = lib.virtualfile_from_vectors(
np.atleast_1d(x),
np.atleast_1d(y),
*extra_arrays,
# text must be in str type, see issue #706
np.atleast_1d(text).astype(str),
)
with file_context as fname:
arg_str = " ".join([fname, build_arg_string(kwargs)])
lib.call_module("text", arg_str)