Skip to content
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

Tutorial "Plotting text": Rewrite to improve structure, explain more parameters, show list input #2760

Merged
merged 57 commits into from
Apr 21, 2024
Merged
Changes from 56 commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
1f0c2d2
Update and Expand text tutorial
Oct 20, 2023
f670414
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Oct 22, 2023
532bcce
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Oct 25, 2023
52b8c85
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Oct 26, 2023
64996b4
Add darft of new structure
Oct 29, 2023
be7108c
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Oct 29, 2023
441d861
Use bullet points to state paramters for adjusting text label
Oct 29, 2023
fcdd028
Fix typo
Oct 29, 2023
b6e8bb8
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Nov 1, 2023
4b792a7
Update code example for optional parameters to adjust text
Nov 1, 2023
c37aac6
Improve comments
Nov 1, 2023
be3996b
Improve code example for optional parameters to adjust text label
Nov 1, 2023
97e855b
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Nov 2, 2023
299d8a2
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Nov 8, 2023
6dd12cd
Improve docs
yvonnefroehlich Nov 10, 2023
b515a1c
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Nov 10, 2023
2e35c04
Fix typo, Fix line length
yvonnefroehlich Nov 10, 2023
add8af1
Make a seperate section for 'Adding a text box'
yvonnefroehlich Nov 11, 2023
71ddc5a
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Nov 13, 2023
d54340c
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Nov 20, 2023
0a19cd0
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Dec 5, 2023
9ac3ba3
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Dec 15, 2023
706fb83
Shorten code
yvonnefroehlich Dec 21, 2023
6b19557
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Dec 21, 2023
2dcbb54
Remove un-needed import
yvonnefroehlich Dec 21, 2023
87ba574
[format-command] fixes
actions-bot Dec 21, 2023
6b5a02f
Try to remove white space
Dec 22, 2023
338bb8b
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Dec 25, 2023
d9c36d3
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Dec 26, 2023
c2c83f6
Improve argument passed to 'xshift'
yvonnefroehlich Dec 26, 2023
040c19f
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Dec 27, 2023
a011e07
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Dec 28, 2023
e0601c4
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Dec 29, 2023
8759d74
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Jan 2, 2024
3b94151
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Jan 5, 2024
1e8d070
Wrap to 88 characters
yvonnefroehlich Jan 16, 2024
946ba2a
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Jan 22, 2024
e1dc06e
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Jan 28, 2024
81a8196
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Jan 30, 2024
2c6ef52
TEST: Remove choropleth example
yvonnefroehlich Jan 31, 2024
ba521f1
TEST: Remove roads example
yvonnefroehlich Jan 31, 2024
9c58e0e
Revert "TEST: Remove choropleth example"
Feb 1, 2024
3fa7763
Revert "TEST: Remove roads example"
Feb 1, 2024
9736676
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Feb 1, 2024
0ce2204
TEST: date_time_charts - Change symbol
yvonnefroehlich Feb 5, 2024
e3afb59
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Mar 9, 2024
cf8b943
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Mar 14, 2024
7e2d975
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Apr 5, 2024
ec295eb
Follow PTH123
yvonnefroehlich Apr 5, 2024
2ece2a8
Improve documentation and comments
yvonnefroehlich Apr 11, 2024
294c8df
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Apr 11, 2024
47002ab
Remove white space
yvonnefroehlich Apr 11, 2024
3bc7d05
Add missing verb
yvonnefroehlich Apr 19, 2024
a405fd3
Remove blank line
yvonnefroehlich Apr 19, 2024
50d196f
Fix line length
yvonnefroehlich Apr 19, 2024
4ea06fb
Merge branch 'main' into add-lists-tut-text
yvonnefroehlich Apr 19, 2024
33c0d7d
Remove blank line
yvonnefroehlich Apr 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
272 changes: 179 additions & 93 deletions examples/tutorials/basics/text.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
Plotting text
=============

