Viewing contents of file '../idllib/contrib/markwardt/plotcolorfill.pro'
;+
; NAME:
; PLOTCOLORFILL
;
; AUTHOR:
; Craig B. Markwardt, NASA/GSFC Code 662, Greenbelt, MD 20770
; craigm@lheamail.gsfc.nasa.gov
;
; PURPOSE:
; Plots colorful bar charts
;
; CALLING SEQUENCE:
; PLOTCOLORFILL, x, y, COLOR=col, BOTTOM=bot, WIDTH=wid, ...
;
; DESCRIPTION:
;
; PLOTCOLORFILL plots a colorful vertical bar chart. This may be
; useful in cases where two dimensions of information need to be
; conveyed in one plot. [ I use it to show total intensity as a
; function of time on the vertical axis, and temperature is coded
; with color. ]
;
; Most aspects of the bars are configurable. The color is specified
; by an array of colors, one for each bar. [ Alternatively, a
; single color for the entire plot can be given. ] Also, one color
; can be designated as transparent.
;
; Stacked bar charts can be constructed using two calls to
; PLOTCOLORFILL. See the example.
;
; INPUTS:
;
; X, Y - Two arrays which give the X and Y position of the points.
; In this style of plot, the x values should be monotonically
; increasing, but not necessarily monospaced (see WIDTH).
;
; OPTIONAL INPUTS:
; NONE
;
; INPUT KEYWORD PARAMETERS:
;
; COLOR - an array giving the color of each bar, or alternatively a
; scalar color for all of the bars. The current color table
; is not changed. Default is color "1"
;
; BOTTOM - normally the bottom of the bars is set to be zero. You
; may either specify a scalar bottom value for all of the
; bars, or an array giving the bottom of each bar
; individually. See the example to see how stacked bar
; charts can be constructed with this keyword.
;
; WIDTH - sets the width of each bar, globally or individually.
; Bars are centered on the "X" value, and extend 0.5 * WIDTH
; to either side. Default is to assume monospacing, using
; the separation between the first two x values.
;
; TRANSPARENT - designates a color which is "transparent". Any bars
; with this color are simply not plotted. Default is
; no transparent color.
;
; PANEL, SUBPANEL - An alternate way to more precisely specify the
; plot and annotation positions. See SUBCELL.
; Default is full-screen.
;
; POSITION - Position of the bar chart in normal coordinates.
; Overrides position given by PANEL/SUBPANEL.
;
; XRANGE, YRANGE - gives plot range for each dimension, as for other
; plot commands. Default is range of data.
;
; Other keywords are passed to the plot command directly.
;
; OUTPUTS:
; NONE
;
; PROCEDURE:
;
; EXAMPLE:
;
; Stacked barcharts can be constructed by first making one chart
; with a flat bottom, and then a second chart whose bottom is top of
; the first.
;
; x = findgen(30)
; y1 = x^2
; y2 = 400.-x
; c1 = bindgen(30)*3+1b
; c2 = 100b-bindgen(30)*3+1b
; plotcolorfill, x, y1, color=c1, bottom=0.
; plotcolorfill, x, y1+y2, color=c2, bottom=y1, /noerase
;
; SEE ALSO:
;
; PLOTPAN
;
; EXTERNAL SUBROUTINES:
;
; SUBCELL, DEFSUBCELL, PLOTPAN
;
; MODIFICATION HISTORY:
; Written, CM, 1997
;
;-
forward_function defsubcell, subcell
function defsubcell, default
if n_elements(default) EQ 0 then default = [-1.,-1,-1,-1]
mysubcell = default
defaultsubpos = [ 0.08, 0.08, 0.95, 0.95 ]
iwh = where(mysubcell LT 0, ict)
if ict GT 0 then $
mysubcell(iwh) = defaultsubpos(iwh)
return, mysubcell
end
function subcell, subpos, position, margin=margin
;; Default value for subposition
if n_elements(subpos) EQ 0 then mysubpos = [-1.,-1,-1,-1] $
else mysubpos = subpos
;; Default value for position - full screen
if n_elements(position) EQ 0 then position = [0.,0.,1.,1.]
;; Get margins if necessary
if keyword_set(margin) EQ 1 OR n_elements(subpos) EQ 0 then $
mysubpos = defsubcell(mysubpos)
;; Compute new window position
x0 = position(0)
y0 = position(1)
dx = position(2)-position(0)
dy = position(3)-position(1)
newsubpos = reform(mysubpos * 0, 4)
newsubpos([0,2]) = x0 + dx * mysubpos([0,2])
newsubpos([1,3]) = y0 + dy * mysubpos([1,3])
return, newsubpos
end
pro plotpan, x, y, $
subpanel=subpanel, panel=panel, $
_EXTRA=extra
;; Default is full-screen
if n_elements(panel) EQ 0 AND n_elements(subpanel) EQ 0 then begin
plot, x, y, /normal, _EXTRA=extra
endif else begin
if n_elements(panel) EQ 0 then panel=[0.0,0.0,1.0,1.0]
plot, x, y, /normal, position=subcell(subpanel, panel, /marg), $
_EXTRA=extra
endelse
return
end
pro plotcolorfill, x, y, color=col, bottom=bot, width=width, $
transparent=transparent, $
subpanel=subpanel, panel=panel, $
xrange=xrange, yrange=yrange, $
position=position, xstyle=xstyle, ystyle=ystyle, $
noerase=noerase, $
_EXTRA=extra
if n_elements(xrange) EQ 0 then xrange = [min(x), max(x)]
if n_elements(yrange) EQ 0 then yrange = [min(y), max(y)]
;; Set default values
if n_elements(bot) EQ 0 then bot = y * 0. + yrange(0)
if n_elements(bot) EQ 1 then bot = y * 0. + bot
if n_elements(col) EQ 0 then col = byte(y)*0b+1b
if n_elements(col) EQ 1 then col = byte(y)*0b+col
if n_elements(width) EQ 0 then width = float(x)*0 + (x(1)-x(0))
if n_elements(width) EQ 1 then width = float(x)*0 + width
if n_elements(xstyle) EQ 0 then xstyle = 0
if n_elements(ystyle) EQ 0 then ystyle = 0
if n_elements(transparent) EQ 0 then transparent = -1L
;; Plot coordinate grid first
if NOT keyword_set(noerase) then begin
if n_elements(panel) EQ 0 AND n_elements(subpanel) EQ 0 then begin
if n_elements(position) GT 0 then $
extra = create_struct(extra, 'POSITION', position)
plot, xrange, yrange, /nodata, xstyle=xstyle, ystyle=ystyle,_EXTRA=extra
endif else begin
;; Set panel size
if n_elements(panel) EQ 0 then panel=[0.0,0.0,1.0,1.0]
if n_elements(subpanel) EQ 0 then subpanel = [-1., -1., -1., -1. ]
subpanel = defsubcell(subpanel)
plotpan, xrange, yrange, /nodata, panel=panel, subpanel=subpanel, $
xstyle=xstyle, ystyle=ystyle, _EXTRA=extra
endelse
endif
;; Compute binsize
numx = n_elements(x)
if n_elements(y) LT numx then numx = n_elements(y)
;; Loop through and draw filled rectangles
for i = 0, numx-2 do begin
binsz = width(i)/2.
;; The vertical size is given by "bot" and "y"
if x(i) GE xrange(0) AND x(i+1) LE xrange(1) $
AND long(col(i)) NE transparent then begin
polyfill, $
[x(i)-binsz, x(i)+binsz, x(i)+binsz, x(i)-binsz], $
[bot(i), bot(i), y(i), y(i)] , $
color=col(i), /data, noclip=0
endif
endfor
;; Overlay the coordinate grid again in case it got partially wiped.
if NOT keyword_set(noerase) then begin
axis, xaxis=0, xtickformat='(A1)', xrange=xrange, xstyle=xstyle
axis, xaxis=1, xtickformat='(A1)', xrange=xrange, xstyle=xstyle
axis, yaxis=0, ytickformat='(A1)', yrange=yrange, ystyle=ystyle
axis, yaxis=1, ytickformat='(A1)', yrange=yrange, ystyle=ystyle
endif
;; Finally, overlay the trace at the top of the curve.
numx = numx
xtop = fltarr(2, numx)
ytop = fltarr(2, numx)
numx = numx - 1
xtop(0, *) = [ x(0:numx)-width(0:numx)/2. ]
xtop(1, *) = [ x(0:numx)+width(0:numx)/2. ]
ytop(0, *) = y(0:numx)
ytop(1, *) = y(0:numx)
;; Plot the data trace at the top
oplot, xtop, ytop
return
end