✍️ 田冬冬 , 姚家园 • 📅 2024-09-09

# 制作CPT

GMT模块 makecpt 和 grd2cpt 可以内置CPT文件为基础，针对用户自己的数据 制作专门的CPT文件；也可以将用户自定义CPT重新调整为一个新的范围、颜色倒转甚至 屏蔽部分颜色的新色标文件。比如某个内置CPT文件定义了从0到1颜色从蓝色变成红色， 用 makecpt 可以制作一个从1000到3000颜色从蓝色变成红色的CPT文件。不同的是， makecpt 常用于已知极值范围的表数据，而 grd2cpt 常用于将cpt适用于一个 或多个格网数据。此外，两者均可通过以下方式翻转颜色：

1. 利用 `-Iz` 选项倒转CPT的z值指向（不包括前景色、背景色）。用于数据的正负 颜色表示和惯例不符的情况（比如用正值表示海平面以下的深度，而不是惯常的负高程）。

2. 利用 `-Ic` 选项翻转颜色的顺序，包括前景色和背景色（与 `colorbar` 的宽度 设为负值效果一致）。

3. `-Icz` 表示以上两种效果的叠加，即颜色顺序不变，只调转了前景色和背景色

4. 利用 `-G` 选项提取主CPT的一部分颜色

5. 最后，将初始的内置CPT或修改后的CPT拉伸为自定义数据范围

    #!/usr/bin/env bash
    SIZE=w15c/0.25c

    gmt begin cpt_4
    gmt makecpt -Chaxby -T-10/10/1 -H > Icpt.cpt
    gmt makecpt -Chaxby -T-10/10/1 -H -Iz > Icpt_z.cpt
    gmt makecpt -Chaxby -T-10/10/1 -H -Ic > Icpt_c.cpt
    gmt makecpt -Chaxby -T-10/10/1 -H -Icz > Icpt_cz.cpt

    gmt plot -R1/10/1/10 -JX20c -T

    gmt colorbar -CIcpt.cpt   -Dn0.5/0.25+jCM+$SIZE+h+e+n -B+l"Master CPT"
    gmt colorbar -CIcpt_c.cpt -Dn0.5/0.4+jCM+$SIZE+h+e+n  -B+l"-Ic"
    gmt colorbar -CIcpt_z.cpt -Dn0.5/0.55+jCM+$SIZE+h+e+n -B+l"-Iz"
    gmt colorbar -CIcpt_cz.cpt -Dn0.5/0.7+jCM+$SIZE+h+e+n -B+l"-Icz"

    rm Icpt*.cpt
    gmt end show

注：这些CPT的调整选项顺序也是有优先级的。比如 `-Iz` 使用后，所有其他的更改 都是基于z值反向的前提进行的。

CPT文件可以在 grdimage、plot、plot3d 等命令中使用。通常，你可以使用 makecpt 或 grd2cpt 对已有的CPT（比如GMT内置的CPT）文件进行重采样， 并适应你目前所使用的数据范围。当然，也可以自己手写CPT文件，或使用 `awk` 、 `perl` 之类的文本处理工具自动生成CPT文件。 由于GMT中可以用多种方式来指定颜色，因而GMT自带的或用户自己的CPT文件中通常含有 如下注释语句:

    # COLOR_MODEL = model

其中 `model` 可以取 RGB、hsv、cmyk，其指定了CPT文件中的颜色要如何进行解释。

## 周期性CPT文件

有一类特殊的CPT文件称之为周期性CPT文件。对于这类CPT文件而言，GMT在根据Z值查找 对应的颜色时，会首先从Z值中减去CPT文件中Z值范围的整数倍，使得Z值永远落在CPT 文件所指定的范围内。这意味着此类CPT文件没有前景色和背景色。

比如，现在有一个周期性CPT文件，其定义了Z值范围在 \(-\pi\) 到 \(\pi\) 之间的颜色表。若Z值等于 \(3/2\pi\) ，则会取 \(-\pi/2\) 处的值作为其 颜色。

在使用 `makecpt` 或 `grd2cpt` 生成CPT文件时加上 `-Ww` 选项即可生成周期性 CPT文件。该选项本质上是在CPT文件中加上一个特殊的注释行:

    # CYCLIC

GMT在CPT中看到这一注释行时就会将该CPT当作时周期性CPT文件。

`Source Code`

## 动态CPT

GMT 内置的 CPT 文件都是动态的。

所有动态CPT文件都按照两种方式中的一种进行了归一化：

1. 如果为存在分界（hinge）的区域填色（如地形颜色在高程为0的海岸线处发生非连续的 分界）那么CPT的z值在一侧为-1到0；另一侧为0到1；分界线上为0。CPT文件中对 分界线的值注释如下:

       # HINGE = <hinge-value>

   按照这种方式归一化的内置CPT包括 `earth` `etopo1` `geo` `globe` `polar` `red2green` `relief` `sealand` `split` `terra` `topo` `world`

2. 如果不存在颜色的分界，则CPT的z值归一化为0到1之间。实际使用中，CPT的z值会拉伸 到用户指定的范围，包括两种拉伸模式：

   1. 默认指定一个数值范围，实际应用中（如地形渲染）再拉伸到真实值。见CPT文件中 的RANGE注释:

          # RANGE = <zmin/zmax>

   2. 若未给定范围，则扩展到数据的极限值

下图展示了动态的内置CPT如何拉伸适用于用户自定义数据，绘制命令如下:

    #!/usr/bin/env bash
    gmt begin cpt_3
    gmt makecpt -Cglobe -T-8000/3000
    gmt colorbar -C -Baf -Dx0/0+w4.5i/0.1i+h
    gmt colorbar -Cglobe -Baf -Dx0/0+w4.5i/0.1i+h -Y0.5i
    gmt end show

原始的内置CPT（globe，上图）的初始范围为-10000至10000，颜色不连续处的分界值 （hinge）为0，小于0的部分为海蓝色系，大于0的部分为大地色系。但实际上，我们要 绘制的区域高程值是非对称的，从-8000米到3000米（下图）。由于hinge值的存在，负高程 依旧由海蓝色拉伸填充，正高程则由大地色压缩填充。

注：若要实现hinge分界效果，makecpt 命令中的 -T 选项不可设置 inc。