It is often useful to add annotations to a plot. This is handled by
:meth:`pygmt.Figure.text`.
It is often useful to add text annotations to a plot or map. This is handled by the
:meth:`pygmt.Figure.text` method of the :class:`pygmt.Figure` class.
"""

# %%
Expand All @@ -12,146 +12,232 @@
import pygmt

# %%
# Basic map annotation
# --------------------
# Adding a single text label
# --------------------------
#
# Text annotations can be added to a map using the :meth:`pygmt.Figure.text`
# method of the :class:`pygmt.Figure` class.
#
# Here we create a simple map and add an annotation using the ``text``, ``x``,
# and ``y`` parameters to specify the annotation text and position in the
# projection frame. ``text`` accepts *str* types, while ``x`` and ``y``
# accept either *int* or *float* numbers, or a list/array of numbers.
# 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()
with pygmt.config(MAP_FRAME_TYPE="plain"):
fig.basemap(region=[108, 120, -5, 8], projection="M20c", frame="a")
fig.coast(land="black", water="skyblue")

# Plot text annotations using single arguments
fig.text(text="SOUTH CHINA SEA", x=112, y=6)

# Plot text annotations using lists of arguments
fig.text(text=["CELEBES SEA", "JAVA SEA"], x=[119, 112], y=[3.25, -4.6])
fig.basemap(region=[-5, 5, -5, 5], projection="X5c", frame=True)
fig.text(x=0, y=0, text="My text")

yvonnefroehlich marked this conversation as resolved.
Show resolved Hide resolved
fig.show()


# %%
# Changing font style
# -------------------
# Adjusting the text label
# ------------------------
#
# There are several optional parameters to adjust the text label:
#
# The size, family/weight, and color of an annotation can be specified using
# the ``font`` parameter.
# * ``font``: Sets the size, family/weight, and color of the font for the text.
# A list of all recognized fonts can be found at
# :gmt-docs:`PostScript Fonts Used by GMT <reference/postscript-fonts.html>`,
# including details of how to use non-default fonts.
# * ``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:
#
# A list of all recognized fonts can be found at
# :gmt-docs:`PostScript Fonts Used by GMT <reference/postscript-fonts.html>`,
# including details of how to use non-default fonts.
# * 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()
with pygmt.config(MAP_FRAME_TYPE="plain"):
fig.basemap(region=[108, 120, -5, 8], projection="M20c", frame="a")
fig.coast(land="black", water="skyblue")

# Customize the font style
fig.text(text="BORNEO", x=114.0, y=0.5, font="22p,Helvetica-Bold,white")
# -----------------------------------------------------------------------------
# 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="TM", 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()


# %%
# Plotting from a text file
# -------------------------
# Adding a text box
# -----------------
#
# There are different optional parameters to add and customize a text box:
#
# It is also possible to add annotations from a file containing ``x``, ``y``,
# and ``text`` columns. Here we give a complete example.
# * ``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()
with pygmt.config(MAP_FRAME_TYPE="plain"):
fig.basemap(region=[108, 120, -5, 8], projection="M20c", frame="a")
fig.coast(land="black", water="skyblue")

# Create space-delimited file
with Path("examples.txt").open(mode="w") as f:
f.write("114 0.5 0 22p,Helvetica-Bold,white CM BORNEO\n")
f.write("119 3.25 0 12p,Helvetica-Bold,black CM CELEBES SEA\n")
f.write("112 -4.6 0 12p,Helvetica-Bold,black CM JAVA SEA\n")
f.write("112 6 40 12p,Helvetica-Bold,black CM SOUTH CHINA SEA\n")
f.write("119.12 7.25 -40 12p,Helvetica-Bold,black CM SULU SEA\n")
f.write("118.4 -1 65 12p,Helvetica-Bold,black CM MAKASSAR STRAIT\n")

# Plot region names / sea names from a text file, where
# the longitude (x) and latitude (y) coordinates are in the first two columns.
# Setting angle/font/justify to True will indicate that those columns are
# present in the text file too (Note: must be in that order!).
# Finally, the text to be printed will be in the last column
fig.text(textfiles="examples.txt", angle=True, font=True, justify=True)

# Cleanups
Path("examples.txt").unlink()
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()


# %%
# ``justify`` parameter
# ---------------------
#
# ``justify`` is used to define the anchor point for the bounding box for text
# being added to a plot. The following code segment demonstrates the
# positioning of the anchor point relative to the text.
#
# The anchor point is specified with a two-letter (order independent) code,
# chosen from:
# Adding multiple text labels with individual configurations
# ----------------------------------------------------------
#
# * Vertical anchor: **T**\(op), **M**\(iddle), **B**\(ottom)
# * Horizontal anchor: **L**\(eft), **C**\(entre), **R**\(ight)
# 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=[0, 3, 0, 3], projection="X10c", frame=["WSne", "af0.5g"])
for position in ("TL", "TC", "TR", "ML", "MC", "MR", "BL", "BC", "BR"):
fig.text(
text=position,
position=position,
font="28p,Helvetica-Bold,black",
justify=position,
)
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()


# %%
# ``angle`` parameter
# -------------------
# Using an external input file
# ----------------------------
#
# ``angle`` is an optional parameter used to specify the counter-clockwise
# rotation in degrees of the text from the horizontal.
# 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=[0, 4, 0, 4], projection="X5c", frame="WSen")
for i in range(0, 360, 30):
fig.text(text=f"` {i}@.", x=2, y=2, justify="LM", angle=i)
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()


# %%
# ``fill`` parameter
# ------------------
# 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:
#
# ``fill`` is used to set the fill color of the area surrounding the text.
# * 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()
fig.basemap(region=[0, 1, 0, 1], projection="X5c", frame="WSen")
fig.text(text="Green", x=0.5, y=0.5, fill="green")

# -----------------------------------------------------------------------------
# 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 :gmt-docs:`text.html` and also the GMT Technical Reference at
# :gmt-docs:`reference/features.html#placement-of-text`. Good luck!
# For crafting more advanced styles, including using special symbols and other character
# sets, be sure to check out the GMT documentation at :gmt-docs:`text.html` and also the
# Technical References at :gmt-docs:`reference/features.html#placement-of-text`. Good
# luck!

# sphinx_gallery_thumbnail_number = 3
# sphinx_gallery_thumbnail_number = 4