---
author: 田冬冬
date: 2022-05-02
---

# 绘制底图

GMT 可以绘制多种不同类型的底图，包括全球地图、区域地图，以及线性坐标轴、
对数轴、指数轴、极坐标轴，甚至 3D 坐标轴。

这一节我们将通过使用 {doc}`/module/coast` 和 {doc}`/module/basemap` 模块绘制
不同类型的底图，并了解 GMT 中 **-J**、**-R**和 **-B** 选项的基本用法。

## 全球地图

要绘制地图，就需要将地球的三维球面投影到一个二维面上，投影的过程需要指定投影方式。
GMT 中使用 **-J** 选项指定地图投影参数以及地图的尺寸。
同时，我们还需要使用 **-R** 选项指定要绘制的区域范围（即经纬度范围）。

下面用最简单的命令绘制了一张全球地图。

```{eval-rst}
.. gmtplot::
    :caption: 全球地图（无边框版）
    :width: 85%

    gmt begin GlobalMap
        gmt coast -JH180/12c -R0/360/-90/90 -W0.5p -A10000
    gmt end show
```

先忽略后面的 **-W0.5p -A10000**（后面章节会介绍到），这里只关注 **-J** 和 **-R** 选项。
此示例中：

1. **-JH180/12c** 指定地图投影参数，**H** 表示使用 Hammer 投影，地图中心位于经度 180° 处，
   地图宽度为 12 厘米（**12c**，**c** 表示单位厘米）；
