[2] | 1 | ; $Id$ |
---|
| 2 | ; |
---|
| 3 | ; Copyright (c) 1990-2000, Research Systems, Inc. All rights reserved. |
---|
| 4 | ; Unauthorized reproduction prohibited. |
---|
| 5 | ; |
---|
| 6 | ;+ |
---|
| 7 | ; PURPOSE: |
---|
| 8 | ; Create a bar graph, or overplot on an existing one. |
---|
| 9 | ; |
---|
| 10 | ; CATEGORY: |
---|
| 11 | ; Graphics. |
---|
| 12 | ; |
---|
| 13 | ; CALLING SEQUENCE: |
---|
| 14 | ; BAR_PLOT, Values |
---|
| 15 | ; |
---|
| 16 | ; INPUTS: |
---|
| 17 | ; Values: A vector containing the values to be represented by the bars. |
---|
| 18 | ; Each element in VALUES corresponds to a single bar in the |
---|
| 19 | ; output. |
---|
| 20 | ; |
---|
| 21 | ; KEYWORD PARAMETERS: |
---|
| 22 | ; BASELINES: A vector, the same size as VALUES, that contains the |
---|
| 23 | ; base value associated with each bar. If not specified, |
---|
| 24 | ; a base value of zero is used for all bars. |
---|
| 25 | ; |
---|
| 26 | ; COLORS: A vector, the same size as VALUES, containing the color index |
---|
| 27 | ; to be used for each bar. If not specified, the colors are |
---|
| 28 | ; selected based on spacing the color indices as widely as |
---|
| 29 | ; possible within the available colors (specified by D.N_COLORS). |
---|
| 30 | ; |
---|
| 31 | ; BARNAMES: A string array, containing one string label per bar. |
---|
| 32 | ; If the bars are vertical, the labels are placed beneath |
---|
| 33 | ; them. If horizontal (rotated) bars are specified, the labels |
---|
| 34 | ; are placed to the left of the bars. |
---|
| 35 | ; |
---|
| 36 | ; TITLE: A string containing the main title to for the bar plot. |
---|
| 37 | ; |
---|
| 38 | ; XTITLE: A string containing the title for the X axis. |
---|
| 39 | ; |
---|
| 40 | ; YTITLE: A string containing the title for the Y axis. |
---|
| 41 | ; |
---|
| 42 | ; BASERANGE: A floating-point scalar in the range 0.0 to 1.0, that |
---|
| 43 | ; determines the fraction of the total available plotting area |
---|
| 44 | ; (in the direction perpendicular to the bars) to be used. |
---|
| 45 | ; If not specified, the full available area is used. |
---|
| 46 | ; |
---|
| 47 | ; BARWIDTH: A floating-point value that specifies the width of the bars |
---|
| 48 | ; in units of "nominal bar width". The nominal bar width is |
---|
| 49 | ; computed so that all the bars (and the space between them, |
---|
| 50 | ; set by default to 20% of the width of the bars) will fill the |
---|
| 51 | ; available space (optionally controlled with the BASERANGE |
---|
| 52 | ; keyword). |
---|
| 53 | ; |
---|
| 54 | ; BARSPACE: A scalar that specifies, in units of "nominal bar width", |
---|
| 55 | ; the spacing between bars. For example, if BARSPACE is 1.0, |
---|
| 56 | ; then all bars will have one bar-width of space between them. |
---|
| 57 | ; If not specified, the bars are spaced apart by 20% of the bar |
---|
| 58 | ; width. |
---|
| 59 | ; |
---|
| 60 | ; BAROFFSET: A scalar that specifies the offset to be applied to the |
---|
| 61 | ; first bar, in units of "nominal bar width". This keyword |
---|
| 62 | ; allows, for example, different groups of bars to be overplotted |
---|
| 63 | ; on the same graph. If not specified, the default offset is |
---|
| 64 | ; equal to BARSPACE. |
---|
| 65 | ; |
---|
| 66 | ; OUTLINE: If set, this keyword specifies that an outline should be |
---|
| 67 | ; drawn around each bar. |
---|
| 68 | ; |
---|
| 69 | ; OVERPLOT: If set, this keyword specifies that the bar plot should be |
---|
| 70 | ; overplotted on an existing graph. |
---|
| 71 | ; |
---|
| 72 | ; BACKGROUND: A scalar that specifies the color index to be used for |
---|
| 73 | ; the background color. By default, the normal IDL background |
---|
| 74 | ; color is used. |
---|
| 75 | ; |
---|
| 76 | ; ROTATE: If set, this keyword indicates that horizontal rather than |
---|
| 77 | ; vertical bars should be drawn. The bases of horizontal bars |
---|
| 78 | ; are on the left, "Y" axis and the bars extend to the right. |
---|
| 79 | ; |
---|
| 80 | ; OUTPUTS: |
---|
| 81 | ; A bar plot is created, or an existing one is overplotted. |
---|
| 82 | ; |
---|
| 83 | ; EXAMPLE: |
---|
| 84 | ; By using the overplotting capability, it is relatively easy to create |
---|
| 85 | ; stacked bar charts, or different groups of bars on the same graph. |
---|
| 86 | ; |
---|
| 87 | ; For example, if ARRAY is a two-dimensional array of 5 columns and 8 |
---|
| 88 | ; rows, it is natural to make a plot with 5 bars, each of which is a |
---|
| 89 | ; "stacked" composite of 8 sections. First, create a 2D COLORS array, |
---|
| 90 | ; equal in size to ARRAY, that has identical color index values across |
---|
| 91 | ; each row to ensure that the same item is represented by the same color |
---|
| 92 | ; in all bars. |
---|
| 93 | ; |
---|
| 94 | ; With ARRAYS and COLORS defined, the following code fragment |
---|
| 95 | ; illustrates the creation of stacked bars (note that the number of rows |
---|
| 96 | ; and columns is arbitrary): |
---|
| 97 | ; |
---|
| 98 | ; !Y.RANGE = [0,ymax] ; Scale range to accommodate the total bar lengths. |
---|
| 99 | ; BASE = INTARR(NROWS) |
---|
| 100 | ; FOR I = 0, NROWS-1 DO BEGIN |
---|
| 101 | ; BAR_PLOT, ARRAY(*,I), COLORS=COLORS(*,I), BASELINES=BASE, $ |
---|
| 102 | ; BARWIDTH=0.75, BARSPACE=0.25, OVER=(I GT 0) |
---|
| 103 | ; BASE = BASE + ARRAY(*,I) |
---|
| 104 | ; ENDFOR |
---|
| 105 | ; |
---|
| 106 | ; To plot each row of ARRAY as a clustered group of bars within the same |
---|
| 107 | ; graph, use the BASERANGE keyword to restrict the available plotting |
---|
| 108 | ; region for each set of bars. The sample code fragment below |
---|
| 109 | ; illustrates this method: |
---|
| 110 | ; |
---|
| 111 | ; FOR I = 0, NROWS-1 DO $ |
---|
| 112 | ; BAR_PLOT, ARRAY(*,I), COLORS=COLORVECT, BARWIDTH=0.8,BARSPACE=0.2, $ |
---|
| 113 | ; BAROFFSET=I*((1.0+BARSPACE)*NCOLS), OVER=(I GT 0), BASERANGE=0.19 |
---|
| 114 | ; |
---|
| 115 | ; where NCOLS is the number of columns in ARRAY, and COLORVECT is a |
---|
| 116 | ; vector containing the color indices to be used for each group of |
---|
| 117 | ; bars. (In this example, each group uses the same set of colors, but |
---|
| 118 | ; this could easily be changed.) |
---|
| 119 | ; |
---|
| 120 | ; MODIFICATION HISTORY: |
---|
| 121 | ; August 1990, T.J. Armitage, RSI, initial programming. Replacement |
---|
| 122 | ; for PLOTBAR and OPLOTBAR routines written by William Thompson. |
---|
| 123 | ; |
---|
| 124 | ; September 1990, Steve Richards, RSI, changed defaults to improve the |
---|
| 125 | ; appearance of the bar plots in the default mode. Included |
---|
| 126 | ; spacing the bars slightly. |
---|
| 127 | ;- |
---|
[97] | 128 | pro bar_plot,values,baselines=baselines,colors=colors,barnames=barnames, $ |
---|
| 129 | title=title,xtitle=xtitle,ytitle=ytitle,baserange=baserange, $ |
---|
| 130 | barwidth=barwidth,barspace=barspace,baroffset=baroffset, $ |
---|
| 131 | outline=outline,overplot=overplot,background=background, $ |
---|
| 132 | rotate=rotate, _EXTRA = ex |
---|
[114] | 133 | ; |
---|
| 134 | compile_opt idl2, strictarrsubs |
---|
| 135 | ; |
---|
[2] | 136 | if (n_params(d) eq 0) then begin ;Print call & return if no parameters |
---|
| 137 | print,'bar_test,values,baselines=baselines,colors=colors,barnames=barnames,$' |
---|
| 138 | print,' title=title,xtitle=xtitle,ytitle=ytitle,baserange=baserange, $' |
---|
| 139 | print,' barwidth=barwidth,barspace=barspace,baroffset=baroffset, $' |
---|
| 140 | print,' outline=outline,overplot=overplot,background=background, $' |
---|
| 141 | print,' rotate=rotate' |
---|
| 142 | return |
---|
| 143 | endif |
---|
| 144 | |
---|
| 145 | nbars=n_elements(values) ; Determine number of bars |
---|
| 146 | ; Baselines (bars extend from baselines through values); default=0 |
---|
| 147 | if not(keyword_set(baselines)) then baselines=intarr(nbars) |
---|
| 148 | ; Default colors spaced evenly in current color table |
---|
| 149 | if not(keyword_set(colors)) then $ |
---|
| 150 | colors=fix((!d.n_colors/float(nbars))*(indgen(nbars)+0.5)) |
---|
| 151 | ; Labels for the individual bars; none by default |
---|
| 152 | if not(keyword_set(barnames)) then barnames=strarr(nbars)+' ' |
---|
| 153 | ; Main title |
---|
| 154 | if not(keyword_set(title)) then title='' |
---|
| 155 | ; Centered title under X-axis |
---|
| 156 | if not(keyword_set(xtitle)) then xtitle='' |
---|
| 157 | ; Title for Y-axis |
---|
| 158 | if not(keyword_set(ytitle)) then ytitle='' |
---|
| 159 | ; Fraction (0-1) of full X range to use |
---|
| 160 | if not(keyword_set(baserange)) then baserange=1.0 |
---|
| 161 | ; Space betw. bars, taken from nominal bar widths; default is none |
---|
| 162 | If not(keyword_set(barspace)) then barspace=0.2 |
---|
| 163 | ; Bar width scaling factor, relative to nominal |
---|
| 164 | if not(keyword_set(barwidth)) then barwidth=1.0 - barspace - barspace / nbars |
---|
| 165 | ; Initial X offset, in scaled bar widths; default is none |
---|
| 166 | if not(keyword_set(baroffset)) then baroffset=barspace/barwidth |
---|
| 167 | ; Outline of bars; default is none |
---|
| 168 | outline = keyword_set(outline) |
---|
| 169 | ; Overplot (do not erase the existing display); default is to create new plot |
---|
| 170 | overplot = keyword_set(overplot) |
---|
| 171 | ; Background color index; defaults to 0 (usually black) if not specified |
---|
| 172 | if not(keyword_set(background)) then background=0 |
---|
| 173 | ; Rotate (make horizontal bars); default is vertical bars |
---|
| 174 | rotate = keyword_set(rotate) |
---|
| 175 | |
---|
| 176 | mnB = MIN(baselines, MAX=mxB, /NAN) |
---|
| 177 | mnV = MIN(values, MAX=mxV, /NAN) |
---|
| 178 | range=[mnB < mnV, $ ;Minimum of bases & values |
---|
| 179 | mxB > mxV] ;Maximum of bases & values |
---|
| 180 | |
---|
| 181 | if (rotate) then begin ;Horizontal bars |
---|
| 182 | if (!x.range[0] eq 0) and (!x.range[1] eq 0) $ ;Determine range for X-axis |
---|
| 183 | then xrange=range $ |
---|
| 184 | else xrange=!x.range ;Or, use range specified |
---|
| 185 | if (!y.range[0] eq 0) and (!y.range[1] eq 0) $ ;Plot will calculate |
---|
| 186 | then $ ; defaults for X, but not |
---|
| 187 | yrange = [0, n_elements(values)] $ ; for Ys, so fill in here. |
---|
| 188 | else $ |
---|
| 189 | yrange=!y.range ;Axis perpend. to bars |
---|
| 190 | yticks=1 ;Suppress ticks in plot |
---|
| 191 | ytickname=strarr(2)+' ' |
---|
| 192 | xticks=0 |
---|
| 193 | xtickname=strarr(1)+'' |
---|
| 194 | endif else begin ;Vertical bars |
---|
| 195 | if (!y.range[0] eq 0) and (!y.range[1] eq 0) $ ;Determine range for Y-axis |
---|
| 196 | then yrange=range $ |
---|
| 197 | else yrange=!y.range ;Or, use range specified |
---|
| 198 | xrange=!x.range ;Axis perpend. to bars |
---|
| 199 | xticks=1 ;Suppress ticks in plot |
---|
| 200 | xtickname=strarr(2)+' ' |
---|
| 201 | yticks=0 |
---|
| 202 | ytickname=strarr(1)+'' |
---|
| 203 | endelse |
---|
| 204 | if (overplot eq 0) then $ ;Create new plot, no data |
---|
| 205 | plot,[values],/nodata,title=title,xtitle=xtitle,ytitle=ytitle, $ |
---|
| 206 | noerase=overplot,xrange=xrange,yrange=yrange,xticks=xticks, $ |
---|
| 207 | xtickname=xtickname,yticks=yticks,ytickname=ytickname, $ |
---|
| 208 | xstyle=1,ystyle=1,/data,background=background, _EXTRA = ex |
---|
| 209 | if (rotate) then begin ;Horizontal bars |
---|
| 210 | base_win=!y.window ;Window range in Y |
---|
| 211 | scal_fact=!x.s ;Scaling factors |
---|
| 212 | tick_scal_fact=!y.s ;Tick scaling factors |
---|
| 213 | endif else begin ;Vertical bars |
---|
| 214 | base_win=!x.window ;Window range in X |
---|
| 215 | scal_fact=!y.s ;Scaling factors |
---|
| 216 | tick_scal_fact=!x.s ;Tick scaling factors |
---|
| 217 | endelse |
---|
| 218 | winrange=baserange*(base_win[1]-base_win[0]) ;Normal. window range |
---|
| 219 | barsize=barwidth*winrange/nbars ;Normal. bar width |
---|
| 220 | winoffset=base_win[0]+(baroffset*barsize) ;Normal. first offset |
---|
| 221 | bases=scal_fact[0]+(scal_fact[1]*baselines) ;Baselines, in normal coor. |
---|
| 222 | normal=scal_fact[0]+(scal_fact[1]*values) ;Values, in normal coor. |
---|
| 223 | barstart=indgen(nbars)*(barsize+barspace*(winrange/nbars)) ;Coor. at left edges |
---|
| 224 | tickv=winoffset+barstart+(0.5*barsize) ;Tick coor. (centered) |
---|
| 225 | for i=0,nbars-1 do begin ;Draw the bars |
---|
| 226 | width=winoffset+[barstart[i],barstart[i], $ ;Compute bar width |
---|
| 227 | (barstart[i]+barsize),(barstart[i]+barsize)] |
---|
| 228 | length=[bases[i],normal[i],normal[i],bases[i]] ;Compute bar length |
---|
| 229 | if (rotate) then begin ;Horizontal bars |
---|
| 230 | x=length ;X-axis is "length" axis |
---|
| 231 | y=width ;Y-axis is "width" axis |
---|
| 232 | endif else begin ;Vertical bars |
---|
| 233 | x=width ;X-axis is "width" axis |
---|
| 234 | y=length ;Y-axis is "length" axis |
---|
| 235 | endelse |
---|
| 236 | polyfill,x,y,color=colors[i],/normal ;Polyfill with color |
---|
| 237 | if (outline) then plots,x,y,/normal ;Outline using !p.color |
---|
| 238 | endfor |
---|
| 239 | |
---|
| 240 | tickv=(tickv-tick_scal_fact[0])/tick_scal_fact[1] ;Locations of the ticks |
---|
| 241 | if (rotate) then $ ;Label the bars (Y-axis) |
---|
| 242 | axis,yaxis=0,ystyle=1,yticks=(nbars-1),ytickv=tickv,ytickname=barnames, $ |
---|
| 243 | yticklen=0.0 $ |
---|
| 244 | else $ ;Label the bars (X-axis) |
---|
| 245 | axis,xaxis=0,xstyle=1,xticks=(nbars-1),xtickv=tickv,xtickname=barnames, $ |
---|
| 246 | xticklen=0.0 |
---|
| 247 | return |
---|
| 248 | end |
---|