Viewing contents of file '../idllib/contrib/windt/legend.pro'
;+
; NAME:
; LEGEND
;
; PURPOSE:
;
; Add to a plot a legend containing lines and plotting symbols,
; enclosed in a box.
;
; CALLING SEQUENCE:
;
; LEGEND,LABELS
;
; INPUTS:
; LABELS - n-element string array of labels.
;
; KEYWORD PARAMETERS:
;
; POSITION - an integer, specifying the location of the legend box:
;
; 0: no legend is drawn.
; 1: below plot, left
; 2: below plot, center
; 3: below plot, right
; 4: lower left
; 5: lower center
; 6: lower right
; 7: middle left
; 8: middle center
; 9: middle right
; 10: upper left
; 11: upper center
; 12: upper right
;
; if not specified, default position=10
;
; COLOR - n-element array of colors. default is !p.color
;
; LINESTYLE - n-element array of linestyles. if ommited, only
; symbols are plotted.
;
; THICK - n-element array of thicknesses. default is !p.thick
;
; PSYM - n-element array of psym values. if positive, only
; symbols are plotted.
;
; SYMSIZE - n-element array of symsize values. default is !p.symsize
;
; SYMBOLS - array of 'symbol' specifiers: each element of
; psym which is equal to 8 (user-defined symbol)
; must have a corresponding value for 'symbol' to be
; used by the procedure SYMBOLS.
; Examples: psym=[8,8,8,8],symbols=[1,2,20,30]
; psym=[1,2,8,8],symbols=[1,2]
;
; CHARSIZE - scalar specifiying the size of the text.
;
; TITLE - scalar string specifying legend title
;
; T_COLOR - scalar specifying the color index of the title.
;
; NOLINES - set to inhibit drawing lines and symbols; just draw
; labels in color.
;
; SYM_ONLY - set to inhibit drawing lines; just draw symbols.
;
; NOBOX - set to inhibit drawing a box around the legend
;
; LINEWIDTH - width in character units. default = 4.
;
; BOXPADX - padding in character units, between text and box in
; x. default=2.0
; BOXPADY - padding in character units, between text and box in
; y. default=0.5
;
; FONT - Set to an integer from 3 to 20, corresponding to the
; Hershey vector font sets, referring to the font used
; to display the text. If a font other than !3 is used
; in the text string, then FONT should be set
; accordingly. (Any font commands embedded in the text
; string are ignored.)
;
; BOXFUDGEX - A scaling factor, used to fudge the width of the
; box surrounding the text. Default=1.0.
;
; RESTRICTIONS:
;
; When specifying a position of 1,2 or 3, you'll need
; to (a) use the same charsize value for the plot and
; for the legend, and (b) draw the plot with an extra
; ymargin(0). i.e., set ymargin(0)=7+n_elements(text_array)
;
;
; MODIFICATION HISTORY:
;
; David L. Windt, Bell Labs, March 1997
; windt@bell-labs.com
;
; October, 1997, dlw:
;
; Now using the TEXT_WIDTH function, in order to do a somewhat
; better job of drawing the box around the text.
;
; NONPRINTER_SCALE keyword parameter is now obsolete.
;
; BOXFUDGEX keyword parameter added.
;
;-
pro legend,labels,position=position, $
color=color,linestyle=linestyle, $
thick=thick,psym=psym,symsize=symsize, $
symbol=symbol, $
charsize=charsize, $
linewidth=linewidth, $
title=title,t_color=t_color, $
nolines=nolines,sym_only=sym_only,nobox=nobox, $
boxpadx=boxpadx,boxpady=boxpady, $
nonprinter_scale=nonprinter_scale, $
font=font,boxfudgex=boxfudgex
on_error,2
if n_params() ne 1 then message,'usage: legend,labels'
if n_elements(position) ne 1 then position=10
if position eq 0 then return
position=position < 12
;; get/set charsize
if n_elements(charsize) eq 0 then charsize=!p.charsize
if charsize eq 0 then charsize=1.
;; scale factor for text, relative to charsize
scale=0.85
;; scale factors for "character" sizes:
sx=float(scale*charsize)
sy=float(charsize)
;; compute number of lines of text:
n_lines=n_elements(labels)
if n_elements(color) ne n_lines then color=fltarr(n_lines)+!p.color
if n_elements(linestyle) ne n_lines then linestyle=fltarr(n_lines)+!p.linestyle
if n_elements(thick) ne n_lines then thick=fltarr(n_lines)+!p.thick
if n_elements(psym) ne n_lines then psym=fltarr(n_lines)+!p.psym
if n_elements(symsize) ne n_lines then symsize=fltarr(n_lines)+!p.symsize
for i=0,n_lines-1 do if symsize(i) eq 0 then symsize(i)=1.
if n_elements(t_color) eq 0 then t_color=!p.color
;; fudge factor to get right side of box close to end of text:
if n_elements(boxfudgex) ne 1 then boxfudgex=1.
;; determine maximum number of printing characters:
width=0
for i=0,n_lines-1 do width=width > text_width(labels(i),font=font)
;; width of text region, in characters:
;; (add sympad characters for padding)
if n_elements(linewidth) ne 1 then linewidth=4.
linewidth=linewidth*sx
linepad=.75*sx
sympad=max(symsize)*(total(psym) ne 0)*sx
if keyword_set(nolines) then begin
linewidth=0
linepad=0
sympad=0
endif
if keyword_set(sym_only) then begin
linewidth=0
linepad=0
endif
if n_elements(boxpadx) ne 1 then boxpadx=2.
lxc=((linewidth+linepad+sympad*1.5)+(width+boxpadx)*sx)*boxfudgex
;; height of text region, in characters:
;; (add boxpady characters for padding)
if n_elements(boxpady) ne 1 then boxpady=.5
lyc=-(n_lines+ (n_elements(title) eq 1) + boxpady)*sy
;; coordinates of plot area, in device units:
xcrange=!x.crange
if !x.type then xcrange=10^xcrange
ycrange=!y.crange
if !y.type then ycrange=10^ycrange
lower_left=convert_coord(xcrange(0),ycrange(0),/data,/to_device)
upper_right=convert_coord(xcrange(1),ycrange(1),/data,/to_device)
;; width of plot area, in characters:
pxc=float(upper_right(0)-lower_left(0))/!d.x_ch_size
;; height of plot area, in characters:
pyc=-float(upper_right(1)-lower_left(1))/!d.y_ch_size
;; define padding: distance (in characters) of edge of
;; text box from plot axes:
padxc=3.*sx
padyc=1.5*sy
;; define coordinates of upper left corner of text region, in
;; characters, relative to upper left corner of plot data area.
case position of
0: return
1: begin ; below plot, left
x1c=0.
y1c=pyc-4.*sy-padyc
end
2: begin ; below plot, center
x1c=.5*(pxc-lxc)
y1c=pyc-4.*sy-padyc
end
3: begin ; below plot, right
x1c=pxc-lxc
y1c=pyc-4.*sy-padyc
end
4: begin ; lower left
x1c=padxc
y1c=pyc-lyc+padyc
end
5: begin ; lower center
x1c=.5*(pxc-lxc)
y1c=pyc-lyc+padyc
end
6: begin ; lower right
x1c=pxc-lxc-padxc
y1c=pyc-lyc+padyc
end
7: begin ; middle left
x1c=padxc
y1c=.5*(pyc-lyc)
end
8: begin ; middle center
x1c=.5*(pxc-lxc)
y1c=.5*(pyc-lyc)
end
9: begin ; middle right
x1c=pxc-lxc-padxc
y1c=.5*(pyc-lyc)
end
10: begin ; upper left
x1c=padxc
y1c=-padyc
end
11: begin ; upper center
x1c=.5*(pxc-lxc)
y1c=-padyc
end
12: begin ; upper right
x1c=pxc-lxc-padxc
y1c=-padyc
end
endcase
;; define bottom right corner of text box, in characters:
x2c=x1c+lxc
y2c=y1c+lyc
;; position for title underline
ytc=y1c-1*sy
;; define bottom right corner of each line of text:
txc=fltarr(n_lines + (n_elements(title) eq 1))+ $
x1c+sx*boxpadx/2.+linewidth+linepad+sympad*1.5
if n_elements(title) eq 1 then txc(0)=x1c+lxc/2.
tyc=fltarr(n_lines + (n_elements(title) eq 1))
for i=0,n_lines + (n_elements(title) eq 1) -1 do $
tyc(i)=y1c-(i+.85)*charsize-boxpady/2.
if n_elements(title) eq 1 then tyc(0)=tyc(0)+.15*charsize
;; define positions for lines/psyms:
linex1c=fltarr(n_lines)+x1c+boxpadx/2.+sympad/2.
linex2c=linex1c+linewidth+sympad/2.
;; if psym is positive, don't draw the line:
for i=0,n_lines-1 do if psym(i) gt 0 then linex1c(i)=linex2c(i)
if keyword_set(sym_only) then begin
linex1c=linex1c*0+x1c+boxpadx/2.+sympad/2.
linex2c=linex1c
endif
lineyc=tyc(n_elements(title) eq 1:*)+.25*sy
;; get coordinates of upper left corner ("origin")
;; of plot in device coords:
x0=lower_left(0)
y0=upper_right(1)
;; convert (x1,y1), (x2,y2), and (tx,ty) to device coords:
x1=x0+x1c*!d.x_ch_size
y1=y0+y1c*!d.y_ch_size
x2=x0+x2c*!d.x_ch_size
y2=y0+y2c*!d.y_ch_size
yt=y0+ytc*!d.y_ch_size
tx=x0+txc*!d.x_ch_size
ty=y0+tyc*!d.y_ch_size
linex1=x0+linex1c*!d.x_ch_size
linex2=x0+linex2c*!d.x_ch_size
liney=y0+lineyc*!d.y_ch_size
;; draw the labels:
i0=0
if n_elements(title) eq 1 then begin
xyouts,tx(0),ty(0),title,color=t_color,charsize=scale*charsize, $
_extra=_extra,/device,alignment=.5
i0=1
endif
for i=0,n_lines-1 do xyouts,tx(i+i0),ty(i+i0),labels(i), $
color=color(i),charsize=scale*charsize,_extra=_extra,/device
;; draw the box around the text:
if keyword_set(nobox) eq 0 then begin
if n_elements(title) eq 1 then $
plots,[x1,x2],[yt,yt],/device,_extra=_extra
plots,[x1,x2,x2,x1,x1],[y1,y1,y2,y2,y1],/device,_extra=_extra
endif
if keyword_set(nolines) then return
i=0
sindex=0
while i lt n_lines do begin
if abs(psym(i)) eq 8 then begin
symbols,symbol(sindex),1
sindex=sindex+1
endif
plots,[linex1(i),linex2(i)],[liney(i),liney(i)], $
color=color(i),linestyle=linestyle(i), $
thick=thick(i),psym=psym(i),symsize=symsize(i),/device
i=i+1
endwhile
return
end