Viewing contents of file '../idllib/idl_5.2/lib/bar_plot.pro'
; $Id: bar_plot.pro,v 1.5.6.1 1999/01/16 16:37:16 scottm Exp $
;
; Copyright (c) 1990-1999, Research Systems, Inc. All rights reserved.
; Unauthorized reproduction prohibited.
;
pro bar_plot,values,baselines=baselines,colors=colors,barnames=barnames, $
title=title,xtitle=xtitle,ytitle=ytitle,baserange=baserange, $
barwidth=barwidth,barspace=barspace,baroffset=baroffset, $
outline=outline,overplot=overplot,background=background, $
rotate=rotate
;+
; NAME:
; BAR_PLOT
;
; PURPOSE:
; Create a bar graph, or overplot on an existing one.
;
; CATEGORY:
; Graphics.
;
; CALLING SEQUENCE:
; BAR_PLOT, Values
;
; INPUTS:
; Values: A vector containing the values to be represented by the bars.
; Each element in VALUES corresponds to a single bar in the
; output.
;
; KEYWORD PARAMETERS:
; BASELINES: A vector, the same size as VALUES, that contains the
; base value associated with each bar. If not specified,
; a base value of zero is used for all bars.
;
; COLORS: A vector, the same size as VALUES, containing the color index
; to be used for each bar. If not specified, the colors are
; selected based on spacing the color indices as widely as
; possible within the available colors (specified by D.N_COLORS).
;
; BARNAMES: A string array, containing one string label per bar.
; If the bars are vertical, the labels are placed beneath
; them. If horizontal (rotated) bars are specified, the labels
; are placed to the left of the bars.
;
; TITLE: A string containing the main title to for the bar plot.
;
; XTITLE: A string containing the title for the X axis.
;
; YTITLE: A string containing the title for the Y axis.
;
; BASERANGE: A floating-point scalar in the range 0.0 to 1.0, that
; determines the fraction of the total available plotting area
; (in the direction perpendicular to the bars) to be used.
; If not specified, the full available area is used.
;
; BARWIDTH: A floating-point value that specifies the width of the bars
; in units of "nominal bar width". The nominal bar width is
; computed so that all the bars (and the space between them,
; set by default to 20% of the width of the bars) will fill the
; available space (optionally controlled with the BASERANGE
; keyword).
;
; BARSPACE: A scalar that specifies, in units of "nominal bar width",
; the spacing between bars. For example, if BARSPACE is 1.0,
; then all bars will have one bar-width of space between them.
; If not specified, the bars are spaced apart by 20% of the bar
; width.
;
; BAROFFSET: A scalar that specifies the offset to be applied to the
; first bar, in units of "nominal bar width". This keyword
; allows, for example, different groups of bars to be overplotted
; on the same graph. If not specified, the default offset is
; equal to BARSPACE.
;
; OUTLINE: If set, this keyword specifies that an outline should be
; drawn around each bar.
;
; OVERPLOT: If set, this keyword specifies that the bar plot should be
; overplotted on an existing graph.
;
; BACKGROUND: A scalar that specifies the color index to be used for
; the background color. By default, the normal IDL background
; color is used.
;
; ROTATE: If set, this keyword indicates that horizontal rather than
; vertical bars should be drawn. The bases of horizontal bars
; are on the left, "Y" axis and the bars extend to the right.
;
; OUTPUTS:
; A bar plot is created, or an existing one is overplotted.
;
; EXAMPLE:
; By using the overplotting capability, it is relatively easy to create
; stacked bar charts, or different groups of bars on the same graph.
;
; For example, if ARRAY is a two-dimensional array of 5 columns and 8
; rows, it is natural to make a plot with 5 bars, each of which is a
; "stacked" composite of 8 sections. First, create a 2D COLORS array,
; equal in size to ARRAY, that has identical color index values across
; each row to ensure that the same item is represented by the same color
; in all bars.
;
; With ARRAYS and COLORS defined, the following code fragment
; illustrates the creation of stacked bars (note that the number of rows
; and columns is arbitrary):
;
; !Y.RANGE = [0,ymax] ; Scale range to accommodate the total bar lengths.
; BASE = INTARR(NROWS)
; FOR I = 0, NROWS-1 DO BEGIN
; BAR_PLOT, ARRAY(*,I), COLORS=COLORS(*,I), BASELINES=BASE, $
; BARWIDTH=0.75, BARSPACE=0.25, OVER=(I GT 0)
; BASE = BASE + ARRAY(*,I)
; ENDFOR
;
; To plot each row of ARRAY as a clustered group of bars within the same
; graph, use the BASERANGE keyword to restrict the available plotting
; region for each set of bars. The sample code fragment below
; illustrates this method:
;
; FOR I = 0, NROWS-1 DO $
; BAR_PLOT, ARRAY(*,I), COLORS=COLORVECT, BARWIDTH=0.8,BARSPACE=0.2, $
; BAROFFSET=I*((1.0+BARSPACE)*NCOLS), OVER=(I GT 0), BASERANGE=0.19
;
; where NCOLS is the number of columns in ARRAY, and COLORVECT is a
; vector containing the color indices to be used for each group of
; bars. (In this example, each group uses the same set of colors, but
; this could easily be changed.)
;
; MODIFICATION HISTORY:
; August 1990, T.J. Armitage, RSI, initial programming. Replacement
; for PLOTBAR and OPLOTBAR routines written by William Thompson.
;
; September 1990, Steve Richards, RSI, changed defaults to improve the
; appearance of the bar plots in the default mode. Included
; spacing the bars slightly.
;-
if (n_params(d) eq 0) then begin ;Print call & return if no parameters
print,'bar_test,values,baselines=baselines,colors=colors,barnames=barnames,$'
print,' title=title,xtitle=xtitle,ytitle=ytitle,baserange=baserange, $'
print,' barwidth=barwidth,barspace=barspace,baroffset=baroffset, $'
print,' outline=outline,overplot=overplot,background=background, $'
print,' rotate=rotate'
return
endif
nbars=n_elements(values) ; Determine number of bars
; Baselines (bars extend from baselines through values); default=0
if not(keyword_set(baselines)) then baselines=intarr(nbars)
; Default colors spaced evenly in current color table
if not(keyword_set(colors)) then $
colors=fix((!d.n_colors/float(nbars))*(indgen(nbars)+0.5))
; Labels for the individual bars; none by default
if not(keyword_set(barnames)) then barnames=strarr(nbars)+' '
; Main title
if not(keyword_set(title)) then title=''
; Centered title under X-axis
if not(keyword_set(xtitle)) then xtitle=''
; Title for Y-axis
if not(keyword_set(ytitle)) then ytitle=''
; Fraction (0-1) of full X range to use
if not(keyword_set(baserange)) then baserange=1.0
; Space betw. bars, taken from nominal bar widths; default is none
If not(keyword_set(barspace)) then barspace=0.2
; Bar width scaling factor, relative to nominal
if not(keyword_set(barwidth)) then barwidth=1.0 - barspace - barspace / nbars
; Initial X offset, in scaled bar widths; default is none
if not(keyword_set(baroffset)) then baroffset=barspace/barwidth
; Outline of bars; default is none
outline = keyword_set(outline)
; Overplot (do not erase the existing display); default is to create new plot
overplot = keyword_set(overplot)
; Background color index; defaults to 0 (usually black) if not specified
if not(keyword_set(background)) then background=0
; Rotate (make horizontal bars); default is vertical bars
rotate = keyword_set(rotate)
if (rotate) then begin ;Horizontal bars
if (!x.range[0] eq 0) and (!x.range[1] eq 0) $ ;Determine range for X-axis
then $
xrange=[(min(baselines)<min(values)), $ ;Minimum of bases & values
(max(baselines)>max(values))] $ ;Maximum of bases & values
else xrange=!x.range ;Or, use range specified
if (!y.range[0] eq 0) and (!y.range[1] eq 0) $ ;Plot will calculate
then $ ; defaults for X, but not
yrange = [0, n_elements(values)] $ ; for Ys, so fill in here.
else $
yrange=!y.range ;Axis perpend. to bars
yticks=1 ;Suppress ticks in plot
ytickname=strarr(2)+' '
xticks=0
xtickname=strarr(1)+''
endif else begin ;Vertical bars
if (!y.range[0] eq 0) and (!y.range[1] eq 0) $ ;Determine range for Y-axis
then $
yrange=[(min(baselines)<min(values)), $ ;Minimum of bases & values
(max(baselines)>max(values))] $ ;Maximum of bases & values
else yrange=!y.range ;Or, use range specified
xrange=!x.range ;Axis perpend. to bars
xticks=1 ;Suppress ticks in plot
xtickname=strarr(2)+' '
yticks=0
ytickname=strarr(1)+''
endelse
if (overplot eq 0) then $ ;Create new plot, no data
plot,[values],/nodata,title=title,xtitle=xtitle,ytitle=ytitle, $
noerase=overplot,xrange=xrange,yrange=yrange,xticks=xticks, $
xtickname=xtickname,yticks=yticks,ytickname=ytickname, $
xstyle=1,ystyle=1,/data,background=background
if (rotate) then begin ;Horizontal bars
base_win=!y.window ;Window range in Y
scal_fact=!x.s ;Scaling factors
tick_scal_fact=!y.s ;Tick scaling factors
endif else begin ;Vertical bars
base_win=!x.window ;Window range in X
scal_fact=!y.s ;Scaling factors
tick_scal_fact=!x.s ;Tick scaling factors
endelse
winrange=baserange*(base_win[1]-base_win[0]) ;Normal. window range
barsize=barwidth*winrange/nbars ;Normal. bar width
winoffset=base_win[0]+(baroffset*barsize) ;Normal. first offset
bases=scal_fact[0]+(scal_fact[1]*baselines) ;Baselines, in normal coor.
normal=scal_fact[0]+(scal_fact[1]*values) ;Values, in normal coor.
barstart=indgen(nbars)*(barsize+barspace*(winrange/nbars)) ;Coor. at left edges
tickv=winoffset+barstart+(0.5*barsize) ;Tick coor. (centered)
for i=0,nbars-1 do begin ;Draw the bars
width=winoffset+[barstart[i],barstart[i], $ ;Compute bar width
(barstart[i]+barsize),(barstart[i]+barsize)]
length=[bases[i],normal[i],normal[i],bases[i]] ;Compute bar length
if (rotate) then begin ;Horizontal bars
x=length ;X-axis is "length" axis
y=width ;Y-axis is "width" axis
endif else begin ;Vertical bars
x=width ;X-axis is "width" axis
y=length ;Y-axis is "length" axis
endelse
polyfill,x,y,color=colors[i],/normal ;Polyfill with color
if (outline) then plots,x,y,/normal ;Outline using !p.color
endfor
tickv=(tickv-tick_scal_fact[0])/tick_scal_fact[1] ;Locations of the ticks
if (rotate) then $ ;Label the bars (Y-axis)
axis,yaxis=0,ystyle=1,yticks=(nbars-1),ytickv=tickv,ytickname=barnames, $
yticklen=0.0 $
else $ ;Label the bars (X-axis)
axis,xaxis=0,xstyle=1,xticks=(nbars-1),xtickv=tickv,xtickname=barnames, $
xticklen=0.0
return
end