Example 10 - publication-quality XY plot |
This example produces a publication-quality plot.
To run this example, you must download the following files:
gsun10n.ncland then type:
gsn_code.ncl
ncl < gsun10n.ncl
Frame 1 |
---|
(Click on frame to see it enlarged.)
1. load "gsn_code.ncl" 2. 3. function wigley(time:integer) 4. local i, j, k 5. begin 6. 7. y = new(dimsizes(time),float) 8. 9. i = ind(time.lt.1953.) ; Get indices where time is < 1953. 10. y(i) = ((time(i)-1860.)/(1953.-1860.)) * 35.0 11. 12. j = ind(time.ge.1953.and.time.le.1973) ; Indices where 1953 <= time < 1973 13. y(j) = ((time(j)-1953.)/(1973.-1953.)) * (68. - 35.) + 35. 14. 15. k = ind(time.gt.1973.and.time.le.1990) ; Indices where 1973 < time <- 1990. 16. y(k) = ((time(k)-1973.)/(1990.-1973.)) * (75. - 68.) + 68. 17. return(y) 18. 19. end 20. 21. begin 22. 23. time1 = (/ 1990, 1985, 1980, 1970, 1960, 1950, 1940, 1930, \ 24. 1920, 1910, 1900, 1890, 1880, 1870, 1860/) 25. 26. y1 = (/68.065, 65.00, 70.67, 63.06, 43.42, 28.28, 23.00, 20.25, \ 27. 17.77, 15.36, 10.01, 6.40, 3.98, 2.18, 1.54/) 28. 29. time2 = ispan(min(time1),max(time1),1) ; Get range of equally space values. 30. y2 = wigley(time2) ; Calculate proposed values as 31. ; a function of time. 32. maxdim = max( (/dimsizes(y1),dimsizes(y2)/) ) 33. 34. y = new((/2,maxdim/),float,-999.) ; Create new 2D arrays to hold 1D 35. time = new((/2,maxdim/),float,-999.) ; arrays you just declared above. 36. 37. y(0,0:dimsizes(y1)-1) = y1 ; Copy y1 and y2 to y. 38. y(1,0:dimsizes(y2)-1) = y2 39. 40. time(0,0:dimsizes(time1)-1) = time1 ; Copy time1 and time2 to time. 41. time(1,0:dimsizes(time2)-1) = time2 42. 43. wks = gsn_open_wks("x11","gsun10n") ; Open an X11 workstation. 44. 45. cmap = (/(/1.,1.,1./),(/0.,0.,0./)/) ; Change background color to white 46. gsn_define_colormap(wks,cmap) ; and foreground color to black. 47. 48. resources = True ; Get ready to set some resources. 49. 50. resources@vpWidthF = 0.8 51. resources@vpXF = 0.13 52. 53. resources@tiMainString = ":F22:Sulfur Emissions" ; ":F22:" changes 54. resources@tiXAxisString = ":F22:Year" ; the font to "22" 55. resources@tiYAxisString = ":F22:Tg s/yr" ; which is helvetica 56. ; bold. 57. resources@tmXBLabelFont = 21 58. resources@tmYLLabelFont = 21 59. 60. resources@trXMinF = 1855 ; Set minimum X axis value. 61. 62. resources@xyDashPatterns = (/16,0/) ; ( dash, solid ) 63. resources@xyMarkLineModes = (/"MarkLines","Lines"/) 64. resources@xyMarker = 1 65. resources@xyMarkerSizeF = 0.05 ; Default is 0.01 66. 67. resources@gsnFrame = False ; Don't advance the frame. 68. resources@gsnScale = True ; Draw X/Y axes labels in same size. 69. 70. xy = gsn_xy(wks,time,y,resources) ; Create and draw XY plot. 71. 72. txresources = True 73. txresources@txFontHeightF = 0.015 74. txresources@txJust = "CenterLeft" ; Default is "CenterCenter". 75. txresources@txFuncCode = "~" ; Default is ":" 76. 77. strings = (/"Wigley (Moller/IPCC)",\ 78. "~F22~CSM-proposed:~F~~C~(Orn et.al./GEIA + Smith)",\ 79. "~F22~CSM SO~B~4~N~ Scaling Factor: ~V1Q~~F22~S~B~emis~N~ (yr)~H-7Q~~V-1Q~---------------~H-9Q~~V-1Q~S~B~emis~N~ (1985)"/) 80. 81. xpos = (/1885.,1940.,1860./) ; Define X/Y locations for text. 82. ypos = (/30.,18.,70./) 83. 84. do i = 0,dimsizes(strings)-1 ; Loop through text strings and draw them. 85. gsn_text(wks,xy,strings(i),xpos(i),ypos(i),txresources) 86. end do 87. 88. frame(wks) ; Advance the frame. 89. end
function wigley(time:integer) local i, j, k begin y = new(dimsizes(time),float) i = ind(time.lt.1953) y(i) = ((time(i)-1860.)/(1953.-1860.)) * 35.0 j = ind(time.ge.1953.and.time.le.1973) y(j) = ((time(j)-1953.)/(1973.-1953.)) * (68. - 35.) + 35. k = ind(time.gt.1973.and.time.le.1990) y(k) = ((time(k)-1973.)/(1990.-1973.)) * (75. - 68.) + 68. return(y) endDefine an NCL function called wigley to calculate some values as a function of time. The function ind returns an array of indices where the input is equal to True. In the wigley function, ind is used to compute the function values based on the different ranges time falls in. Functions in NCL are covered in more detail in example 9.
begin
Begin the main body of the NCL script.
time1 = (/ 1990, 1985, 1980, 1970, 1960, 1950, 1940, 1930, \ 1920, 1910, 1900, 1890, 1880, 1870, 1860/) y1 = (/68.065, 65.00, 70.67, 63.06, 43.42, 28.28, 23.00, 20.25, \ 17.77, 15.36, 10.01, 6.40, 3.98, 2.18, 1.54/)Define some data for the XY plot. These data are from a number of sources and were compiled to show the total global annual emissions of sulfur.
time2 = ispan(min(time1),max(time1),1) y2 = wigley(time2)Interpolate data using the wigley function you defined above. See example 8 for a detailed description of ispan.
maxdim = max( (/dimsizes(y1),dimsizes(y2)/) ) y = new((/2,maxdim/),float,-999.) time = new((/2,maxdim/),float,-999.) y(0,0:dimsizes(y1)-1) = y1 y(1,0:dimsizes(y2)-1) = y2 time(0,0:dimsizes(time1)-1) = time1 time(1,0:dimsizes(time2)-1) = time2To create an XY plot that draws the actual data values (y1) and the interpolated data values (y2) as two separate curves, define a 2-dimensional array y to hold the values for both of these curves, where the first dimension is number of curves (2) and the second dimension is the number of points. The two curves might not have the same number of points, so the second dimension of y is set to the maximum of the dimensions of y1 and y2.
By setting the third argument of new to -999.0, you are setting a missing value and at the same time initializing every point in y and time to this missing value. When y1 and y2 get copied to y, any elements of y that aren't filled in contain the missing value. gsn_xy does not plot these missing value points.
The same is done for the time variable that you'll plot against the y variable.
cmap = (/(/1.,1.,1./),(/0.,0.,0./)/) gsn_define_colormap(wks,cmap)By default, frames are drawn with a black background and a white foreground, so here you are redefining the color map to get a white background and a black foreground.
Details on creating your own color map are covered in example 2.
resources@trXMinF = 1855Change the minimum value of the left bound of the X axis (the actual minimum of the X axis is 1860). This is to provide extra space around the curves.
resources@xyDashPatterns = (/16,0/) resources@xyMarkLineModes = (/"MarkLines","Lines"/) resources@xyMarker = 1 resources@xyMarkerSizeF = 0.05Set some resources so that the actual data values are drawn with a dashed line and round markers and the interpolated values are drawn with a solid line. The marker size is increased by a factor of 5, since the default size is 0.01.
resources@gsnFrame = FalseSince you are drawing text strings on the XY plot with separate calls to gsn_text, you don't want the frame to be advanced just yet.
resources@gsnScale = TrueSet gsnScale to True to force the X and Y axes labels to be the same size.
xy = gsn_xy(wks,time,y,resources)Call gsn_xy to draw the XY plot with the two curves.
Note: You may see a warning message that looks like the following:
warning:XyPlotSetValues:Setting xyComputeXMin to False because trXMinF was specifiedYou can safely ignore this warning. To get rid of it, add the following line before the call to gsn_xy:
resources@xyComputeXMin = FalseLine 72:
txresources = TrueTo draw text strings on the XY plot with some calls to gsn_text, set up a variable to hold the resources you want to set for the text strings.
txresources@txJust = "CenterLeft"Change the resource that determines how strings are centered with respect to the X/Y position they are drawn at. By setting the txJust resource to "CenterLeft", strings are centered vertically about the Y coordinate location, and flush left horizontally with respect to the X coordinate location. The default of txJust is "CenterCenter".
txresources@txFuncCode = "~"As noted in example 5, NCL allows text function codes to be embedded in strings to get sub/superscripting, different fonts, carriage returns, etc. By default, each function code is preceded and succeeded with a colon, so use the txFuncCode resource to set the function code to something other than a colon. This is only necessary if you want to use a colon as part of one or more of the text strings. In this case, you are changing the function code to "~".
strings = (/"Wigley (Moller/IPCC)",\ "~F22~CSM-proposed:~F~~C~(Orn et.al./GEIA + Smith)",\ "~F22~CSM SO~B~4~N~ Scaling Factor: ~V1Q~~F22~S~B~emis~N~ (yr)~H-7Q~~V-1Q~---------------~H-9Q~~V-1Q~S~B~emis~N~ (1985)"/)Define three strings to draw on the plot. You are using text function codes to change the font to Helvetica-bold ("~F22~"), to change the vertical and horizontal spacing ("~V1Q~", "~V-1Q~", "~H-7Q~", and "~H-9Q~"), to add a carriage return ("~C~"), and to do subscripting ("~B~"). The text function codes are bold-faced in the line above so you can see them better. The function codes "~F~" and "~N~" are used to return to the default font and to get out of subscript mode.
The following figure:
is an example of what the following string with the embedded function codes produces:
~V1Q~~F22~S~B~emis~N~ (yr)~H-7Q~~V-1Q~---------------~H-9Q~~V-1Q~S~B~emis~N~ (1985)Lines 81-82:
xpos = (/1885.,1940.,1860./) ypos = (/30.,18.,70./)Create two arrays to define the X and Y positions of each text string you created in lines 77-79 (which are drawn later with a call to gsn_text). The X and Y positions are specified in the same data space as the curves in the XY plot you created.
do i = 0,dimsizes(strings)-1 gsn_text(wks,xy,strings(i),xpos(i),ypos(i),txresources) end doLoop through the array of text strings you created and draw each one using gsn_text.
frame(wks)Advance the frame.
endEnd the NCL script.