diff --git a/doc/api/index.rst b/doc/api/index.rst index 0c07c18a364..7d30a2a0d75 100644 --- a/doc/api/index.rst +++ b/doc/api/index.rst @@ -42,6 +42,7 @@ Plotting data and laying out the map: Figure.solar Figure.subplot Figure.text + Figure.wiggle Color palette table generation: diff --git a/examples/gallery/lines/wiggle.py b/examples/gallery/lines/wiggle.py new file mode 100644 index 00000000000..48ea5140cd0 --- /dev/null +++ b/examples/gallery/lines/wiggle.py @@ -0,0 +1,38 @@ +""" +Wiggle along tracks +------------------- + +The :meth:`pygmt.Figure.wiggle` method can plot z = f(x,y) anomalies along +tracks. ``x``, ``y``, ``z`` can be specified as 1d arrays or within a specified +file. The ``scale`` parameter can be used to set the scale of the anomaly in +data/distance units. The positive and/or negative areas can be filled with +color by setting the ``color`` parameter. +""" + +import numpy as np +import pygmt + +# Create (x, y, z) triplets +x = np.arange(-7, 7, 0.1) +y = np.zeros(x.size) +z = 50 * np.exp(-((x / 3) ** 2)) * np.cos(2 * np.pi * x) + +fig = pygmt.Figure() +fig.basemap(region=[-8, 12, -1, 1], projection="X10c", frame=["Snlr", "xa2f1"]) +fig.wiggle( + x=x, + y=y, + z=z, + # Set anomaly scale to "20c" + scale="20c", + # Fill positive and negative areas red and gray, respectively + color=["red+p", "gray+n"], + # Set the outline width to "1.0p" + pen="1.0p", + # Draw a blue track with a width of 0.5 points + track="0.5p,blue", + # Plot a vertical scale bar at the right middle. The bar length is 100 in + # data (z) units. Set the z unit label to "nT". + position="jRM+w100+lnT", +) +fig.show() diff --git a/pygmt/figure.py b/pygmt/figure.py index ef9269a5994..b6b7128c060 100644 --- a/pygmt/figure.py +++ b/pygmt/figure.py @@ -423,6 +423,7 @@ def _repr_html_(self): solar, subplot, text, + wiggle, ) diff --git a/pygmt/src/__init__.py b/pygmt/src/__init__.py index 7911195bf57..22821804822 100644 --- a/pygmt/src/__init__.py +++ b/pygmt/src/__init__.py @@ -32,5 +32,6 @@ from pygmt.src.surface import surface from pygmt.src.text import text_ as text # "text" is an argument within "text_" from pygmt.src.which import which +from pygmt.src.wiggle import wiggle from pygmt.src.x2sys_cross import x2sys_cross from pygmt.src.x2sys_init import x2sys_init diff --git a/pygmt/src/wiggle.py b/pygmt/src/wiggle.py new file mode 100644 index 00000000000..2e3235e9b64 --- /dev/null +++ b/pygmt/src/wiggle.py @@ -0,0 +1,95 @@ +""" +wiggle - Plot z=f(x,y) anomalies along tracks. +""" +from pygmt.clib import Session +from pygmt.helpers import build_arg_string, fmt_docstring, kwargs_to_strings, use_alias + + +@fmt_docstring +@use_alias( + B="frame", + D="position", + G="color", + J="projection", + R="region", + T="track", + U="timestamp", + V="verbose", + W="pen", + X="xshift", + Y="yshift", + Z="scale", + c="panel", + i="columns", + p="perspective", +) +@kwargs_to_strings(R="sequence", c="sequence_comma", i="sequence_comma", p="sequence") +def wiggle(self, x=None, y=None, z=None, data=None, **kwargs): + r""" + Plot z=f(x,y) anomalies along tracks. + + Takes a matrix, (x,y,z) triplets, or a file name as input and plots z as a + function of distance along track. + + Must provide either ``data`` or ``x``/``y``/``z``. + + Full parameter list at :gmt-docs:`wiggle.html` + + {aliases} + + Parameters + ---------- + x/y/z : 1d arrays + The arrays of x and y coordinates and z data points. + data : str or 2d array + Either a data file name or a 2d numpy array with the tabular data. + Use parameter ``columns`` to choose which columns are x, y, z, + respectively. + {J} + {R} + scale : str or float + Gives anomaly scale in data-units/distance-unit. Append **c**, **i**, + or **p** to indicate the distance unit (cm, inch, or point); if no unit + is given we use the default unit that is controlled by + :gmt-term:`PROJ_LENGTH_UNIT`. + {B} + position : str + [**g**\|\ **j**\|\ **J**\|\ **n**\|\ **x**]\ *refpoint*\ + **+w**\ *length*\ [**+j**\ *justify*]\ [**+al**\ |\ **r**]\ + [**+o**\ *dx*\ [/*dy*]][**+l**\ [*label*]]. + Defines the reference point on the map for the vertical scale bar. + color : str + Set fill shade, color or pattern for positive and/or negative wiggles + [Default is no fill]. Optionally, append **+p** to fill positive areas + (this is the default behavior). Append **+n** to fill negative areas. + Append **+n+p** to fill both positive and negative areas with the same + fill. Note: You will need to repeat the color parameter to select + different fills for the positive and negative wiggles. + + track : str + Draw track [Default is no track]. Append pen attributes to use + [Default is **0.25p,black,solid**]. + {U} + {V} + pen : str + Specify outline pen attributes [Default is no outline]. + {XY} + {c} + columns : str or 1d array + Choose which columns are x, y, and z, respectively if input is provided + via *data*. E.g. ``columns = [0, 1, 2]`` or ``columns = "0,1,2"`` if + the *x* values are stored in the first column, *y* values in the second + one and *z* values in the third one. Note: zero-based indexing is used. + {p} + """ + kwargs = self._preprocess(**kwargs) # pylint: disable=protected-access + + with Session() as lib: + # Choose how data will be passed in to the module + file_context = lib.virtualfile_from_data( + check_kind="vector", data=data, x=x, y=y, z=z + ) + + with file_context as fname: + arg_str = " ".join([fname, build_arg_string(kwargs)]) + lib.call_module("wiggle", arg_str) diff --git a/pygmt/tests/baseline/test_wiggle.png.dvc b/pygmt/tests/baseline/test_wiggle.png.dvc new file mode 100644 index 00000000000..5f3819fb339 --- /dev/null +++ b/pygmt/tests/baseline/test_wiggle.png.dvc @@ -0,0 +1,4 @@ +outs: +- md5: 5ac12f7e91127dae1fa70cec77b84c0b + size: 9144 + path: test_wiggle.png diff --git a/pygmt/tests/test_wiggle.py b/pygmt/tests/test_wiggle.py new file mode 100644 index 00000000000..7bd92e15bb1 --- /dev/null +++ b/pygmt/tests/test_wiggle.py @@ -0,0 +1,31 @@ +""" +Tests wiggle. +""" +import numpy as np +import pytest +from pygmt import Figure + + +@pytest.mark.mpl_image_compare +def test_wiggle(): + """ + Plot the z=f(x,y) anomalies along tracks. + """ + x = np.arange(-2, 2, 0.02) + y = np.zeros(x.size) + z = np.cos(2 * np.pi * x) + + fig = Figure() + fig.wiggle( + region=[-4, 4, -1, 1], + projection="X8c", + x=x, + y=y, + z=z, + scale="0.5c", + color=["red+p", "gray+n"], + pen="1.0p", + track="0.5p", + position="jRM+w2+lnT", + ) + return fig