查看原文
其他

NCL画图个例讲解

Exmaple2——contour plots

这个示例展示如何从 netCDF 文件中读取数据,如何改变地图的颜色,如何创建和绘制等值线,如何打印变量,如何将数据写入到 ASCII 文件

MATLAB深度学习工具箱由郁磊博士主讲的科研经验分享与科研工具推荐视频可扫码观看啦

...................全干货内容


这个例子读取netCDF文件,并且用3个不同的数据的绘制了5条等值线图,为每个等值线图获得不同的类型设置了 resources。这个示例同样从 netCDF ASCII 文件写入数据

想要了解 netCDF 更多,参见 http://www.unidata.ucar.edu/packages/netcdf/。

运行这个示例,必须下载以下文件:gsun02n.ncl,然后键入:ncl gsun02n.ncl

示例 2 代码及解释    

1. load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl"

载入本示例使用的包含函数和程序(以 gsn 开头的)的 NCL 脚本。NCL load 语句的作用和 C Fortran90 程序中 include 作用一样。

2.

3. begin

开始 NCL 脚本

4.

5. cdf_file = addfile("$NCARG_ROOT/lib/ncarg/data/cdf/contour.cdf","r")

addfile 打开 netCDF 文件,addfile 支持 NCL 支持的许多数据格式提供。这些数据格式的列表,请参阅本章“Introdution”的“File input and output”。

Addfile 的第一个参数(一个字符串)是文件名字,通过后缀来决定文件类型。在这里,后缀“cdf”表明是一个 netCDF 文件,后缀“.nc”也是可以的。

重要说明:实际的文件名并不需要包括这个后缀,只是为了让 NCL 知道将要处理何种类型的文件。如果带有后缀的文件名在指定的路径下不存在,那么NCL 就要需找不带后缀的文件。例如,如果实际文件名叫做“x”,是一个 netCDF文件,在 addfile 中的“x.nc”会使 NCL 找“x.nc”和“x”。

Addfile 的第二个参数是一个字符串,表明你是要读取(“r”)、写(“w”)还是创建(“c”)这个文件。

另一个重要说明:此功能不会从 netCDF 文件中读取任何数据,它只是返回一个对该文件的引用。

6.

7. temp = cdf_file->T(0,0,:,:) ; temperature

8. Z = cdf_file->Z(0,0,:,:) ; geopotential height

9. pres = cdf_file->Psl(0,:,:) ; pressure at mean sea level

10. lat = cdf_file->lat ; latitude

11. lon = cdf_file->lon ; longitude

现在已经对刚打开的 netCDF 文件有了引用,你可以进入 netCDF 文件中所有的变量和存储在其中的其他信息。TZPsllat lon 都是 netCDF 文件中的变量。T Z 有四维,对应 timelevellatitude longtitudePsl 有三维,对timelatitude longtitude。记住,NCL 使用的是“C”类型的 indexing,第一个元素是 index0,从左到右的维数变化得越快。

符号“->”用来获得用 addfie 打开的文件中的变量。你可以使用冒号表明选择的范围来选择数组的子集。更多关于数组处理和选择的信息,

请参阅Introduction”一章中的“Array processing”一节。

符号“(0,0,:,:)”用来选择 netCDF 文件中变量 T Z 的第一个时间步长和第一层。符号“(0,:,:)”选择变量 Psl 的第一个时间步长。这三个 netCDF 量都存储到 NCL 变量 tempZ pres 中。

如果没有指定数值的范围,就如同纬度和经度变量,那么所有的值都被选中。

上述赋值语句仍然保留了 netCDF 变量可能包含的元数据信息,如 attributesnamed dimensions coordinate variables(下面会讨论的概念)。

12.

13. temp = temp - 273.15 ; Convert Kelvin -> Celsius

14. pres = pres * 0.01 ; Convert Pa -> mb

使用 NCL 数组语句,将 temp 所有值从开尔文转成摄氏度,pres 所有制从帕斯卡转成百帕。因为这些变量都是以前定义的,所以它们包含了 attributesnamed dimensions coordinate variables(下面会讨论的概念)。

7-8 行可以和 13-14 行合并,如下所示:

temp = cdf_file->T(0,0,:,:) - 273.15 ; Won't retain metadata 

pres = cdf_file->Psl(0,:,:) * 0.01 ; of T or Psl.

