diff --git a/pygmt/src/coast.py b/pygmt/src/coast.py index 7111f3d6f5a..a89da6a43a1 100644 --- a/pygmt/src/coast.py +++ b/pygmt/src/coast.py @@ -37,7 +37,7 @@ t="transparency", ) @kwargs_to_strings(R="sequence", c="sequence_comma", p="sequence") -def coast(self, **kwargs): +def coast(self, clip=None, **kwargs): r""" Plot continents, shorelines, rivers, and borders on maps @@ -81,7 +81,7 @@ def coast(self, **kwargs): (**h**\ )igh, (**i**\ )ntermediate, (**l**\ )ow, and (**c**\ )rude. land : str - Select filling or clipping of "dry" areas. + Select filling of "dry" areas. rivers : int or str or list *river*\ [/*pen*]. Draw rivers. Specify the type of rivers and [optionally] append @@ -147,7 +147,7 @@ def coast(self, **kwargs): a = All boundaries (1-3) water : str - Select filling or clipping of "wet" areas. + Select filling of "wet" areas. {U} shorelines : int or str or list [*level*\ /]\ *pen*. @@ -159,6 +159,13 @@ def coast(self, **kwargs): lake-in-island-in-lake shore. Pass a list of *level*\ /*pen* strings to ``shorelines`` to set multiple levels. When specific level pens are set, those not listed will not be drawn. + clip : str + To clip land do ``clip="land"``, ``clip="water"`` clips water. Use + ``clip="end"`` to mark end of existing clip path. The clip path applies + to all plotting calls between the start of the clip path and the end of + the clip path. No projection information is needed. Also supply + ``xshift`` and ``yshift`` settings if you have moved since the clip + started. dcw : str or list *code1,code2,…*\ [**+l**\|\ **L**\ ][**+g**\ *fill*\ ] [**+p**\ *pen*\ ][**+z**]. @@ -181,12 +188,47 @@ def coast(self, **kwargs): {p} {t} {V} + + Example + ------- + >>> # Initiate a clip path for Africa so that the subsequent colorimage of + >>> # gridded topography is only seen over land + >>> import pygmt # doctest: +SKIP + >>> # Load a grid of earth_relief_05m data, with an x-range of -30 to 30, + >>> # and a y-range of -40 to 40 + >>> grid = pygmt.datasets.load_earth_relief( + ... resolution="05m", region=[-30, 30, -40, 40] + ... ) # doctest: +SKIP + >>> # Create an instance of the Figure class + >>> fig = pygmt.Figure() # doctest: +SKIP + >>> # Initiate clip path for land areas based on low-resolution coastlines + >>> fig.coast( + ... projection="M12c", resolution="l", clip="land", frame=True + ... ) # doctest: +SKIP + >>> # Plot the clipped grid + >>> fig.grdimage(grid=grid, cmap="relief") # doctest: +SKIP + >>> # End clip path + >>> fig.coast(clip="end") # doctest: +SKIP """ kwargs = self._preprocess(**kwargs) # pylint: disable=protected-access + + if clip: + if clip == "land": + kwargs["G"] = True + elif clip == "water": + kwargs["S"] = True + elif clip == "end": + kwargs["Q"] = True + else: + raise GMTInvalidInput( + "Invalid clip parameter. Must be one of 'land', 'water', and 'end'." + ) + if not args_in_kwargs(args=["C", "G", "S", "I", "N", "E", "Q", "W"], kwargs=kwargs): raise GMTInvalidInput( """At least one of the following parameters must be specified: - lakes, land, water, rivers, borders, dcw, Q, or shorelines""" + lakes, land, water, rivers, borders, dcw, clip, or shorelines""" ) + with Session() as lib: lib.call_module("coast", build_arg_string(kwargs)) diff --git a/pygmt/tests/baseline/test_coast_clip_land.png.dvc b/pygmt/tests/baseline/test_coast_clip_land.png.dvc new file mode 100644 index 00000000000..2ab18888f9d --- /dev/null +++ b/pygmt/tests/baseline/test_coast_clip_land.png.dvc @@ -0,0 +1,4 @@ +outs: +- md5: 12f5586967f870a7e70e012a5dadf76c + size: 14597 + path: test_coast_clip_land.png diff --git a/pygmt/tests/baseline/test_coast_clip_water.png.dvc b/pygmt/tests/baseline/test_coast_clip_water.png.dvc new file mode 100644 index 00000000000..0712f34faa9 --- /dev/null +++ b/pygmt/tests/baseline/test_coast_clip_water.png.dvc @@ -0,0 +1,4 @@ +outs: +- md5: dcae0e21783cd153f6daaae927e3a771 + size: 23423 + path: test_coast_clip_water.png diff --git a/pygmt/tests/test_coast.py b/pygmt/tests/test_coast.py index 1fc66a0ae9b..35f28b24abe 100644 --- a/pygmt/tests/test_coast.py +++ b/pygmt/tests/test_coast.py @@ -72,3 +72,57 @@ def test_coast_dcw_list(): dcw=["ES+gbisque+pgreen", "IT+gcyan+pblue"], ) return fig + + +@pytest.mark.mpl_image_compare +def test_coast_clip_land(): + """ + Test to clip dry areas. + """ + region = [-28, -10, 62, 68] + + fig = Figure() + fig.basemap(region=region, projection="M8c", frame=True) + fig.coast(resolution="l", clip="land") + fig.plot( + x=[-22.5, -22.5, -15, -15], + y=[66, 64, 66, 64], + style="c4c", + color="red", + pen="1.5p,black", + ) + fig.coast(clip="end") + return fig + + +@pytest.mark.mpl_image_compare +def test_coast_clip_water(): + """ + Test to clip wet areas. + """ + region = [-28, -10, 62, 68] + + fig = Figure() + fig.basemap(region=region, projection="M8c", frame=True) + fig.coast(resolution="l", clip="water") + fig.plot( + x=[-22.5, -22.5, -15, -15], + y=[66, 64, 66, 64], + style="c4c", + color="red", + pen="1.5p,black", + ) + fig.coast(clip="end") + return fig + + +def test_coast_fail_invalid_parameter(): + """ + Coast should raise an exception if an invalid parameter is given as input. + """ + region = [-28, -10, 62, 68] + + fig = Figure() + + with pytest.raises(GMTInvalidInput): + fig.coast(region=region, resolution="l", clip="invalid")