Skip to content

Commit

Permalink
Update how CPT hinges are handled (#2416)
Browse files Browse the repository at this point in the history
* Update how CPT hinges are done

Separate between soft and hard hinges.  Hard hinges are data driven like those for bathymetry or magnetics, while soft hinges are ignored unless +h[hinge] is given.

* Updates so far - in progress

* Add warning that +h cannot affect hard hinges

* Update scripts and PS to show short and hard hinges

* Update GMT_tut_17.ps

* Update docs

Explain soft and hard hinges

* Add include files explaining CPT syntax for creation and use

* Polish cpt docs

* Fix handing of soft hinge assignment

* Improve hinge documentationand CPT

* Update list of CPTs to indicate hard or soft hinge

* Update world.cpt

* Update haxby.cpt

* Turn wysiwig, haxby, no_green, and world into continuous CPTs

Update a few PS files that changed.

* Restrict CPT resampling to continuous CPTs

We ban the resampling of discrete CPTs to another set of nodes.  Only stretching of the range is allowed.

* Allow colorlists to pass as discrete input CPT

* Strengthening handling of color lists and categorical tables

* Update std_opts_classic.rst

typo

* Add new CPT section on color-lists

Adds a new script figure as well

* Improve colorlist figure and discussion

* Update features.rst

* Check hinge and warn if outside data range (and ignore)

* Add new CPT test for hinges

* Update common_SYN_OPTs.rst_

* Update common_SYN_OPTs.rst_

* Deal with distcalc ref

* Better reporting for hinge violations in CPTs

* Allow slow or zhigh to equal hinge

Not fully working yet.  If hinge == zlow or hinge == zhigh we need to eliminate one entry in the resulting CPT (not done yet).

* Update doc/rst/source/cookbook/features.rst

Co-Authored-By: Dongdong Tian <[email protected]>

* Update src/gmt_support.c

Co-Authored-By: Dongdong Tian <[email protected]>

* Update gmt_api.c

* Improve GMT_colorlist.sh script to show options

* Update gmt_api.c

* Fix CPT stretching with hinges

Needed to update tut 19 and its PS.

* Fix discrete resampling of CPTs with hinges

Trim the CPT if needed before resampling.

* Address soft hinge and fix -T parsing check

I had labeled a CPT with soft hinge as a hard hinge if +h was given, but it should stay a soft hinge internally.  Also, add validation of possible modifiers for parse_array.

* Fix print message in validate_cpt function

* Leave user zmin/zmax selection as is

* Add new test, update cpthinges to new behavior

* Avoid freeing same array twice

Co-authored-by: Dongdong Tian <[email protected]>
  • Loading branch information
PaulWessel and seisman authored Jan 21, 2020
1 parent 8462336 commit b8106c1
Show file tree
Hide file tree
Showing 76 changed files with 683 additions and 379 deletions.
2 changes: 1 addition & 1 deletion doc/examples/ex19/ex19.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
gmt begin ex19
gmt grdmath -Rd -I1 -r Y COSD 2 POW = lat.nc
gmt grdmath X = lon.nc
gmt makecpt -Cwhite,blue -T0,1 -Z -N -H > lat.cpt
gmt makecpt -Cwhite,blue -T0/1 -N -H > lat.cpt
gmt makecpt -Crainbow -T-180/180 -H > lon.cpt
gmt subplot begin 3x1 -Fs6.5i/0 -M0 -Bbltr -Rd -JI0/6.5i
# First make a worldmap with graded blue oceans and rainbow continents
Expand Down
3 changes: 1 addition & 2 deletions doc/rst/source/colorbar_common.rst_
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ Optional Arguments
is given then we read stdin. By default all
color changes are annotated. To use a subset, add an extra column to
the CPT with a L, U, or B to annotate Lower, Upper, or Both
color segment boundaries (but see **-B**). If not given, the module
will read stdin. Like :doc:`grdview`, we can understand
color segment boundaries (but see **-B**). Like :doc:`grdview`, we can understand
pattern specifications in the CPT. For CPTs where the
*z* range is in meters, it may be useful to change to another unit
when plotting. To do so, append **+U**\ *unit* to the file name.
Expand Down
2 changes: 1 addition & 1 deletion doc/rst/source/common_SYN_OPTs.rst_
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

.. |SYN_OPT-i| replace:: **-i**\ :ref:`flags <-icols_full>`

.. |SYN_OPT-j| replace:: **-j**\ :ref:`flags <distcalc_full>`
.. |SYN_OPT-j| replace:: **-j**\ :ref:`flags <-distcalc_full>`

.. |SYN_OPT-l| replace:: **-l**\ :ref:`flags <-l_full>`

Expand Down
2 changes: 2 additions & 0 deletions doc/rst/source/cookbook/cpts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ original color scale, which can be either discrete or continuous, though
some (like **globe**) are a mix of the two. The bottom half the color
bar are built by using :doc:`/makecpt`
**-T**-1/1/0.25, thus splitting the color scale into 8 discrete colors.
Black and white triangles indicate which tables have hard or soft hinges,
respectively.

.. _CPT_files_a:

Expand Down
84 changes: 66 additions & 18 deletions doc/rst/source/cookbook/features.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1128,45 +1128,91 @@ Master (dynamic) CPTs

The CPTs distributed with GMT are *dynamic*. This means they have several
special properties that modify the behavior of programs that use them.
All dynamic CPTs are normalized in one of two ways: If a CPT was designed
Dynamic CPTs comes in a few different flavors: Some CPTs were designed
to behave differently across a *hinge* value (e.g., a CPT designed specifically
for topographic relief may include a discontinuity in color across the
coastline at *z = 0*), then the CPT's *z*-values will range from -1, via 0
at the hinge, to +1 at the other end. The hinge value is specified via the special
comment

| ``# HINGE = <hinge-value>``
CPTs without a hinge are instead normalized with *z*-values from 0 to 1.
Dynamic CPTs will need to be stretched to the user's preferred range, and there
coastline at *z = 0*), and when users select these CPTs they will be stretched
to fit the user's desired data range separately for each side of this *hard* hinge.
Basically, a *hard* hinge CPT is the juxtaposition of two different CPTs joined
at the hinge and these sections are stretched independently. Such CPT files
are identified as such via the special comment