但是,这个方法将不保留从 netCDF 文件中的任何元数据信息。上述语句中唯一获得的就是缺失值,如果有缺失值的话(缺失值以下将会讨论)。可以在“NCL variables overview”的“Value-only assignment”获得更多信息。

15. temp@units = "(C)" ; Change units to reflect

16. pres@units = "(mb)" ; conversion done

.因为 temp pres 的单位已经改变,上面的变动创建了“untis”变量(如果units”变量以前不存在)来反映新的单位。请注意,设置这个属性没有任何NCL 代码的效果,但是确实是良好的编程实践来更新元数据信息,同时在标题或者标签中你可能需要这个信息。

17.

18. xwks = gsn_open_wks("x11","gsun02n") ; Open an X11 workstation.

打开一个 X11 工作站绘制等值线图。

19.

20. plot = gsn_contour(xwks,temp,False) ; Draw a contour plot.

创建并且绘制 2 维数组 temp 的等值线图。gsn_contour 函数的第一个参数是上一个调用 gsn_open_wks 的返回的工作站变量。第二个参数是要画等值线的二维标量场,类型可以是 floatdouble 或者 integer。第一维必须是 Y 维,第二个X。最后一个参数是逻辑值,表明你是否设置了任何的 resources。为了得到NCL 提供的默认等值线图,最后一个参数留为 False

默认绘制的等值线图包括标记的刻度线、在图的右下角带有“informational标签,说明等值线的范围和间距。下一个示例说明如何关闭这个 informational标签,如何自定义刻度。此外,因为在这个图里没有定义 X/Y 轴的范围,默认的范围值是 0 n-1n 是该维度中点的数量。

如果要画等值线的变量已经有“long_name”的变量,那么 gsn_contour 将用这个变量作为图的标题。在此,temp 有“long_name”的属性(字符串“temperature”),因此将用作标题。如果没有“long_name”的属性,或者虽然有定义,但并不想用作标题,你可以使用 tiMainString resource 来定义自己的标题。下一个图中就是一个例子

21.

22. ;----------- Begin second plot -----------------------------------------

绘制第二个等值线图,这次只通过设置一些等值 resources 来绘制彩色的等值线。23.

24. resources = True ; Indicate you want to set some

25. ; resources.

使用 resources 来改变等值线图的外观(查阅示例 1 的如何设置 resources 解释)。等值线 resources 是“ContourPlot”组的一部分,以“cn”开头。

与等值线图有关的数据称作“标量场“,标量场 resources 以“sf”开头。

26.

27. resources@cnMonoLineColor = False ; Turn off the drawing of

28. ; contours lines in one color.

偶尔你会看到 resource 名字带有“Mono”。此时,通过设置 cnMonoLineColorFalse,你告诉 NCL 你并不想使用单一颜色的等值线图,因此使用复数 resource cnLineColors 来确定每条曲线的颜色。如果 cnMonoLineColor 设为 True,所有的曲线都会是同样的颜色。

CnLineColors resource 是运行 NCL 脚本自动生成的 resource 的一个例子。NCL 决定你有多少等值层次,然后设置 cnLineColors 为每一条曲线有足够的颜index

29.

30. resources@tiMainString = "Temperature (C)" ; Create a title

为第二个等值线图创建题目(覆盖了由“long_name”变量提供的默认的标题)。31.

32. plot = gsn_contour(xwks,temp,resources) ; Draw a contour plot.

用设置的 resources 绘制一个新的等值线图。

33.

34. ;----------- Begin third plot -----------------------------------------

绘制相同的等值线,只是这次用默认的阴影类型来填充等值线。此外,明确定义了 XY 的范围。

35.

36. resources@cnFillOn = True ; Turn on contour line fill.

37. resources@cnMonoFillPattern = False ; Turn off using a single fill

38. ; pattern.

39. resources@cnMonoFillColor = True

40. resources@cnMonoLineColor = True

默认情况下,等值线之间是没有填充的,所以当你需要填充时,设置 resource cnFillOn True。同样在默认情况下,当你填充等值线时,它们都将用一种固定的颜色填充,因此你需要将 cnMonoFillPattern 设为 False,告诉 NCL 使用对每个等值线之间使用不同的填充类型。

可用的“Fill patterns”在绘图文件中有列表。

通过设定 cnMonoFillColor cnMonoLineColor 都为 True,你告诉 NCL 对所有的填充和曲线使用同样的颜色(默认值是前景色)。

41.

42. resources@tiXAxisString = lon@long_name

43. resources@tiYAxisString = lat@long_name

使用 long_name 属性来为等值线图的 X/Y 轴创建标签。long_name 属性来自netCDF 文件,当你读取 lat/lon 变量到本地变量时。

44. resources@sfXArray = lon

45. resources@sfYArray = lat通过设置标量场 resources sfXArray sfYArray 1 维数组 lon lat,你可以明确定义 X/Y 轴的范围。

46.

47. plot = gsn_contour(xwks,temp,resources) ; Draw a contour plot.

绘制等值线图。请注意 XY 轴的新范围和新标题和 X/Y 轴的标签。

48.

49. ;---------- Begin fourth plot ------------------------------------------

绘制 Z 变量的等合资线图,用固定颜色填充等值线,在边上添加标签(label bar)。

50.

51. resources@cnMonoFillPattern = True ; Turn solid fill back on.

52. resources@cnMonoFillColor = False ; Use multiple colors.

53. resources@cnLineLabelsOn = False ; Turn off line labels.

54. resources@cnInfoLabelOn = False ; Turn off informational

55. ; label.

56. resources@cnLinesOn = False ; Turn off contour lines.

用不同颜色实心填充等值线,需要将 cnMonoFillPattern 重新设为 True,告gsn_contour 对所有等值线之间都是用实心填充,cnMonoFillColor 设为 False得到多种填充颜色。其他的 resources 关闭标签和停止绘制等值线,关闭在前面等值线图右下角的“informational”标签

57.

58. resources@pmLabelBarDisplayMode = "Always" ; Turn on label bar.

59. resources@lbPerimOn = False ; Turn off perimeter on

60. ; label bar.

还有的时候,当你想要添加其他图形对象到等值线图,就像是 label bar,图例、刻度或者标题。在 NCL 中,有个被叫做“PlotManager”的东西,能够让你做到这一点。它被称作这样是因为它管理者这些额外的对象的外观,而且试图智能化管理这些额外的东西应当绘制到原图的什么位置。此外,如果你调整了原图的大小,这些额外的对象也会同时进行调整。有些对象始终是在默认状态下进行绘制,就像是刻度和标题(如果你指定了的话)。Label bar 并不是默认绘制的,因此你应当通过设置 PlotManager resource pmLabelBarDisplayMode 为事先定义的字符串“Always”(默认值是“Never”)告诉 PlotManager 将它绘制出来。PlotManager resources 以“pm”开始,laber bar resources 以“lb”开头。

如示例 1 中指出,事先定义的字符串是不区分大小写的,因此pmLabelBarDisplayMode resource 可以使“always”或“ALWAYS”或者其他任何大小写字符的着。

设置lbPerimOn resourceFalse表明你不想在 laber bar周围绘制一个边界

61.

62. resources@tiMainString = Z@long_name

63. resources@tiMainFont = 26

64. resources@tiXAxisFont = 26

65. resources@tiYAxisFont = 26

Z long_name 设置了主标题。同时改变了标题和 X/Y 轴标签的字体。请参阅 table of all the available fonts 看它们的 index 值。在这里,将字体改变成了Times-bold”。注意:也可以使用字体的实际名字来设置这些resource,例如用“Times-bold来代替数字 26

66.

67. plot = gsn_contour(xwks,Z,resources) ; Draw a contour plot.

用新的数据库来绘制第四个等值线图。请注意,等值线图里的一些地方并没有绘制。这是因为数据中存在一些缺失值。默认情况下,如果数据通过任何 gsn_*的包含了属性“_FillValue”的图形进程,那么这个属性的值就假定为缺失值,同时,gsn_*进程将不会绘制和该值相等的数据。缺失值将在后面的例子中更加详细的解释,你可以在 NCL Reference Manua 中的“NCL variables overview”一节中获得更多信息。

68.

69. ;---------- Begin fifth plot ------------------------------------------

绘制变量 pres 的等值线图,用实心颜色填充等值线,颜色是自己定义的灰度颜色图。

70.

