-
Notifications
You must be signed in to change notification settings - Fork 224
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
*Wrap grd2cpt function *Add tests for grd2cpt function *Modify docstring in makecpt function Co-authored-by: Wei Ji <[email protected]> Co-authored-by: Dongdong Tian <[email protected]>
- Loading branch information
1 parent
c869531
commit 2efcbba
Showing
6 changed files
with
273 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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", | ||
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://soliton.vm.bytemark.co.uk/pub/cpt-city/>`_ and | ||
`Scientific Colour-Maps <http://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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |