Note
Go to the end to download the full example code.
Plotting text
It is often useful to add text annotations to a plot or map. This is handled by the
pygmt.Figure.text
method of the pygmt.Figure
class.
from pathlib import Path
import pygmt
Adding a single text label
To add a single text label to a plot, use the text
and x
and y
parameters
to specify the text and position.
fig = pygmt.Figure()
fig.basemap(region=[-5, 5, -5, 5], projection="X5c", frame=True)
fig.text(x=0, y=0, text="My text")
fig.show()
Adjusting the text label
There are several optional parameters to adjust the text label:
font
: Sets the size, family/weight, and color of the font for the text. A list of all recognized fonts can be found at Supported Fonts. For details of how to use non-default fonts, refer to PostScript Fonts Used by GMT.angle
: Specifies the rotation of the text. It is measured counter-clockwise from the horizontal in degrees.justify
: Defines the anchor point of the bounding box for the text. It is specified by a two-letter (order independent) code, chosen from:Vertical: T(op), M(iddle), B(ottom)
Horizontal: L(eft), C(entre), R(ight)
offset
: Shifts the text relatively to the reference point.
fig = pygmt.Figure()
# -----------------------------------------------------------------------------
# Left: "font", "angle", and "offset" parameters
fig.basemap(region=[-5, 5, -5, 5], projection="X5c", frame="rtlb")
# Change font size, family/weight, color of the text
fig.text(x=0, y=3, text="my text", font="12p,Helvetica-Bold,blue")
# Rotate the text by 30 degrees counter-clockwise from the horizontal
fig.text(x=0, y=0, text="my text", angle=30)
# Plot marker and text label for reference
fig.plot(x=0, y=-3, style="s0.2c", fill="darkorange", pen="0.7p,darkgray")
fig.text(x=0, y=-3, text="my text")
# Shift the text label relatively to the position given via the x and y parameters
# by 1 centimeter to the right (positive x direction) and 0.5 centimeters down
# (negative y direction)
fig.text(x=0, y=-3, text="my text", offset="1c/-0.5c")
fig.shift_origin(xshift="w+0.5c")
# -----------------------------------------------------------------------------
# Right: "justify" parameter
fig.basemap(region=[-1, 1, -1, 1], projection="X5c", frame="rtlb")
# Plot markers for reference
fig.plot(
x=[-0.5, 0, 0.5, -0.5, 0, 0.5, -0.5, 0, 0.5],
y=[0.5, 0.5, 0.5, 0, 0, 0, -0.5, -0.5, -0.5],
style="s0.2c",
fill="darkorange",
pen="0.7p,darkgray",
)
# Plot text labels at the x and y positions of the markers while varying the anchor
# point via the justify parameter
fig.text(x=-0.5, y=0.5, text="TL", justify="TL") # TopLeft
fig.text(x=0, y=0.5, text="TC", justify="TC") # TopCenter
fig.text(x=0.5, y=0.5, text="TR", justify="TR") # TopRight
fig.text(x=-0.5, y=0, text="ML", justify="ML") # MiddleLeft
fig.text(x=0, y=0, text="MC", justify="MC") # MiddleCenter
fig.text(x=0.5, y=0, text="MR", justify="MR") # MiddleRight
fig.text(x=-0.5, y=-0.5, text="BL", justify="BL") # BottomLeft
fig.text(x=0, y=-0.5, text="BC", justify="BC") # BottomCenter
fig.text(x=0.5, y=-0.5, text="BR", justify="BR") # BottomRight
fig.show()
Adding a text box
There are different optional parameters to add and customize a text box:
fill
: Fills the text box with a color.pen
: Outlines the text box.clearance
: Adds margins in x and y directions between the text and the outline of the text box. Can be used to get a text box with rounded edges.
fig = pygmt.Figure()
fig.basemap(region=[-5, 5, -5, 5], projection="X5c", frame="rtlb")
# Add a box with a fill in green color
fig.text(x=0, y=3, text="My text", fill="green")
# Add box with a seagreen, 1-point thick, solid outline
fig.text(x=0, y=1, text="My text", pen="1p,seagreen,solid")
# Add margins between the text and the outline of the text box of 0.1
# centimeters in x direction and 0.2 centimeters in y direction
fig.text(x=0, y=-1, text="My text", pen="1p,seagreen,dashed", clearance="0.1c/0.2c")
# Get rounded edges by passing "+tO" to the "clearance" parameter
fig.text(x=0, y=-3, text="My text", pen="1p,seagreen,solid", clearance="0.2c/0.2c+tO")
fig.show()
Adding multiple text labels with individual configurations
To add multiple text labels with individual font
, angle
, and justify
,
one can provide lists with the corresponding arguments.
fig = pygmt.Figure()
fig.basemap(region=[-5, 5, -5, 5], projection="X5c", frame=True)
fig.text(
x=[0, 0, 0],
y=[3, 2, -2],
font=["5p,Helvetica,black", "5p,Helvetica,blue", "6p,Courier-Bold,red"],
angle=[0, 0, 30],
justify=["CM", "LT", "CM"],
text=[
"black text with justify='CM'",
"blue text with justify='LT'",
"red text with angle=30",
],
)
fig.show()
Using an external input file
It is also possible to add text labels via an external input file containing x
,
y
, and text
columns. Addionaly, columns to set the angle
, front
,
and justify
parameters can be provided. Here, we give a complete example.
fig = pygmt.Figure()
fig.basemap(region=[108, 121, -5, 8], projection="M10c", frame="a2f1")
fig.coast(land="darkgray", water="steelblue", shorelines="1/0.1p,gray30")
# Create space-delimited file with region / sea names:
# - longitude (x) and latitude (y) coordinates are in the first two columns
# - angle, font, and justify muss be present in this order in the next three columns
# - the text to be printed is given in the last column
with Path.open("examples.txt", "w") as f:
f.write("114.00 0.50 0 15p,Helvetica-Bold,white CM BORNEO\n")
f.write("119.00 3.25 0 8p,Helvetica-Bold,black CM CELEBES SEA\n")
f.write("112.00 -4.60 0 8p,Helvetica-Bold,black CM JAVA SEA\n")
f.write("112.00 6.00 40 8p,Helvetica-Bold,black CM SOUTH CHINA SEA\n")
f.write("119.12 7.25 -40 8p,Helvetica-Bold,black CM SULU SEA\n")
f.write("118.40 -1.00 65 8p,Helvetica-Bold,black CM MAKASSAR STRAIT\n")
# Setting the angle, font, and justify parameters to True indicates that those columns
# are present in the text file
fig.text(textfiles="examples.txt", angle=True, font=True, justify=True)
# Cleanups
Path("examples.txt").unlink()
fig.show()
Using the position parameter
Instead of using the x
and y
parameters, the position
parameter can be
specified to set the reference point for the text on the plot. As for the justify
parameter, the position
parameter is specified by a two-letter (order independent)
code, chosen from:
Vertical: T(op), M(iddle), B(ottom)
Horizontal: L(eft), C(entre), R(ight)
This can be helpful to add a tag to a subplot or text labels out of the plot or map frame, e.g., for depth slices.
fig = pygmt.Figure()
# -----------------------------------------------------------------------------
# Left: Add a tag to a subplot
fig.basemap(region=[-5, 5, -5, 5], projection="X5c", frame=["WStr", "af"])
fig.text(
text="(a)",
position="TL", # Top Left
justify="TL", # Top Left
offset="0.1c/-0.1c",
)
fig.shift_origin(xshift="w+1c")
# -----------------------------------------------------------------------------
# Right: Add a text label outside of the plot or map frame
fig.basemap(region=[-30, 30, 10, 60], projection="L0/35/23/47/5c", frame=["wSnE", "af"])
fig.text(
text="@@100 km", # "@@" gives "@" in GMT or PyGMT
position="TC", # Top Center
justify="MC", # Middle Center
offset="0c/0.2c",
no_clip=True, # Allow plotting outside of the map or plot frame
)
fig.show()
Advanced configuration
For crafting more advanced styles, including using special symbols and other character sets, be sure to check out the GMT documentation at https://docs.generic-mapping-tools.org/6.5/text.html and also the Technical References at https://docs.generic-mapping-tools.org/6.5/reference/features.html#placement-of-text. Good luck!
Total running time of the script: (0 minutes 0.806 seconds)