[Generic Mapping Tools (GMT)] Generic Mapping Tools (GMT) 实际使用心得和随笔(1):散点图 ...

[复制链接]
Generic Mapping Tools(GMT)是科研人员常用的绘图工具。GMT具有强大的功能和一些内置的统计模块。与其他常用的绘图工具(或具有绘图功能的软件,如MATLAB、python、R等)相比,GMT的特点是绘图效率高,但没有可操作的直观界面(GUI)。
我在本系列文章中的文章基于“打开袋子即可食用”的概念,并直接从示例开始。我还将提到gmt4、5和6之间的一些差异。在本文中,我将提前给出示例代码。至于如何从一个例子中推断,请根据GMT手册学习。
前言:GMT使用环境
(1) 装置
我个人使用MAC作为我的工作计算机环境,因此我可以简单地使用诸如自制和macport之类的工具安装GMT。在终端中输入:
brew install gmt
brew install gmt@5
请注意,自制的GMT软件包是gmt6的版本。如果要安装gmt5版本,需要使用第二个命令。
(2) 使用
通常,GMT代码需要在批处理文档(如bash)中编写。
例如,此实例中使用的代码可以写入plscatter.sh等文件,然后通过以下命令执行。
sh plscatter.sh
正文:(1)散点图+拟合-这是gmt5版本
先上效果图(数据是我随手选的)。

0 G8 |) O0 _) P" u1 Q+ J' }                               
登录/注册后可看大图
这张图上,包含了大部分GMT画散点图所需要用到内容:
  • 绘制子图
  • 根据数据绘制点并着色。
  • 绘制颜色尺度
  • 添加不同字体、颜色的文本和绘制文本框
  • 上下标等小功能
    " `1 w5 ?# e# B1 `  ~3 E
