diff --git a/doc/api/index.rst b/doc/api/index.rst index 747c1fb8a9a..80cb112d015 100644 --- a/doc/api/index.rst +++ b/doc/api/index.rst @@ -24,6 +24,7 @@ Plotting data and laying out the map: Figure.basemap Figure.coast + Figure.colorbar Figure.plot Figure.contour Figure.grdcontour diff --git a/examples/gallery/plot/README.txt b/examples/gallery/plot/README.txt index d8f769a3ced..c213e06feea 100644 --- a/examples/gallery/plot/README.txt +++ b/examples/gallery/plot/README.txt @@ -1,2 +1,2 @@ -Lines, points, and scatters ---------------------------- +Plotting map items +------------------ diff --git a/examples/gallery/plot/colorbar.py b/examples/gallery/plot/colorbar.py new file mode 100644 index 00000000000..195198cfdac --- /dev/null +++ b/examples/gallery/plot/colorbar.py @@ -0,0 +1,52 @@ +""" +Colorbar +-------- + +The :meth:`pygmt.Figure.colorbar` method creates a color scalebar. We must specify the +colormap via the ``cmap`` argument, and set the placement via the ``position`` argument. +The full list of color paletted tables can be found at :gmt-docs:`cookbook/cpts.html`. +You can set the `position` of the colorbar using the following options: + +- j/J: justified inside/outside the mapframe 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. `position="jTR"` for top right. +- g: using map coordinates, e.g. `position="g170/-45"` for longitude 170E, latitude 45S. +- x: using paper coordinates, e.g. `position="x5c/7c"` for 5cm,7cm from anchor point. +- n: using normalized (0-1) coordinates, e.g. `position="n0.4/0.8"`. + +Note that the anchor point defaults to the bottom left (BL). Append +h to ``position`` +to get a horizontal colorbar instead of a vertical one. For more advanced styling +options, see the full option list at :gmt-docs:`colorbar.html`. +""" +import pygmt + +fig = pygmt.Figure() +fig.basemap(region=[0, 3, 6, 9], projection="t0/3c", frame=True) + +# Create a colorbar suitable for surface topography- oleron + +fig.colorbar( + cmap="oleron", + position="jTC+w6c/1c+h", # justified inside map frame (j) at Top Center (TC) + box=True, + frame=["+Loleron", "xaf", "y+lm"], + scale=10, +) +# Create a colorbar designed for seismic tomography- roma +fig.colorbar( + cmap="roma", + position="x1.2c/4.75c+w6c/1c+h", # plot using paper coordinates (x) at 1.2cm,4.75cm + box=True, + frame=["+Lroma", "xaf", "y+lm/s"], + scale=10, +) +# Create a colorbar showing the scientific rainbow - batlow +fig.colorbar( + cmap="batlow", + position="g0.45/6.6+w6c/1c+h", # plot using map coordinates (g) at lon/lat 0.45/6.6 + box=True, + frame=["+Lbatlow", "xaf", r"y+l\260C"], + scale=10, +) + +fig.show() diff --git a/pygmt/base_plotting.py b/pygmt/base_plotting.py index 8d43c88c162..811b2aba505 100644 --- a/pygmt/base_plotting.py +++ b/pygmt/base_plotting.py @@ -131,6 +131,86 @@ def coast(self, **kwargs): with Session() as lib: lib.call_module("coast", build_arg_string(kwargs)) + @fmt_docstring + @use_alias( + R="region", + J="projection", + B="frame", + C="cmap", + D="position", + F="box", + G="truncate", + W="scale", + ) + @kwargs_to_strings(R="sequence", G="sequence") + def colorbar(self, **kwargs): + """ + Plot a gray or color scale-bar on maps. + + Both horizontal and vertical scales are supported. For CPTs with gradational + colors (i.e., the lower and upper boundary of an interval have different colors) + we will interpolate to give a continuous scale. Variations in intensity due to + shading/illumination may be displayed by setting the option -I. Colors may be + spaced according to a linear scale, all be equal size, or by providing a file + with individual tile widths. + + Full option list at :gmt-docs:`colorbar.html` + + Parameters + ---------- + position (D) : str + ``[g|j|J|n|x]refpoint[+wlength[/width]][+e[b|f][length]][+h|v][+jjustify] + [+m[a|c|l|u]][+n[txt]][+odx[/dy]]``. + Defines the reference point on the map for the color scale using one of four + coordinate systems: + (1) Use -Dg for map (user) coordinates, + (2) use -Dj or -DJ for setting refpoint via a 2-char justification code that + refers to the (invisible) map domain rectangle, + (3) use -Dn for normalized (0-1) coordinates, or + (4) use -Dx for plot coordinates (inches, cm, etc.).\ + All but -Dx requires both -R and -J to be specified. + Append +w followed by the length and width of the color bar. + If width is not specified then it is set to 4% of the given length. + Give a negative length to 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-char + justification code justify. + + box (F) : bool or str + ``[+cclearances][+gfill][+i[[gap/]pen]][+p[pen]][+r[radius]][+s[[dx/dy/] + [shade]]]``. + If set to True, draws a rectangular border around the color scale. + Alternatively, specify a different pen with +ppen. + Add +gfill to fill the scale panel [no fill]. + Append +cclearance where clearance is either gap, xgap/ygap, or + lgap/rgap/bgap/tgap where these items are uniform, separate in x- and + y-direction, or individual side spacings between scale and border. + Append +i to draw a secondary, inner border as well. We use a uniform gap + between borders of 2p and the MAP_DEFAULTS_PEN unless other values are + specified. + Append +r to draw rounded rectangular borders instead, with a 6p corner + radius. You can override this radius by appending another value. + Finally, append +s to draw an offset background shaded region. Here, dx/dy + indicates the shift relative to the foreground frame [4p/-4p] and shade sets + the fill style to use for shading [gray50]. + + truncate (G) : list or str + ``zlo/zhi`` + Truncate the incoming CPT so that the lowest and highest z-levels are to zlo + and zhi. If one of these equal NaN then we leave that end of the CPT alone. + The truncation takes place before the plotting. + + scale (W) : float + Multiply all z-values in the CPT by the provided scale. By default the CPT + is used as is. + + {aliases} + """ + kwargs = self._preprocess(**kwargs) + with Session() as lib: + lib.call_module("colorbar", build_arg_string(kwargs)) + @fmt_docstring @use_alias( A="annotation", diff --git a/pygmt/tests/baseline/test_colorbar_box.png b/pygmt/tests/baseline/test_colorbar_box.png new file mode 100644 index 00000000000..895ac1031f7 Binary files /dev/null and b/pygmt/tests/baseline/test_colorbar_box.png differ diff --git a/pygmt/tests/baseline/test_colorbar_box_with_clearance.png b/pygmt/tests/baseline/test_colorbar_box_with_clearance.png new file mode 100644 index 00000000000..1511a8d7231 Binary files /dev/null and b/pygmt/tests/baseline/test_colorbar_box_with_clearance.png differ diff --git a/pygmt/tests/baseline/test_colorbar_box_with_fill.png b/pygmt/tests/baseline/test_colorbar_box_with_fill.png new file mode 100644 index 00000000000..3c52057604c Binary files /dev/null and b/pygmt/tests/baseline/test_colorbar_box_with_fill.png differ diff --git a/pygmt/tests/baseline/test_colorbar_box_with_offset_background.png b/pygmt/tests/baseline/test_colorbar_box_with_offset_background.png new file mode 100644 index 00000000000..273540f0c79 Binary files /dev/null and b/pygmt/tests/baseline/test_colorbar_box_with_offset_background.png differ diff --git a/pygmt/tests/baseline/test_colorbar_box_with_pen.png b/pygmt/tests/baseline/test_colorbar_box_with_pen.png new file mode 100644 index 00000000000..3ca2b1855c5 Binary files /dev/null and b/pygmt/tests/baseline/test_colorbar_box_with_pen.png differ diff --git a/pygmt/tests/baseline/test_colorbar_box_with_rounded_corners.png b/pygmt/tests/baseline/test_colorbar_box_with_rounded_corners.png new file mode 100644 index 00000000000..88cef9fd49e Binary files /dev/null and b/pygmt/tests/baseline/test_colorbar_box_with_rounded_corners.png differ diff --git a/pygmt/tests/baseline/test_colorbar_box_with_secondary_border.png b/pygmt/tests/baseline/test_colorbar_box_with_secondary_border.png new file mode 100644 index 00000000000..7e88ab113b4 Binary files /dev/null and b/pygmt/tests/baseline/test_colorbar_box_with_secondary_border.png differ diff --git a/pygmt/tests/baseline/test_colorbar_positioned_using_justification_code.png b/pygmt/tests/baseline/test_colorbar_positioned_using_justification_code.png new file mode 100644 index 00000000000..7f26712d622 Binary files /dev/null and b/pygmt/tests/baseline/test_colorbar_positioned_using_justification_code.png differ diff --git a/pygmt/tests/baseline/test_colorbar_positioned_using_map_coordinates.png b/pygmt/tests/baseline/test_colorbar_positioned_using_map_coordinates.png new file mode 100644 index 00000000000..b7ccbfb9f3b Binary files /dev/null and b/pygmt/tests/baseline/test_colorbar_positioned_using_map_coordinates.png differ diff --git a/pygmt/tests/baseline/test_colorbar_positioned_using_normalized_coords.png b/pygmt/tests/baseline/test_colorbar_positioned_using_normalized_coords.png new file mode 100644 index 00000000000..efcc94dfbbc Binary files /dev/null and b/pygmt/tests/baseline/test_colorbar_positioned_using_normalized_coords.png differ diff --git a/pygmt/tests/baseline/test_colorbar_scaled_z_values.png b/pygmt/tests/baseline/test_colorbar_scaled_z_values.png new file mode 100644 index 00000000000..7fc3170c818 Binary files /dev/null and b/pygmt/tests/baseline/test_colorbar_scaled_z_values.png differ diff --git a/pygmt/tests/baseline/test_colorbar_truncated_to_zlow_zhigh.png b/pygmt/tests/baseline/test_colorbar_truncated_to_zlow_zhigh.png new file mode 100644 index 00000000000..1a8f80a90c8 Binary files /dev/null and b/pygmt/tests/baseline/test_colorbar_truncated_to_zlow_zhigh.png differ diff --git a/pygmt/tests/baseline/test_colorbar_using_paper_coordinates.png b/pygmt/tests/baseline/test_colorbar_using_paper_coordinates.png new file mode 100644 index 00000000000..f7f8b99d407 Binary files /dev/null and b/pygmt/tests/baseline/test_colorbar_using_paper_coordinates.png differ diff --git a/pygmt/tests/baseline/test_colorbar_using_paper_coordinates_horizontal.png b/pygmt/tests/baseline/test_colorbar_using_paper_coordinates_horizontal.png new file mode 100644 index 00000000000..dced4c597bc Binary files /dev/null and b/pygmt/tests/baseline/test_colorbar_using_paper_coordinates_horizontal.png differ diff --git a/pygmt/tests/test_colorbar.py b/pygmt/tests/test_colorbar.py new file mode 100644 index 00000000000..5fea02100db --- /dev/null +++ b/pygmt/tests/test_colorbar.py @@ -0,0 +1,150 @@ +""" +Tests colorbar +""" +import pytest + +from .. import Figure + + +@pytest.mark.mpl_image_compare +def test_colorbar_using_paper_coordinates(): + """ + Create colorbar positioned at 0cm,0cm with length 1cm and width 0.5cm. + """ + fig = Figure() + fig.colorbar(cmap="rainbow", position="x0c/0c+w1c/0.5c") + return fig + + +@pytest.mark.mpl_image_compare +def test_colorbar_using_paper_coordinates_horizontal(): + """ + Create colorbar positioned at 0cm,0cm with length 2cm oriented horizontally. + """ + fig = Figure() + fig.colorbar(cmap="rainbow", position="x0c/0c+w2c+h") + return fig + + +@pytest.mark.mpl_image_compare +def test_colorbar_positioned_using_map_coordinates(): + """ + Create colorbar positioned at longitude,latitude 3,6 with length 2cm. + """ + fig = Figure() + fig.basemap(region=[2, 4, 6, 8], projection="t0/2c", frame=True) + fig.colorbar(cmap="rainbow", position="g3/6+w2c") + return fig + + +@pytest.mark.mpl_image_compare +def test_colorbar_positioned_using_justification_code(): + """ + Create colorbar positioned at Top Center inside the map frame with length 2cm. + """ + fig = Figure() + fig.basemap(region=[2, 4, 6, 8], projection="t0/2c", frame=True) + fig.colorbar(cmap="rainbow", position="jTC+w2c") + return fig + + +@pytest.mark.mpl_image_compare +def test_colorbar_positioned_using_normalized_coords(): + """ + Create colorbar positioned at normalized coordinates 0.75,0.25 with length 2cm. + """ + fig = Figure() + fig.basemap(region=[2, 4, 6, 8], projection="t0/2c", frame=True) + fig.colorbar(cmap="rainbow", position="n0.75/0.25+w2c") + return fig + + +@pytest.mark.mpl_image_compare +def test_colorbar_box(): + """ + Create colorbar with box around it. + """ + fig = Figure() + fig.colorbar(cmap="rainbow", box=True, position="x0c/0c+w1c/0.5c") + return fig + + +@pytest.mark.mpl_image_compare +def test_colorbar_box_with_pen(): + """ + Create colorbar with box that has a different colored pen. + """ + fig = Figure() + fig.colorbar(cmap="rainbow", box="+porange", position="x0c/0c+w1c/0.5c") + return fig + + +@pytest.mark.mpl_image_compare +def test_colorbar_box_with_fill(): + """ + Create colorbar with box that has a different colored fill. + """ + fig = Figure() + fig.colorbar(cmap="rainbow", box="+gorange", position="x0c/0c+w1c/0.5c") + return fig + + +@pytest.mark.mpl_image_compare +def test_colorbar_box_with_clearance(): + """ + Create colorbar with box that has an x-clearance of 0.8cm and y-clearance of 0.4cm. + """ + fig = Figure() + fig.colorbar(cmap="rainbow", box="+c0.8c/0.4c+porange", position="x0c/0c+w1c/0.5c") + return fig + + +@pytest.mark.mpl_image_compare +def test_colorbar_box_with_secondary_border(): + """ + Create colorbar with box that has a secondary, inner border in addition to the main + primary, outer border. + """ + fig = Figure() + fig.colorbar(cmap="rainbow", box="+porange+imagenta", position="x0c/0c+w1c/0.5c") + return fig + + +@pytest.mark.mpl_image_compare +def test_colorbar_box_with_rounded_corners(): + """ + Create colorbar with box that has rounded corners. + """ + fig = Figure() + fig.colorbar(cmap="rainbow", box="+porange+r", position="x0c/0c+w1c/0.5c") + return fig + + +@pytest.mark.mpl_image_compare +def test_colorbar_box_with_offset_background(): + """ + Create colorbar with box and an offset background shaded region. + """ + fig = Figure() + fig.colorbar(cmap="rainbow", box="+s5p/-5p", position="x0c/0c+w1c/0.5c") + return fig + + +@pytest.mark.mpl_image_compare +def test_colorbar_truncated_to_zlow_zhigh(): + """ + Create colorbar truncated to z-low and z-high. + """ + fig = Figure() + fig.colorbar(cmap="rainbow", truncate=[0.15, 0.85], position="x0c/0c+w2c/0.5c") + return fig + + +@pytest.mark.mpl_image_compare +def test_colorbar_scaled_z_values(): + """ + Create colorbar with z-values scaled to 0.1x of the original CPT. + """ + fig = Figure() + fig.colorbar(cmap="rainbow", scale=0.1, position="x0c/0c+w2c/0.5c") + return fig