Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrap grd2cpt #803

Merged
merged 76 commits into from
Feb 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
27f5d20
Add cyl_transverse_mercator.py
willschlitzer Dec 11, 2020
d64983f
Add cyl_universal_transverse_mercator.py
willschlitzer Dec 11, 2020
6ba8185
Changing land color to red in cyl_mercator.py to match GMT docs examp…
willschlitzer Dec 11, 2020
76850ee
Merge branch 'master' into cylindrical-projections
willschlitzer Dec 13, 2020
48431db
Merge branch 'master' of https://github.com/GenericMappingTools/pygmt
willschlitzer Jan 12, 2021
01052d2
Merge branch 'master' of https://github.com/GenericMappingTools/pygmt
willschlitzer Jan 18, 2021
c710988
Merge remote-tracking branch 'origin/master'
willschlitzer Jan 21, 2021
b94e0a2
Merge branch 'master' of https://github.com/GenericMappingTools/pygmt
willschlitzer Jan 21, 2021
413fec1
Merge branch 'master' of https://github.com/GenericMappingTools/pygmt
willschlitzer Jan 22, 2021
be51e2c
Merge branch 'master' of https://github.com/GenericMappingTools/pygmt
willschlitzer Jan 22, 2021
d0d697e
Wrap grd2cpt and add it to pygmt init file
willschlitzer Jan 23, 2021
cb77714
Add grd2cpt doc string
willschlitzer Jan 23, 2021
e6753b8
Update api/index.rst
willschlitzer Jan 23, 2021
be38238
Write first test in test_grd2cpt.py
willschlitzer Jan 23, 2021
5047a24
Add tests for invalid and blank outputs
willschlitzer Jan 23, 2021
dbf04d7
Add test_grd2cpt_to_plot_points
willschlitzer Jan 23, 2021
d7b57df
Fix formatting typos
willschlitzer Jan 23, 2021
89eb39b
Move verbose string to end of grd2cpt docstring
willschlitzer Jan 23, 2021
1725667
Update sequences for kwargs_to_strings for grd2cpt
willschlitzer Jan 23, 2021
12f97e2
Add test_grd2cpt_truncated_to_zlow_zhigh
willschlitzer Jan 23, 2021
b28556b
Fix test_grd2cpt_truncated_to_zlow_zhigh
willschlitzer Jan 23, 2021
3174515
Add failing test test_grd2cpt_grdimage
willschlitzer Jan 23, 2021
2b72baa
Update test_grd2cpt_grdimage
willschlitzer Jan 23, 2021
e02eea3
Fix style for unused variable
willschlitzer Jan 23, 2021
cef25c0
Remove redundant test
willschlitzer Jan 23, 2021
77ed1fd
Reduce arguments tests in grd2cpt; use single-letter aliases for ref
willschlitzer Jan 23, 2021
06fc8c6
Update tests to use basemap in test_grd2cpt.py
willschlitzer Jan 23, 2021
683262a
Add test_grd2cpt_unrecognized_data_type and test_grd2cpt_categorical_…
willschlitzer Jan 23, 2021
b2ce4c7
Add test_grd2cpt_scaled_with_series, test_grd2cpt_truncated_to_zlow_o…
willschlitzer Jan 23, 2021
305fb91
Add test_grd2cpt_reverse_color_only
willschlitzer Jan 23, 2021
426e681
Add test_grd2cpt_reverse_zsign_only
willschlitzer Jan 23, 2021
7a777bd
Add test_grd2cpt_reverse_color_and_zsign
willschlitzer Jan 23, 2021
477eefe
Add test_grd2cpt_continuous, test_grd2cpt_categorical, and test_grd2c…
willschlitzer Jan 23, 2021
2029656
Add test_grd2cpt_limit
willschlitzer Jan 23, 2021
84f9e64
Merge branch 'master' into wrap-grd2cpt
willschlitzer Jan 25, 2021
7940dd0
Remove grdimage from grd2cpt tests
willschlitzer Jan 25, 2021
21fbf02
Merge branch 'master' into wrap-grd2cpt
willschlitzer Feb 3, 2021
81e6e90
Remove unnecessary with statement
willschlitzer Feb 3, 2021
c0ac492
Apply suggestions from code review
willschlitzer Feb 6, 2021
b99f666
Move grd2cpt function from gridops.py to grd2cpt.py
willschlitzer Feb 6, 2021
698f876
Merge branch 'master' into wrap-grd2cpt
willschlitzer Feb 6, 2021
1812b93
Move grd2cpt location in index.rst
willschlitzer Feb 6, 2021
1fe882c
Run make format
willschlitzer Feb 6, 2021
c6714f0
Remove unnecessary imports
willschlitzer Feb 6, 2021
4ce86e9
Merge branch 'master' into wrap-grd2cpt
willschlitzer Feb 7, 2021
ad997c6
Merge branch 'master' into wrap-grd2cpt
willschlitzer Feb 7, 2021
0bdd8a5
Apply suggestions from code review
willschlitzer Feb 7, 2021
8aa3ba2
Run make format
willschlitzer Feb 8, 2021
3e4b017
Wrap nlelvels function
willschlitzer Feb 8, 2021
5924a8e
Format GMT arguments
willschlitzer Feb 8, 2021
a84f424
Add raw string
willschlitzer Feb 8, 2021
08101c2
Merge branch 'master' into wrap-grd2cpt
willschlitzer Feb 8, 2021
e12ea34
Format fix
willschlitzer Feb 8, 2021
dae83e4
Apply suggestions from code review
willschlitzer Feb 10, 2021
2eaad74
Merge branch 'master' into wrap-grd2cpt
willschlitzer Feb 10, 2021
1ef9fb9
Fix line length issue
willschlitzer Feb 10, 2021
72130a9
Remove unnecessary test
willschlitzer Feb 10, 2021
1013c3f
Fixed saving CPT issue
willschlitzer Feb 10, 2021
201f0f6
Correct arg_string building
willschlitzer Feb 10, 2021
c8c8811
Run make format
willschlitzer Feb 10, 2021
cfcb78c
Fix style issue
willschlitzer Feb 10, 2021
93fc686
Move GMTInvalidInput raising statement outside of context manager
willschlitzer Feb 10, 2021
9cd9684
Revert "Remove unnecessary test"
willschlitzer Feb 10, 2021
e0ad7f7
Change test to determine if CPT file size is greater than zero
willschlitzer Feb 10, 2021
b7c88de
Merge branch 'master' into wrap-grd2cpt
willschlitzer Feb 10, 2021
3360258
Update pygmt/src/grd2cpt.py
seisman Feb 11, 2021
b859b4f
Merge branch 'master' into wrap-grd2cpt
seisman Feb 11, 2021
bf68c85
Remove tests in test_grd2cpt.py
willschlitzer Feb 12, 2021
8481a6d
Merge remote-tracking branch 'origin/wrap-grd2cpt' into wrap-grd2cpt
willschlitzer Feb 12, 2021
ea4244b
Update pygmt/tests/test_grd2cpt.py
willschlitzer Feb 12, 2021
ab91134
Merge branch 'master' into wrap-grd2cpt
willschlitzer Feb 12, 2021
826c8f9
Remove unused import in test_grd2cpt.py
willschlitzer Feb 12, 2021
0892ea5
Merge branch 'master' into wrap-grd2cpt
willschlitzer Feb 12, 2021
ecb7fdc
Apply suggestions from code review
willschlitzer Feb 12, 2021
e0fd4ab
Add string input in overrule_bg docstring in makecpt.py
willschlitzer Feb 12, 2021
2d77e66
Merge branch 'master' into wrap-grd2cpt
willschlitzer Feb 12, 2021
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
1 change: 1 addition & 0 deletions doc/api/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Color palette table generation:
.. autosummary::
:toctree: generated

