; ******************************************************************** ; ***** Procedure to draw a colorbar using data coordinates **** ; ***** by default, but may specify normalized coordinates. **** ; ***** Choice of vertical or horizontal colorbar is made **** ; ***** depending upon the aspect ration of input coordinates. **** ; ******************************************************************** ; ; ORIGINATOR: Andrew F. Loughe ; ; xbegin = beginning x-position (left) ; xend = ending x-position (right) ; ybegin = beginning y-position (lower) ; yend = ending y-position (upper) ; labels = vector of numerical values to be placed next to colorbar ; colors = array of colors used in the colorbar ; unit = unit text to be placed near the colorbar ; charsize = character size of printed labels ; charcolor = color of the printed text and borders of the colorbar ; ctickname = array of labels for the colorbar ; nobox = draw no bax around the colorbar ; every = print every (1,2,3...) label ; orientation = rotation in degrees for the label text ; nudgex = move label this much to the right ; nudgey = move label this much up ; mod1 = if (label mod mod1 eq 0) then print label ; norm = use normalized coordiantes (default is data coordinates) ; ticklen = length of optional tick marks (default=0) pro cb_help base = widget_base (title='CB_HELP', /row) list = widget_text (base, xsize=52, ysize=30 ,/scroll ,$ font='-adobe-helvetica-medium-r-normal--14-140-75-75-p-77-iso8859-1',$ ; font='a14' ,$ value=[ $ ' >>>> COLORBAR HELP MENU <<<< ',$ ' ',$ ' ',$ 'USAGE: ',$ 'cont_cbar, xbegin, xend, ybegin, yend, labels, colors, ',$ ' unit=unit, charsize=charsize, charcolor=charcolor, ',$ ' nobox=nobox, every=every, orientation=orientation, ',$ ' nudgex=nudgex, nudgey=nudgey, mod1=mod1, norm=norm ',$ ' ticklen=ticklen ',$ 'PARAMETERS (required): ',$ ' xbegin = beginning x-position (left) ',$ ' xend = ending x-position (right) ',$ ' ybegin = beginning y-position (lower) ',$ ' yend = ending y-position (upper) ',$ ' labels = vector of numerical values to be placed next to colorbar ',$ ' colors = array of colors used in the colorbar ',$ ' ',$ 'KEYWORDS (optional): ',$ ' unit = text to be placed near the colorbar ',$ ' charsize = character size of printed labels ',$ ' charcolor = color of the printed text and border of the colorbar ',$ ' ctickname = array of labels for the colorbar ',$ ' nobox = draw no box around the colorbar ',$ ' every = print every (1,2,3...) label ',$ ' orientation = rotation in degrees for the label text ',$ ' nudgex = move label this much to the right ',$ ' nudgey = move label this much up ',$ ' mod1 = if (label mod mod1 eq 0) then print label ',$ ' norm = use normalized coordinates (default is data coordinates) ',$ ' ticklen = length of optional tick marks (default=0) ',$ ' ' ]) widget_control, /realize, base end pro cont_cbar, xbegin, xend, ybegin, yend, labels, colors, unit=unit, $ charsize=charsize, charcolor=charcolor, nobox=nobox, every=every, $ orientation=orientation, nudgex=nudgex, nudgey=nudgey, $ mod1=mod1, norm=norm, ctickname=ctn,ticklen=ticklen,thick=th ;on_error, 2 ; Must pass in 6 parameters if n_params() lt 6 then begin cb_help print, " Must specify xbegin, xend, ybegin, yend, labels, colors" endif ; Store original values oxbegin = xbegin oxend = xend oybegin = ybegin oyend = yend ; Must have one more label than colors szl = size(labels) szc = size(colors) ;if (szl(1) gt szc(1)+1) then print, " Need more color entries." ; Set some defaults if n_elements(unit) le 0 then unit = '' if n_elements(th) le 0 then th=1 if n_elements(charsize) le 0 then charsize = 1.0 if n_elements(charcolor) le 0 then charcolor = !p.color if n_elements(every) le 0 then every = 1 if n_elements(mod1) le 0 then mod1 = 0 if n_elements(orientation) le 0 then orientation = 0 if n_elements(nudgex) le 0 then nudgex = 0 if n_elements(nudgey) le 0 then nudgey = 0 norm = keyword_set(norm) nobox = keyword_set(nobox) ; Determine if colorbar is vertical or horizontal dx = abs(xend - xbegin) dy = abs(yend - ybegin) if (dx ge dy) then begin vertical = 0 horizontal = 1 endif else begin vertical = 1 horizontal = 0 endelse ; Determine if colorbar is on rhs or lhs l_xedge = !x.crange(0) r_xedge = !x.crange(1) if (!x.type eq 3) then begin l_xedge = !map.ll_box(2) r_xedge = !map.ll_box(3) if (l_xedge eq r_xedge) then r_xedge = l_xedge + 360. endif if (norm eq 0) then begin rhs = 0 & lhs = 0 if (xbegin ge r_xedge) then rhs = 1 if (xbegin lt l_xedge) then lhs = 1 endif else begin rhs = 0 & lhs = 0 y_strt = convert_coord( [xbegin,ybegin], /norm, /to_data) l_xedgen = convert_coord( [l_xedge,y_strt(1)], /data, /to_norm) r_xedgen = convert_coord( [r_xedge,y_strt(1)], /data, /to_norm) if (xbegin ge r_xedgen(0)) then rhs = 1 if (xbegin lt l_xedgen(0)) then lhs = 1 endelse if (!x.type eq 3 and lhs eq 0 and rhs eq 0 and vertical eq 1) then rhs=1 ;if (lhs eq 0 and rhs eq 0 and vertical eq 1) then $ ; print, 'Error in xbegin, xend specification!' ; Convert numerical labels to strings. Omit numerous decimal places. type = szl(2) ; Determine variable type fmt = ' ' label2 = strarr(szl(1)) if (type eq 7) then fmt = '(a5)' ; Vector of strings if (type eq 2) then fmt ='(i25)' ; Vector of integers if (type eq 4) then begin ; Vector of reals if (max(labels) ge 1000 and fmt eq ' ') then fmt='(i25)' if (max(labels) ge 100 and fmt eq ' ') then fmt='(i25)' if (max(labels) ge 10 and fmt eq ' ') then fmt='(i25)' if (max(labels) ge 1 and fmt eq ' ') then fmt='(f4.1)' if (max(labels) ge .1 and fmt eq ' ') then fmt='(f5.2)' if (max(labels) ge .01 and fmt eq ' ') then fmt='(f6.3)' if (max(labels) ge .001 and fmt eq ' ') then fmt='(f7.4)' if (max(labels) ge .0001 and fmt eq ' ') then fmt='(f8.5)' if (max(labels) ge .00001 and fmt eq ' ') then fmt='(f9.6)' if (max(labels) ge .000001 and fmt eq ' ') then fmt='(f10.7)' if (max(labels) ge .0000001 and fmt eq ' ') then fmt='(f11.8)' endif maxlen=0 if n_elements(ctn) eq 1 then begin for j = 0, szl(1)-1 do begin label2(j) = strcompress( string(format=fmt,labels(j)), /remove_all ) if (strlen(label2(j)) GT maxlen) then maxlen=strlen(label2(j)) endfor endif else begin for j = 0, szl(1)-1 do begin if (j lt n_elements(ctn)) then begin label2(j) = ctn(j) endif else begin label2(j) = '' endelse endfor endelse ; Convert data coordinates to normalized if (norm eq 0) then begin ; Find spacial midpoints x_avg = 0.5 * ( !x.crange(0) + !x.crange(1) ) y_avg = 0.5 * ( !y.crange(0) + !y.crange(1) ) ; Find corners of the colorbar bl = convert_coord( [xbegin, ybegin], /data, /to_norm ) tr1 = convert_coord( [xend, yend ], /data, /to_norm ) tr2 = convert_coord([xbegin - abs(xbegin-xend), yend ],/data,/to_norm) tr = tr1 if (tr1(0) - bl(0) gt 0) then tr = tr1 if (tr1(0) - bl(0) lt 0) then begin tr2(0) = tr2(0) + 2.*(bl(0) - tr2(0)) tr = tr2 endif ;...................................................................... ; Special case for vertical colorbars next to a map if (!x.type eq 3 and vertical eq 1) then begin ; Get boundaries of the map. lonmin = !map.ll_box(2) lonmax = !map.ll_box(3) latmin = !map.ll_box(4) latmax = !map.ll_box(5) ; Find spacial midpoints (again) x_avg = 0.5 * ( lonmin + lonmax ) if (x_avg eq lonmin and x_avg eq lonmax) then x_avg = lonmin + 180. y_avg = 0.5 * ( latmin + latmax ) ; Handle case where lonmax=0., not 360. if (xbegin gt 360 and xend gt 360 and lonmax lt 360) then begin xbegin = xbegin - 360. xend = xend - 360. endif ; Find separation between map edge and xbegin (normalized coordinates) if (rhs eq 1) then dx = (xbegin - lonmax) if (lhs eq 1) then dx = (xbegin - lonmin) x1 = convert_coord( [x_avg, y_avg], /data, /to_norm ) x2 = convert_coord( [x_avg+dx, y_avg], /data, /to_norm ) dx = x2(0) - x1(0) ; Add this dx to position of the normalized map edge if (rhs eq 1) then $ x1 = convert_coord( [lonmax-.001, y_avg], /data, /to_norm ) if (lhs eq 1) then $ x1 = convert_coord( [lonmin+.001, y_avg], /data, /to_norm ) if (rhs eq 1) then bl(0) = x1(0) + dx if (lhs eq 1) then bl(0) = x1(0) + dx ; Find separation between xbegin and xend (normalized coordinates). if (rhs eq 1) then dx = xend - xbegin if (lhs eq 1) then dx = xend - xbegin x1 = convert_coord( [x_avg , y_avg], /data, /to_norm ) x2 = convert_coord( [x_avg+dx , y_avg], /data, /to_norm ) dx = x2(0) - x1(0) ; Add this dx to position of the normalized xbegin tr(0) = bl(0) + dx endif ;...................................................................... ; Real corners of the colorbar xbegin = bl(0) xend = tr(0) ybegin = bl(1) yend = tr(1) ; Nudging factor nudgex1 = convert_coord( [nudgex,y_avg], /data, /to_norm ) nudgex2 = convert_coord( [nudgex+nudgex,y_avg], /data, /to_norm ) nudgex = nudgex2 - nudgex1 nudgex = nudgex(0) nudgey1 = convert_coord( [x_avg,nudgey], /data, /to_norm ) nudgey2 = convert_coord( [x_avg,nudgey+nudgey], /data, /to_norm ) nudgey = nudgey2 - nudgey1 nudgey = nudgey(1) endif ; norm eq 0 xpos = [xbegin, xend, xend, xbegin] ypos = [ybegin, yend, yend, ybegin] xbegin2 = xbegin ; Save the initial values ybegin2 = ybegin xbegin3 = xbegin ; Save the initial values ybegin3 = ybegin ; Vertical increment in the color bar ; (In normalized coordinates) dy = (yend - ybegin)/(szc(1)-1.) ; For normalized coordinates dyl = (yend - ybegin)/(szl(1)-1.) ; For normalized coordinates ; Horizontal increment in the color bar ; (In normalized coordinates) dx = (xend - xbegin)/(szc(1)-1.) ; For normalized coordinates dxl = (xend - xbegin)/(szl(1)-1.) ; For normalized coordinates ; Determine character height and width. Apply charsize. char_ht=convert_coord([0,!d.y_ch_size],/device,/to_norm) char_ht = char_ht(1) char_ht = char_ht * charsize char_wd=convert_coord([0,!d.x_ch_size],/device,/to_norm) char_wd=char_wd(1) char_wd = char_wd * charsize ;========================== VERTICAL COLORBAR ======================== if (vertical eq 1) then begin ; Loop through all labels for j = 0, szc(1)-1 do begin yend2 = ybegin2 + dy ; Assign new yend if (j lt szc(1)-1) then begin ypos = [ybegin2, ybegin2, yend2, yend2] polyfill, xpos, ypos, color=colors(j), /norm endif ybegin2 = yend2 ; Assign new ybegin endfor for j = 0, szl(1)-1 do begin yend3 = ybegin3 + dyl ; Assign new yend if (j lt szl(1)-1) then begin ypos = [ybegin3, ybegin3, yend3, yend3] if (nobox eq 0) then $ plots,[xpos, xbegin],[ypos, ybegin3],color=charcolor,/norm, $ thick=th endif ybegin3 = yend3 ; Assign new ybegin endfor plot,[0,1],[0,1],position=[xbegin,ybegin,xend,yend],xstyle=4,ystyle=4, $ /nodata,/noerase,xthick=th,ythick=th axis,yaxis=1,ystyle=9,yticks=n_elements(label2)-1,yminor=1,ytickv=labels, $ yrange=[min(labels),max(labels)],ytickname=label2,yticklen=ticklen, $ color=charcolor,charsize=charsize,ytitle=unit,ythick=th endif ; Vertical ;======================== HORIZONTAL COLORBAR ======================= if (horizontal eq 1) then begin ; Loop through all labels for i = 0, szc(1)-1 do begin xend2 = xbegin2 + dx if (i lt szc(1)-1) then begin xpos = [xbegin2, xbegin2, xend2, xend2] polyfill, xpos, ypos, color=colors(i), /norm endif xbegin2 = xend2 endfor for i = 0, szl(1)-1 do begin xend3 = xbegin3 + dxl if (i lt szl(1)-1) then begin xpos = [xbegin3, xbegin3, xend3, xend3] if (nobox eq 0) then $ plots,[xpos, xbegin3],[ypos, ybegin],color=charcolor,/norm, $ thick=th endif xbegin3 = xend3 endfor plot,[0,1],[0,1],position=[xbegin,ybegin,xend,yend],xstyle=4,ystyle=4, $ /nodata,/noerase,xthick=th,ythick=th axis,xaxis=0,xstyle=9,xticks=n_elements(label2)-1,xminor=1,xtickv=labels, $ xrange=[min(labels),max(labels)],xtickname=label2,xticklen=ticklen, $ color=charcolor,charsize=charsize,xtitle=unit,xthick=th endif ; Horizontal ; Restore original values xbegin = oxbegin xend = oxend ybegin = oybegin yend = oyend end