Skip to content

Commit

Permalink
Figure.grdcontour: Adjust processing of arguments passed to the "anno…
Browse files Browse the repository at this point in the history
…tation" and "interval" parameters, deprecate "sequence_plus" (#3116)

Co-authored-by: Dongdong Tian <[email protected]>
Co-authored-by: actions-bot <[email protected]>
Co-authored-by: Yvonne <[email protected]>
  • Loading branch information
4 people authored Apr 27, 2024
1 parent 72ce692 commit 0e630e3
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 30 deletions.
90 changes: 61 additions & 29 deletions pygmt/src/grdcontour.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,16 @@
grdcontour - Plot a contour figure.
"""

import warnings

from pygmt.clib import Session
from pygmt.helpers import build_arg_list, fmt_docstring, kwargs_to_strings, use_alias
from pygmt.helpers import (
build_arg_list,
fmt_docstring,
is_nonstr_iter,
kwargs_to_strings,
use_alias,
)

__doctest_skip__ = ["grdcontour"]

Expand All @@ -27,9 +35,7 @@
p="perspective",
t="transparency",
)
@kwargs_to_strings(
R="sequence", L="sequence", A="sequence_plus", c="sequence_comma", p="sequence"
)
@kwargs_to_strings(R="sequence", L="sequence", c="sequence_comma", p="sequence")
def grdcontour(self, grid, **kwargs):
r"""
Convert grids or images to contours and plot them on maps.
Expand All @@ -43,26 +49,26 @@ def grdcontour(self, grid, **kwargs):
Parameters
----------
{grid}
interval : str or int
interval : float, list, or str
Specify the contour lines to generate.
- The file name of a CPT file where the color boundaries will
be used as contour levels.
- The file name of a 2 (or 3) column file containing the contour
levels (col 1), (**C**)ontour or (**A**)nnotate (col 2), and optional
angle (col 3).
- A fixed contour interval *cont_int* or a single contour with
+\ *cont_int*.
annotation : str, int, or list
- The file name of a CPT file where the color boundaries will be used as
contour levels.
- The file name of a 2 (or 3) column file containing the contour levels (col 0),
(**C**)ontour or (**A**)nnotate (col 1), and optional angle (col 2).
- A fixed contour interval.
- A list of contour levels.
annotation : float, list, or str
Specify or disable annotated contour levels, modifies annotated
contours specified in ``interval``.
- Specify a fixed annotation interval *annot_int* or a
single annotation level +\ *annot_int*.
- Disable all annotation with **-**.
- Optional label modifiers can be specified as a single string
``"[annot_int]+e"`` or with a list of arguments
``([annot_int], "e", "f10p", "gred")``.
- Specify a fixed annotation interval.
- Specify a list of annotation levels.
- Disable all annotations by setting ``annotation="n"``.
- Adjust the appearance by appending different modifiers, e.g.,
``"annot_int+f10p+gred"`` gives annotations with a font size of 10 points
and a red filled box. For all available modifiers see
:gmt-docs:`grdcontour.html#a`.
limit : str or list of 2 ints
*low*/*high*.
Do no draw contours below `low` or above `high`, specify as string
Expand Down Expand Up @@ -96,32 +102,58 @@ def grdcontour(self, grid, **kwargs):
Example
-------
>>> import pygmt
>>> # load the 15 arc-minutes grid with "gridline" registration
>>> # in a specified region
>>> # Load the 15 arc-minutes grid with "gridline" registration in the
>>> # specified region
>>> grid = pygmt.datasets.load_earth_relief(
... resolution="15m",
... region=[-92.5, -82.5, -3, 7],
... registration="gridline",
... )
>>> # create a new plot with pygmt.Figure()
>>> # Create a new plot with pygmt.Figure()
>>> fig = pygmt.Figure()
>>> # create the contour plot
>>> # Create the contour plot
>>> fig.grdcontour(
... # pass in the grid downloaded above
... # Pass in the grid downloaded above
... grid=grid,
... # set the interval for contour lines at 250 meters
... # Set the interval for contour lines at 250 meters
... interval=250,
... # set the interval for annotated contour lines at 1,000 meters
... # Set the interval for annotated contour lines at 1,000 meters
... annotation=1000,
... # add a frame for the plot
... # Add a frame for the plot
... frame="a",
... # set the projection to Mercator for the 10 cm figure
... # Set the projection to Mercator for the 10 cm figure
... projection="M10c",
... )
>>> # show the plot
>>> # Show the plot
>>> fig.show()
"""
kwargs = self._preprocess(**kwargs)

# Backward compatibility with the old syntax for the annotation parameter, e.g.,
# [100, "e", "f10p", "gred"].
if is_nonstr_iter(kwargs.get("A")) and any(
i[0] in "acdefgijlLnoprtuvwx=" for i in kwargs["A"] if isinstance(i, str)
):
msg = (
"Argument of the parameter 'annotation'/'A' is using the old, deprecated "
"syntax. Please refer to the PyGMT documentation for the new syntax. "
"The warning will be removed in v0.14.0 and the old syntax will no longer "
"be supported. "
)
warnings.warn(msg, category=FutureWarning, stacklevel=2)
kwargs["A"] = "+".join(f"{item}" for item in kwargs["A"])

# Specify levels for the annotation and interval parameters.
# One level is converted to a string with a trailing comma to separate it from
# specifying an interval.
# Multiple levels are concatenated to a comma-separated string.
for arg in ["A", "C"]:
if is_nonstr_iter(kwargs.get(arg)):
if len(kwargs[arg]) == 1: # One level
kwargs[arg] = str(kwargs[arg][0]) + ","
else: # Multiple levels
kwargs[arg] = ",".join(f"{item}" for item in kwargs[arg])

with Session() as lib:
with lib.virtualfile_in(check_kind="raster", data=grid) as vingrd:
lib.call_module(
Expand Down
6 changes: 6 additions & 0 deletions pygmt/tests/baseline/test_grdcontour_multiple_levels.png.dvc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
outs:
- md5: 4d20cdb71af2e6568f64f0246ec860ea
size: 64008
isexec: true
hash: md5
path: test_grdcontour_multiple_levels.png
6 changes: 6 additions & 0 deletions pygmt/tests/baseline/test_grdcontour_one_level.png.dvc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
outs:
- md5: fc624766f0b8eac8206735a05c7c9662
size: 45023
isexec: true
hash: md5
path: test_grdcontour_one_level.png
50 changes: 49 additions & 1 deletion pygmt/tests/test_grdcontour.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ def fixture_grid():
@pytest.mark.mpl_image_compare
def test_grdcontour(grid):
"""
Plot a contour image using an xarray grid with fixed contour interval.
Plot a contour image using an xarray grid with fixed (different) contour and
annotation intervals.
"""
fig = Figure()
fig.grdcontour(
Expand All @@ -33,6 +34,53 @@ def test_grdcontour(grid):
return fig


@pytest.mark.mpl_image_compare
def test_grdcontour_one_level(grid):
"""
Plot a contour image using an xarray grid with one contour level and one
(different) annotation level.
"""
fig = Figure()
fig.grdcontour(
grid=grid, interval=[400], annotation=[570], projection="M10c", frame=True
)
return fig


@pytest.mark.mpl_image_compare(filename="test_grdcontour_one_level.png")
def test_grdcontour_old_annotations(grid):
"""
Test the old syntax for the annotation parameter using "sequence_plus".
Modified from the "test_grdcontour_one_level()" test. Can be removed in v0.14.0.
"""
fig = Figure()
fig.grdcontour(
grid=grid,
interval=[400],
annotation=["570,", "gwhite"],
projection="M10c",
frame=True,
)
return fig


@pytest.mark.mpl_image_compare
def test_grdcontour_multiple_levels(grid):
"""
Plot a contour image using an xarray grid with multiple (different) contour
and annotation levels.
"""
fig = Figure()
fig.grdcontour(
grid=grid,
interval=[400, 450, 500],
annotation=[400, 570],
projection="M10c",
frame=True,
)
return fig


@pytest.mark.benchmark
@pytest.mark.mpl_image_compare
def test_grdcontour_labels(grid):
Expand Down

0 comments on commit 0e630e3

Please sign in to comment.