| ``# HARD_HINGE``
and all hard hinges occur at data value *z = 0* (but you can change this value by
adding **+h**\ *value* to the name of the CPT).
Other CPTs may instead have a *soft* hinge which indicates a natural hinge or transition
point in the CPT itself, unrelated to any natural data set *per se*. These CPTs
are flagged by the special comment

| ``# SOFT_HINGE``
CPTs with soft hinges behave as regular (non-hinge) CPTs *unless* the user activates then by
appending **+h**\ [*hinge*] to the CPT name. This modifier will convert the soft
hinge into a hard hinge at the user-specified data value *hinge* [which defaults to 0].
Note that if your specified data range *excludes* an activated soft or hard hinge then we
only perform color sampling from the *half* of the CPT that pertains to the data range.
All dynamic CPTs will need to be stretched to the user's preferred range, and there
are two modes of such scaling: Some CPTs designed for a specific application
(again, the topographic relief is a good example) have a *default range*
specified in the master table via the special comment


| ``# RANGE = <zmin/zmax>``
and when used by applications the normalized *z*-values will be stretched to reflect
this natural range. In contrast, CPTs without a natural range are instead
and when used by applications the CPT may be automatically stretched to reflect
this natural range. In contrast, dynamic CPTs *without* a natural range are instead
stretched to fit the range of the data in question (e.g., a grid's range).
Exceptions to these rules are implemented in the two CPT-producing modules
Exceptions to these rules are implemented in the two *CPT-producing* modules
:doc:`/makecpt` and :doc:`/grd2cpt`, both of which can read dynamic CPTs
and produce *static* CPTs satisfying a user's specific range needs. These
tools can also read static CPTs where the new range must be specified (or computed
tools can also read static CPTs for which a new range must be specified (or computed
from data), reversing the order of colors, and even isolating a section
of an incoming CPT. Here, :doc:`/makecpt` can be told the range of compute it from data tables
while :doc:`/grd2cpt` can derive the range from one or more grids.
of an incoming CPT. Here, :doc:`/makecpt` can be told the data range or compute
it from data tables while :doc:`/grd2cpt` can derive the range from one or more grids.

.. figure:: /_images/GMT_hinge.*
:width: 500 px
:align: center

The top color bar is a dynamic master CPT (here, globe) with a hinge at sea level and
The top color bar is a dynamic master CPT (here, globe) with a hard hinge at sea level and
a natural range from -10,000 to +10,000 meters. However, our data range
is asymmetrical, going from -8,000 meter depths up to +3,000 meter elevations.
Because of the hinge, the two sides of the CPT will be stretched separately
to honor the desired range while utilizing the full color range.

All CPT master tables can be found in Chapter :ref:`Of Colors and Color Legends`
where those with hard or soft hinges are identified by triangles at their hinges.

CPTs from color lists
~~~~~~~~~~~~~~~~~~~~~

GMT can build color tables "on the fly" from a comma-separated list of colors
and a range of *z*-values to go with them. As illustrated below, there are
four different ways to create such CPTs. In this example, we will operate with
a list of three colors: red,yellow and purple, given to modules with the option **-C**\ red,yellow,purple,
and utilize a fixed data range of *z = 0-6*.
Four different CPTs result because we either select a *continuous* or *discrete table*, and because the *z*-intervals are
either *equidistant* or *arbitrary*. The top continuous color table with equidistant spacing (a) is selected
with the range **-T**\ 0/6, meaning the colors will continuously change from red (at *z = 0*) via
yellow (at *z = 3*) to purple (at *z = 6*). Next, a discrete table with the same range (b)
is obtained with **-T**\ 0/6/2, yielding colors that are either constant red (*z = 0-2*), yellow (*z = 2-4*)
or purple (*z = 4-6*). The next discrete table (c) illustrates how to specify arbitrary
node points in the CPT by providing a comma-separated list of values (**-T**\ 0,4,5.5,6). Now, the constant
color intervals have unequal ranges, illustrated by red (*z = 0-4*), yellow (*z = 4-5.5*) and purple (*z = 5.5-6*). Finally, we
create a continuous color table (d) with arbitrary nodes by giving **-T**\ 0,2,6 and adding **-Z**;
the latter option forces a continuous CPT pinned to a given list of node values. Now, the colors
continuously change from red (at *z = 0*) via yellow (at *z = 2*) to purple (at *z = 6*).
Modules that obtain the *z*-range indirectly (e.g., :doc:`/grdimage`) may use the exact data range
to set the quivalent of a **-T**\ *min/max* option. You may append **+i**\ *dz* to the
color list to have the *min* and *max* values rounded down and up to nearest multiple of *dz*, respectively.

.. figure:: /_images/GMT_colorlist.*
:width: 500 px
:align: center

Lists of colors (here red,yellow,purple) can be turned into discrete or continuous CPT tables on the fly.

Cyclic (wrapped) CPTs
~~~~~~~~~~~~~~~~~~~~~

Expand Down Expand Up @@ -1227,7 +1273,10 @@ A few modules (:doc:`/grdimage`, :doc:`/grdview`) that expects a CPT option will
provide a default CPT if none is provided. By default, the default CPT is the
"turbo" color table, but this is overridden if the user uses the @eart_relief
(we select "geo") or @srtm_relief (we select "srtm") data sets. After selection,
these CPTs are read and scaled to match the range of the grid values.
these CPTs are read and scaled to match the range of the grid values. You may append
**+i**\ *dz* to the CPT to have the exact range rounded to nearest multiple of *dz*.
THis is helpful if you plan to place a colorbar and prefer start and stop *z*-values
that are multiples of *dz*.

The Drawing of Vectors
----------------------
Expand Down Expand Up @@ -2544,4 +2593,3 @@ any of these directories.
.. [19]
Requires building GMT with GDAL.
File renamed without changes.
11 changes: 11 additions & 0 deletions doc/rst/source/create_cpt.rst_
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
**-C**\ [*cpt*\ \|\ *master*\ [**+h**\ [*hinge*]][**+i**\ *zinc*][**+u**\ \|\ **U**\ *unit*] \|\ *color1,color2*\ [,\ *color3*\ ,...]]
Name of the CPT. If given a GMT Master soft-hinge CPT (see :ref:`Of Colors and Color Legends`) then
you can enable the hinge at data value *hinge* [0] via **+h**, whereas for hard-hinge CPTs you
can adjust the location of the hinge [0]. For other CPTs, you may convert their *z*-values
from meter to another distance unit (append **+U**\ *unit*) or from another unit to meter (append **+u**\ *unit*),
with *unit* taken from **e**\ \|\ **f**\ \|\ **k**\ \|\ **M**\ \|\ **n**\ \|\ **u**.
Alternatively, give *color1,color2*\ [*,color3*\ ,...]
to build a linear continuous CPT from those colors automatically,
where *z* starts at 0 and is incremented by one for each color.
In this case *color*\ **n** can be a r/g/b triplet, a color name,
or an HTML hexadecimal color (e.g. #aabbcc).
2 changes: 1 addition & 1 deletion doc/rst/source/explain_distcalc.rst_
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
**-je**\ \|\ **f**\ \|\ **g** :ref:`(more ...) <distcalc_full>`
**-je**\ \|\ **f**\ \|\ **g** :ref:`(more ...) <-distcalc_full>`
Determine how spherical distances are calculated.
2 changes: 1 addition & 1 deletion doc/rst/source/explain_distcalc_full.rst_
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.. _distcalc_full:
.. _-distcalc_full:

**-je**\ \|\ **f**\ \|\ **g**
Determine how spherical distances are calculated in modules that support this.
Expand Down
50 changes: 27 additions & 23 deletions doc/rst/source/grd2cpt.rst
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,7 @@ Optional Arguments

.. _-C:


**-C**\ *cpt*
Selects the master color table to use in the interpolation. Choose
among the built-in tables (type **grd2cpt** to see the list) or give
the name of an existing CPT [Default gives the turbo CPT].
Yet another option is to specify -Ccolor1,color2[,color3,...]
to build a linear continuous CPT from those colors automatically.
In this case *color*\ **n** can be a r/g/b triplet, a color name,
or an HTML hexadecimal color (e.g. #aabbcc ).
.. include:: create_cpt.rst_

.. _-D:

Expand Down Expand Up @@ -213,30 +205,42 @@ Optional Arguments
**-W**\ [**w**]
Do not interpolate the input color table but pick the output colors
starting at the beginning of the map. This is particularly useful in
combination with a categorical color table. Cannot be used in
combination with **-Z**. Alternatively, use **-Ww** to produce
a wrapped (cyclic) color table that endlessly repeats its range.
combination with a categorical color table. Alternatively, use **-Ww**
to produce a wrapped (cyclic) color table that endlessly repeats its range.

.. _-Z:

**-Z**
Will create a continuous color palette. [Default is discontinuous,
i.e., constant color intervals]
Force a continuous CPT [Default is discontinuous].

.. include:: explain_help.rst_

.. include:: explain_grd_inout_short.rst_

.. include:: explain_transparency.rst_

Color Aliasing
--------------

For best result when **-E** is used we recommend you do no append
a specific *nlevels*. This way the original CPT is used exactly
as is but the *z* boundaries are adjusted to match the grid limits.
Otherwise you may, depending on the nature of the input CPT, miss
aspects of the color changes by aliasing the signal.
Color Hinges
------------

Some of the GMT master dynamic CPTs are actually two separate CPTs
meeting at a *hinge*. Usually, colors may change dramatically across
the hinge, which is used to separate two different domains (e.g., land
and ocean across the shoreline, for instance). CPTs with a hinge will
have their two parts stretched to the required range separately, i.e.,
the bottom part up to the hinge will be stretched independently of the
part from the hinge to the top, according to the prescribed new range.
Hinges are either *hard* or *soft*. Soft hinges must be *activated* by
appending **+h**\ [*hinge*] to the CPT name.
If the selected range does not include an activated soft or hard hinge then
we only resample colors from the half of the CPT that pertains to the range.
See :ref:`Of Colors and Color Legends` for more information.

Discrete versus Continuous CPT
------------------------------

All CPTs can be stretched, but only continuous CPTs can be sampled
at new nodes (i.e., by given an increment in **-T**). We impose this
limitation to avoid aliasing the original CPT.

Examples
--------
Expand Down Expand Up @@ -265,7 +269,7 @@ file relief, run

gmt grd2cpt mydata.nc -Crelief -L0/10000 -T0/200/20 > mydata.cpt

.. include:: explain_cpt.rst_
.. include:: cpt_notes.rst_

See Also
--------
Expand Down
12 changes: 1 addition & 11 deletions doc/rst/source/grd2kml.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,7 @@ Optional Arguments

.. _-C:

**-C**\ [*cpt* \|\ *master*\ [**+i**\ *zinc*] \|\ *color1,color2*\ [,\ *color3*\ ,...]]
Name of the CPT (for *grd_z* only). Alternatively,
supply the name of a GMT color master dynamic CPT [turbo, but geo
for @earth_relief and srtm for @srtm_relief data] to
automatically determine a continuous CPT from
the grid's z-range; you may round up/down the z-range by adding **+i**\ *zinc*.
Yet another option is to specify **-C**\ *color1*\ ,\ *color2*\ [,\ *color3*\ ,...]
to build a linear continuous CPT from those colors automatically.
In this case *color1* etc can be a r/g/b triplet, a color name,
or an HTML hexadecimal color (e.g. #aabbcc ). If no argument is given to **-C**
then under modern mode we select the current CPT.
.. include:: use_cpt_grd.rst_

.. _-E:

Expand Down
2 changes: 1 addition & 1 deletion doc/rst/source/grdimage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ remotely located Jessica Rabbit::

gmt grdimage -JI15c -Rd http://larryfire.files.wordpress.com/2009/07/untooned_jessicarabbit.jpg -pdf jess

.. include:: explain_cpt.rst_
.. include:: cpt_notes.rst_

See Also
--------
Expand Down
12 changes: 1 addition & 11 deletions doc/rst/source/grdimage_common.rst_
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,7 @@ Optional Arguments

.. _-C:

**-C**\ [*cpt* \|\ *master*\ [**+i**\ *zinc*] \|\ *color1,color2*\ [,\ *color3*\ ,...]]
Name of the CPT (for *grd_z* only). Alternatively,
supply the name of a GMT color master dynamic CPT [turbo, but geo
for @earth_relief and srtm for @srtm_relief data] to
automatically determine a continuous CPT from
the grid's z-range; you may round up/down the z-range by adding **+i**\ *zinc*.
Yet another option is to specify **-C**\ *color1*\ ,\ *color2*\ [,\ *color3*\ ,...]
to build a linear continuous CPT from those colors automatically.
In this case *color1* etc can be a r/g/b triplet, a color name,
or an HTML hexadecimal color (e.g. #aabbcc ). If no argument is given to **-C**
then under modern mode we select the current CPT.
.. include:: use_cpt_grd.rst_

.. _-D:

Expand Down
11 changes: 1 addition & 10 deletions doc/rst/source/grdvector_common.rst_
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,7 @@ Optional Arguments

.. _-C:

**-C**\ [*cpt* \|\ *master*\ [**+i**\ *zinc*] \|\ *color1,color2*\ [,\ *color3*,...]]
Use *cpt* to assign colors based on vector length. Alternatively,
supply the name of a GMT color master dynamic CPT [turbo] to
automatically determine a continuous CPT from
the grid's z-range; you may round up/down the z-range by adding **+i**\ *zinc*..
Yet another option is to specify **-C**\ *color1,color2*\ [,\ *color3*,...]
to build a linear continuous cpt from those colors automatically.
In this case *color*\ **n** can be a r/g/b triplet, a color name,
or an HTML hexadecimal color (e.g. #aabbcc ). If no argument is given to **-C**
then under modern mode we select the current CPT.
.. include:: use_cpt_grd.rst_

.. _-G:

Expand Down
13 changes: 1 addition & 12 deletions doc/rst/source/grdview_common.rst_
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,7 @@ Optional Arguments

.. _-C:

**-C**\ [*cpt* \|\ *master*\ [**+i**\ *zinc*] \|\ *color1,color2*\ [,\ *color3*\ ,...]]
The name of the CPT. Must be present if you want
(1) mesh plot with contours (**-Qm**), or
(2) shaded/colored perspective image (**-Qs** or
**-Qi**). For **-Qs**: You can specify that you want to skip a
z-slice by setting the red r/g/b component to -; to use a pattern give red =
**P\|p**\ *pattern*\ [**+b**\ *color*\ ][**+f**\ *color*\ ][**+r**\ *dpi*\ ].
Alternatively, supply the name of a GMT color master dynamic CPT [turbo, but
geo for @earth_relief and srtm for @srtm_relief data] to
automatically determine a continuous CPT from
the grid's z-range; you may round up/down the z-range by adding **+i**\ *zinc*.
If no argument is given to **-C** then under modern mode we select the current CPT.
.. include:: use_cpt_grd.rst_

.. _-G:

Expand Down
Loading

0 comments on commit b8106c1

Please sign in to comment.