55from collections .abc import Sequence
66from typing import Literal
77
8+ from pygmt ._typing import AnchorCode
89from pygmt .alias import Alias , AliasSystem
910from pygmt .clib import Session
11+ from pygmt .exceptions import GMTValueError
1012from pygmt .helpers import build_arg_list , fmt_docstring , use_alias
11- from pygmt .params import Box
13+ from pygmt .helpers .utils import is_nonstr_iter
14+ from pygmt .params import Box , Position
15+ from pygmt .src ._common import _parse_position
1216
1317__doctest_skip__ = ["colorbar" ]
1418
1519
20+ def _parse_move_text (
21+ move_text : Sequence [str ] | None , label_as_column : bool = False
22+ ) -> str | None :
23+ """
24+ Parse the move_text parameter into the format required by GMT.
25+
26+ Examples
27+ --------
28+ >>> _parse_move_text(None)
29+ >>> _parse_move_text(["annotations", "label"])
30+ 'al'
31+ >>> _parse_move_text(["unit"])
32+ 'u'
33+ >>> _parse_move_text(["annotations", "label", "unit"])
34+ 'alu'
35+ >>> _parse_move_text(["annotations"], label_as_column=True)
36+ 'ac'
37+ >>> _parse_move_text(["invalid"])
38+ Traceback (most recent call last):
39+ ...
40+ GMTValueError: 'invalid' is not a valid value for 'move_text'...
41+
42+ """
43+ _valids = {"annotations" , "label" , "unit" }
44+ match move_text :
45+ case Sequence () if is_nonstr_iter (move_text ) and all (
46+ v in _valids for v in move_text
47+ ):
48+ argstr = "" .join (item [0 ] for item in move_text )
49+ if label_as_column is True :
50+ argstr += "c"
51+ return argstr
52+ case None :
53+ return None
54+ case _:
55+ raise GMTValueError (
56+ move_text ,
57+ description = "move_text" ,
58+ choices = _valids ,
59+ )
60+
61+
1662@fmt_docstring
17- @use_alias (C = "cmap" , D = "position" , L = "equalsize" , Z = "zfile" )
63+ @use_alias (C = "cmap" , L = "equalsize" , Z = "zfile" )
1864def colorbar ( # noqa: PLR0913
1965 self ,
66+ position : Position | Sequence [float | str ] | AnchorCode | None = None ,
67+ length : float | str | None = None ,
68+ width : float | str | None = None ,
69+ orientation : Literal ["horizontal" , "vertical" ] | None = None ,
70+ reverse : bool = False ,
71+ nan_rectangle : bool | str = False ,
72+ nan_rectangle_position : Literal ["start" , "end" ] | None = None ,
73+ sidebar_triangles : bool | Literal ["foreground" , "background" ] = False ,
74+ sidebar_triangles_height : float | None = None ,
75+ move_text : Sequence [str ] | None = None ,
76+ label_as_column : bool = False ,
77+ box : Box | bool = False ,
2078 truncate : Sequence [float ] | None = None ,
2179 shading : float | Sequence [float ] | bool = False ,
2280 log : bool = False ,
2381 scale : float | None = None ,
2482 projection : str | None = None ,
25- box : Box | bool = False ,
26- frame : str | Sequence [str ] | bool = False ,
2783 region : Sequence [float | str ] | str | None = None ,
84+ frame : str | Sequence [str ] | bool = False ,
2885 verbose : Literal ["quiet" , "error" , "warning" , "timing" , "info" , "compat" , "debug" ]
2986 | bool = False ,
3087 panel : int | Sequence [int ] | bool = False ,
31- transparency : float | None = None ,
3288 perspective : float | Sequence [float ] | str | bool = False ,
89+ transparency : float | None = None ,
3390 ** kwargs ,
3491):
3592 r"""
@@ -58,6 +115,9 @@ def colorbar( # noqa: PLR0913
58115
59116 $aliases
60117 - B = frame
118+ - D = position, **+w**: length/width, **+h**/**+v**: orientation,
119+ **+r**: reverse, **+n**: nan_rectangle, **+e**: sidebar_triangles,
120+ **+m**: move_annots
61121 - F = box
62122 - G = truncate
63123 - I = shading
@@ -72,31 +132,56 @@ def colorbar( # noqa: PLR0913
72132
73133 Parameters
74134 ----------
75- frame : str or list
76- Set colorbar boundary frame, labels, and axes attributes.
77135 $cmap
78- position : str
79- [**g**\|\ **j**\|\ **J**\|\ **n**\|\ **x**]\ *refpoint*\
80- [**+w**\ *length*\ [/\ *width*]]\ [**+e**\ [**b**\|\ **f**][*length*]]\
81- [**+h**\|\ **v**][**+j**\ *justify*]\
82- [**+m**\ [**a**\|\ **c**\|\ **l**\|\ **u**]]\
83- [**+n**\ [*txt*]][**+o**\ *dx*\ [/*dy*]].
84- Define the reference point on the map for the color scale using one of
85- four coordinate systems: (1) Use **g** for map (user) coordinates, (2)
86- use **j** or **J** for setting *refpoint* via a
87- :doc:`2-character justification code </techref/justification_codes>`
88- that refers to the (invisible) map domain rectangle,
89- (3) use **n** for normalized (0-1) coordinates, or (4) use **x** for
90- plot coordinates (inches, cm, etc.). All but **x** requires both
91- ``region`` and ``projection`` to be specified. Append **+w** followed
92- by the length and width of the colorbar. If width is not specified
93- then it is set to 4% of the given length. Give a negative length to
94- reverse the scale bar. Append **+h** to get a horizontal scale
95- [Default is vertical (**+v**)]. By default, the anchor point on the
96- scale is assumed to be the bottom left corner (**BL**), but this can
97- be changed by appending **+j** followed by a
98- :doc:`2-character justification code </techref/justification_codes>`
99- *justify*.
136+ position
137+ Position of the GMT logo on the plot. It can be specified in multiple ways:
138+
139+ - A :class:`pygmt.params.Position` object to fully control the reference point,
140+ anchor point, and offset.
141+ - A sequence of two values representing the x and y coordinates in plot
142+ coordinates, e.g., ``(1, 2)`` or ``("1c", "2c")``.
143+ - A :doc:`2-character justification code </techref/justification_codes>` for a
144+ position inside the plot, e.g., ``"TL"`` for Top Left corner inside the plot.
145+
146+ If not specified, defaults to the bottom-center corner outside of the plot.
147+ length
148+ width
149+ Length and width of the color bar. If length is given with a unit ``%`` then it
150+ is in percentage of the corrresponding plot side dimension (i.e., plot width for
151+ a horizontal colorbar, or plot height for a vertical colorbar). If width is
152+ given with unit ``%`` then it is in percentage of the bar length. [Length
153+ default to 80% of the corresponding plot side dimension, and width default to
154+ 4% of the bar length].
155+ orientation
156+ Set the colorbar orientation to either ``"horizontal"`` or ``"vertical"``.
157+ [Default is vertical, unless position is set to bottom-center or top-center with
158+ ``cstype="outside"`` or ``cstype="inside"``, then horizontal is the default].
159+ reverse
160+ Reverse the positive direction of the bar.
161+ nan_rectangle
162+ Draw a rectangle filled with the NaN color (via the **N** entry in the CPT or
163+ :term:`COLOR_NAN` if no such entry) at the start of the colorbar. If a string
164+ is given, use that string as the label for the NaN color.
165+ nan_rectangle_position
166+ Set the position of the NaN rectangle. Choose from ``"start"`` or ``"end"``.
167+ [Default is ``"start"``].
168+ sidebar_triangles
169+ Draw sidebar triangles for back- and/or foreground colors. If set to ``True``,
170+ both triangles are drawn. Alternatively, set it to ``"foreground"`` or
171+ ``"background"`` to draw only one triangle. The back- and/or foreground colors
172+ are taken from the **B** and **F** entries in the CPT. If no such entries exist,
173+ then the system default colors for **B** and **F** are used instead (
174+ :term:`COLOR_BACKGROUND` and :term:`COLOR_FOREGROUND`).
175+ sidebar_triangles_height
176+ Height of the sidebar triangles [Default is half the bar width].
177+ move_text
178+ Move text (annotations, label, and unit) to opposite side. Accept a sequence of
179+ strings containing one or more of ``"annotations"``, ``"label"``, and
180+ ``"unit"``. The default placement of these texts depends on the colorbar
181+ orientation and position.
182+ label_as_column
183+ Print a vertical label as a column of characters (does not work with special
184+ characters).
100185 box
101186 Draw a background box behind the colorbar. If set to ``True``, a simple
102187 rectangular box is drawn using :gmt-term:`MAP_FRAME_PEN`. To customize the box
@@ -138,6 +223,10 @@ def colorbar( # noqa: PLR0913
138223 may be in plot distance units or given as relative fractions and will
139224 be automatically scaled so that the sum of the widths equals the
140225 requested colorbar length.
226+ $projection
227+ $region
228+ frame : str or list
229+ Set colorbar boundary frame, labels, and axes attributes.
141230 $verbose
142231 $panel
143232 $perspective
@@ -162,7 +251,57 @@ def colorbar( # noqa: PLR0913
162251 """
163252 self ._activate_figure ()
164253
254+ position = _parse_position (
255+ position ,
256+ kwdict = {
257+ "length" : length ,
258+ "width" : width ,
259+ "orientation" : orientation ,
260+ "reverse" : reverse ,
261+ "nan_rectangle" : nan_rectangle ,
262+ "nan_rectangle_position" : nan_rectangle_position ,
263+ "sidebar_triangles" : sidebar_triangles ,
264+ "sidebar_triangles_height" : sidebar_triangles_height ,
265+ "move_text" : move_text ,
266+ "label_as_column" : label_as_column ,
267+ },
268+ default = None , # Use GMT's default behavior if position is not provided.
269+ )
270+
165271 aliasdict = AliasSystem (
272+ D = [
273+ Alias (position , name = "position" ),
274+ Alias (length , name = "length" , prefix = "+w" ), # +wlength/width
275+ Alias (width , name = "width" , prefix = "/" ),
276+ Alias (
277+ orientation ,
278+ name = "orientation" ,
279+ mapping = {"horizontal" : "+h" , "vertical" : "+v" },
280+ ),
281+ Alias (reverse , name = "reverse" , prefix = "+r" ),
282+ Alias (
283+ nan_rectangle ,
284+ name = "nan_rectangle" ,
285+ prefix = "+n" if nan_rectangle_position == "start" else "+N" ,
286+ ),
287+ Alias (
288+ sidebar_triangles ,
289+ name = "sidebar_triangles" ,
290+ prefix = "+e" ,
291+ mapping = {
292+ True : True ,
293+ False : False ,
294+ "foreground" : "f" ,
295+ "background" : "b" ,
296+ },
297+ ),
298+ Alias (sidebar_triangles_height , name = "sidebar_triangles_height" ),
299+ Alias (
300+ _parse_move_text (move_text , label_as_column ),
301+ name = "move_text" ,
302+ prefix = "+m" ,
303+ ),
304+ ],
166305 F = Alias (box , name = "box" ),
167306 G = Alias (truncate , name = "truncate" , sep = "/" , size = 2 ),
168307 I = Alias (shading , name = "shading" , sep = "/" , size = 2 ),
0 commit comments