2. **-R0/360/-90/90** 指定要绘制的区域范围，即经度 0° 到 360°，纬度 -90° 到 90°，
   四个数字之间用斜杠 **/** 分隔。

上面使用了非常简单的 GMT 命令即绘制出了一张全球地图的底图，但其跟我们常见的
全球地图比还缺了个底图边框。GMT 中可以使用 **-B** 选项为地理底图加上边框
并绘制经纬线。

```{eval-rst}
.. gmtplot::
    :caption: 全球地图（有边框版）
    :width: 85%

    gmt begin GlobalMap
        gmt coast -JH180/12c -Rg -Bg -W0.5p -A10000
    gmt end show
```

跟上一个脚本相比，此处我们做了两点修改：

1. 使用 **-Rg** 代替了 **-R0/360/-90/90**。这二者是完全等效的。
   由于绘制全球地图是很常见的需求，因而 GMT 为其设计了一个更简单的写法。
   **-Rg** 中 **g** 代表 **g**lobal。
2. 增加了 **-Bg** 选项。**-B** 用于给底图加上边框，其中的 **g** 则用于
   向底图中加入网格线（**g** 代表 **g**rid）。

:::{tip}
GMT 支持 30 多种不同的地图投影方式，详情见 {doc}`/proj/index` 一章。
将上面的示例脚本中 **-JH180/12c** 修改为下面列出的一些值以了解不同投影方式之间的差异：

- **-JA280/30/12c**
- **-JI180/12c**
- **-JK180/12c**
- **-JN180/12c**
- **-JR180/12c**
:::

## 区域地图

绘制区域地图与绘制全球地图没有本质区别，我们依然需要使用 **-J** 指定投影方式，
使用 **-R** 指定绘图区域范围，使用 **-B** 指定底图边框。

下面的 GMT 命令绘制了一张新西兰地图。

```{eval-rst}
.. gmtplot::
    :caption: 使用国家代码指定绘图区域
    :width: 50%

    gmt begin NewZealandMap
        gmt coast -JM12c -RNZ -Ba -W0.5p -A10000
    gmt end show
```

这里我们使用了：

- **-JM12c** 指定了使用墨卡托投影（绘制区域地图最常用的投影方式），地图宽度为 12 厘米；
- **-RNZ** 指定了绘图区域范围，此处 **NZ** 是新西兰的国家代码，GMT 会自动根据国家代码
  提取该国家的区域范围并用于绘图；
- **-Ba** 用于给底图添加边框。对于某些地图投影，GMT 默认使用图中所示的黑白相间的
  底图边框。**a** 用于添加标注（**a**nnotation，即图中的经纬度数字）。

如果对于根据国家代码自动确定的区域范围不太满意，我们也可以使用 **-R** 选项
最原始的方式来指定区域范围。
即依次给定绘图区域的最小经度、最大经度、最小纬度和最大纬度。记起来也很容易，
可以记为 *xmin/xmax/ymin/ymax*，或者直接记 “西东南北”。

通过上面的图，我们大概知道了新西兰的经纬度范围。我们可以直接使用
**-R165/180/-48/-32** 指定绘图区域。

```{eval-rst}
.. gmtplot::
    :caption: 使用经纬度范围指定绘图区域
    :width: 50%

    gmt begin NewZealandMap
        gmt coast -JM12c -R165/180/-48/-32 -Bafg -W0.5p -A10000
    gmt end show
```

上面的例子中我们还调整了 **-B** 选项，**-Bafg** 表示绘制底图边框的标注（**a**nnotation）、
刻度线（**f**rame，即图中黑白线段的间隔）和网格线（**g**rid）。
标注、刻度线以及网格线的间隔由 GMT 算法自动决定。

对 GMT 自动算法确定的间隔不满意？你还可以任意指定自己想要的间隔。
下面例子中，我们对底图进行了进一步的自定义，为 X 轴和 Y 轴分别指定了间隔，
并给底图添加了标题：

- **-Bxa4g2** 表示设置 X 轴（**x**）的标注间隔为 4 度、网格线间隔为 2 度（**a4g2**）
- **-Bya3g3** 表示设置 Y 轴（**y**）的标注间隔为 3 度、网格间隔为 3 度（**a3g3**）
- **-BWSen** 中 WSEN 分别是西南东北四个方向的英文单词首字母，用于控制四条边的属性。
  大写的 **WS** 表示给西边和南边添加标注，而小写的 **en** 则表示对于东边和北边
  只绘制边框但不显示标注
- **-BWSen+t"New Zealand"** 中 **+t** 用于给整张图添加标题（**t**itle）。
  由于标题 New Zealand 中含有空格，我们需要使用引号将其括起来

```{eval-rst}
.. gmtplot::
    :caption: 为区域地图添加标题
    :width: 50%

    gmt begin NewZealandMap
        gmt coast -JM12c -R165/180/-48/-32 -Bxa4g2 -Bya3g3 -BWSen+t"New Zealand" -W0.5p -A10000
    gmt end show
```

## 线性坐标轴

GMT 最擅长绘制地图，同时也适合绘制最简单的线性坐标轴。同样的，要想绘制线性坐标轴，
我们依然需要使用 **-R** 指定坐标轴范围，使用 **-B** 绘制边框并指定边框和坐标轴属性，
同时，我们还需要使用 **-JX** 指定线性坐标轴的宽度和高度。

下面的示例中，我们使用了：

- **-JX8c/5c** 表明线性坐标轴的宽度为 8 厘米，高度为 5 厘米
- **-R10/70/-4/8** 表明 X 轴范围为 10 到 70，Y 轴范围为 -4 到 8
- **-Bxa10f5g10+l"X Label"** 设置了 X 轴的属性，
  **a10f5g10** 分别设置了标注（**a**nnotation）间隔为 10，
  刻度（**f**rame）间隔为 5，网格线（**g**rid ）间隔为 10；
  **+l"X Label"** 则为 X 轴添加了标签；对于 Y 轴同理；

```{eval-rst}
.. gmtplot::
    :width: 60%
    :caption: 线性坐标轴

    gmt begin linearXY
        gmt basemap -R10/70/-4/8 -JX8c/5c -Bxa10f5g10+l"X Label" -Bya4f2g2+l"Y Label" -BWSen+t"Linear X-Y Plot"
    gmt end show
```

GMT 同样也可以绘制对数轴、指数轴以及极坐标轴，在这一节中不再介绍。

## 三维线性坐标轴

三维坐标轴相对于二维坐标轴多了一个 Z 轴。与二维线性坐标轴类似，我们需要针对 Z 轴
指定 Z 轴的范围、Z 轴的高度以及三维视角。

下面的命令绘制了一个三维线性坐标轴，相比于传统的二维线性坐标轴，其不同之处在于：

- **-R** 选项中有 6 个数字，后面两个数字表示 Z 轴最小值和最大值
- **-JZ5c** 指定了 Z 轴的高度为 5 厘米
- **-Bzaf** 指定了 Z 轴的标注和刻度属性
- **-BSEwnZ+b** 中 **Z+b** 表示绘制一条 Z 轴，并绘制出整个长方体的所有边
- **-p130/30** 指定了看这个长方形的视角。130 和 30 分别为三维视角的方位角和高度角。
  这个解释起来稍复杂，读者可以自己试试修改这两个参数并查看效果。方位角的取值范围
  为 0 到 360 度，高度角的取值范围为 0 到 90 度。

```{eval-rst}
.. gmtplot::
    :width: 50%
    :caption: 三维线性坐标轴

    gmt begin 3DMap
        gmt basemap -R10/70/-4/8/-10/10 -JX8c/5c -JZ5c -Bxa10+lX -Bya4+lY -Bzaf+lDepth -BSEwnZ+b+t"3D Plot" -p130/30
    gmt end show
```
