Place text annotations connected to data points by arrows or leader lines, with automatic non-overlapping label placement.
Description
annotate is a high-level convenience function inspired by Matplotlib’s annotate. It handles the full labeling pipeline in a single call:
Computes non-overlapping label positions automatically via textrepel (unless positions are supplied explicitly).
Places the labels with text using GMT’s per-record offset mechanism (-D+f).
Draws connecting lines from each anchor point to its label, either as arrows (default) or as thin GMT leader lines.
Required Arguments
points : Nx2 Matrix or GMTdataset with (x, y) coordinates of the anchor points.
labels : Vector{String} with one annotation per point.
Optional Arguments
text_pos : Nx2 matrix or GMTdataset with explicit label positions in data coordinates. When provided the labels are placed here and connecting lines go from points to text_pos. When omitted (together with offsets) positions are computed automatically by textrepel.
offsets : Nx2 matrix of per-label displacements in cm from each anchor point. Passed to text via GMT’s -D+f per-record offset mechanism. Omit to let textrepel compute them automatically.
arrowprops : Controls the connecting arrow drawn between each anchor and its label.
false (default) — no arrow.
true — draws a default filled arrow pointing to the data point (pen=1, arrow=(len=0.6,stop=true), fill=:black).
A NamedTuple with any kwargs accepted by arrows!() — custom arrow styling. E.g. arrowprops=(pen="0.5p,gray", arrow=(len=0.3, stop=true, shape=0.5), fill=:gray).
leader : Pen string for a thin GMT leader line (-D+f+v<pen>) drawn from the anchor point to the edge of the text box (no arrowhead). E.g.leader="0.5p,gray50".
nobox : If true, render the label with fill only — no box border is drawn and clearance is forced to "0p" so the fill hugs the text. Useful for clean map labels with a coloured background but no visible rectangle.
nofill : If true, render the label as plain text with no box and no background fill.
justify : GMT justification code for the text anchor (default "CM", centre-middle).
fontsize : Font size in points used by textrepel for bounding-box estimation (default 10). Use F=(font=...) to control the rendered font.
force_push, force_pull, max_iter, pad, min_offset : textrepel tuning parameters (used only when neither text_pos nor offsets is given).
Remaining kwargs are forwarded to text() and control label appearance — e.g. fill, pen, clearance, F=(font=...), font, etc.
U or time_stamp : – time_stamp=true|time_stamp=(just=“code”, pos=(dx,dy), label=“label”, com=true)
Draw GMT time stamp logo on plot. More at timestamp
V or verbose : – verbose=true|verbose=level
Select verbosity level. More at verbose
figname or savefig or name : – figname=name.png
Save the figure with the figname=name.ext where ext chooses the figure image format.
Examples
Automatic non-overlapping scatter labels
The simplest usage: pass points and labels, and annotate places everything automatically. Label positions are computed by textrepel to avoid overlaps; arrows connect labels to anchors.
Pass leader=<pen> to use GMT’s hairline connector — a thin line from the anchor to the edge of the text box, with no arrowhead. Since no arrow is drawn by default, just setting leader is sufficient.