;************************************************* ; lcmask_4.ncl ; ; Concepts illustrated: ; - Adding longitude/latitude labels to a masked Lambert Conformal map ; - Moving the main title up ; - Attaching text strings to the outside of a plot ; - Converting lat/lon values to NDC values ; - Changing the angle of text strings ; - Adding a carriage return to a text string using a function code ;************************************************* ; ; These files are loaded by default in NCL V6.2.0 and newer load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl" load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl" ;---------------------------------------------------------------------- ; This procedure attaches lat/lon labels to a masked lambert plot ; ; You will likely need to change lat_values and/or lon_values to ; contain the locations where you want lat/lon labels. ;---------------------------------------------------------------------- procedure add_lc_labels(wks,map,minlat,maxlat,minlon,maxlon) local lat_values, nlat, lat1_ndc, lat2_ndc, lon1_ndc, lon2_ndc,slope,txres, \ lon_values, PI, RAD_TO_DEG, dum_lft, dum_rgt, dum_bot begin PI = 3.14159 RAD_TO_DEG = 180./PI ;---Pick some "nice" values for the latitude labels. lat_values = ispan(toint(minlat),toint(maxlat),10) * 1. nlat = dimsizes(lat_values) ; ; We need to get the slope of the left and right min/max longitude lines. ; Use NDC coordinates to do this. ; lat1_ndc = new(1,float) lon1_ndc = new(1,float) lat2_ndc = new(1,float) lon2_ndc = new(1,float) datatondc(map,minlon,lat_values(0),lon1_ndc,lat1_ndc) datatondc(map,minlon,lat_values(nlat-1),lon2_ndc,lat2_ndc) slope_lft = (lat2_ndc-lat1_ndc)/(lon2_ndc-lon1_ndc) datatondc(map,maxlon,lat_values(0),lon1_ndc,lat1_ndc) datatondc(map,maxlon,lat_values(nlat-1),lon2_ndc,lat2_ndc) slope_rgt = (lat2_ndc-lat1_ndc)/(lon2_ndc-lon1_ndc) ;---Set some text resources txres = True txres@txFontHeightF = 0.02 txres@txPosXF = 0.1 ; ; Loop through lat values, and attach labels to the left and ; right edges of the masked LC plot. The labels will be ; rotated to fit the line better. ; dum_lft = new(nlat,graphic) ; Dummy array to hold attached strings. dum_rgt = new(nlat,graphic) ; Dummy array to hold attached strings. do n=0,nlat-1 ; Add extra white space to labels. lat_label_rgt = " " + lat_values(n) + "~S~o~N~" lat_label_rgt = " " + lat_values(n) + "~S~o~N~" ;---Check if North, South, or Zero if(lat_values(n).lt.0) then lat_label_lft = lat_values(n) + "~S~o~N~S " lat_label_rgt = lat_label_rgt + "S" end if if(lat_values(n).gt.0) then lat_label_lft = lat_values(n) + "~S~o~N~N " lat_label_rgt = lat_label_rgt + "N" end if if(lat_values(n).eq.0) then lat_label_lft = lat_values(n) + "~S~o~N~ " end if ;---Left label txres@txAngleF = RAD_TO_DEG * atan(slope_lft) - 90 dum_lft(n) = gsn_add_text(wks,map,lat_label_lft,minlon,lat_values(n),txres) ;---Right label txres@txAngleF = RAD_TO_DEG * atan(slope_rgt) + 90 dum_rgt(n) = gsn_add_text(wks,map,lat_label_rgt,maxlon,lat_values(n),txres) end do ;---------------------------------------------------------------------- ; Now do longitude labels. These are harder because we're not ; adding them to a straight line. ; ; Loop through lon values, and attach labels to the bottom edge of the ; masked LC plot. ; delete(txres@txPosXF) txres@txPosYF = -5.0 ;---Pick some "nice" values for the longitude labels. lon_values = ispan(toint(minlon+10),toint(maxlon-10),10) * 1. nlon = dimsizes(lon_values) dum_bot = new(nlon,graphic) ; Dummy array to hold attached strings. do n=0,nlon-1 ; ; For each longitude label, we need to figure out how much to rotate ; it, so get the approximate slope at that point. ; datatondc(map,lon_values(n)-0.25,minlat,lon1_ndc,lat1_ndc) datatondc(map,lon_values(n)+0.25,minlat,lon2_ndc,lat2_ndc) slope_bot = (lat1_ndc-lat2_ndc)/(lon1_ndc-lon2_ndc) txres@txAngleF = atan(slope_bot) * RAD_TO_DEG ; ; Create longitude label. Add extra carriage returns to ; move label away from plot. ; ;---Check if East, West, or Zero lon_label_bot = " ~C~ ~C~" + abs(lon_values(n)) + "~S~o~N~" if(lon_values(n).lt.0) then lon_label_bot = lon_label_bot + "W" end if if(lon_values(n).gt.0) then lon_label_bot = lon_label_bot + "E" end if ;---Attach to map. dum_bot(n) = gsn_add_text(wks,map,lon_label_bot,lon_values(n),minlat,txres) end do end ;---------------------------------------------------------------------- ; Main code. ;---------------------------------------------------------------------- begin ;************************************************ ; read in netCDF file ;************************************************ a = addfile("UNEP_o_int2.nc","r") b = addfile("UNEP_h_int2.nc","r") c = addfile("UNEP_s1_int2.nc","r") d = addfile("UNEP_s2_int2.nc","r") un1 = a->unep(:,:) un2 = b->unep(:,:) un3 = c->unep(:,:) un4 = d->unep(:,:) minlat = 30 ; min lat to mask maxlat = 75 ; max lat to mask minlon = -20 ; min lon to mask maxlon = 40 ; max lon to mask ;************************************************ ; create plot ;************************************************ wks = gsn_open_wks("png","unep") ; send graphics to PNG file cmap = read_colormap_file("aridity") ; cmap = (/ (/19,0,196/),(/102,255,255/), \ ; (/153,255,51/), (/255,255,101/),(/204,153,0/) /) / 255. plot = new(4,graphic) res = True ; plot mods desired res@gsnMaximize = True ; enlarge plot res@gsnDraw = False ; Don't draw yet res@gsnFrame = False ; Don't advance frame yet res@mpProjection = "LambertConformal"; choose projection res@cnFillOn = True ; turn on color res@cnLinesOn = False ; turn off contour lines res@lbLabelBarOn = False res@cnLevelSelectionMode = "ManualLevels" ; res@cnMinLevelValF = 1 ; res@cnMaxLevelValF = 5 ; res@cnLevelSpacingF = 1 res@cnLevels = (/1,2,3,4,5/) res@cnFillPalette = cmap(::-1,:) ; set color map res@mpMinLatF = minlat res@mpMaxLatF = maxlat res@mpMinLonF = minlon res@mpMaxLonF = maxlon res@gsnMaskLambertConformal = True ; turn on lc masking res@mpGridAndLimbOn = True res@mpGridLatSpacingF = 10 res@mpGridLonSpacingF = 5 res@gsnAddCyclic = False res@tiMainString = "" res@tiMainOffsetYF = 0.01 ; Move title up a little res@gsnRightString = "A" res@gsnLeftString = "" ; pr&lon = pr&lon-180 ; make lon go -180 to 180 plot(0) = gsn_csm_contour_map(wks,un1({minlat:maxlat},{minlon:maxlon}),res); create plot resb = True ; plot mods desired resb@gsnMaximize = True ; enlarge plot resb@gsnDraw = False ; Don't draw yet resb@gsnFrame = False ; Don't advance frame yet resb@mpProjection = "LambertConformal"; choose projection resb@cnFillOn = True ; turn on color resb@cnLinesOn = False ; turn off contour lines resb@lbLabelBarOn = False resb@cnLevelSelectionMode = "ManualLevels" ; resb@cnMinLevelValF = 1 ; resb@cnMaxLevelValF = 5 ; resb@cnLevelSpacingF = 1 resb@cnLevels = (/1,2,3,4,5/) resb@cnFillPalette = cmap(::-1,:) ; set color map resb@mpMinLatF = minlat resb@mpMaxLatF = maxlat resb@mpMinLonF = minlon resb@mpMaxLonF = maxlon resb@gsnMaskLambertConformal = True ; turn on lc masking resb@mpGridAndLimbOn = True resb@mpGridLatSpacingF = 10 resb@mpGridLonSpacingF = 5 resb@gsnAddCyclic = False resb@tiMainString = "" resb@tiMainOffsetYF = 0.01 ; Move title up a little resb@gsnRightString = "B" resb@gsnLeftString = "" plot(1) = gsn_csm_contour_map(wks,un2({minlat:maxlat},{minlon:maxlon}),resb); create plot resc = True ; plot mods desired resc@gsnMaximize = True ; enlarge plot resc@gsnDraw = False ; Don't draw yet resc@gsnFrame = False ; Don't advance frame yet resc@mpProjection = "LambertConformal"; choose projection resc@cnFillOn = True ; turn on color resc@cnLinesOn = False ; turn off contour lines resc@lbLabelBarOn = False resc@cnLevelSelectionMode = "ManualLevels" ; resc@cnMinLevelValF = 1 ; resc@cnMaxLevelValF = 5 ; resc@cnLevelSpacingF = 1 resc@cnLevels = (/1,2,3,4,5/) resc@cnFillPalette = cmap(::-1,:) ; set color map resc@mpMinLatF = minlat resc@mpMaxLatF = maxlat resc@mpMinLonF = minlon resc@mpMaxLonF = maxlon resc@gsnMaskLambertConformal = True ; turn on lc masking resc@mpGridAndLimbOn = True resc@mpGridLatSpacingF = 10 resc@mpGridLonSpacingF = 5 resc@gsnAddCyclic = False resc@tiMainString = "" resc@tiMainOffsetYF = 0.01 ; Move title up a little resc@gsnRightString = "C" resc@gsnLeftString = "" plot(2) = gsn_csm_contour_map(wks,un3({minlat:maxlat},{minlon:maxlon}),resc); create plot resd = True ; plot mods desired resd@gsnMaximize = True ; enlarge plot resd@gsnDraw = False ; Don't draw yet resd@gsnFrame = False ; Don't advance frame yet resd@mpProjection = "LambertConformal"; choose projection resd@cnFillOn = True ; turn on color resd@cnLinesOn = False ; turn off contour lines resd@lbLabelBarOn = False resd@cnLevelSelectionMode = "ManualLevels" ; resd@cnMinLevelValF = 1 ; resd@cnMaxLevelValF = 5 ; resd@cnLevelSpacingF = 1 resd@cnLevels = (/1,2,3,4,5/) resd@cnFillPalette = cmap(::-1,:) ; set color map resd@mpMinLatF = minlat resd@mpMaxLatF = maxlat resd@mpMinLonF = minlon resd@mpMaxLonF = maxlon resd@gsnMaskLambertConformal = True ; turn on lc masking resd@mpGridAndLimbOn = True resd@mpGridLatSpacingF = 10 resd@mpGridLonSpacingF = 5 resd@gsnAddCyclic = False resd@tiMainString = "" resd@tiMainOffsetYF = 0.01 ; Move title up a little resd@gsnRightString = "D" resd@gsnLeftString = "" plot(3) = gsn_csm_contour_map(wks,un4({minlat:maxlat},{minlon:maxlon}),resd); create plot ;---Attach latitude labels add_lc_labels(wks,plot(0),minlat,maxlat,minlon,maxlon) add_lc_labels(wks,plot(1),minlat,maxlat,minlon,maxlon) add_lc_labels(wks,plot(2),minlat,maxlat,minlon,maxlon) add_lc_labels(wks,plot(3),minlat,maxlat,minlon,maxlon) ;---Drawing the plot will also draw all the attached labels. draw(plot(0)) draw(plot(1)) draw(plot(2)) draw(plot(3)) frame(wks) ;-- create panel plot ;************************************************ resP = True ; modify the panel plot resP@gsnPanelLabelBar = True ; add common colorbar resP@lbLabelFontHeightF = 0.007 ; make labels smaller resP@cnExplicitLabelBarLabelOn = True resP@lbMonoFillPattern = True resP@boxCount = 5 ; resP@lbLabelStrings = (/"","Hyper-arid","Arid", \ ; "Semi-arid","Sub-humid","Humid"/) ; Convert levels to a string array. gsn_panel(wks,plot,(/2,2/),resP) end