Skip to content

Commit fabc9d2

Browse files
authored
Wrap makecpt (#329)
* Wrap makecpt Initial commit for wrapping the makecpt function raised at #214, tentatively implemented here under the mathops.py file which will hold functions for "Mathematical operations on tables or grids", but with documentation placed under 'Plotting'. Original GMT `makecpt` documentation can be found at https://docs.generic-mapping-tools.org/latest/makecpt.html. Tests are stored under test_makecpt.py, and there are now some basic tests ensuring that we can change the color when plotting points and grids. Current implementation uses 'cmap' and 'series' as aliases for 'C' and 'T' respectively. * Enable makecpt to save to a cpt file via output (H) parameter Allow makecpt to save the generated color palette table to a file via the output (H) argument. The 'H' setting in GMT upstream (see https://docs.generic-mapping-tools.org/latest/makecpt.html#h) is actually a flag to force the creation of an output (to stdout) in modern mode. Here we use it to set the filename too. See also GenericMappingTools/gmt#827 and GenericMappingTools/gmt#823 * Add truncate (G) alias for makecpt With rainbow cmap checks to test various zlow/zhigh combinations. * Add reverse (I) alias for makecpt Used 'earth' cmap to test various reversed colormap examples. * Alias continuous (Z) for makecpt Included one test to create a continuous cpt from blue to white. Also updated link to the full list of GMT's color palette tables due to documentation reorganization during GenericMappingTools/gmt#1594.
1 parent 89ff6fd commit fabc9d2

14 files changed

+250
-0
lines changed

doc/api/index.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ Plotting data and laying out the map:
3232
Figure.image
3333
Figure.shift_origin
3434

35+
Color palette table generation:
36+
37+
.. autosummary::
38+
:toctree: generated
39+
40+
makecpt
41+
3542
Saving and displaying the figure:
3643

3744
.. autosummary::

pygmt/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from .session_management import begin as _begin, end as _end
1616
from .figure import Figure
1717
from .gridding import surface
18+
from .mathops import makecpt
1819
from .modules import info, grdinfo, which
1920
from . import datasets
2021

pygmt/mathops.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
"""
2+
GMT modules for Mathematical operations on tables or grids
3+
"""
4+
from .clib import Session
5+
from .exceptions import GMTInvalidInput
6+
from .helpers import build_arg_string, fmt_docstring, kwargs_to_strings, use_alias
7+
8+
9+
@fmt_docstring
10+
@use_alias(C="cmap", T="series", G="truncate", H="output", I="reverse", Z="continuous")
11+
@kwargs_to_strings(T="sequence", G="sequence")
12+
def makecpt(**kwargs):
13+
"""
14+
Creates a static color palette table (CPT).
15+
16+
Full option list at :gmt-docs:`makecpt.html`
17+
18+
Parameters
19+
----------
20+
cmap (C) : str
21+
Selects the master color palette table (CPT) to use in the interpolation.
22+
Full list of built-in color palette tables can be found at
23+
:gmt-docs:`cookbook/cpts.html#built-in-color-palette-tables-cpt`.
24+
25+
series (T) : list or str
26+
``[min/max/inc[+b|l|n]|file|list]``.
27+
Defines the range of the new CPT by giving the lowest and highest z-value (and
28+
optionally an interval). If this is not given, the existing range in the master
29+
CPT will be used intact.
30+
31+
truncate (G) : list or str
32+
``zlo/zhi``.
33+
Truncate the incoming CPT so that the lowest and highest z-levels are to zlo and
34+
zhi. If one of these equal NaN then we leave that end of the CPT alone. The
35+
truncation takes place before any resampling. See also
36+
:gmt-docs:`cookbook/features.html#manipulating-cpts`.
37+
38+
output (H) : str
39+
Optional. The file name with extension .cpt to store the generated CPT file.
40+
If not given or False (default), saves the CPT as the session current CPT.
41+
42+
reverse (I) : str
43+
Set this to True or c [Default] to reverse the sense of color progression in the
44+
master CPT. Set this to z to reverse the sign of z-values in the color table.
45+
Note that this change of z-direction happens before -G and -T values are used so
46+
the latter must be compatible with the changed z-range. See also
47+
:gmt-docs:`cookbook/features.html#manipulating-cpts`.
48+
49+
continuous (Z) : bool
50+
Creates a continuous CPT [Default is discontinuous, i.e., constant colors for
51+
each interval]. This option has no effect when no -T is used, or when using
52+
-Tz_min/z_max; in the first case the input CPT remains untouched, in the second
53+
case it is only scaled to match the range z_min/z_max.
54+
55+
{aliases}
56+
"""
57+
with Session() as lib:
58+
if "H" not in kwargs.keys(): # if no output is set
59+
arg_str = build_arg_string(kwargs)
60+
elif "H" in kwargs.keys(): # if output is set
61+
outfile = kwargs.pop("H")
62+
if not outfile or not isinstance(outfile, str):
63+
raise GMTInvalidInput("'output' should be a proper file name.")
64+
arg_str = " ".join([build_arg_string(kwargs), f"-H > {outfile}"])
65+
lib.call_module(module="makecpt", args=arg_str)
80.9 KB
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading

pygmt/tests/test_makecpt.py

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
# pylint: disable=redefined-outer-name
2+
"""
3+
Tests for makecpt
4+
"""
5+
import os
6+
7+
import numpy as np
8+
import pytest
9+
10+
from .. import Figure, makecpt
11+
from ..datasets import load_earth_relief
12+
from ..exceptions import GMTInvalidInput
13+
from ..helpers import GMTTempFile
14+
15+
TEST_DATA_DIR = os.path.join(os.path.dirname(__file__), "data")
16+
POINTS_DATA = os.path.join(TEST_DATA_DIR, "points.txt")
17+
18+
19+
@pytest.fixture(scope="module")
20+
def points():
21+
"Load the points data from the test file"
22+
return np.loadtxt(POINTS_DATA)
23+
24+
25+
@pytest.fixture(scope="module")
26+
def region():
27+
"The data region"
28+
return [10, 70, -5, 10]
29+
30+
31+
@pytest.fixture(scope="module")
32+
def grid():
33+
"Load the grid data from the sample earth_relief file"
34+
return load_earth_relief()
35+
36+
37+
@pytest.mark.mpl_image_compare
38+
def test_makecpt_to_plot_points(points, region):
39+
"""
40+
Use static color palette table to change color of points
41+
"""
42+
fig = Figure()
43+
makecpt(cmap="rainbow")
44+
fig.plot(
45+
x=points[:, 0],
46+
y=points[:, 1],
47+
color=points[:, 2],
48+
region=region,
49+
style="c1c",
50+
cmap=True,
51+
)
52+
return fig
53+
54+
55+
@pytest.mark.mpl_image_compare
56+
def test_makecpt_to_plot_grid(grid):
57+
"""
58+
Use static color palette table to change color of grid
59+
"""
60+
fig = Figure()
61+
makecpt(cmap="relief")
62+
fig.grdimage(grid, projection="W0/6i")
63+
return fig
64+
65+
66+
@pytest.mark.mpl_image_compare
67+
def test_makecpt_to_plot_grid_scaled_with_series(grid):
68+
"""
69+
Use static color palette table scaled to a min/max series to change color of grid
70+
"""
71+
fig = Figure()
72+
makecpt(cmap="oleron", series="-4500/4500")
73+
fig.grdimage(grid, projection="W0/6i")
74+
return fig
75+
76+
77+
def test_makecpt_output_to_cpt_file():
78+
"""
79+
Save the generated static color palette table to a .cpt file
80+
"""
81+
with GMTTempFile(suffix=".cpt") as cptfile:
82+
makecpt(output=cptfile.name)
83+
assert os.path.exists(cptfile.name)
84+
85+
86+
def test_makecpt_blank_output():
87+
"""
88+
Use incorrect setting by passing in blank file name to output parameter
89+
"""
90+
with pytest.raises(GMTInvalidInput):
91+
makecpt(output="")
92+
93+
94+
def test_makecpt_invalid_output():
95+
"""
96+
Use incorrect setting by passing in invalid type to output parameter
97+
"""
98+
with pytest.raises(GMTInvalidInput):
99+
makecpt(output=["some.cpt"])
100+
101+
102+
@pytest.mark.mpl_image_compare
103+
def test_makecpt_truncated_to_zlow_zhigh(grid):
104+
"""
105+
Use static color palette table that is truncated to z-low and z-high
106+
"""
107+
fig = Figure()
108+
makecpt(cmap="rainbow", truncate=[0.15, 0.85], series=[-4500, 4500])
109+
fig.grdimage(grid, projection="W0/6i")
110+
return fig
111+
112+
113+
@pytest.mark.mpl_image_compare
114+
def test_makecpt_truncated_at_zlow_only(grid):
115+
"""
116+
Use static color palette table that is truncated at z-low only
117+
"""
118+
fig = Figure()
119+
makecpt(cmap="rainbow", truncate=[0.5, None], series=[-4500, 4500])
120+
fig.grdimage(grid, projection="W0/6i")
121+
return fig
122+
123+
124+
@pytest.mark.mpl_image_compare
125+
def test_makecpt_truncated_at_zhigh_only(grid):
126+
"""
127+
Use static color palette table that is truncated at z-high only
128+
"""
129+
fig = Figure()
130+
makecpt(cmap="rainbow", truncate=[None, 0.5], series=[-4500, 4500])
131+
fig.grdimage(grid, projection="W0/6i")
132+
return fig
133+
134+
135+
@pytest.mark.mpl_image_compare
136+
def test_makecpt_reverse_color_only(grid):
137+
"""
138+
Use static color palette table with its colors reversed
139+
"""
140+
fig = Figure()
141+
makecpt(cmap="earth", reverse=True)
142+
fig.grdimage(grid, projection="W0/6i")
143+
return fig
144+
145+
146+
@pytest.mark.mpl_image_compare
147+
def test_makecpt_reverse_zsign_only(grid):
148+
"""
149+
Use static color palette table with its z-value sign reversed
150+
"""
151+
fig = Figure()
152+
makecpt(cmap="earth", reverse="z")
153+
fig.grdimage(grid, projection="W0/6i")
154+
return fig
155+
156+
157+
@pytest.mark.mpl_image_compare
158+
def test_makecpt_reverse_color_and_zsign(grid):
159+
"""
160+
Use static color palette table with both its colors and z-value sign reversed
161+
"""
162+
fig = Figure()
163+
makecpt(cmap="earth", reverse="cz")
164+
fig.grdimage(grid, projection="W0/6i")
165+
return fig
166+
167+
168+
@pytest.mark.mpl_image_compare
169+
def test_makecpt_continuous(grid):
170+
"""
171+
Use static color palette table that is continuous from blue to white and scaled from
172+
-4500 to 4500m.
173+
"""
174+
fig = Figure()
175+
makecpt(cmap="blue,white", continuous=True, series="-4500,4500")
176+
fig.grdimage(grid, projection="W0/6i")
177+
return fig

0 commit comments

Comments
 (0)