---
author: 田冬冬, 姚家园
date: 2024-09-09
---

# 制作CPT

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

1. 利用 `-Iz` 选项倒转CPT的z值指向（不包括前景色、背景色）。用于数据的正负
   颜色表示和惯例不符的情况（比如用正值表示海平面以下的深度，而不是惯常的负高程）。
2. 利用 `-Ic` 选项翻转颜色的顺序，包括前景色和背景色（与 `colorbar` 的宽度
   设为负值效果一致）。
3. `-Icz` 表示以上两种效果的叠加，即颜色顺序不变，只调转了前景色和背景色
4. 利用 `-G` 选项提取主CPT的一部分颜色
5. 最后，将初始的内置CPT或修改后的CPT拉伸为自定义数据范围

```{eval-rst}
.. gmtplot:: GMT_CPT_4.sh
    :caption: CPT颜色翻转
```

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

CPT文件可以在 {doc}`/module/grdimage`、{doc}`/module/plot`、{doc}`/module/plot3d`
等命令中使用。通常，你可以使用 {doc}`/module/makecpt` 或 {doc}`/module/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文件。

```{eval-rst}
.. gmtplot:: cpt_cyclic.sh
    :show-code: false
    :caption: 绘制周期CPT时会在其左边加上环状符号
```

## 动态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如何拉伸适用于用户自定义数据，绘制命令如下:

```{eval-rst}
.. gmtplot:: GMT_CPT_3.sh
    :caption: 动态CPT的拉伸
```

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

注：若要实现hinge分界效果，{doc}`/module/makecpt` 命令中的 **-T** 选项不可设置 *inc*。
