;***********************************************************************; ; Procedure : add_labelbar ; ; wks: graphic ; ; plot: graphic ; ; zone: integer ; ; font_height: numeric ; ; type: string ; ; lbar_on : logical ; ; res: logical ; ; ; ; This procedure attaches a labelbar to "plot" (which must be either a ; ; contour or vector plot). The default is to add the labelbar to the ; ; bottom of the plot, unless resources are set to change this. The zone ; ; must be passed in, as well as the font height for the labelbar labels.; ; "type" is the type of plot ("ce", "polar", and so on) so the labelbar ; ; can be positioned differently depending on the plot. ; ; ; ; Eventually we want to deprecate this procedure and use the PlotManager; ; labelbar. This is what the global GSN_OLD_LABELBAR variable is for. ; ; If set to True, then the PlotManager labelbar is *not* used, and a ; ; a custom labelbar via this routine, is created. ; ; ; In V6.4.0 we changed this code to create the lablebar, but only add ; ; it as an annotation if lbar_on is True. ; ;***********************************************************************; undef("add_labelbar") procedure add_labelbar(wks:graphic,plot,zone:integer, \ font_height:numeric,type:string,\ lbar_on,res:logical) local anno, num_res, amres, lbres, labelbar_object, lbar_orient, \ lbar_side, lbar_just, fill_patterns, fill_scales, mono_fill_pat, \ mono_fill_scl, mono_fill_col, levels, class_name, the_plot, anno_off begin lbres = True ; hold labelbar resources amres = True ; hold annomanager resources parallel = get_res_value(res,"pmLabelBarParallelPosF",0.5) ;---Check for annotation/labelbar resources lbres = get_res_eq(res,(/"lb","vp"/)) amres = get_res_eq(res,"am") ;---Set some defaults, which may be overridden later. set_attr(amres,"amZone",zone) set_attr(amres,"amResizeNotify",True) set_attr(amres,"amParallelPosF",parallel) set_attr(lbres,"lbLabelFontHeightF",font_height) set_attr(lbres,"lbBoxEndCapStyle",get_enum_value("RectangleEnds")) ;---The default is to attach a horizontal labelbar at the bottom of the plot. if(check_attr_enum_value(lbres,"lbOrientation","vertical")) then lbar_orient = "vertical" lbar_side = "right" lbar_just = "centerright" else lbar_orient = "horizontal" lbar_side = "bottom" lbar_just = "bottomcenter" end if set_attr(lbres,"lbOrientation",lbar_orient) set_attr(amres,"amSide",lbar_side) set_attr(amres,"amJust",lbar_just) ; ; Calculate the labelbar width and height, based on the plot type and ; shape. Also calculate how far to move the labelbar from the plot. ; ; Here are some examples on how the width/height are determined. ; ; - Square plot: make the labelbar the same width as the plot. ; - Plot w/aspect ratio of 1-to-2: make the labelbar 3/4 the width of ; the plot. ; - Plot w/vertical labelbar: make the height the same as the height ; of the plot. ; getvalues plot "vpWidthF" : width ; Width of plot "vpHeightF" : height ; Height of plot end getvalues ratio1 = width/height ratio2 = height/width ratio = min((/ratio1,ratio2/)) ratios = (/0.50, 0.75, 1.00/) ; viewport ratios lwscale = (/0.75, 0.90, 1.00/) wh_ind = ind(ratio.le.ratios) def_lvpwf = lwscale(wh_ind(0)) ; default width scale for labelbar if(lbar_orient.eq."vertical") then if(type.eq."polar") orth = get_res_value(res,"pmLabelBarOrthogonalPosF",0.05) else orth = get_res_value(res,"pmLabelBarOrthogonalPosF",0.03) end if height = get_res_value(res,"pmLabelBarHeightF",height) width = get_res_value(res,"pmLabelBarWidthF",0.2*width) else height = get_res_value(res,"pmLabelBarHeightF",0.3*height) width = get_res_value(res,"pmLabelBarWidthF",def_lvpwf*width) if(zone.eq.2) if(type.eq."polar") orth = get_res_value(res,"pmLabelBarOrthogonalPosF",0.03) else orth = get_res_value(res,"pmLabelBarOrthogonalPosF",0.06) end if else orth = get_res_value(res,"pmLabelBarOrthogonalPosF",0.0) end if end if set_attr(lbres,"vpHeightF",height) set_attr(lbres,"vpWidthF",width) set_attr(amres,"amOrthogonalPosF",orth) ; ; If we have a contour plot, then there are a bunch of contour ; resources that we have to retrieve in order to reconstruct the ; labelbar. ; class_name = NhlClassName(plot) if(class_name.eq."logLinPlotClass".or.class_name.eq."irregularPlotClass") the_plot = plot@contour else the_plot = plot end if if(class_name.eq."contourPlotClass".or.class_name.eq."logLinPlotClass".or.\ class_name.eq."irregularPlotClass") getvalues the_plot "cnLevels" : levels "cnFillDotSizeF" : dot_size "cnFillColors" : tmp_colors "cnFillOpacityF" : fill_opacity "cnFillPatterns" : tmp_fill_patterns "cnFillPattern" : fill_pattern "cnFillScales" : tmp_fill_scales "cnFillScaleF" : fill_scale "cnFillMode" : fill_mode "cnMonoFillPattern" : mono_fill_pat "cnMonoFillScale" : mono_fill_scl "cnMonoFillColor" : mono_fill_col "cnLabelBarEndStyle" : end_labelbar_style "cnLabelBarEndLabelsOn" : end_labels_on "cnLineLabelFormat" : line_format ; default is "*+^sg" "lbLabelStrings" : lbstrings end getvalues ; ; This next section is a bit of a nightmare. ; ; It's an attempt to handle various combinations of lbBoxEndCapStyle, ; cnLabelBarEndStyle, cnLabelBarEndLabelsOn, vcLabelBarEndLabelsOn, ; and stLabelBarEndLabelsOn. ; ; To make things more complicated, cnLabelBarEndLabelsOn is deprecated ; and replaced with cnLabelBarEndStyle, but we still have to deal with ; it. On top of that, vcLabelBarEndLabelsOn and stLabelBarEndLabelsOn ; are NOT deprecated, because we don't have vcLabelBarEndStyle or ; stLabelBarEndStyle resources. ; ; lbBoxEndCapStyle was added in V6.4.0 and allows you to add triangle ; ends for the labelbar. ; ; cnLabelBarEndLabelsOn was deprecated in V5.0, but we still need to ; check for it. It's been replaced by cnLabelBarEndStyle. ; ; If the end label style is IncludeOuterBoxes *and* ; xxLabelBarEndLabelsOn is True, then set the style to ; IncludeMinMaxLabels. Conversely, if the style is IncludeMinMaxLabels ; or ExcludeOuterBoxes, then xxLabelBarEndLabelsOn should be set True. ; cap_style = lbres@lbBoxEndCapStyle if(end_labelbar_style.eq.get_enum_value("IncludeOuterBoxes")) then if(end_labels_on) then end_labelbar_style = get_enum_value("IncludeMinMaxLabels") end if else end_labels_on = True end if if(end_labelbar_style.eq.get_enum_value("ExcludeOuterBoxes")) then ; Don't use the first fill color, scale, or pattern. nc2 = dimsizes(tmp_colors) end_labels_on = True colors = tmp_colors(1:nc2-2) fill_scales = tmp_fill_scales(1:nc2-2) fill_patterns = tmp_fill_patterns(1:nc2-2) else colors = tmp_colors fill_scales = tmp_fill_scales fill_patterns = tmp_fill_patterns end if delete([/tmp_colors,tmp_fill_scales,tmp_fill_patterns/]) ; ; Check if the fill mode is "RasterFill". If so, be sure to ; set lbRasterFillOn to True ; if(.not.isatt(lbres,"lbRasterFillOn").and.fill_mode.eq.get_enum_value("RasterFill")) lbres@lbRasterFillOn = True end if ; ; Check if we want different fill patterns or fill scales. If so, we ; have to pass these on to the labelbar. ; lbres@lbMonoFillColor = mono_fill_col lbres@lbBoxEndCapStyle = cap_style if(.not.mono_fill_pat) lbres@lbMonoFillPattern = False lbres@lbFillPatterns = fill_patterns lbres@lbFillDotSizeF = dot_size else lbres@lbFillPattern = fill_pattern end if if(.not.mono_fill_scl) lbres@lbMonoFillScale = False lbres@lbFillScales = fill_scales lbres@lbFillDotSizeF = dot_size else lbres@lbFillScaleF = fill_scale end if lbres@lbFillOpacityF = fill_opacity ; Added in NCL V6.4.0 else if(class_name.eq."vectorPlotClass") then line_format = "*+^sg" ; VectorPlot doesn't have an equivalent "cnLineLabelFormat" resource getvalues the_plot "vcLevels" : levels "vcLevelColors" : colors "vcLabelBarEndLabelsOn" : end_labels_on "lbLabelStrings" : lbstrings end getvalues else line_format = "*+^sg" ; StreamlinePlot doesn't have an equivalent "cnLineLabelFormat" resource ;---Better be a streamline plot! getvalues the_plot "stLevels" : levels "stLevelColors" : colors "stLabelBarEndLabelsOn" : end_labels_on "lbLabelStrings" : lbstrings end getvalues end if end if ; ; Vector and Streamline don't have the xxLabelBarEndStyle resource ; implemented yet. So, based on setting of xxLabelBarEndLabelsOn, ; we can set the style. ; if(.not.isvar("end_labelbar_style")) then if(end_labels_on) then end_labelbar_style = get_enum_value("IncludeMinMaxLabels") else end_labelbar_style = get_enum_value("IncludeOuterBoxes") end if end if ; ; Now we have to figure out what labels to use for the labelbar. ; ; If user set cn/st/vcLabelBarEndLabelsOn to True or the LabelBarStyle ; resource to IncludeMinMaxLabels, then we need to add min/max ; labels, if the user hasn't done so (by setting lbLabelStrings). ; Use lbLabelStrings rather than actual min/max of data, because the ; labels will already be formatted correctly. ; if(.not.isatt(res,"lbLabelStrings")) then nlev = dimsizes(levels) nlab = dimsizes(lbstrings) if(end_labels_on.and.end_labelbar_style.eq.get_enum_value("IncludeMinMaxLabels").and. \ (lbstrings(0).eq."".or.lbstrings(nlab-1).eq."")) then print("Warning: add_labelbar: invalid end labels, turning them off.") end_labels_on = False end if if(end_labels_on) then if(end_labelbar_style.eq.get_enum_value("IncludeMinMaxLabels")) then lbres@lbLabelStrings = lbstrings end if end if if(line_format.ne."*+^sg") then lbres@lbLabelStrings = lbstrings end if end if if(end_labels_on) then set_attr(lbres,"lbLabelAlignment","ExternalEdges") end if levels = fix_zero_contour(levels) labelbar_object = create_labelbar(wks,dimsizes(colors),colors,levels,lbres) ; ; Check if the user has requested to turn off the labelbar. ; We will go ahead and create it, just in case it is needed ; later (by gsn_panel, for example), but we will turn it off ; by setting amOn to False. ; anno = NhlAddAnnotation(plot,labelbar_object) set_attr(amres,"amOn",lbar_on) attsetvalues_check(anno,amres) ; Set annotation resources. return end