AL_LEGEND
Name
AL_LEGEND
Purpose
Create an annotation legend for a plot.
Explanation
This procedure was originally named LEGEND, but a distinct LEGEND()
function was introduced into IDL V8.0. Therefore, the
original LEGEND procedure in the Astronomy Library is renamed to
AL_LEGEND.
This procedure makes a legend for a plot. The legend can contain
a mixture of symbols, linestyles, Hershey characters (vectorfont),
and filled polygons (usersym). A test procedure, legendtest.pro,
shows legend's capabilities. Placement of the legend is controlled
with keywords like /right, /top, and /center or by using a position
keyword for exact placement (position=[x,y]) or via mouse (/position).
Calling Sequence
AL_LEGEND [,items][,keyword options]
Examples
The call:
al_legend,['Plus sign','Asterisk','Period'],psym=[1,2,3]
produces:
-----------------
| |
| + Plus sign |
| * Asterisk |
| . Period |
| |
-----------------
Each symbol is drawn with a cgPlots command, so they look OK.
Other examples are given in optional output keywords.
lines = indgen(6) ; for line styles
items = 'linestyle '+strtrim(lines,2) ; annotations
al_legend,items,linestyle=lines ; vertical legend---upper left
items = ['Plus sign','Asterisk','Period']
sym = [1,2,3]
al_legend,items,psym=sym ; ditto except using symbols
al_legend,items,psym=sym,/horizontal ; horizontal format
al_legend,items,psym=sym,box=0 ; sans border
al_legend,items,psym=sym,delimiter='=' ; embed '=' betw psym & text
al_legend,items,psym=sym,margin=2 ; 2-character margin
al_legend,items,psym=sym,position=[x,y] ; upper left in data coords
al_legend,items,psym=sym,pos=[x,y],/norm ; upper left in normal coords
al_legend,items,psym=sym,pos=[x,y],/device ; upper left in device coords
al_legend,items,psym=sym,/position ; interactive position
al_legend,items,psym=sym,/right ; at upper right
al_legend,items,psym=sym,/bottom ; at lower left
al_legenditems,psym=sym,/center ; approximately near center
al_legend,items,psym=sym,number=2 ; plot two symbols, not one
Plot 3 filled colored squares
al_legend,items,/fill,psym=[8,8,8],colors=['red','green','blue']
Another example of the use of AL_LEGEND can be found at
http://www.idlcoyote.com/cg_tips/al_legend.php
Inputs
items = text for the items in the legend, a string array.
For example, items = ['diamond','asterisk','square'].
You can omit items if you don't want any text labels.
Optional Input Keywords
linestyle = array of linestyle numbers If linestyle[i] < 0, then omit
ith symbol or line to allow a multi-line entry. If
linestyle = -99 then text will be left-justified.
psym = array of plot symbol numbers or names. If psym[i] is negative,
then a line connects pts for ith item. If psym[i] = 8, then the
procedure USERSYM is called with vertices defined in the
keyword usersym. If psym[i] = 88, then use the previously
defined user symbol. If 11 <= psym[i] <= 46 then David
Fanning's function CGSYMCAT() will be used for additional
symbols. Note that
PSYM=10 (histogram plot mode) is not allowed since it
cannot be used with the cgPlots command.
vectorfont = vector-drawn characters for the sym/line column, e.g.,
['!9B!3','!9C!3','!9D!3'] produces an open square, a checkmark,
and a partial derivative, which might have accompanying items
['BOX','CHECK','PARTIAL DERIVATIVE'].
There is no check that !p.font is set properly, e.g., -1 for
X and 0 for PostScript. This can produce an error, e.g., use
!20 with PostScript and !p.font=0, but allows use of Hershey
*AND* PostScript fonts together.
N. B.: Choose any of linestyle, psym, and/or vectorfont. If none is
present, only the text is output. If more than one
is present, all need the same number of elements, and normal
plot behaviour occurs.
By default, if psym is positive, you get one point so there is
no connecting line. If vectorfont[i] = '',
then cgPlots is called to make a symbol or a line, but if
vectorfont[i] is a non-null string, then cgText is called.
/help = flag to print header
/horizontal = flag to make the legend horizontal
/vertical = flag to make the legend vertical (D=vertical)
background_color - color name or number to fill the legend box.
Automatically sets /clear. (D = -1)
box = flag to include/omit box around the legend (D=include)
outline_color = color of box outline (D = !P.color)
bthick = thickness of the legend box (D = !P.thick)
charsize = just like !p.charsize for plot labels
charthick = just like !p.charthick for plot labels
clear = flag to clear the box area before drawing the legend
colors = array of colors names or numbers for plot symbols/lines
See cgCOLOR for list of color names. Default is 'Opposite'
If you are using index colors (0-255), then supply color as a byte,
integer or string, but not as a long, which will be interpreted as
a decomposed color. See http://www.idlcoyote.com/cg_tips/legcolor.php
delimiter = embedded character(s) between symbol and text (D=none)
font = scalar font graphics keyword (-1,0 or 1) for text
linsize = Scale factor for line length (0-1), default = 1
Set to 0 to give a dot, 0.5 give half default line length
margin = margin around text measured in characters and lines
number = number of plot symbols to plot or length of line (D=1)
spacing = line spacing (D=bit more than character height)
position = data coordinates of the /top (D) /left (D) of the legend
pspacing = psym spacing (D=3 characters) (when number of symbols is
greater than 1)
textcolors = array of color names or numbers for text. See cgCOLOR
for a list of color names. Default is 'Opposite' of background
thick = array of line thickness numbers (D = !P.thick), if used, then
linestyle must also be specified
normal = use normal coordinates for position, not data
device = use device coordinates for position, not data
/window - if set then send legend to a resizeable graphics window
usersym = 2-D array of vertices, cf. usersym in IDL manual.
(/USERSYM =square, default is to use existing USERSYM definition)
/fill = flag to fill the usersym
/left_legend = flag to place legend snug against left side of plot
window (D)
/right_legend = flag to place legend snug against right side of plot
window. If /right,pos=[x,y], then x is position of RHS and
text runs right-to-left.
/top_legend = flag to place legend snug against top of plot window (D)
/bottom = flag to place legend snug against bottom of plot window
/top,pos=[x,y] and /bottom,pos=[x,y] produce same positions.
If LINESTYLE, PSYM, VECTORFONT, SYMSIZE, THICK, COLORS, or
TEXTCOLORS are supplied as scalars, then the scalar value is set for
every line or symbol in the legend.
Outputs
legend to current plot device
Optional Output Keywords
corners = 4-element array, like !p.position, of the normalized
coords for the box (even if box=0): [llx,lly,urx,ury].
Useful for multi-column or multi-line legends, for example,
to make a 2-column legend, you might do the following:
c1_items = ['diamond','asterisk','square']
c1_psym = [4,2,6]
c2_items = ['solid','dashed','dotted']
c2_line = [0,2,1]
al_legend,c1_items,psym=c1_psym,corners=c1,box=0
al_legend,c2_items,line=c2_line,corners=c2,box=0,pos=[c1[2],c1[3]]
c = [c1[0]<c2[0],c1[1]c2[3]]
cgplots,[c[0],c[0],c[2],c[2],c[0]],[c[1],c[3],c[3],c[1],c[1]],/norm
Useful also to place the legend. Here's an automatic way to place
the legend in the lower right corner. The difficulty is that the
legend's width is unknown until it is plotted. In this example,
the legend is plotted twice: the first time in the upper left, the
second time in the lower right.
al_legend,['1','22','333','4444'],linestyle=indgen(4),corners=corners
; BOGUS LEGEND---FIRST TIME TO REPORT CORNERS
xydims = [corners[2]-corners[0],corners[3]-corners[1]]
; SAVE WIDTH AND HEIGHT
chdim=[!d.x_ch_size/float(!d.x_size),!d.y_ch_size/float(!d.y_size)]
; DIMENSIONS OF ONE CHARACTER IN NORMALIZED COORDS
pos = [!x.window[1]-chdim[0]-xydims[0] $
,!y.window[0]+chdim[1]+xydims[1]]
; CALCULATE POSITION FOR LOWER RIGHT
cgplot,findgen(10) ; SIMPLE PLOT; YOU DO WHATEVER YOU WANT HERE.
al_legend,['1','22','333','4444'],linestyle=indgen(4),pos=pos
; REDO THE LEGEND IN LOWER RIGHT CORNER
You can modify the pos calculation to place the legend where you
want. For example to place it in the upper right:
pos = [!x.window[1]-chdim[0]-xydims[0],!y.window[1]-xydims[1]]
Common Blocks
none
Procedure
If keyword help is set, call doc_library to print header.
See notes in the code. Much of the code deals with placement of the
legend. The main problem with placement is not being
able to sense the length of a string before it is output. Some crude
approximations are used for centering.
Restrictions
Here are some things that aren't implemented.
- An orientation keyword would allow lines at angles in the legend.
- An array of usersyms would be nice---simple change.
- An order option to interchange symbols and text might be nice.
- Somebody might like double boxes, e.g., with box = 2.
- Another feature might be a continuous bar with ticks and text.
- There are no guards to avoid writing outside the plot area.
- There is no provision for multi-line text, e.g., '1st line!c2nd line'
Sensing !c would be easy, but !c isn't implemented for PostScript.
A better way might be to simply output the 2nd line as another item
but without any accompanying symbol or linestyle. A flag to omit
the symbol and linestyle is linestyle[i] = -1.
- There is no ability to make a title line containing any of titles
for the legend, for the symbols, or for the text.
Side Effects
Modification History
write, 24-25 Aug 92, F K Knight (knight@ll.mit.edu)
allow omission of items or omission of both psym and linestyle, add
corners keyword to facilitate multi-column legends, improve place-
ment of symbols and text, add guards for unequal size, 26 Aug 92, FKK
add linestyle(i)=-1 to suppress a single symbol/line, 27 Aug 92, FKK
add keyword vectorfont to allow characters in the sym/line column,
28 Aug 92, FKK
add /top, /bottom, /left, /right keywords for automatic placement at
the four corners of the plot window. The /right keyword forces
right-to-left printing of menu. 18 Jun 93, FKK
change default position to data coords and add normal, data, and
device keywords, 17 Jan 94, FKK
add /center keyword for positioning, but it is not precise because
text string lengths cannot be known in advance, 17 Jan 94, FKK
add interactive positioning with /position keyword, 17 Jan 94, FKK
allow a legend with just text, no plotting symbols. This helps in
simply describing a plot or writing assumptions done, 4 Feb 94, FKK
added thick, symsize, and clear keyword Feb 96, W. Landsman HSTX
David Seed, HR Wallingford, d.seed@hrwallingford.co.uk
allow scalar specification of keywords, Mar 96, W. Landsman HSTX
added charthick keyword, June 96, W. Landsman HSTX
Made keyword names left,right,top,bottom,center longer,
Aug 16, 2000, Kim Tolbert
Added ability to have regular text lines in addition to plot legend
lines in legend. If linestyle is -99 that item is left-justified.
Previously, only option for no sym/line was linestyle=-1, but then text
was lined up after sym/line column. 10 Oct 2000, Kim Tolbert
Make default value of thick = !P.thick W. Landsman Jan. 2001
Don't overwrite existing USERSYM definition W. Landsman Mar. 2002
Added outline_color BT 24 MAY 2004
Pass font keyword to cgText commands. M. Fitzgerald, Sep. 2005
Default spacing, pspacing should be relative to charsize. M. Perrin, July 2007
Don't modify position keyword A. Kimball/ W. Landsman Jul 2007
Small update to Jul 2007 for /NORMAL coords. W. Landsman Aug 2007
Use SYMCAT() plotting symbols for 11<=PSYM<=46 W. Landsman Nov 2009
Make a sharper box edge T. Robishaw/W.Landsman July 2010
Added BTHICK keyword W. Landsman October 2010
Added BACKGROUND_COLOR keyword W. Landsman February 2011
Incorporate Coyote graphics W. Landsman February 2011
Added LINSIZE keyword W.L./V.Gonzalez May 2011
Fixed a small problem with Convert_Coord when the Window keyword is set.
David Fanning, May 2011.
Fixed problem when /clear and /Window are set J. Bailin/WL May 2011
CGQUERY was called instead of CGCONTROL W.L. June 2011
Fixed typo preventing BTHICK keyword from working W.L. Dec 2011
Remove call to SYMCAT() W.L. Dec 2011
Changed the way the WINDOW keyword adds commands to cgWindow, and
now default to BACKGROUND for background color. 1 Feb 2012 David Fanning
Allow 1 element SYMSIZE for vector input, WL Apr 2012.
Allow to specify symbols by cgSYMCAT() name WL Aug 2012