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()
63 changes: 51 additions & 12 deletions pygmt/src/wiggle.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
from collections.abc import Sequence
from typing import Literal

from pygmt._typing import PathLike, TableLike
from pygmt._typing import AnchorCode, PathLike, TableLike
from pygmt.alias import Alias, AliasSystem
from pygmt.clib import Session
from pygmt.helpers import build_arg_list, deprecate_parameter, fmt_docstring, use_alias
from pygmt.params import Position
from pygmt.src._common import _parse_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 | Sequence[float | str] | AnchorCode | 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 All @@ -72,8 +77,8 @@ def wiggle( # noqa: PLR0913
verbose: Literal["quiet", "error", "warning", "timing", "info", "compat", "debug"]
| bool = False,
panel: int | Sequence[int] | bool = False,
transparency: float | None = None,
perspective: float | Sequence[float] | str | bool = False,
transparency: float | None = None,
incols: int | str | Sequence[int | str] | None = None,
**kwargs,
):
Expand All @@ -89,6 +94,7 @@ def wiggle( # noqa: PLR0913

$aliases
- B = frame
- D = **+w**: length, **+l**: label, **+a**: label_alignment
- G = **+p**: positive_fill, **+n**: negative_fill
- J = projection
- R = region
Expand All @@ -107,29 +113,45 @@ def wiggle( # noqa: PLR0913
$table_classes.
Use parameter ``incols`` to choose which columns are x, y, z,
respectively.
$projection
$region

position
Position of the vertical scale on the plot. It can be specified in multiple
ways:

- A :class:`pygmt.params.Position` object to fully control the reference point,
anchor point, and offset.
- A sequence of two values representing the x and y coordinates in plot
coordinates, e.g., ``(1, 2)`` or ``("1c", "2c")``.
- A :doc:`2-character justification code </techref/justification_codes>` for a
position inside the plot, e.g., ``"TL"`` for Top Left corner inside the plot.

If not specified, defaults to the bottom-left corner of the plot with a 0.2-cm
offset.
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 +166,26 @@ def wiggle( # noqa: PLR0913
"""
self._activate_figure()

position = _parse_position(
position,
kwdict={"length": length, "label": label, "label_alignment": label_alignment},
default=Position("BL", offset=0.2), # Default to BL with 0.2-cm offset.
)

_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
5 changes: 5 additions & 0 deletions pygmt/tests/baseline/test_wiggle_default_position.png.dvc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
outs:
- md5: 362640b4554c7e5097340c578a672988
size: 16058
hash: md5
path: test_wiggle_default_position.png
103 changes: 93 additions & 10 deletions pygmt/tests/test_wiggle.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,73 @@
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
def test_wiggle():
@pytest.fixture(scope="module", name="data")
def fixture_xyz():
"""
Plot the z=f(x,y) anomalies along tracks.
Create sample (x, y, z) data for testing.
"""
x = np.arange(-2, 2, 0.02)
y = np.zeros(x.size)
z = np.cos(2 * np.pi * x)
return (x, y, z)


@pytest.mark.mpl_image_compare
def test_wiggle(data):
"""
Plot the z=f(x,y) anomalies along tracks.
"""
x, y, z = data
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=Position("MR"),
length=2,
label="nT",
)
return fig


@pytest.mark.mpl_image_compare
def test_wiggle_default_position(data):
"""
Test that wiggle works when position is not provided.
"""
x, y, z = data
fig = Figure()
fig.wiggle(
region=[-4, 4, -1, 1],
projection="X8c",
frame=True,
x=x,
y=y,
z=z,
pen="1p",
scale="0.5c",
length=1,
)
return fig


@pytest.mark.mpl_image_compare(filename="test_wiggle.png")
def test_wiggle_deprecated_position_syntax(data):
"""
Test the deprecated position syntax for wiggle.
"""
x, y, z = data
fig = Figure()
fig.wiggle(
region=[-4, 4, -1, 1],
Expand All @@ -28,23 +84,20 @@ def test_wiggle():
negative_fill="gray",
pen="1.0p",
track="0.5p",
position="jRM+w2+lnT",
position="jMR+w2+lnT",
)
return fig


@pytest.mark.benchmark
@pytest.mark.mpl_image_compare(filename="test_wiggle.png")
def test_wiggle_data_incols():
def test_wiggle_data_incols(data):
"""
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)
y = np.zeros(x.size)
z = np.cos(2 * np.pi * x)
x, y, z = data
data = np.array([y, x, z]).T

fig = Figure()
Expand All @@ -58,6 +111,36 @@ 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(data):
"""
Test that an error is raised when mixing new and deprecated syntax in 'position'.
"""
x, y, z = data
fig = Figure()
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)
Loading