伸手党可以直接复制走。如果想学习,则可以继续往后看。
游客,如果您要查看本帖隐藏内容请回复
下面,我们来根据代码分别解读以上功能。
首先,作为bash script文件,文件头必不可少。之后的部分,#之后是注释,不会参与执行。
#!/bin/bash
然后,进入一般设置部分。 我这里针对页面和边框等进行了以下设置:
游客,如果您要查看本帖隐藏内容请回复
7 F0 C6 E$ z8 A# D  f* D! i2 O
以上可以保存在某一个公用文件(如gmtpar.sh)中,使用时调用即可。
. ./gmtpar.sh     
之后,进入具体画图设置。由于bash提供了参数赋值功能,因此将某些设置内容写成参数,这样可以方便同一调控和修改和参照。
range=1800/2400/1800/2400  x、y轴的绘制范围格式为 xmin/xmax/ymin/ymaxcptfile=compare.cpt     颜色盘文件名size=2.8   每张子图大小为2.8 (因为之前设置,这里不加单位,默认为英寸)
- }; m% |% ~% B- G- N  d3 P1 k, L$ D2 dxanot=a200f100g300    x轴每隔200作为主刻度,每隔100为副刻度,每隔300画背景线(图中央交叉灰线)yanot=a200f100g300    y轴每隔200作为主刻度,每隔100为副刻度,每隔300画背景线(图中央交叉灰线)in=sample.txt     这是输入文件,内容大概如下:
$ `/ D( {" G) T8 x; ^- C------------------参考:sample.txt内容---------------------#    depth    Sample1_OBS   Sample1_model   Sample2_OBS   Sample2_model
5 {6 C- D/ R2 \: N       14.99     2262.00     2061.40     2274.55     2100.88* L0 S' A- @& k; e3 Z; P
       34.88     2287.70     2087.80     2297.18     2117.82
5 O: s5 g  _+ d4 p       54.36     2296.70     2150.90     2313.25     2152.175 M( c! B% b( ]8 {* H
       78.84     2288.50     2177.80     2302.91     2150.539 s$ k; O% C: q) G4 r1 @$ {
-----------------------sample.txt内容-----------------------out=sample.ps     这是原始输出文件,为postscript格式(最后我用psconvert转换为了jpg格式)
以上对实际用途的基本设置完成。大家可以看出,这里主要是设置了图的大小、范围、坐标轴、输入和输出的文件名。紧接着,我们就开始正式画图了。
  • 绘图第一步:确定图的样式
    % d, r3 _/ Q& _1 h- h0 m
根据上面给出的sample.txt的内容和格式,我们需要在XY平面上绘制两个不同样本的三个信息(深度、观测值和模拟值)。同时,面对此类数据,我们一般需要观察对比模拟值是否接近观测值,以及不同深度是否对其产生影响。因此,我们可以使用散点图来验证我们的模拟值可以接近观测值,并分别与观测和模拟的X和Y坐标一一对应。理想情况下,模拟值应等于观测值,即满足y=X的函数。我们选择使用颜色表示深度,这不会破坏y=X的对应关系,但也会看到深度的影响。
因为有两种样本并共享深度信息,所以可以清楚地得出结论,需要绘制两个子图并使用相同的颜色比例。
  • 绘图第二步:指定颜色
    4 M# h+ }2 I6 [- t0 H
gmt makecpt -Cseis -T0/60/2 -D  -I > $cptfile
-C: 使用seis基准颜色盘设置
-T: 颜色对应的最小值为0,最大值60,间隔为2
-I:颠倒seis基准的最大最小值代表的颜色
-D:如果数据超过上面设置的最大最小值,则用前景和背景色代替
  • 绘图第三步:绘制第一子图(panel1)的底图
    & @2 [) I/ w4 q
我这里根据命令和选项,加了注释,方便大家理解。部分参数(如range等)在上面已经进行了设置。
########panel 1gmt psbasemap  -R${range} -JX${size} -B${xanot}:"Sample 1 Obs. [m@+2@+]":/${yanot}:"Sample 1 Model [m@+2@+]":WSne   -X1  -K >  $out
选项表示意思:
psbasemap: 底图命令
-R: 指定范围
-J: 底图类型
-B: 轴设置,并标注文字。 这里为了表示平方米,用了上标。 两个@+ @+中间的内容即为上标 。
-B选项后的WSne:轴标注仅在大写的W(左)S(下)出现,小写表示n(上)和e(右)只画线不标注。WSNE中任意一个不写,则对应方向不画线也不标注。
-X1: 图的起始点横向移动1英寸,这是根据图的数量和大小调整的,可以自行更改。GMT6开始因为纸张无限大,一般无需设置。
-K :下方还有命令,不要结束
> : 一个大于号表示新建并输出到文件,类似地>>表示不新建而是追加输入。
  • 绘图第四步:绘制带颜色的点
    - K. }  a; [( F* _
读取输入文件,并逐行读取。如果满足条件的话,取输出第2列、第四列、第一列      这里的竖线表示下面一行接上% a0 f7 b. ]5 c  P
awk  '{if ( $1 != "#" && $2 > -900. && $4 > -900. )      print $2,$4,$1}'  $in         |绘制点; z* R9 h* _' c+ n! H( Q! G! R) i
gmt psxy -R -J  -Sc0.04 -C$cptfile -O -K >> $out
这里我用到了awk命令,主要是为了增加if条件判断。
上文条件的意思是:第一列不是“#”号,且第二列和第四列都大于-900。 增加这一条是为了防止读取空值或是读取第一行的注释,造成不必要的麻烦。
&& 表示if语句中的【并且】(and)
psxy:用于绘制点线面等
-Sc:绘制图样、用c表示绘制圆(circle)、0.04表示圆的直径为0.04(英寸)
-R和-J:和之前一样。这里因为没有更改,所以可以省略具体内容。
-C:使用颜色文件
-O:追加到已有的ps文件中
  • 绘图第五步:拟合直线并绘出

      E* m& Q+ u5 f9 ], R. u; N
游客,如果您要查看本帖隐藏内容请回复
利用了GMT内置的线性拟合功能,拟合出了一条直线(1700<x<2500,间隔1)并输出。这稍微有点进阶,具体可以参加GMT的手册。
这里的psxy,没有添加-S选项,则默认是画线。
-W0.5:线的粗细为0.5
  • 绘图第六步:图中添加文字
    ' k( a6 N* r" U% O* o
gmt pstext -R -J -N -F+a0+f14p,Helvetica-Bold+jLT  -O -K >> $out << EOF1850 2350 a)EOFgmt pstext -R -J -N -F+a0+f12p,Times-Italic+jLT -Gwhite -Wthinner  -O -K >> $out << EOF2000 1900 @;blue;y = 0.791 x + 481.469@;; % T) }% o9 ]* A- @( S
EOF
pstext:添加文字
-F:设置文字角度(a)为0,大小(f)为14,字体Helvetica-Bold,基准锚点为左(L)上(T)
<< EOF: 常见的bash命令,与GMT无关。本行命令使用到出现EOF为止的内容。
-N:表示如果坐标超出底图范围,也依然绘制
1850 2350 a): 前俩数字分别表示x,y坐标。 'a)' 是书写内容。
-G: 文本框底色
-W:文本框边框粗细
这里有一个进阶颜色用法。通常,文字的颜色是在-F中设置。 但是如果想要在一次输出中,出现多种颜色,就需要用到GMT5引入的颜色调用命令 @;【颜色】;【输出内容】@;;
【颜色】:格式多种多样,red, blue, green等是内建的,也可以用RGB值,比如蓝色是0/0/255
注意:这些@和分号都要保留。
例子中是GMT5的格式,GMT4可以参考下面:
#For GMT4gmt pstext -R -J -N -O -K >> $out << EOF1850 2350 14 0 2 LT a)EOFgmt pstext -R -J -N -W0.5 -Gblue  -O -K >> $out << EOF2000 1900 12 0 6 y = 0.791 x + 481.469EOF
  • 绘图第七步:子图2

    % e: G/ J. m: l$ y, H$ Y; a
GMT5中的子图,是通过追加绘制和移动来实现的。
gmt psbasemap -R${range} -JX${size} -B${xanot}:"@~D@~Sample 2@-Obs.@- [m@+-2@+]":/${yanot}:"@~D@~Sample 2@-model@- [m@+-2@+]":WSne -X4  -O -K >>  $out
类似子图1,但是我这里使用了 -O表示追加,并且用了两个大于号>>
这里,我用到了希腊字母

% v' ]* {5 I- u                               
登录/注册后可看大图
。 在GMT中,特殊符号需要用到@~@~。其中,@~D@~是大写的Delta,类似地@~d@~是小写的delta:

$ [" n7 o, ?7 N; H# T                               
登录/注册后可看大图
, f4 I" ^6 S4 n9 R
此外,我也给出了下标的用法:@-@- (参考上标是@+@+)。
之后的内容,和子图1类似。
注:GMT6有更简单的子图绘制方式,在之后的文章中会提到,此处略过不表。
  • 绘图第八步:绘制colorbar
    1 Y  l2 E5 A& u' f5 ]% |3 z
gmt psscale -R -J -DJMR+v+ef -C${cptfile} -Bx+l"Depth" -By+l"m" -Np -B20 -O >> $out
psscale 绘制颜色色条
-D:设定位置和样式。其中子选项J之后的MR表示在图右侧(R)中间(M)的位置,v表示vertical(竖)。e表示在前景(f)方向增加小三角。
注:因为我在makecpt时用了-D选项。输入的深度数据最小值也不比0小,而最大值则超过了60,因此我仅在60处加了三角。
-C: 颜色基准文件。应与之前使用的文件相同
-B:设置颜色色条的间隔,标记。 -Bx是设定色条的x轴,-By是设定色条的y轴。l子选项表示添加标注文字。-Np是让色条按照间隔,每个颜色输出为方形色块(需细看),而非连续变化的色条。-B20表示色条轴数字值的间隔为20,实例中就是0,20,40和60。
注:-Bx,-By可以分开设置。
  • 绘图第九步:转换格式
    ' B: Z: L# ~3 _* y
gmt psconvert -A0.3c -P -E600 -Tj $outecho Output : $outrm $out
在不同的场合,我们需要不同的图片格式,并不是所有的计算机都能打开PostScript(PS)格式的文件。因此,GMT还提供格式转换功能。这里,GMT可以通过命令来裁剪图中的空白区域。
答:意指控制图片的大小并切断空白区域。0.3C表示切割边缘与每个底图之间的距离,单位为cm(c)。这里的底图不包括颜色栏和轴比例编号,因此需要小心处理。
-P:强制门户模式。
-E:图片分辨率(单位:PPI)。由于PS格式是矢量格式,没有分辨率的概念,因此有必要指定转换图片的分辨率。一般来说,提交线图的分辨率PPI大于1000,而其他图片的分辨率约为300-600。您还可以将其转换为PDF格式,以避免图片模糊。
-T:转换格式。常用的有J(JPEG)、P(PDF)、t(TIFF)等。
最后,我用echo输出文件名并删除原始PS文件,只留下转换后的JPEG文件。
  • 小结

    $ q6 _# f1 K$ E1 w
以上就是绘制一幅散点图所需要的所有步骤。
个人体验,GMT绘图较Python,Matlab等,绘制的速度会快一些。以此图为例的时间如下,图中每个子图有大概4000个点,并且还包括了格式转换的时间。

  U# |3 R0 _' M, l. y( [                               
登录/注册后可看大图
但是由于没有GUI,每次绘制需要一步一步的对图片内容,标注位置等进行调整。比如,为了生成此图,我大概进行了10分钟左右的修改和调整。
6 v! q! J0 t6 F4 a/ ^/ t
                               
登录/注册后可看大图
当然,努力工作的结果是有目共睹的。绘制的图片非常漂亮,非常适合学术报告、海报印刷和期刊投稿。自从我获得硕士学位以来,我一直在使用gmt4。我还使用了MATLAB、Python和originpro的绘图功能,但由于绘图的习惯和统一性,我回到了GMT。最近,它经历了从gmt4到gmt5再到gmt6的自我更新和升级。我一时兴起,用GMT写了一些常用的句子,希望能帮助和启发想要或正在使用GMT的学生。当然,我的代码不一定是最佳的解决方案,欢迎您进行更正。
! Q- O9 O6 A0 X3 b; i8 G9 s* h
回复

举报 使用道具

相关帖子

全部回帖
暂无回帖,快来参与回复吧
懒得打字?点击右侧快捷回复 【吾爱海洋论坛发文有奖】
您需要登录后才可以回帖 登录 | 立即注册
失意
活跃在2022-11-2
快速回复 返回顶部 返回列表