From 991257a2705e1336cfa2d85483348c8aaff7578f Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sat, 23 May 2026 00:11:07 +0800 Subject: [PATCH 1/2] Figure.text: Allow passing a sequence of offset to the 'offset' parameter --- examples/gallery/images/cross_section.py | 2 +- examples/gallery/lines/decorated_lines.py | 2 +- examples/gallery/lines/linefronts.py | 2 +- examples/gallery/lines/linestyles.py | 8 +++---- examples/gallery/lines/quoted_lines.py | 2 +- examples/gallery/lines/vector_heads_tails.py | 2 +- examples/gallery/symbols/points_cities.py | 2 +- examples/tutorials/basics/text.py | 14 ++++--------- pygmt/src/text.py | 22 ++++++++++---------- 9 files changed, 25 insertions(+), 31 deletions(-) diff --git a/examples/gallery/images/cross_section.py b/examples/gallery/images/cross_section.py index 822b971c92c..f5a24dbaca0 100644 --- a/examples/gallery/images/cross_section.py +++ b/examples/gallery/images/cross_section.py @@ -61,7 +61,7 @@ x=[lonA, lonB], y=[latA, latB], text=["A", "B"], - offset="0c/0.3c", # Move text 0.2 centimeters up (y-direction) + offset=(0, 0.3), # Move text 0.2 centimeters up (y-direction) font="15p,red", # Use a red font with a size of 15 points ) diff --git a/examples/gallery/lines/decorated_lines.py b/examples/gallery/lines/decorated_lines.py index 1a8cecffa8e..52444fd3240 100644 --- a/examples/gallery/lines/decorated_lines.py +++ b/examples/gallery/lines/decorated_lines.py @@ -80,7 +80,7 @@ text=decoline, font="Courier-Bold", justify="ML", - offset="0.75c/0c", + offset=(0.75, 0), ) fig.show() diff --git a/examples/gallery/lines/linefronts.py b/examples/gallery/lines/linefronts.py index 67f6b492eac..8cb848604e3 100644 --- a/examples/gallery/lines/linefronts.py +++ b/examples/gallery/lines/linefronts.py @@ -90,7 +90,7 @@ text=frontstyle, font="Courier-Bold", justify="ML", - offset="0.75c/0c", + offset=(0.75, 0), ) fig.show() diff --git a/examples/gallery/lines/linestyles.py b/examples/gallery/lines/linestyles.py index 70571a4ec10..6a971ff670c 100644 --- a/examples/gallery/lines/linestyles.py +++ b/examples/gallery/lines/linestyles.py @@ -33,7 +33,7 @@ # Plot the line using the default line style fig.plot(x=x, y=y) -fig.text(x=x[-1], y=y[-1], text="solid (default)", justify="ML", offset="0.2c/0c") +fig.text(x=x[-1], y=y[-1], text="solid (default)", justify="ML", offset=(0.2, 0)) # Plot the line using different line styles for linestyle in [ @@ -48,14 +48,14 @@ ]: y -= 1 # Move the current line down fig.plot(x=x, y=y, pen=linestyle) - fig.text(x=x[-1], y=y[-1], text=linestyle, justify="ML", offset="0.2c/0c") + fig.text(x=x[-1], y=y[-1], text=linestyle, justify="ML", offset=(0.2, 0)) # Plot the line like a railway track (black/white). # The trick here is plotting the same line twice but with different line styles y -= 1 # move the current line down fig.plot(x=x, y=y, pen="5p,black") fig.plot(x=x, y=y, pen="4p,white,20p_20p") -fig.text(x=x[-1], y=y[-1], text="5p,black", justify="ML", offset="0.2c/0.2c") -fig.text(x=x[-1], y=y[-1], text="4p,white,20p_20p", justify="ML", offset="0.2c/-0.2c") +fig.text(x=x[-1], y=y[-1], text="5p,black", justify="ML", offset=(0.2, 0.2)) +fig.text(x=x[-1], y=y[-1], text="4p,white,20p_20p", justify="ML", offset=(0.2, -0.2)) fig.show() diff --git a/examples/gallery/lines/quoted_lines.py b/examples/gallery/lines/quoted_lines.py index b04bc1c2e0b..5f1d78317fe 100644 --- a/examples/gallery/lines/quoted_lines.py +++ b/examples/gallery/lines/quoted_lines.py @@ -70,7 +70,7 @@ text=quotedline, font="Courier-Bold", justify="ML", - offset="0.75c/0c", + offset=(0.75, 0), ) fig.show() diff --git a/examples/gallery/lines/vector_heads_tails.py b/examples/gallery/lines/vector_heads_tails.py index d58150698c0..e26c404807a 100644 --- a/examples/gallery/lines/vector_heads_tails.py +++ b/examples/gallery/lines/vector_heads_tails.py @@ -82,7 +82,7 @@ x=x, y=y, style=vecstyle, direction=([angle], [length]), pen="2p", fill="red3" ) fig.text( - x=6, y=y, text=vecstyle, font="Courier-Bold", justify="ML", offset="0.2c/0c" + x=6, y=y, text=vecstyle, font="Courier-Bold", justify="ML", offset=(0.2, 0) ) y -= 1 # move the next vector down diff --git a/examples/gallery/symbols/points_cities.py b/examples/gallery/symbols/points_cities.py index 474292a9fd4..a7314545d46 100644 --- a/examples/gallery/symbols/points_cities.py +++ b/examples/gallery/symbols/points_cities.py @@ -41,7 +41,7 @@ x=cities_large.geometry.x, y=cities_large.geometry.y, text=cities_large["name"], - offset="0.12c", + offset=0.12, justify="BL", font="6p,Helvetica-Bold", fill="white@30", diff --git a/examples/tutorials/basics/text.py b/examples/tutorials/basics/text.py index ba3d88ff47a..d1b4989ed5d 100644 --- a/examples/tutorials/basics/text.py +++ b/examples/tutorials/basics/text.py @@ -59,7 +59,7 @@ # 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.text(x=0, y=-3, text="my text", offset=(1, -0.5)) fig.shift_origin(xshift="w+0.5c") @@ -196,19 +196,13 @@ fig = pygmt.Figure() # ----------------------------------------------------------------------------- -# Left: Add a tag to a subplot +# Left: Add a tag to a subplot at the Top Left corner fig.basemap( region=[-5, 5, -5, 5], projection="X5c", frame=Frame(axes="WStr", axis=Axis(annot=True, tick=True)), ) - -fig.text( - text="(a)", - position="TL", # Top Left - justify="TL", # Top Left - offset="0.1c/-0.1c", -) +fig.text(text="(a)", position="TL", justify="TL", offset=(0.1, -0.1)) fig.shift_origin(xshift="w+1c") @@ -224,7 +218,7 @@ text="@@100 km", # "@@" gives "@" in GMT or PyGMT position="TC", # Top Center justify="MC", # Middle Center - offset="0c/0.2c", + offset=(0, 0.2), no_clip=True, # Allow plotting outside of the plot frame ) diff --git a/pygmt/src/text.py b/pygmt/src/text.py index 78b1d23b905..271d79da1ee 100644 --- a/pygmt/src/text.py +++ b/pygmt/src/text.py @@ -25,7 +25,6 @@ @fmt_docstring @use_alias( C="clearance", - D="offset", a="aspatial", e="find", f="coltypes", @@ -45,6 +44,7 @@ def text( # noqa: PLR0912, PLR0913, PLR0915 fill: str | None = None, pen: str | None = None, justify: bool | None | AnchorCode | Sequence[AnchorCode] = None, + offset: Sequence[float | str] | str | None = None, no_clip: bool = False, projection: str | None = None, region: Sequence[float | str] | str | None = None, @@ -77,6 +77,7 @@ def text( # noqa: PLR0912, PLR0913, PLR0915 $aliases - B = frame + - D = offset - F = **+a**: angle, **+c**: position, **+j**: justify, **+f**: font - G = fill - J = projection @@ -157,16 +158,14 @@ def text( # noqa: PLR0912, PLR0913, PLR0915 pen Set the pen used to draw a rectangle around the text string (see ``clearance``) [Default is ``"0.25p,black,solid"``]. - offset : str - [**j**\|\ **J**]\ *dx*\[/*dy*][**+v**\[*pen*]]. - Offset the text from the projected (x, y) point by *dx*/\ *dy* - [Default is ``"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 + offset + (*dx*, *dy*) or [**j**\|\ **J**]\ *dx*\[/*dy*][**+v**\[*pen*]]. + Offset the text from the projected (x, y) point by (*dx*, *dy*) [Default is + (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. no_clip Do **not** clip text at the frame boundaries [Default is ``False``]. @@ -281,6 +280,7 @@ def text( # noqa: PLR0912, PLR0913, PLR0915 ) aliasdict = AliasSystem( + D=Alias(offset, name="offset", sep="/", size=2), G=Alias(fill, name="fill"), N=Alias(no_clip, name="no_clip"), W=Alias(pen, name="pen"), From 6ec96f1893838ad1b7726c0fa341b38a8fad77c5 Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sat, 23 May 2026 00:13:04 +0800 Subject: [PATCH 2/2] Fix a typo --- examples/gallery/images/cross_section.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/gallery/images/cross_section.py b/examples/gallery/images/cross_section.py index f5a24dbaca0..9523db6150e 100644 --- a/examples/gallery/images/cross_section.py +++ b/examples/gallery/images/cross_section.py @@ -61,7 +61,7 @@ x=[lonA, lonB], y=[latA, latB], text=["A", "B"], - offset=(0, 0.3), # Move text 0.2 centimeters up (y-direction) + offset=(0, 0.3), # Move text 0.3 centimeters up (y-direction) font="15p,red", # Use a red font with a size of 15 points )