Skip to content

Commit f339678

Browse files
Tutorial "Plotting text": Rewrite to improve structure, add parameters, add list input (#2760)
1 parent 62872d3 commit f339678

File tree

1 file changed

+179
-94
lines changed

1 file changed

+179
-94
lines changed

examples/tutorials/basics/text.py

Lines changed: 179 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
Plotting text
33
=============
44
5-
It is often useful to add annotations to a plot. This is handled by
6-
:meth:`pygmt.Figure.text`.
5+
It is often useful to add text annotations to a plot or map. This is handled by the
6+
:meth:`pygmt.Figure.text` method of the :class:`pygmt.Figure` class.
77
"""
88

99
# %%
@@ -12,146 +12,231 @@
1212
import pygmt
1313

1414
# %%
15-
# Basic map annotation
16-
# --------------------
15+
# Adding a single text label
16+
# --------------------------
1717
#
18-
# Text annotations can be added to a map using the :meth:`pygmt.Figure.text`
19-
# method of the :class:`pygmt.Figure` class.
20-
#
21-
# Here we create a simple map and add an annotation using the ``text``, ``x``,
22-
# and ``y`` parameters to specify the annotation text and position in the
23-
# projection frame. ``text`` accepts *str* types, while ``x`` and ``y``
24-
# accept either *int* or *float* numbers, or a list/array of numbers.
18+
# To add a single text label to a plot, use the ``text`` and ``x`` and ``y`` parameters
19+
# to specify the text and position.
2520

2621
fig = pygmt.Figure()
27-
with pygmt.config(MAP_FRAME_TYPE="plain"):
28-
fig.basemap(region=[108, 120, -5, 8], projection="M20c", frame="a")
29-
fig.coast(land="black", water="skyblue")
30-
31-
# Plot text annotations using single arguments
32-
fig.text(text="SOUTH CHINA SEA", x=112, y=6)
33-
34-
# Plot text annotations using lists of arguments
35-
fig.text(text=["CELEBES SEA", "JAVA SEA"], x=[119, 112], y=[3.25, -4.6])
36-
22+
fig.basemap(region=[-5, 5, -5, 5], projection="X5c", frame=True)
23+
fig.text(x=0, y=0, text="My text")
3724
fig.show()
3825

3926

4027
# %%
41-
# Changing font style
42-
# -------------------
28+
# Adjusting the text label
29+
# ------------------------
4330
#
44-
# The size, family/weight, and color of an annotation can be specified using
45-
# the ``font`` parameter.
31+
# There are several optional parameters to adjust the text label:
4632
#
47-
# A list of all recognized fonts can be found at
48-
# :gmt-docs:`PostScript Fonts Used by GMT <reference/postscript-fonts.html>`,
49-
# including details of how to use non-default fonts.
33+
# * ``font``: Sets the size, family/weight, and color of the font for the text.
34+
# A list of all recognized fonts can be found at
35+
# :gmt-docs:`PostScript Fonts Used by GMT <reference/postscript-fonts.html>`,
36+
# including details of how to use non-default fonts.
37+
# * ``angle``: Specifies the rotation of the text. It is measured counter-clockwise
38+
# from the horizontal in degrees.
39+
# * ``justify``: Defines the anchor point of the bounding box for the text. It is
40+
# specified by a two-letter (order independent) code, chosen from:
41+
#
42+
# * Vertical: **T**\(op), **M**\(iddle), **B**\(ottom)
43+
# * Horizontal: **L**\(eft), **C**\(entre), **R**\(ight)
44+
#
45+
# * ``offset``: Shifts the text relatively to the reference point.
5046

5147
fig = pygmt.Figure()
52-
with pygmt.config(MAP_FRAME_TYPE="plain"):
53-
fig.basemap(region=[108, 120, -5, 8], projection="M20c", frame="a")
54-
fig.coast(land="black", water="skyblue")
5548

56-
# Customize the font style
57-
fig.text(text="BORNEO", x=114.0, y=0.5, font="22p,Helvetica-Bold,white")
49+
# -----------------------------------------------------------------------------
50+
# Left: "font", "angle", and "offset" parameters
51+
fig.basemap(region=[-5, 5, -5, 5], projection="X5c", frame="rtlb")
52+
53+
# Change font size, family/weight, color of the text
54+
fig.text(x=0, y=3, text="my text", font="12p,Helvetica-Bold,blue")
55+
56+
# Rotate the text by 30 degrees counter-clockwise from the horizontal
57+
fig.text(x=0, y=0, text="my text", angle=30)
58+
59+
# Plot marker and text label for reference
60+
fig.plot(x=0, y=-3, style="s0.2c", fill="darkorange", pen="0.7p,darkgray")
61+
fig.text(x=0, y=-3, text="my text")
62+
# Shift the text label relatively to the position given via the x and y parameters
63+
# by 1 centimeter to the right (positive x direction) and 0.5 centimeters down
64+
# (negative y direction)
65+
fig.text(x=0, y=-3, text="my text", offset="1c/-0.5c")
66+
67+
fig.shift_origin(xshift="w+0.5c")
68+
69+
# -----------------------------------------------------------------------------
70+
# Right: "justify" parameter
71+
fig.basemap(region=[-1, 1, -1, 1], projection="X5c", frame="rtlb")
72+
73+
# Plot markers for reference
74+
fig.plot(
75+
x=[-0.5, 0, 0.5, -0.5, 0, 0.5, -0.5, 0, 0.5],
76+
y=[0.5, 0.5, 0.5, 0, 0, 0, -0.5, -0.5, -0.5],
77+
style="s0.2c",
78+
fill="darkorange",
79+
pen="0.7p,darkgray",
80+
)
81+
82+
# Plot text labels at the x and y positions of the markers while varying the anchor
83+
# point via the justify parameter
84+
fig.text(x=-0.5, y=0.5, text="TL", justify="TL") # TopLeft
85+
fig.text(x=0, y=0.5, text="TM", justify="TC") # TopCenter
86+
fig.text(x=0.5, y=0.5, text="TR", justify="TR") # TopRight
87+
fig.text(x=-0.5, y=0, text="ML", justify="ML") # MiddleLeft
88+
fig.text(x=0, y=0, text="MC", justify="MC") # MiddleCenter
89+
fig.text(x=0.5, y=0, text="MR", justify="MR") # MiddleRight
90+
fig.text(x=-0.5, y=-0.5, text="BL", justify="BL") # BottomLeft
91+
fig.text(x=0, y=-0.5, text="BC", justify="BC") # BottomCenter
92+
fig.text(x=0.5, y=-0.5, text="BR", justify="BR") # BottomRight
5893

5994
fig.show()
6095

6196

6297
# %%
63-
# Plotting from a text file
64-
# -------------------------
98+
# Adding a text box
99+
# -----------------
65100
#
66-
# It is also possible to add annotations from a file containing ``x``, ``y``,
67-
# and ``text`` columns. Here we give a complete example.
101+
# There are different optional parameters to add and customize a text box:
102+
#
103+
# * ``fill``: Fills the text box with a color.
104+
# * ``pen``: Outlines the text box.
105+
# * ``clearance``: Adds margins in x and y directions between the text and the outline
106+
# of the text box. Can be used to get a text box with rounded edges.
68107

69108
fig = pygmt.Figure()
70-
with pygmt.config(MAP_FRAME_TYPE="plain"):
71-
fig.basemap(region=[108, 120, -5, 8], projection="M20c", frame="a")
72-
fig.coast(land="black", water="skyblue")
73-
74-
# Create space-delimited file
75-
with Path("examples.txt").open(mode="w") as f:
76-
f.write("114 0.5 0 22p,Helvetica-Bold,white CM BORNEO\n")
77-
f.write("119 3.25 0 12p,Helvetica-Bold,black CM CELEBES SEA\n")
78-
f.write("112 -4.6 0 12p,Helvetica-Bold,black CM JAVA SEA\n")
79-
f.write("112 6 40 12p,Helvetica-Bold,black CM SOUTH CHINA SEA\n")
80-
f.write("119.12 7.25 -40 12p,Helvetica-Bold,black CM SULU SEA\n")
81-
f.write("118.4 -1 65 12p,Helvetica-Bold,black CM MAKASSAR STRAIT\n")
82-
83-
# Plot region names / sea names from a text file, where
84-
# the longitude (x) and latitude (y) coordinates are in the first two columns.
85-
# Setting angle/font/justify to True will indicate that those columns are
86-
# present in the text file too (Note: must be in that order!).
87-
# Finally, the text to be printed will be in the last column
88-
fig.text(textfiles="examples.txt", angle=True, font=True, justify=True)
89109

90-
# Cleanups
91-
Path("examples.txt").unlink()
110+
fig.basemap(region=[-5, 5, -5, 5], projection="X5c", frame="rtlb")
111+
112+
# Add a box with a fill in green color
113+
fig.text(x=0, y=3, text="My text", fill="green")
114+
115+
# Add box with a seagreen, 1-point thick, solid outline
116+
fig.text(x=0, y=1, text="My text", pen="1p,seagreen,solid")
117+
118+
# Add margins between the text and the outline of the text box of 0.1
119+
# centimeters in x direction and 0.2 centimeters in y direction
120+
fig.text(x=0, y=-1, text="My text", pen="1p,seagreen,dashed", clearance="0.1c/0.2c")
121+
122+
# Get rounded edges by passing "+tO" to the "clearance" parameter
123+
fig.text(x=0, y=-3, text="My text", pen="1p,seagreen,solid", clearance="0.2c/0.2c+tO")
92124

93125
fig.show()
94126

95127

96128
# %%
97-
# ``justify`` parameter
98-
# ---------------------
99-
#
100-
# ``justify`` is used to define the anchor point for the bounding box for text
101-
# being added to a plot. The following code segment demonstrates the
102-
# positioning of the anchor point relative to the text.
129+
# Adding multiple text labels with individual configurations
130+
# ----------------------------------------------------------
103131
#
104-
# The anchor point is specified with a two-letter (order independent) code,
105-
# chosen from:
106-
#
107-
# * Vertical anchor: **T**\(op), **M**\(iddle), **B**\(ottom)
108-
# * Horizontal anchor: **L**\(eft), **C**\(entre), **R**\(ight)
132+
# To add multiple text labels with individual ``font``, ``angle``, and ``justify``,
133+
# one can provide lists with the corresponding arguments.
109134

110135
fig = pygmt.Figure()
111-
fig.basemap(region=[0, 3, 0, 3], projection="X10c", frame=["WSne", "af0.5g"])
112-
for position in ("TL", "TC", "TR", "ML", "MC", "MR", "BL", "BC", "BR"):
113-
fig.text(
114-
text=position,
115-
position=position,
116-
font="28p,Helvetica-Bold,black",
117-
justify=position,
118-
)
136+
fig.basemap(region=[-5, 5, -5, 5], projection="X5c", frame=True)
137+
138+
fig.text(
139+
x=[0, 0, 0],
140+
y=[3, 2, -2],
141+
font=["5p,Helvetica,black", "5p,Helvetica,blue", "6p,Courier-Bold,red"],
142+
angle=[0, 0, 30],
143+
justify=["CM", "LT", "CM"],
144+
text=[
145+
"black text with justify='CM'",
146+
"blue text with justify='LT'",
147+
"red text with angle=30",
148+
],
149+
)
150+
119151
fig.show()
120152

121153

122154
# %%
123-
# ``angle`` parameter
124-
# -------------------
155+
# Using an external input file
156+
# ----------------------------
125157
#
126-
# ``angle`` is an optional parameter used to specify the counter-clockwise
127-
# rotation in degrees of the text from the horizontal.
158+
# It is also possible to add text labels via an external input file containing ``x``,
159+
# ``y``, and ``text`` columns. Addionaly, columns to set the ``angle``, ``front``,
160+
# and ``justify`` parameters can be provided. Here, we give a complete example.
128161

129162
fig = pygmt.Figure()
130-
fig.basemap(region=[0, 4, 0, 4], projection="X5c", frame="WSen")
131-
for i in range(0, 360, 30):
132-
fig.text(text=f"` {i}@.", x=2, y=2, justify="LM", angle=i)
163+
fig.basemap(region=[108, 121, -5, 8], projection="M10c", frame="a2f1")
164+
fig.coast(land="darkgray", water="steelblue", shorelines="1/0.1p,gray30")
165+
166+
# Create space-delimited file with region / sea names:
167+
# - longitude (x) and latitude (y) coordinates are in the first two columns
168+
# - angle, font, and justify muss be present in this order in the next three columns
169+
# - the text to be printed is given in the last column
170+
with Path.open("examples.txt", "w") as f:
171+
f.write("114.00 0.50 0 15p,Helvetica-Bold,white CM BORNEO\n")
172+
f.write("119.00 3.25 0 8p,Helvetica-Bold,black CM CELEBES SEA\n")
173+
f.write("112.00 -4.60 0 8p,Helvetica-Bold,black CM JAVA SEA\n")
174+
f.write("112.00 6.00 40 8p,Helvetica-Bold,black CM SOUTH CHINA SEA\n")
175+
f.write("119.12 7.25 -40 8p,Helvetica-Bold,black CM SULU SEA\n")
176+
f.write("118.40 -1.00 65 8p,Helvetica-Bold,black CM MAKASSAR STRAIT\n")
177+
178+
# Setting the angle, font, and justify parameters to True indicates that those columns
179+
# are present in the text file
180+
fig.text(textfiles="examples.txt", angle=True, font=True, justify=True)
181+
182+
# Cleanups
183+
Path("examples.txt").unlink()
184+
133185
fig.show()
134186

135187

136188
# %%
137-
# ``fill`` parameter
138-
# ------------------
189+
# Using the position parameter
190+
# ----------------------------
191+
#
192+
# Instead of using the ``x`` and ``y`` parameters, the ``position`` parameter can be
193+
# specified to set the reference point for the text on the plot. As for the ``justify``
194+
# parameter, the ``position`` parameter is specified by a two-letter (order independent)
195+
# code, chosen from:
139196
#
140-
# ``fill`` is used to set the fill color of the area surrounding the text.
197+
# * Vertical: **T**\(op), **M**\(iddle), **B**\(ottom)
198+
# * Horizontal: **L**\(eft), **C**\(entre), **R**\(ight)
199+
#
200+
# This can be helpful to add a tag to a subplot or text labels out of the plot or map
201+
# frame, e.g., for depth slices.
141202

142203
fig = pygmt.Figure()
143-
fig.basemap(region=[0, 1, 0, 1], projection="X5c", frame="WSen")
144-
fig.text(text="Green", x=0.5, y=0.5, fill="green")
204+
205+
# -----------------------------------------------------------------------------
206+
# Left: Add a tag to a subplot
207+
fig.basemap(region=[-5, 5, -5, 5], projection="X5c", frame=["WStr", "af"])
208+
209+
fig.text(
210+
text="(a)",
211+
position="TL", # Top Left
212+
justify="TL", # Top Left
213+
offset="0.1c/-0.1c",
214+
)
215+
216+
fig.shift_origin(xshift="w+1c")
217+
218+
# -----------------------------------------------------------------------------
219+
# Right: Add a text label outside of the plot or map frame
220+
fig.basemap(region=[-30, 30, 10, 60], projection="L0/35/23/47/5c", frame=["wSnE", "af"])
221+
222+
fig.text(
223+
text="@@100 km", # "@@" gives "@" in GMT or PyGMT
224+
position="TC", # Top Center
225+
justify="MC", # Middle Center
226+
offset="0c/0.2c",
227+
no_clip=True, # Allow plotting outside of the map or plot frame
228+
)
229+
145230
fig.show()
146231

147232

148233
# %%
149234
# Advanced configuration
150235
# ----------------------
151236
#
152-
# For crafting more advanced styles, including using special symbols and
153-
# other character sets, be sure to check out the GMT documentation
154-
# at :gmt-docs:`text.html` and also the GMT Technical Reference at
155-
# :gmt-docs:`reference/features.html#placement-of-text`. Good luck!
237+
# For crafting more advanced styles, including using special symbols and other character
238+
# sets, be sure to check out the GMT documentation at :gmt-docs:`text.html` and also the
239+
# Technical References at :gmt-docs:`reference/features.html#placement-of-text`. Good
240+
# luck!
156241

157-
# sphinx_gallery_thumbnail_number = 3
242+
# sphinx_gallery_thumbnail_number = 4

0 commit comments

Comments
 (0)