---
author: 田冬冬
date: 2024-09-12
---

```{index} ! pen
```

# 画笔

有画笔才能画线条、三角形、圆形等各种复杂的形状。

GMT中的画笔有三个属性：笔宽、颜色和线型，三者用逗号分隔，即 *width*,*color*,*style*。

在 GMT 模块的语法介绍中，一般用 *pen* 表示画笔属性，读者在见到 *pen*
时应自行脑补成 *width*,*color*,*style*。

在指定画笔属性时，可以指定三个属性中的任意一个或多个属性，但要保证属性的相对顺序。

## 画笔线宽

GMT中可以通过两种方式指定画笔宽度：

1. 宽度值+单位，即 *width***c**|**i**|**p**

   在不指定线宽单位时，GMT使用的默认线宽单位为 **p**。
   除了 **p** 之外，还可以使用 **c** 或 **i** 指定线宽单位为厘米或英寸。

   推荐只使用 **p** 作为线宽单位，毕竟多数情况下线条的宽度都比较小，用“小”单位
   **p** 作为单位更方便些。且建议总是显式指定线宽单位，以使得命令的参数更加易读，
   比如 **1p**、**0.25p**。

2. 预定义画笔宽度名

   对于一些常用的画笔宽度，GMT将其定义为特定的名字，以方便用户使用。
   下表中列出了GMT预定义画笔宽度名及其对应的线宽。

   ```{eval-rst}
   .. table:: GMT预定义画笔宽度名
      :align: center

      +---------------+---------+---------------+--------+
      | 线宽名        | 线宽    | 线宽名        | 线宽   |
      +===============+=========+===============+========+
      | **faint**     | 0       | **thicker**   | 1.5p   |
      +---------------+---------+---------------+--------+
      | **default**   | 0.25p   | **thickest**  | 2p     |
      +---------------+---------+---------------+--------+
      | **thinnest**  | 0.25p   | **fat**       | 3p     |
      +---------------+---------+---------------+--------+
      | **thinner**   | 0.50p   | **fatter**    | 6p     |
      +---------------+---------+---------------+--------+
      | **thin**      | 0.75p   | **fattest**   | 10p    |
      +---------------+---------+---------------+--------+
      | **thick**     | 1.0p    | **obese**     | 18p    |
      +---------------+---------+---------------+--------+
   ```

:::{note}
指定线宽为 **0p** 或者 **faint** 并不表示不绘制线段，而是指定了画笔的宽度
为最细宽度。画笔的实际最细宽度由具体的设备来决定。
通常情况下，线宽为 **0p** 的线条在图片缩放时线条宽度总是保持最小值。
:::

## 画笔颜色

在 {doc}`color` 中已经介绍了如何指定颜色，所有的颜色均可用于指定画笔的颜色。

## 画笔线型

画笔线型属性 *style* 控制了线条的外观，可以用四种方式表示：

1. 简单符号

   - `.` 表示点线
   - `-` 表示虚线

2. 组合符号

   通过对简单符号的任意组合可以获得更多的线型，比如 `.-` 表示
   点划线，`..-` 表示两个点号与一个连字号交替出现。

3. 预定义线型名

   GMT预定义了几种线型名，包括：

   - **solid**：即实线
   - **dashed**：即虚线，等效于 `-`
   - **dotted**：即点线，等效于 `.`
   - **dashdot**：划点线，等效于 `-.`
   - **dotdash**：点划线，等效于 `.-`

:::{note}
`.` 和 `-` 的绝对长度由画笔宽度来决定。
`.` 的长度等于画笔宽度；`-` 的长度为8倍画笔宽度；
点线或虚线中段间空白的长度为4倍画笔宽度。
:::

4. 复杂线型

   通过 *string*\[**:**_offset_\] 的形式可以自定义任意复杂的线型。

   *string* 是一系列由下划线 `_` 分隔的数字组成。这一系列数字中，
   第奇数个数字表示实线的长度，第偶数个数字表示空白的长度。
   通过实线和空白的长度的不同组合，即可构成多种复杂的线型。
   *offset* 表示线段开始处整个线型的初始相位移动（默认值为0）。

   例如，**4_8_5_8:2p** 表示线型首先是长度为 **4p** 的实线，然后是长度为 **8p**
   的空白，紧接着长度为 **5p** 的实线和长度为 **8p** 的空白，然后按照该模式不断
   重复。此处的 *offset* 值为 **2p**，因而线段的最开始处，第一条实线的长度
   **4p** 经过相移后长度为 **2p**。

   线型中的这些数值，默认单位是 **p**，也可以使用 **c** 或 **i**。

## 小练习

下面的命令用 {doc}`/module/plot` 模块绘制了一条线段。读者可以将命令中
**-W***pen* 中的 *pen* 修改为不同的值来理解如何指定不同的画笔属性:

```
gmt plot -R0/10/0/5 -JX10c/5c -Wpen -pdf pens << EOF
0 2
10 2
EOF
```

(fig-pen-styles)=

```{eval-rst}
.. gmtplot:: pens.sh
    :show-code: false
    :width: 75%
    :caption: GMT画笔示例
```

发挥你的想象力，想想如何绘制如下图所示的黑白相间的铁轨线？点击“Source Code”
可以查看下图对应的绘图脚本。

```{eval-rst}
.. gmtplot::
    :show-code: false
    :width: 75%

    gmt begin rail-trail
    gmt basemap -R0/10/0/4 -Jx1c -B+n
    # 绘制黑色线段
    gmt plot -W5p,black << EOF
    1 2
    9 2
    EOF
    # 使用相同的数据点绘制稍细的白色线段
    gmt plot -W4p,white,20_20 << EOF
    1 2
    9 2
    EOF
    gmt end show
```