grd2cpt
makecpt

Saving and displaying the figure:
Expand Down
1 change: 1 addition & 0 deletions pygmt/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from pygmt.session_management import end as _end
from pygmt.src import (
blockmedian,
grd2cpt,
grdcut,
grdfilter,
grdinfo,
Expand Down
1 change: 1 addition & 0 deletions pygmt/src/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from pygmt.src.coast import coast
from pygmt.src.colorbar import colorbar
from pygmt.src.contour import contour
from pygmt.src.grd2cpt import grd2cpt
from pygmt.src.grdcontour import grdcontour
from pygmt.src.grdcut import grdcut
from pygmt.src.grdfilter import grdfilter
Expand Down
190 changes: 190 additions & 0 deletions pygmt/src/grd2cpt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
"""
grd2cpt - Create a CPT from a grid file.
"""

from pygmt.clib import Session
from pygmt.exceptions import GMTInvalidInput
from pygmt.helpers import (
build_arg_string,
data_kind,
dummy_context,
fmt_docstring,
kwargs_to_strings,
use_alias,
)


@fmt_docstring
@use_alias(
A="transparency",
C="cmap",
D="background",
F="color_model",
willschlitzer marked this conversation as resolved.
Show resolved Hide resolved
E="nlevels",
G="truncate",
H="output",
I="reverse",
L="limit",
M="overrule_bg",
N="no_bg",
Q="log",
R="region",
T="series",
V="verbose",
W="categorical",
Ww="cyclic",
Z="continuous",
)
@kwargs_to_strings(G="sequence", L="sequence", R="sequence", T="sequence")
def grd2cpt(grid, **kwargs):
r"""
Make GMT color palette tables from a grid file.

This is a module that will help you make static color palette tables
(CPTs). By default, the CPT will simply be saved to the current session,
but you can use ``output`` to save it to a file. The CPT is based on an
existing dynamic master CPT of your choice, and the mapping from data value
to colors is through the data's cumulative distribution function (CDF), so
that the colors are histogram equalized. Thus if the grid(s) and the
resulting CPT are used in :meth:`pygmt.Figure.grdimage` with a linear
projection, the colors will be uniformly distributed in area on the plot.
Let z be the data values in the grid. Define CDF(Z) = (# of z < Z) / (# of
z in grid). (NaNs are ignored). These z-values are then normalized to the
master CPT and colors are sampled at the desired intervals.

The CPT includes three additional colors beyond the range of z-values.
These are the background color (B) assigned to values lower than the lowest
*z*-value, the foreground color (F) assigned to values higher than the
highest *z*-value, and the NaN color (N) painted wherever values are
undefined. For color tables beyond the standard GMT offerings, visit
`cpt-city <http:https://soliton.vm.bytemark.co.uk/pub/cpt-city/>`_ and
`Scientific Colour-Maps <http:https://www.fabiocrameri.ch/colourmaps.php>`_.

If the master CPT includes B, F, and N entries, these will be copied into
the new master file. If not, the parameters :gmt-term:`COLOR_BACKGROUND`,
:gmt-term:`COLOR_FOREGROUND`, and :gmt-term:`COLOR_NAN` from the
:gmt-docs:`gmt.conf <gmt.conf>` file or the command line will be used. This
default behavior can be overruled using the options ``background``,
``overrule_bg`` or ``no_bg``.

The color model (RGB, HSV or CMYK) of the palette created by
:meth:`pygmt.grd2cpt` will be the same as specified in the header of the
master CPT. When there is no :gmt-term:`COLOR_MODEL` entry in the master
CPT, the :gmt-term:`COLOR_MODEL` specified in the
:gmt-docs:`gmt.conf <gmt.conf>` file or the ``color_model`` option will be
used.

Full option list at :gmt-docs:`grd2cpt.html`

{aliases}

Parameters
----------
grid : str or xarray.DataArray
The file name of the input grid or the grid loaded as a DataArray.
transparency : int or float or str
Sets a constant level of transparency (0-100) for all color slices.
Append **+a** to also affect the fore-, back-, and nan-colors
[Default is no transparency, i.e., 0 (opaque)].
cmap : str
Selects the master color palette table (CPT) to use in the
interpolation. Full list of built-in color palette tables can be found
at :gmt-docs:`cookbook/cpts.html#built-in-color-palette-tables-cpt`.
background : bool or str
Select the back- and foreground colors to match the colors for lowest
and highest *z*-values in the output CPT [Default (``background=True``
or ``background='o'``) uses the colors specified in the master file, or
those defined by the parameters :gmt-term:`COLOR_BACKGROUND`,
:gmt-term:`COLOR_FOREGROUND`, and :gmt-term:`COLOR_NAN`]. Use
``background='i'`` to match the colors for the lowest and highest
values in the input (instead of the output) CPT.
color_model :
[**R**\|\ **r**\|\ **h**\|\ **c**][**+c**\ [*label*]].
Force output CPT to be written with r/g/b codes, gray-scale values or
color name (**R**, default) or r/g/b codes only (**r**), or h-s-v codes
(**h**), or c/m/y/k codes (**c**). Optionally or alternatively, append
**+c** to write discrete palettes in categorical format. If *label* is
appended then we create labels for each category to be used when the
CPT is plotted. The *label* may be a comma-separated list of category
names (you can skip a category by not giving a name), or give
*start*\[-], where we automatically build monotonically increasing
labels from *start* (a single letter or an integer). Append ``-`` to
build ranges *start*-*start+1* instead.
nlevels : bool or int or str
Set to ``True`` to create a linear color table by using the grid
z-range as the new limits in the CPT. Alternatively, set *nlevels*
to resample the color table into *nlevels* equidistant slices.
series : list or str
[*min/max/inc*\ [**+b**\|\ **l**\|\ **n**\]|\ *file*\|\ *list*\].
Defines the range of the new CPT by giving the lowest and highest
z-value (and optionally an interval). If this is not given, the
existing range in the master CPT will be used intact. The values
produced defines the color slice boundaries. If **+n** is used it
refers to the number of such boundaries and not the number of slices.
For details on array creation, see
:gmt-docs:`makecpt.html#generate-1d-array`.
truncate : list or str
*zlo/zhi*.
Truncate the incoming CPT so that the lowest and highest z-levels are
to *zlo* and *zhi*. If one of these equal NaN then we leave that end of
the CPT alone. The truncation takes place before any resampling. See
also :gmt-docs:`cookbook/features.html#manipulating-cpts`.
output : str
Optional argument to set the file name with extension .cpt to store
the generated CPT file. If not given or False (default), saves the CPT
as the session current CPT.
reverse : str
Set this to True or c [Default] to reverse the sense of color
progression in the master CPT. Set this to z to reverse the sign of
z-values in the color table. Note that this change of z-direction
happens before *truncate* and *series* values are used so the latter
must be compatible with the changed *z*-range. See also
:gmt-docs:`cookbook/features.html#manipulating-cpts`.
overrule_bg : str
Overrule background, foreground, and NaN colors specified in the master
CPT with the values of the parameters :gmt-term:`COLOR_BACKGROUND`,
:gmt-term:`COLOR_FOREGROUND`, and :gmt-term:`COLOR_NAN` specified in
the :gmt-docs:`gmt.conf <gmt.conf>` file or on the command line. When
combined with ``background``, only :gmt-term:`COLOR_NAN` is considered.
no_bg : bool
Do not write out the background, foreground, and NaN-color fields
[Default will write them, i.e. ``no_bg=False``].
log : bool
For logarithmic interpolation scheme with input given as logarithms.
Expects input z-values provided via ``series`` to be log10(*z*),
assigns colors, and writes out *z*.
continuous : bool
Force a continuous CPT when building from a list of colors and a list
of z-values [Default is None, i.e. discrete values].
categorical : bool
Do not interpolate the input color table but pick the output colors
starting at the beginning of the color table, until colors for all
intervals are assigned. This is particularly useful in combination with
a categorical color table, like ``cmap='categorical'``.
cyclic : bool
Produce a wrapped (cyclic) color table that endlessly repeats its
range. Note that ``cyclic=True`` cannot be set together with
``categorical=True``.
{V}
"""
if "W" in kwargs and "Ww" in kwargs:
raise GMTInvalidInput("Set only categorical or cyclic to True, not both.")
kind = data_kind(grid)
with Session() as lib:
if kind == "file":
file_context = dummy_context(grid)
elif kind == "grid":
file_context = lib.virtualfile_from_grid(grid)
else:
raise GMTInvalidInput(f"Unrecognized data type: {type(grid)}")
with file_context as infile:
if "H" not in kwargs.keys(): # if no output is set
arg_str = " ".join([infile, build_arg_string(kwargs)])
elif "H" in kwargs.keys(): # if output is set
outfile = kwargs.pop("H")
if not outfile or not isinstance(outfile, str):
raise GMTInvalidInput("'output' should be a proper file name.")
arg_str = " ".join(
[infile, build_arg_string(kwargs), f"-H > {outfile}"]
)
lib.call_module("grd2cpt", arg_str)
2 changes: 1 addition & 1 deletion pygmt/src/makecpt.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ def makecpt(**kwargs):
happens before *truncate* and *series* values are used so the latter
must be compatible with the changed *z*-range. See also
:gmt-docs:`cookbook/features.html#manipulating-cpts`.
overrule_bg :
overrule_bg : str
Overrule background, foreground, and NaN colors specified in the master
CPT with the values of the parameters :gmt-term:`COLOR_BACKGROUND`,
:gmt-term:`COLOR_FOREGROUND`, and :gmt-term:`COLOR_NAN` specified in
Expand Down
79 changes: 79 additions & 0 deletions pygmt/tests/test_grd2cpt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
"""
Tests for grd2cpt.
"""
import os

import pytest
from pygmt import Figure
from pygmt.datasets import load_earth_relief
from pygmt.exceptions import GMTInvalidInput
from pygmt.helpers import GMTTempFile
from pygmt.helpers.testing import check_figures_equal
from pygmt.src.grd2cpt import grd2cpt


@pytest.fixture(scope="module", name="grid")
def fixture_grid():
"""
Load the grid data from the sample earth_relief file.
"""
return load_earth_relief()


@check_figures_equal()
def test_grd2cpt(grid):
"""
Test creating a CPT with grd2cpt to create a CPT based off a grid input and
plot it with a color bar.
"""
fig_ref, fig_test = Figure(), Figure()
# Use single-character arguments for the reference image
fig_ref.basemap(B="a", J="W0/15c", R="d")
grd2cpt(grid="@earth_relief_01d")
fig_ref.colorbar(B="a2000")
fig_test.basemap(frame="a", projection="W0/15c", region="d")
grd2cpt(grid=grid)
fig_test.colorbar(frame="a2000")
return fig_ref, fig_test


def test_grd2cpt_blank_output(grid):
"""
Use incorrect setting by passing in blank file name to output parameter.
"""
with pytest.raises(GMTInvalidInput):
grd2cpt(grid=grid, output="")


def test_grd2cpt_invalid_output(grid):
"""
Use incorrect setting by passing in invalid type to output parameter.
"""
with pytest.raises(GMTInvalidInput):
grd2cpt(grid=grid, output=["some.cpt"])


def test_grd2cpt_output_to_cpt_file(grid):
"""
Save the generated static color palette table to a .cpt file.
"""
with GMTTempFile(suffix=".cpt") as cptfile:
grd2cpt(grid=grid, output=cptfile.name)
assert os.path.getsize(cptfile.name) > 0


def test_grd2cpt_unrecognized_data_type():
"""
Test that an error will be raised if an invalid data type is passed to
grid.
"""
with pytest.raises(GMTInvalidInput):
grd2cpt(grid=0)


def test_grd2cpt_categorical_and_cyclic(grid):
"""
Use incorrect setting by setting both categorical and cyclic to True.
"""
with pytest.raises(GMTInvalidInput):
grd2cpt(grid=grid, cmap="batlow", categorical=True, cyclic=True)