;---------------------------------------------------------------------------- ; :File: contour_legend.pro ; :Author: Brian Vanderwende ; ; :Description: Creates a legend for a contour plot based on inputted values: ; x - the X positional vector (x0,x1) ; y - the Y positional vector (y0,y1) ; levs - the chosen contour levels ; cols - the colors corresponding to the contour levels ; cSize - character size of contour level labels ; offset - the normal left offset of the labels from box left edge ; - the normal down offset of the labels from the box bottom edge ; fCode - if inputted, user manually submits string format code ; ; :History: ; Version 1.2 - Fixed zero level bug ; Version 1.1 - Code comments and use of diffuse gradients above 15 pts ; Version 1 - Implementation of code ; ;---------------------------------------------------------------------------- pro contour_legend, x, y, levs, cols, cSize = cSize, unitLab = unitLab, $ offset = offset, fCode = fCode ; Find the number of levels. Set boolean to determine formatting generation n = n_elements(levs) if n_elements(fCode) EQ 0 then noskip = 1 else noskip = 0 ; Set diffuse/discrete boolean based on number of grid points if n_elements(levs) LE 15 then begin nodiff = 1 dlabs = 0 endif else begin ; Calculate the increment between labels dlabs = floor(n_elements(levs) / 10.) nodiff = 0 endelse ; If bar is to be of horizontal alignment if x(1) - x(0) GT y(1) - y(0) then begin ; Pull the y-bounds of the box ypts = [y(0), y(0), y(1), y(1), y(0)] ; Determine the spacing of the x-cells dx = (x(1) - x(0)) / float(n) ; Run through every cell box for i = 0, n - 1 do begin ; Find the beginning of the cell and assign x-bounds (double for all but last as a buffer) xi = x(0) + dx * i if i NE n - 1 then begin xpts = [xi, xi, xi + 2 * dx, xi + 2 * dx, xi] endif else begin xpts = [xi, xi, xi + dx, xi + dx, xi] endelse ; Fill polygon of appropriate size and add divider if appropriate polyfill, xpts, ypts, color = cols(i), /normal if nodiff OR (i MOD dlabs EQ 0 AND i / dlabs LT 10) then plots, [xi, xi], [y(1), y(0) - 0.01], thick = 2, /normal ; Generate format code if not automatically provided based on size of numbers ; These levels are only output occasionally if diffuse according to dlabs if nodiff OR (i MOD dlabs EQ 0 AND i / dlabs LT 10) then begin if noskip then begin if levs(i) EQ 0 then front = 1 else front = floor(alog10(levs(i))) + 1 if floor(levs(i)) EQ levs(i) then begin fCode = '(I' + string(front, format = '(I1)') + ')' endif else begin front = front + 3 fCode = '(F' + string(front, format = '(I1)') + '.2)' endelse endif ; If no offset provided, then offset equals zero. Then output level ID if n_elements(offset) EQ 0 then offset = 0 if n_elements(cSize) EQ 0 then begin xyouts, xi - offset, y(0) - 0.06, string(levs(i), format = fCode), /normal endif else begin xyouts, xi - offset, y(0) - 0.06, string(levs(i), format = fCode), charsize = cSize, /normal endelse endif endfor ; Frame the legend using a box if NOT nodiff then plots, [x(0), x(0)], [y(0), y(1)], thick = 2, /normal plots, [xi + dx, xi + dx], [y(0), y(1)], thick = 2, /normal plots, [x(0), x(1)], [y(0), y(0)], thick = 2, /normal plots, [x(0), x(1)], [y(1), y(1)], thick = 2, /normal ; Assign unit label if one is desired if n_elements(unitLab) NE 0 then begin if n_elements(cSize) NE 0 then xyouts, xi + dx - offset, y(0) - 0.06, unitLab, charsize = cSize, /normal $ else xyouts, xi + dx - offset, y(0) - 0.06, unitLab, /normal endif ;else if bar is to be vertical alignment endif else begin ; Pull the x-bounds of the box xpts = [x(0), x(1), x(1), x(0), x(0)] ; Determine the spacing of the y-cells dy = (y(1) - y(0)) / float(n) ; Run through every cell box for i = 0, n - 1 do begin ; Find the beginning of the cell and assign y-bounds (double dy if not last as buffer) yi = y(0) + dy * i if i NE n - 1 then begin ypts = [yi, yi, yi + 2 * dy, yi + 2 * dy, yi] endif else begin ypts = [yi, yi, yi + dy, yi + dy, yi] endelse ; Fill polygon of appropriate size and add divider if appropriate polyfill, xpts, ypts, color = cols(i), /normal if nodiff OR (i MOD dlabs EQ 0 AND i / dlabs LT 10) then plots, [x(0), x(1) + 0.01], [yi, yi], thick = 2, /normal ; Generate format code if not automatically provided based on size of numbers ; These levels are only output occasionally if diffuse according to dlabs if nodiff OR (i MOD dlabs EQ 0 AND i / dlabs LT 10) then begin if noskip then begin if levs(i) EQ 0 then front = 1 else front = floor(alog10(levs(i))) + 1 if floor(levs(i)) EQ levs(i) then begin fCode = '(I' + string(front, format = '(I1)') + ')' endif else begin front = front + 3 fCode = '(F' + string(front, format = '(I1)') + '.2)' endelse endif ; If no offset provided, then offset equals zero. Then output level ID if n_elements(offset) EQ 0 then offset = 0 if n_elements(cSize) EQ 0 then begin xyouts, x(1) + 0.015, yi - offset, string(levs(i), format = fCode), /normal endif else begin xyouts, x(1) + 0.015, yi - offset, string(levs(i), format = fCode), charsize = cSize, /normal endelse endif endfor ; Frame the legend using a box if NOT nodiff then plots, [x(0), x(1)], [y(0), y(0)], thick = 2, /normal plots, [x(0), x(1)], [yi + dy, yi + dy], thick = 2, /normal plots, [x(0), x(0)], [y(0), y(1)], thick = 2, /normal plots, [x(1), x(1)], [y(0), y(1)], thick = 2, /normal ; Assign unit label if one is desired if n_elements(unitLab) NE 0 then begin if n_elements(cSize) NE 0 then xyouts, x(1) + 0.015, yi + dy + (dy / 10.) - offset, unitLab, charsize = cSize, /normal $ else xyouts, x(1) + 0.015, yi + dy + (dy / 10.) - offset, unitLab, /normal endif endelse end