;---------------------------------------------------------------------- ; Procedure for adding a labelbar at a given NDC location, given ; the levels and colors to use. ;---------------------------------------------------------------------- undef("add_labelbar2") procedure add_labelbar2(wks,plot,levels,colors) local lbres, labels begin nlevels = dimsizes(levels) ;---------------------------------------------------------------------- ; Draw a labelbar ;---------------------------------------------------------------------- lbres = True lbres@vpWidthF = 0.80 ; width lbres@vpHeightF = 0.10 ; height lbres@lbPerimOn = False ; Turn off perimeter. lbres@lbOrientation = "Horizontal" ; Default is vertical. lbres@lbLabelAlignment = "InteriorEdges" ; Default is "BoxCenters" lbres@lbFillColors = colors ; Colors for boxes. lbres@lbLabelFontHeightF = 0.02 ; label font height lbres@lbMonoFillPattern = True ; Fill them all solid. lbres@lbTitleString = " Length (year)" lbres@lbTitleFontHeightF = 0.02 lbres@lbTitlePosition = "Right" lbres@lbTitleDirection = "Across" lbres@lbLabelStride = 2 labels = sprinti("%2.0i", levels) ;Creates a labelbar lbid = gsn_create_labelbar(wks,nlevels+1,labels,lbres) ; ; Now, create some annotation resources indicating how we want to ; attach the labelbar to the plot. Here, we are using the top right ; corner of the labelbar as the point which we are going to position ; it, and then we use amParallelPosF and amOrthogonalPosF to indicate ; where we want to place it. ; ; amParallelPosF/amOrthogonalPosF ; ; 0.0/ 0.0 - annotation in dead center of plot ; 0.5/ 0.5 - annotation at bottom right of plot ; 0.5/-0.5 - annotation at top right of plot ; -0.5/-0.5 - annotation at top left of plot ; -0.5/ 0.5 - annotation at bottom left of plot ; amres = True amres@amJust = "TopCenter" amres@amParallelPosF = 0.0 ; keep labelbar centered amres@amOrthogonalPosF = 0.61 ; move down and outside of plot ; ; Give both annotation id and labelbar id unique names. ; ; Attaching them to plot with unique names ensures that ; labelbar "lives" outside this procedure. ; tmpid1 = "anno"+unique_string("id") tmpid2 = "lbar"+unique_string("id") plot@$tmpid1$ = gsn_add_annotation(plot,lbid,amres) plot@$tmpid2$ = lbid end ;------------------------------------------------------------------------------- ; read CSV data file dd = asciiread("5SURF_CLI_GLB_TEM_DAY_STATION_QC_HOMO_SelectInbase15.csv", -1, "string") val = str_split_csv(dd, ",", 0) lon = tofloat(val(1:, 1)) ; lat = tofloat(val(1:, 2)) R = tofloat(val(1:, 4)) ; the length of station npts = dimsizes(lon) ds = asciiread("6SURF_CLI_GLB_TEM_DAY_STATION_QC_HOMO_StationNumberEachYear.csv", -1, "string") val2 = str_split_csv(ds, ",", 0) Year = tofloat(val2(1:, 0)) StationNumber = tofloat(val2(1:, 1)) ;------------------------------------------------------------------------------- ; Main code. ;------------------------------------------------------------------------------- begin ;-------Options-------- ; Begin plotting section. wkstype = "png" ;wkstype@wkWidth = 2400 ; image resolution, default 1024 ;wkstype@wkHeight = 2400 ; image resolution wks = gsn_open_wks(wkstype, "Station_Location") ; send graphics to PNG file map = new(2, graphic) ; create graphic array ;levels = (/0.,5.,10.,15.,20.,23.,26./) ; bin settings (bin0 = < 0., ; bin1 = 0.:4.999, etc.) levels = ispan(10, 60, 5) nlevels = dimsizes(levels) colors = span_color_rgba("cosam",nlevels+1) ; span_color_rgba: Given the number of desired color values, return an array of ; RGB triplets or RGBA quadruplets that nicely span the given color map. ;------------------------------------------------------------------------------- ; Create X and Y arrays to hold the points for each range and initialize ; them to missing values. We want to use num_distinct_markers ; different colors, so we need num_distinct_markers sets of X and ; Y points. ; num_distinct_markers = nlevels+1 ; number of distinct markers lat_new = new((/num_distinct_markers,npts/),float,-999) lon_new = new((/num_distinct_markers,npts/),float,-999) ; ; Group the points according to which range they fall in. At the ; same time, create the label that we will use later in the labelbar do i = 0, num_distinct_markers-1 if (i.eq.0) then indexes = ind(R.lt.levels(0)) ; ind: Returns the indices where the input is True end if if (i.eq.num_distinct_markers-1) then indexes = ind(R.ge.max(levels)) end if if (i.gt.0.and.i.lt.num_distinct_markers-1) then indexes = ind(R.ge.levels(i-1).and.R.lt.levels(i)) end if ; ; Now that we have the set of indexes whose values fall within ; the given range, take the corresponding lat/lon values and store ; them, so later we can color this set of markers with the appropriate ; color. ; any: Returns True if any of the values of its input evaluate as True. ; ismissing: Returns True for every element of the input that contains a missing value. ; Deletes variables, attributes, and coordinate variables. if (.not.any(ismissing(indexes))) then ;如果不是缺失值,则执行 npts_range = dimsizes(indexes) ; # of points in this range. lat_new(i,0:npts_range-1) = lat(indexes) lon_new(i,0:npts_range-1) = lon(indexes) end if delete(indexes) ; Necessary b/c "indexes" may be a different ; size next time. end do ;=========================================================================== ;---Set up some map resources. mpres = True mpres@gsnMaximize = True ; Maximize plot in frame. mpres@gsnDraw = False ; Will draw later mpres@gsnFrame = False ; Don't advance the frame mpres@pmTickMarkDisplayMode = "Always" mpres@mpLandFillColor = "white" mpres@mpOutlineOn = True mpres@mpGeophysicalLineColor= "black" mpres@tmXBLabelFontHeightF = 0.02 mpres@tmYLLabelFontHeightF = 0.02 mpres@vpHeightF = 0.4 ; Changes the aspect ratio mpres@vpWidthF = 0.8 ; of plots mpres@gsnMajorLonSpacing = 90 mpres@gsnMajorLatSpacing = 45 mpres@gsnMinorLonSpacing = 18 mpres@gsnMinorLatSpacing = 9 mpres@mpLabelsOn = True mpres@mpProjection = "CylindricalEquidistant"; "Robinson"; "Mollweide"; mpres@mpCenterLatF = 0 mpres@mpCenterLonF = 148 mpres@gsnStringFontHeightF = 0.022 mpres@gsnLeftString = "(a) Temperature stations (11221)" map(0) = gsn_csm_map(wks,mpres) ;--Create logical variables to hold the marker resources. gsres = True gsres@gsMarkerIndex = 1 ; Use filled dots for markers. gsres@gsMarkerSizeF = 0.015 gsres@gsMarkerOpacityF = 0.8 ; Loop through each grouping of markers, and draw them one set at ; a time, assigning the proper color and size with gsn_marker. ; ;base_size = 0.01 pmid = new(num_distinct_markers,graphic) do i = 0, num_distinct_markers-1 if (.not.ismissing(lat_new(i,0))) gsres@gsMarkerColor = colors(i,:) pmid(i) = gsn_add_polymarker(wks,map(0), lon_new(i,:), lat_new(i,:), gsres) end if end do ;---Draw labelbar and advance frame. add_labelbar2(wks,map(0),levels,colors) ;------------------------------------------------------------------------------------------ ; plot the station numbers of each year lres = True lres@gsnDraw = False ; Will draw later lres@gsnFrame = False ; Don't advance the frame lres@gsnLeftString = "(b) The number of stations each year" lres@gsnLeftStringFontHeightF = 0.022 lres@vpHeightF = 0.4 ; Changes the aspect ratio lres@vpWidthF = 0.85 ; of plots lres@tmXBLabelFontHeightF = 0.022 lres@tmYLLabelFontHeightF = 0.022 lres@tmYLMode = "Manual" lres@tmYLTickSpacingF = 2000 lres@tmYLMinorPerMajor = 5 lres@xyLineColor = "navyblue" ; color of lines lres@xyLineThicknesses = 7 lres@trXMinF = 1950 lres@trXMaxF = 2016 lres@tiXAxisString = "Year" lres@tiYAxisString = "Station Numbers" lres@tiXAxisFontHeightF = 0.023 lres@tiYAxisFontHeightF = 0.023 lres@tmXMajorGrid = True ; implement x grid lres@tmXMajorGridThicknessF = 1.0 ; 2.0 is default lres@tmXMajorGridLineDashPattern = 2 ; select short dash lines lres@tmYMajorGrid = True ; implement y grid lres@tmYMajorGridThicknessF = 1.0 ; 2.0 is default lres@tmYMajorGridLineDashPattern = 2 ; select short dash lines map(1) = gsn_csm_xy(wks, Year, StationNumber, lres) pres = True ;pres@gsnPanelYWhiteSpacePercent = 0.5 gsn_panel(wks, map, (/2, 1/), pres) ;draw(map) ;frame(wks) end