Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 14 additions & 19 deletions examples/gallery/lines/wiggle.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@
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 1-D 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 ``positive_fill`` and/or ``negative_fill``
parameters.
The :meth:`pygmt.Figure.wiggle` method can plot z = f(x,y) anomalies along tracks.
``x``, ``y``, ``z`` can be specified as 1-D 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
``positive_fill`` and/or ``negative_fill`` parameters.
"""

# %%
import numpy as np
import pygmt
from pygmt.params import Position

# Create (x, y, z) triplets
x = np.arange(-7, 7, 0.1)
Expand All @@ -25,18 +25,13 @@
x=x,
y=y,
z=z,
# Set anomaly scale to 20 centimeters
scale="20c",
# Fill positive areas red
positive_fill="red",
# Fill negative areas gray
negative_fill="gray",
# Set the outline width to 1.0 point
pen="1.0p",
# Draw a blue track with a width of 0.5 points
track="0.5p,blue",
# Plot a vertical scale bar at Middle Right (MR). The bar length (+w)
# is 100 in data (z) units. Set the z unit label (+l) to "nT".
position="jMR+w100+lnT",
scale="20c", # Set anomaly scale to 20 centimeters
positive_fill="red", # Fill positive areas red
negative_fill="gray", # Fill negative areas gray
pen="1.0p", # Set the outline width to 1.0 point
track="0.5p,blue", # Draw a blue track with a width of 0.5 points
position=Position("MR"), # Plot a vertical scale bar at Middle Right (MR).
length=100, # Bar length is 100 in data (z) units.
label="nT", # Set the z unit label to "nT".
)
fig.show()
50 changes: 40 additions & 10 deletions pygmt/src/wiggle.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
from pygmt._typing import PathLike, TableLike
from pygmt.alias import Alias, AliasSystem
from pygmt.clib import Session
from pygmt.exceptions import GMTInvalidInput
from pygmt.helpers import build_arg_list, deprecate_parameter, fmt_docstring, use_alias
from pygmt.params import Position


def _parse_fills(positive_fill, negative_fill):
Expand Down Expand Up @@ -46,7 +48,6 @@ def _parse_fills(positive_fill, negative_fill):
"fillnegative", "negative_fill", "v0.18.0", remove_version="v0.20.0"
)
@use_alias(
D="position",
T="track",
W="pen",
Z="scale",
Expand All @@ -64,6 +65,10 @@ def wiggle( # noqa: PLR0913
x=None,
y=None,
z=None,
position: Position | None = None,
length: float | str | None = None,
label: str | None = None,
label_alignment: Literal["left", "right"] | None = None,
positive_fill=None,
negative_fill=None,
projection: str | None = None,
Expand Down Expand Up @@ -107,29 +112,34 @@ def wiggle( # noqa: PLR0913
$table_classes.
Use parameter ``incols`` to choose which columns are x, y, z,
respectively.
$projection
$region
position
Specify the position of the vertical scale bar on the plot. See
:class:`pygmt.params.Position` for more details.
length
Length of the vertical scale bar in data (z) units.
label
Set the z unit label that is used in the scale label [Default is no unit].
label_alignment
Set the alignment of the scale label. Choose from ``"left"`` or ``"right"``
[Default is ``"left"``].
scale : str or float
Give anomaly scale in data-units/distance-unit. Append **c**, **i**,
or **p** to indicate the distance unit (centimeters, inches, or
points); if no unit is given we use the default unit that is
controlled by :gmt-term:`PROJ_LENGTH_UNIT`.
$frame
position : str
[**g**\|\ **j**\|\ **J**\|\ **n**\|\ **x**]\ *refpoint*\
**+w**\ *length*\ [**+j**\ *justify*]\ [**+al**\|\ **r**]\
[**+o**\ *dx*\ [/*dy*]][**+l**\ [*label*]].
Define the reference point on the map for the vertical scale bar.
positive_fill : str
Set color or pattern for filling positive wiggles [Default is no fill].
negative_fill : str
Set color or pattern for filling negative wiggles [Default is no fill].
track : str
Draw track [Default is no track]. Append pen attributes to use
[Default is ``"0.25p,black,solid"``].
$verbose
pen : str
Specify outline pen attributes [Default is no outline].
$projection
$region
$frame
$verbose
$binary
$panel
$nodata
Expand All @@ -144,9 +154,29 @@ def wiggle( # noqa: PLR0913
"""
self._activate_figure()

if isinstance(position, str) and any(
v is not None for v in (length, label, label_alignment)
):
msg = (
"Parameter 'position' is given with a raw GMT command string, and conflicts "
"with parameters 'length', 'label', and 'label_alignment'."
)
raise GMTInvalidInput(msg)

_fills = _parse_fills(positive_fill, negative_fill)

aliasdict = AliasSystem(
D=[
Alias(position, name="position"),
Alias(length, name="length", prefix="+w"),
Alias(
label_alignment,
name="label_alignment",
prefix="+a",
mapping={"left": "l", "right": "r"},
),
Alias(label, name="label", prefix="+l"),
],
G=Alias(_fills, name="positive_fill/negative_fill"),
).add_common(
B=frame,
Expand Down
68 changes: 65 additions & 3 deletions pygmt/tests/test_wiggle.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import numpy as np
import pytest
from pygmt import Figure
from pygmt.exceptions import GMTInvalidInput
from pygmt.params import Position


@pytest.mark.mpl_image_compare
Expand All @@ -28,7 +30,35 @@ def test_wiggle():
negative_fill="gray",
pen="1.0p",
track="0.5p",
position="jRM+w2+lnT",
position=Position("MR"),
length=2,
label="nT",
)
return fig


@pytest.mark.mpl_image_compare(filename="test_wiggle.png")
def test_wiggle_deprecated_position_syntax():
"""
Test the deprecated position syntax for wiggle.
"""
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",
positive_fill="red",
negative_fill="gray",
pen="1.0p",
track="0.5p",
position="jMR+w2+lnT",
)
return fig

Expand All @@ -39,7 +69,6 @@ def test_wiggle_data_incols():
"""
Make sure that incols parameter works with input data array.
"""

# put data into numpy array and swap x and y columns
# as the use of the 'incols' parameter will reverse this action
x = np.arange(-2, 2, 0.02)
Expand All @@ -58,6 +87,39 @@ def test_wiggle_data_incols():
negative_fill="gray",
pen="1.0p",
track="0.5p",
position="jRM+w2+lnT",
position=Position("MR"),
length=2,
label="nT",
)
return fig


def test_wiggle_mixed_syntax():
"""
Test that an error is raised when mixing new and deprecated syntax in 'position'.
"""
fig = Figure()
x = np.arange(-2, 2, 0.02)
y = np.zeros(x.size)
z = np.cos(2 * np.pi * x)

kwargs = {
"region": [-4, 4, -1, 1],
"projection": "X8c",
"x": x,
"y": y,
"z": z,
"scale": "0.5c",
"positive_fill": "red",
"negative_fill": "gray",
"pen": "1.0p",
"track": "0.5p",
}
with pytest.raises(GMTInvalidInput):
fig.wiggle(position="jMR+w2+lnT", length=2, **kwargs)

with pytest.raises(GMTInvalidInput):
fig.wiggle(position="jMR+w2+lnT", label="nT", **kwargs)

with pytest.raises(GMTInvalidInput):
fig.wiggle(position="jMR+w2+lnT", length_alignment="left", **kwargs)