NCL 语言中图形绘制基本概念辨析

2021-03-23 06:37李玉鹏高梦竹曲骅倩
科学技术创新 2021年7期
关键词:画纸调用画板

李玉鹏 李 吉* 高梦竹 曲骅倩

(1、长白山气象与气候变化吉林省重点实验室,吉林 长春130062 2、吉林省气象科学研究所,吉林 长春130062 3、伊通满族自治县气象局,吉林 四平130700 4、成都信息工程大学,四川 成都610200 5、黑龙江省气象台,黑龙江 哈尔滨150001 6、桓仁满族自治县气象局,辽宁 本溪117200)

NCL 是一种专门为大气科学专业数据处理以及图形绘制而开发的编程语言,其在气象领域的应用在国内外十分广泛[1,2]。NCL 支持丰富的数据类型,如NetCDF 3/4、GRIB 1/2、HDF 4/5、HDF-EOS 2/5、shapefile、ASCII 以及二进制文件,而且对数据接口进行了封装,使得读取不同数据格式都十分方便。NCL有令人喜爱的数据可视化能力,默认参数下输出的图形质量已经十分出色,国内外众多气象相关的期刊上的图形很多都由NCL 绘制。除了在图形绘制方面的优势外,NCL 还内建了许多气象专业常用的公式和函数,可以方便使用者直接调用,另外,NCL 支持众多的投影和网格类型,因此也可以对众多模式结果进行后处理和可视化[3,4]。

NCL 虽然有着优秀的数据处理和高品质图形绘制能力,但其语言设计方面和Matlab、Grads 等其他气象常用编程语言有着较大的差异,其特有的以@为标志的面向对象的属性设置更让众多初学者都感到不适。

而在数据可视过程中,draw、frame、gsnDraw、gsnFrame 这几个语句是十分重要也是十分常见的,但往往不易理解。因此本文主要对以上这些语句以及背景概念进行详细分析。

1 理解draw 与frame 过程

下面来详细地分析draw 和frame 的区别。首先draw(plot),括号内还可以是数组,这个“过程”即procedure,相当于执行“绘制”,绘制不是直接地绘制到png、pdf 等图形中,而是绘制在workstation 中,这一过程就像执行了一个动作,当然这个动作的对象必须是view object(可理解为图形对象),view object 可以通过gsn 方式或者create 方式产生。frame (wks) 也是一个procedure,它的参数同样也可以是一个数组,它所做的就是先对workstation 中的图形对象进行更新,然后再清空。同样workstation 对象除了通过gsn_open_wks 产生,也同样可以由create 方式生成。通俗一点说就是:每调用frame(wks)一次,都会产生一个画板,如果之前draw(plot)了,那么画板上就会有plot的图,如果前面没有draw 任何plot,那么产生的画板就是空白的,表现在(e)ps 或pdf 文件中就是空白页。

所以,当完成完整的一组绘制时再进行frame,而且如果紧接着没有新的draw 动作,马上再frame,新产生的画板也是空白的,并不会产生之前图形的副本,即frame 一次清空一次wks 中的图形对象。如果从头到尾一直都没frame,那么最后也还会frame 的,因为只要生成了workstation,脚本结束时会自动有一次frame。同样,如果没有draw 过任何东西,这张画板就是空白的(以上这些讨论都是基于gsnDraw 和gsnFrame 属性都是False的情形)。gsnDraw 属性表示是否在调用gsn function 或者procedure 时顺便执行draw 命令。gsnFrame 表示是否在调用gsn function 或者procedure 时顺便执行frame 命令。如果所需绘制的图形中包含不同场的叠加等较为复杂的操作时,这时往往要执行不止一条gsn 命令,这两个属性一般都设成False。所以一般当要产生和操作的图形对象比较多时,gsnDraw 和gsnFrame 最好还是关掉,采用显示手动的方式控制整个绘图流程。

2 gsn 绘图function 和procedure 的区别

function 有返回值,调用时前边必须要有一个变量来接收这一返回值。而且其作用效果是跟随图形对象的。如果把gsnFrame 和gsnDraw 设成了False,那么必须执行draw(wks),然后这个function 产生的图才会被打印到画板上。以gsn_add_text这个function 为例,draw (plot) 之后再执行该function,然后再frame 是没有效果的,因为附着有文字信息的plot 根本没有被draw 过。如果一直执行draw 动作而后面不跟随frame,所有图都会被放到同一个页面中,当frame 时会一起出现在画板上,当然如果你一直draw 的是一个图形对象的话,你可能看不出来是多个对象,因为这些对象正好完全重叠在一起了,只能看到最上面的。

procedure 无返回值,不能赋值给变量。而且这一动作可以自行完成,不需要后续的draw 跟随。procedure 执行的结果不附着于其操作的图形对象,也可以说它是和图形对象分离的另一个过程(虽然中间可能会用到view object 对象,主要用来作为绘图位置等信息的参考),所以当图形对象又经历了放大(gsnMaximize)、覆盖(overlay)之类的操作后,procedure 之前的结果不会被更新,所以,就可能会出现procedure 的绘制结果错位或者消失(被覆盖)。

通过下边这段代码及其执行结果可以帮助我们更准确地理解上述内容。

图1 代码的执行结果

其执行的结果如图1 所示,结合图和代码不难发现:如果只关注大写字母的顺序,它们的图层顺序由底到顶依次为C->A->B->D,从而我们不难分析得到:与frame 不同,draw 重复使用时不会清空之前结果;procedure 生成时也需要借助于plot 对象,但draw 的时候只draw 自身图形,与plot 相分离,本身自带draw 功能,不带frame 功能;function 跟随、附着于plot 对象,但自身无draw 和frame 功能;只要生成了一个wks,即使gsnFrame 设置为False,程序结束时仍会自带一个frame(wks)。

最后用一系列类比来加强对上面论述的理解,当gsnDraw和gsnFrame 都设置为False 时,这时是手动控制绘图流程,具有更大的自由度和灵活性,当需要绘制复杂的图形时,往往需要采用这种设置。gsn_open_wks 函数表示绘画开始,主要作用是提供绘画的画本,会根据后期的绘画需要进行纸张供给。gsn 绘图函数的作用可以类比于篆刻图形印章的过程,其绘制内容最初是保存在模子上的,只有当执行“盖章”(draw)这一动作时,图形才会被印在画纸上。而gsn 绘图过程的作用可以类比于直接在画纸上作画,没有中间过程,其绘制内容直接出现在当前的画纸上。而frame 这个过程则相当于将当前作画的画纸从绘画本子上取下来并放到作品集中,而这个作品集就是我们程序运行的最终输出结果,也就是我们看到的pdf 文件(单页或是多页),或者png(一张或多张)等图形。

3 结论

以上较为详细地介绍了NCL 在图形绘制过程中可能遇到的一些基本概念问题。

3.1 详细介绍了draw 和frame 过程(procedure)的区别和用法。

3.2 详细辨析了gsn 绘图过程与函数的区别和用法。

3.3 在绘制复杂图形时,要将gsnDraw 和gsnFrame 属性设为False,这样可以更自由地控制绘图顺序和显示效果。

猜你喜欢
画纸调用画板
核电项目物项调用管理的应用研究
系统虚拟化环境下客户机系统调用信息捕获与分析①
石头草莓
把手掌放在画纸上描一描,画出一只幽灵吧
把手掌放在画纸上描一描,画出一只企鹅吧
七彩画板
七彩画板
七彩画板
利用RFC技术实现SAP系统接口通信
C++语言中函数参数传递方式剖析