71. cmap = (/(/0.,0.,0./),(/1.,1.,1./),(/.1,.1,.1/),(/.15,.15,.15/),\

72. (/.2,.2,.2/),(/.25,.25,.25/),(/.3,.3,.3/),(/.35,.35,.35/),\

73. (/.4,.4,.4/),(/.45,.45,.45/),(/.5,.5,.5/),(/.55,.55,.55/),\

74. (/.6,.6,.6/),(/.65,.65,.65/),(/.7,.7,.7/),(/.75,.75,.75/),\

75. (/.8,.8,.8/),(/.85,.85,.85/)/)

对于这个等值线图,使用灰度值来填充等值线。为了做到这点,需要自己定义颜色图。颜色度图通过红、绿和蓝的浮点值的数组来代表(简称 RGB 值),值得范围是 0-1(表示特定颜色的强度)。颜色图中的第一块是背景色,第二块是前景色。为了得到灰度值的颜色图,对 R/G/B 要使用相同的值。

更多创建自己的颜色图,请参阅“Basics”一章中的“Color maps”。

76.

77. gsn_define_colormap(xwks,cmap) ; Define a new color map.

使用 NCL 程序 gsn_define_colormap 来定义颜色图。第一个参数是前一个调用 gsn_open_wks 的返回的工作站变量。第二个参数是刚在 71-75 行创建的颜色图。

78.

79. resources@tiMainString = pres@long_name

80.

81. plot = gsn_contour(xwks,pres,resources) ; Draw a contour plot.

改变标题来反映等值线的新的数据,并且绘制变量 pres 的等值线图。

82.

83. print(temp(2:5,7:9)) ; Print subset of "temp" variable.

打印温度的子集(第一个维度中 2 到 5 的每个元素,第二个维度中 7 至 9的每个元素)。打印过程需要 NCL 变量作为参数,并打印出来。请注意,打印不会进行任何形式的格式化打印。要获得格式化打印,需要用自己的 C 或者 Fortran 来创建,写在 NCL wrapper 上告诉 NCL 来调用这个程序。更多如何为自己的 C 或者 Fortran 子程序创建 wrappers,请参见“Beyond the basics”一章中的“Beyond the basics”一节。

84.

85. print(temp!0) ; Print the dimension names for the

86. print(temp!1) ; first two dimensions of T.

87. print(temp@long_name) ; Print "long_name" and "units"

88. print(temp@units) ; attributes of "T".

89. print(temp&lat) ; Print coordinate variables "lat"

90. print(temp&lon) ; and "lon".

如示例 1 中所指,一个 NCL 变量可以含有关于自己的额外信息被称作“元数据”。元数据由 attributes、coordinate variables 和 named dimensions 组成。上述六个 print 语句打印了 temp 变量的一些元数据信息。符号“temp!0”表明了一个维度的维度名字,temp&lat 表明 coordiante variable 叫做 lat,temp@long_name表明属性叫做“long_name”。如果其中任何元数据不存在,print 语句就会出现一个错误信息。

更多 attributes、coordinate variables 和 named dimensions 的信息,参见“Introduction”一章中的“Variables”一节

91.

92. ascii_file = "data.asc" ; Create name of ASCII file.

93. system("/bin/rm -f " + ascii_file) ; Remove ASCII file.

94. asciiwrite(ascii_file,temp(7:3:2,0:4)) ; Write part of temp to ASCII 

95. ; file.

使用 asciiwrite 将温度数据的子集写入 ASCII 中。Asciiwrtie 的第一个变量是要写入数据文件的名字,第二个参数是要写入的数据。符号“7:3:2”选择了 7 到 3 间距为 2 的 index,所以只有 index“7”、“5”和“3”选择了。

system 调用作为参数的字符串,从 NCL 执行 UNIX 系统的命令。在这种情况下,用来在写入之前删除文件。符号“+”,除了用作算术运算符之外,在 NCL中也可以用作链接字符串。

更多有关 asciiwrite、system 和其他 NCL 函数和程序的信息,

请参阅 built-in NCL functions and procedures。

96. delete(plot) ; Clean up

97. delete(temp)

98. delete(resources)

清除不再需要的变量。正如前面的例子所说,因为在 NCL 脚本的末端,这其实是不必要的,但是这确实一个好习惯。

99. end

结束 NCL 脚本



另有上篇主介绍了NCL基础知识,例如如何开始和结束 NCL 脚本,如何创 建和初始化变量,如何创建和绘制 XY 坐标图,以及如何设置 resources 来改变 XY 坐标图的外观








您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存