diff --git a/doc/techref/index.md b/doc/techref/index.md index 9d6367ac055..0380c229290 100644 --- a/doc/techref/index.md +++ b/doc/techref/index.md @@ -14,5 +14,6 @@ fonts.md text_formatting.md patterns.md encodings.md +justification_codes.md environment_variables.md ``` diff --git a/doc/techref/justification_codes.md b/doc/techref/justification_codes.md new file mode 100644 index 00000000000..63768657ddf --- /dev/null +++ b/doc/techref/justification_codes.md @@ -0,0 +1,119 @@ +--- +file_format: mystnb +--- + +# Justification codes + +To place plot embellishments, such as scalebars, directional roses, colorbars, +legends, text, and images on a figure two points have to be specified: a point +somewhere on the figure (reference point) and a point on the feature (anchor +point). For both, users can use a two-character (order-independent) code, a +combination of a vertical code and a horizontal code: + +- Vertical: **T**\(op), **M**\(iddle), **B**\(ottom) +- Horizontal: **L**\(eft), **C**\(entre), **R**\(ight) + +The possible nine justification codes are visualized in the sketch below: + +```{code-cell} +--- +tags: [remove-input] +--- +""" +Script showing the justification codes used in GMT / PyGMT. +""" +import pygmt + +size = 5 +x1 = [-size, 0, size, size, size, 0, -size, -size, 0] +y1 = [-size, -size, -size, 0, size, size, size, 0, 0] +codes = ["BL", "BC", "BR", "MR", "TR", "TC", "TL", "ML", "MC"] + +fig = pygmt.Figure() +fig.basemap(projection="X10c/6c", region=[-size, size, -size, size], frame=0) + +fig.text( + font="15p,1,black", + x=x1, + y=y1, + text=codes, + justify=codes, + offset="j0.5c/0.5c+v2p,gray30", +) + +fig.plot(x=x1, y=y1, style="c0.3c", fill="steelblue", no_clip=True) + +fig.text( + font="15p", + offset="j0.5c/0.5c", + no_clip=True, + x=[size, size, size, -size, 0, size], + y=[size, 0, -size, size, size, size], + justify=["ML", "ML", "ML", "BC", "BC", "BC"], + text=[ + "@%1%T@%%op", + "@%1%M@%%iddle", + "@%1%B@%%ottom", + "@%1%L@%%eft", + "@%1%C@%%enter", + "@%1%R@%%ight", + ], +) + +fig.show(width=600) +``` + +For a non-rectangular geographic basemap, the justification codes refer to the map +bounding box: + +```{code-cell} +--- +tags: [remove-input] +--- +""" +Script showing justification codes for non-rectangular geographic basemaps. +""" +fig = pygmt.Figure() +fig.basemap(projection="H10c", region="g", frame=0) + +for code in codes: + fig.text( + font="10p,1,black", + position=code, + justify=code, + text=code, + offset="j0.5c/0.5c+v2p,gray30", + ) + fig.text(font="10p,steelblue", position=code, justify="MC", text="●", no_clip=True) + +fig.show(width=600) +``` + + +Plot embellishments can be abstracted as rectangles. Here, the justification codes are +shown exemplary for a colorbar. + +```{code-cell} +--- +tags: [remove-input] +--- +""" +Script showing justification codes for plot embellishments, e.g., a colorbar. +""" +fig = pygmt.Figure() +fig.basemap(projection="X10c/2c", region=[-size, size, -size, size], frame=0) + +fig.colorbar(cmap="buda", frame=0, position="jMC+w10c/2c+h") + +for code in codes: + fig.text( + font="10p,1,black", + position=code, + justify=code, + text=code, + offset="j0.3c/0.15c+v1p,gray30", + ) +fig.plot(x=x1, y=y1, style="c0.2c", fill="steelblue", no_clip=True) + +fig.show(width=600) +``` diff --git a/examples/gallery/embellishments/colorbar.py b/examples/gallery/embellishments/colorbar.py index 84010591e4a..c97f8b42838 100644 --- a/examples/gallery/embellishments/colorbar.py +++ b/examples/gallery/embellishments/colorbar.py @@ -11,9 +11,8 @@ followed by the desired interval. The placement of the colorbar is set via the ``position`` parameter. There are the following options: -- **j/J**: placed inside/outside the plot bounding box using any 2-character - combination of vertical (**T**\ op, **M**\ iddle, **B**\ ottom) and - horizontal (**L**\ eft, **C**\ enter, **R**\ ight) alignment codes, e.g. +- **j/J**: placed inside/outside the plot bounding box using a + :doc:`2-character justification code `, e.g., ``position="jTR"`` for Top Right. - **g**: using map coordinates, e.g. ``position="g170/-45"`` for longitude 170° East, latitude 45° South. diff --git a/examples/gallery/embellishments/scalebar.py b/examples/gallery/embellishments/scalebar.py index 88794cb5c95..1980307b602 100644 --- a/examples/gallery/embellishments/scalebar.py +++ b/examples/gallery/embellishments/scalebar.py @@ -10,11 +10,10 @@ of the reference point. Choose from - **g**: Give map coordinates as *longitude*\/\ *latitude*. - - **j**\|\ **J**: Specify a two-character (order independent) code. - Choose from vertical **T**\(op), **M**\(iddle), or **B**\(ottom) and - horizontal **L**\(eft), **C**\(entre), or **R**\(ight). Lower / - uppercase **j** / **J** mean inside / outside of the map bounding - box. + - **j**\|\ **J**: Specify a + :doc:`2-character justification code `. + Lower / uppercase **j** / **J** mean inside / outside of the map + bounding box. - **n**: Give normalized bounding box coordinates as *nx*\/\ *ny*. - **x**: Give plot coordinates as *x*\/\ *y*. @@ -26,9 +25,8 @@ **+c** is appended the middle of the map is used. Note that *slon* is only optional for projections with constant scale along parallels, e.g., Mercator projection. - - justify: **+j**. Set the anchor point. Specify a two-character (order - independent) code. Choose from vertical **T**\(op), **M**\(iddle), or - **B**\(ottom) and horizontal **L**\(eft), **C**\(entre), or **R**\(ight). + - justify: **+j**. Set the anchor point. Specify a + :doc:`2-character justification code `. - offset: **+o**\ *offset* or **+o**\ *xoffset*/\ *yoffset*. Give either a common shift or individual shifts in x- (longitude) and y- (latitude) directions. diff --git a/examples/tutorials/basics/text.py b/examples/tutorials/basics/text.py index 6ac39ebc174..fb12cfa65b9 100644 --- a/examples/tutorials/basics/text.py +++ b/examples/tutorials/basics/text.py @@ -37,11 +37,7 @@ # * ``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) -# +# specified by a :doc:`2-character justification code `. # * ``offset``: Shifts the text relatively to the reference point. fig = pygmt.Figure() @@ -191,12 +187,8 @@ # # 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) -# +# parameter, the ``position`` parameter is specified by a +# :doc:`2-character justification code `. # 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. diff --git a/pygmt/src/colorbar.py b/pygmt/src/colorbar.py index 97018f836de..6e85db5ec76 100644 --- a/pygmt/src/colorbar.py +++ b/pygmt/src/colorbar.py @@ -68,8 +68,9 @@ def colorbar( [**+n**\ [*txt*]][**+o**\ *dx*\ [/*dy*]]. Define the reference point on the map for the color scale using one of four coordinate systems: (1) Use **g** for map (user) coordinates, (2) - use **j** or **J** for setting *refpoint* via a 2-character - justification code that refers to the (invisible) map domain rectangle, + use **j** or **J** for setting *refpoint* via a + :doc:`2-character justification code ` + that refers to the (invisible) map domain rectangle, (3) use **n** for normalized (0-1) coordinates, or (4) use **x** for plot coordinates (inches, cm, etc.). All but **x** requires both ``region`` and ``projection`` to be specified. Append **+w** followed @@ -78,8 +79,9 @@ def colorbar( reverse the scale bar. Append **+h** to get a horizontal scale [Default is vertical (**+v**)]. By default, the anchor point on the scale is assumed to be the bottom left corner (**BL**), but this can - be changed by appending **+j** followed by a 2-character - justification code *justify*. + be changed by appending **+j** followed by a + :doc:`2-character justification code ` + *justify*. box : bool or str [**+c**\ *clearances*][**+g**\ *fill*][**+i**\ [[*gap*/]\ *pen*]]\ [**+p**\ [*pen*]][**+r**\ [*radius*]][**+s**\ [[*dx*/*dy*/][*shade*]]]. diff --git a/pygmt/src/inset.py b/pygmt/src/inset.py index ef9fe5aeca4..ad0195875e8 100644 --- a/pygmt/src/inset.py +++ b/pygmt/src/inset.py @@ -56,7 +56,8 @@ def inset( Append **g**\ *lon*/*lat* for map (user) coordinates, **j**\ *code* or **J**\ *code* for setting the *refpoint* via a - 2-character justification code that refers to the (invisible) + :doc:`2-character justification code ` + that refers to the (invisible) projected map bounding box, **n**\ *xn*/*yn* for normalized (0-1) bounding box coordinates, or **x**\ *x*/*y* for plot coordinates (inches, centimeters, points, append unit). @@ -75,8 +76,9 @@ def inset( Append **+w**\ *width*\ [/*height*] of bounding rectangle or box in plot coordinates (inches, centimeters, etc.). By default, the anchor point on the scale is assumed to be the bottom left corner - (**BL**), but this can be changed by appending **+j** followed by - a 2-character justification code *justify*. + (**BL**), but this can be changed by appending **+j** followed by a + :doc:`2-character justification code ` + *justify*. **Note**: If **j** is used then *justify* defaults to the same as *refpoint*, if **J** is used then *justify* defaults to the mirror opposite of *refpoint*. Specify inset box attributes via diff --git a/pygmt/src/text.py b/pygmt/src/text.py index fe589ef6e77..ad5ae887097 100644 --- a/pygmt/src/text.py +++ b/pygmt/src/text.py @@ -90,7 +90,8 @@ def text_( # noqa: PLR0912, PLR0913, PLR0915 * *y*: Y coordinate or latitude * *angle*: Angle in degrees counter-clockwise from horizontal * *font*: Text size, font, and color - * *justify*: Two-character justification code + * *justify*: + :doc:`2-character justification code ` * *text*: The text string to typeset The *angle*, *font*, and *justify* columns are optional and can be set @@ -104,12 +105,8 @@ def text_( # noqa: PLR0912, PLR0913, PLR0915 position Set reference point on the map for the text by using x, y coordinates extracted from ``region`` instead of providing them - through ``x``/``y``. Specify with a two-letter (order independent) - code, chosen from: - - * Vertical: **T**\ (op), **M**\ (iddle), **B**\ (ottom) - * Horizontal: **L**\ (eft), **C**\ (entre), **R**\ (ight) - + through ``x``/``y``. Specify with a + :doc:`2-character justification code `. For example, ``position="TL"`` plots the text at the Top Left corner of the map. text @@ -129,10 +126,9 @@ def text_( # noqa: PLR0912, PLR0913, PLR0915 columns. justify Set the alignment which refers to the part of the text string that - will be mapped onto the (x, y) point. Choose a two-letter - combination of **L**, **C**, **R** (for left, center, or right) and - **T**, **M**, **B** (for top, middle, or bottom). E.g., **BL** for - bottom left. If no justification is explicitly given + will be mapped onto the (x, y) point. Choose a + :doc:`2-character justification code `, + e.g., **BL** for Bottom Left. If no justification is explicitly given (i.e. ``justify=True``), then the input to ``textfiles`` must have this as a column. {projection}