使用 NCL 进行科学可视化
我之前的许多文章都着眼于进行科学计算并生成科学结果的软件包。但是,对于普通人来说,理解数字列几乎是不可能的。那么你能做什么呢?答案是可视化。我们通过视觉进行大量的处理,而我们查看信息的最简单方法是通过某种图形格式。由于图形表示的强大功能,不同的团队编写了几个软件包。在本文中,我将介绍 NCL(NCAR 命令语言,http://www.ncl.ucar.edu)。NCAR 是国家大气研究中心,计算和信息系统实验室在那里开发了 NCL。NCL 是一种专门为数据分析和可视化设计的解释型语言。它支持科学计算中使用的几种不同的文件格式,并且还提供了几个内置的数据分析函数。
NCL 以源代码和预编译二进制文件的形式提供。这些文件托管在地球系统网格网站 (http://www.earthsystemgrid.org) 上。第一步是在地球系统网格站点上获得一个帐户。注册完成后,您可以下载感兴趣的系统的源代码或二进制文件。二进制文件打包为 tarball,并且已针对基于 Debian 和基于 Red Hat 的系统编译。您可以在 32 位和 64 位二进制文件之间进行选择。下载正确的 tarball 后,您可以将其解压缩到您选择的目录中。UNIX 系统上的常用位置是 /usr/local,但您可以将其放置在系统上的任何位置。
解压缩后,您需要在实际使用 NCL 之前设置几个环境变量。第一个是环境变量 NCARG_ROOT
。您需要将其设置为包含 NCL 可执行文件和库的父目录。例如,如果您将 NCL 解压缩到 /usr/local 中,则应设置 NCARG_ROOT=/usr/local
。您还需要将 NCL 可执行文件的位置添加到您的路径中。在此示例中,您应将 $NCARG_ROOT/bin
或 /usr/local/bin
添加到 PATH 环境变量。您还需要在您的主目录中创建一个名为 .hluresfile 的配置文件。此文件将保存配置选项,例如默认字体和默认颜色表。
一切设置完成后,您可以通过运行以下命令快速测试 NCL 是否正常工作
ng4ex gsun01n
此命令将名为 gsun01n.ncl 的 NCL 脚本文件复制到您当前的工作目录中,并通过 NCL 运行它以生成一些图形输出。
如果您决定从源代码构建 NCL,则需要安装许多额外的库来处理所有可能的输入文件格式以及所有可能的输出图形格式。完整的说明可在 http://www.ncl.ucar.edu/Download/build_from_src.shtml 获得。
强烈建议您先尝试使用预构建的二进制文件,然后再进行从头开始构建 NCL 所涉及的所有工作。
现在 NCL 已经安装并可以使用了,您实际上可以用它做什么呢?如果您输入命令 ncl
,您将获得一个提示符,您可以在其中输入命令。输入以下命令告诉 NCL 开始记录您在当前 NCL 会话中发出的命令
record "my_script.ncl"
完成后,键入 stop record
以告诉 NCL 停止记录您的会话。此时,您将拥有一个 NCL 脚本,如果您愿意,以后可以重复使用它。
获得 NCL 脚本后,您可以使用以下命令通过 NCL 运行它
ncl <my_script.ncl
这只是开发 NCL 脚本的一种方法。请记住,NCL 是一种完整的编程语言,一旦您了解了足够的可用命令,就可以从头开始编写脚本。
要学习的第一个结构是 NCL 脚本的格式。脚本都以命令 begin
开头,并以命令 end
结尾。其他所有内容都发生在两个语句之间。
在 NCL 中,有四个通用的对象组可用。第一组是工作站对象。这些对象表示图形设备,这些设备充当图形函数用来在其上绘制的显示设备。这些可以是 X11 窗口、NCAR 计算机图形元文件或 PostScript 文件。第二组是数据对象。数据对象存储在您的分析和图形演示中使用的实际信息。第三组是视图对象,它表示您的图形表示的元素。这些可能是诸如文本对象、刻度线或轮廓图等内容。第四组是“其他”对象组,其中包括所有其他内容,例如叠加层或注释。您可以使用以下命令创建新对象
objectname = create "object_character_name"
↪class_name parent_object
end create
您可以在其中基于现有的父对象创建新对象。
那么,基本的图形显示是什么样的呢?您可以使用以下示例生成一些简单的内容
begin
x11 = create "x11" xWorkstationClass defaultapp
end create
text = create "text" textItemClass x11
end create
draw(text)
frame(x11)
end
将这些命令保存到名为 sample1.ncl 的文件中。要运行它,您可以执行 ncl <sample1.ncl
。前三行创建一个 X11 对象以在其上绘制。接下来的两行创建一个文本对象。您需要 draw
命令来生成文本对象,而 frame
命令会在您的屏幕上实例化图形显示。
如果您想导入数据以进行一些处理怎么办?NCL 可以处理科学计算工作中使用的许多文件格式。作为一个简单的例子,假设您有一些代码只是将结果转储为感兴趣的值的 ASCII 表示形式。您可以使用以下命令加载此数据
file_data = asciiread("/full/path/to/file", file_size, "float")
这将从给定的文件中读取 file_size
个数字,并将它们作为浮点类型导入。完成此操作后,您可以使用索引抓取子集并将它们分配给变量。例如,您可以使用以下命令创建一个新数组
array1 = new(64, float)
然后使用以下命令从文件中分配前 64 个元素
array1(0:63) = file_data(0:63)
绘图有点复杂。第一步是创建一个数据对象,该对象将存储要绘制图形的值。例如,您可以使用如下内容
field1 = create "field1" coordArraysClass defaultapp
"caYArray": (Y-data)
"caXArray": (X-data)
end create
您将在其中将 X-data
和 Y-data
替换为您要使用的实际数据数组。完成此操作后,您实际上可以使用以下命令进行绘图
xy_plot = create "xy_plot" xyPlotClass wks
"xyCoordData": field1
end create
draw(xy_plot)
frame(wks)
这将创建一个 xy_plot
对象,该对象基于您导入到 NCL 中的数据。接下来,您需要运行 draw
命令,然后调用 frame
命令来实例化绘图。
如果您只想查看图形,可以在 X11 显示对象上调用 frame
。或者,您可以通过使用文件对象(如 PostScript 文件)调用 frame
将图形保存到文件中。
在编写和运行 NCL 脚本时,可能存在许多潜在的陷阱。其中许多会导致代码效率低下,这主要是因为 NCL 是一种解释型语言。要查看的第一项是您是否不必要地使用了循环。在可能的情况下,您应该尝试使用内置函数来完成任何处理,而不是尝试自己进行处理。例如,假设您要将两个 100x100 数组相乘。如果您自己做,您可能会编写一些如下所示的循环代码
do i = 0,99
do j = 0,99
c(i,j) = a(i,j)*b(i,j)
end do
end do
在 NCL 中,您可以等效地编写
c = a*b
这不仅更短,而且效率也更高。不必遍历循环的每次迭代并最终承担评估循环每次迭代语句的成本,乘法由 NCL 作为单个语句进行评估,并传递给处理矩阵乘法作为单个语句的底层库。您还应该尝试确保从循环中提取尽可能多的操作,并在循环操作完成后一次性应用它们。此外,有时您尝试执行的处理只是太密集了。在这些情况下,您可以告诉 NCL 加载并使用外部 C 或 FORTRAN 编译的对象来处理此处理。
这只是对 NCL 的最基本介绍。NCL 是一种完整的编程语言,具有循环结构和条件语句。您有变量、对象和大量内置函数。您可以通过访问 NCL 和地球系统网格网站来查看所有可能性。您可能会对可能进行的分析感到惊讶。