Viewing contents of file '../idllib/contrib/markwardt/plotcube.pro'
;+
; NAME:
; PLOTCUBE
;
; AUTHOR:
; Craig B. Markwardt, NASA/GSFC Code 662, Greenbelt, MD 20770
; craigm@lheamail.gsfc.nasa.gov
;
; PURPOSE:
; Plots a three dimensional data that can be printed and made into a cube
;
; CALLING SEQUENCE:
; PLOTCUBE, x, y, z
;
; DESCRIPTION:
;
; PLOTCUBE plots a three dimensional data set so that it can be
; printed on paper, cut out, and folded together to make a real-life
; three dimensional cube. This may be useful in visualization
; applications. The six faces of the cube contain a projection of
; the data onto that face.
;
; The output consists of a flat matrix of six plots, which are
; joined together at the proper edges of the cube. Your task,
; should you choose to accept it, is to cut out the cube and
; assemble it.
;
; Before folding the cube together, it will look like the diagram
; below. You need to match together edges labelled with the same
; letter.
;
; A
; +----+
; B| |G
; B | | G
; +----+----+----+
; | | | |
; C| | | |E
; +----+----+----+
; D | | F
; D| |F
; +----+
; | |
; C| |E
; +----+
; A
;
; HINT 1: When printing, be sure that the XSIZE and YSIZE are given
; in the ratio of 3 to 4. A size of 6 in by 8 in is
; suitable.
;
; HINT 2: As a practical matter for assembling the cube once it has
; been printed, you should leave some extra paper tabs so
; that adhesive can be applied.
;
; INPUTS:
;
; X, Y, Z - Three arrays which specify position in three dimensional
; space. All three arrays should be of the same length.
;
; OPTIONAL INPUTS:
; NONE
;
; INPUT KEYWORD PARAMETERS:
;
; PANEL, SUBPANEL - An alternate way to more precisely specify the
; plot and annotation positions. See SUBCELL.
; Default is full-screen.
;
; XRANGE, YRANGE, ZRANGE - gives plot range for each dimension, as
; for other plot commands. Default is
; range of data.
;
; XTITLE, YTITLE, ZTITLE - gives title for each axis. The title
; labels each face of the cube where
; possible.
;
; NOERASE - If set, the display is not erased before graphics
; operations.
;
; Other options are passed along to the PLOT command directly.
;
; OUTPUTS:
; NONE
;
; PROCEDURE:
;
; EXAMPLE:
;
; This example takes some synthetic data and makes a cube out of it.
; Visualizing the trace of the curve is more convenient when it can
; be projected on the cube in each dimension.
;
; t = findgen(200)/20. - 10.
; x = cos(t)
; y = sin(t) + 0.05*t
; z = exp(t) + 0.05*randomn(seed, 200)
; plotcube, x, y, z, xrange=[-1.5,1.5], yrange=[-1.5,1.5], zrange=[-1.5,1.5]
;
; SEE ALSO:
;
; DEFSUBCELL, SUBCELLARRAY
;
; EXTERNAL SUBROUTINES:
;
; SUBCELL, DEFSUBCELL, PLOTPAN
;
; MODIFICATION HISTORY:
; Written, CM, 1997
;
;-
forward_function defsubcell, subcell
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
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 subcellarray, xdivs, ydivs, newpanels, newsubpanels, $
panel=panel, subpanel=subpanel
nx = n_elements(xdivs)
ny = n_elements(ydivs)
xd = double(xdivs)/total(xdivs)
yd = double(ydivs)/total(ydivs)
newpanels = dblarr(nx, ny, 4)
newsubpanels = dblarr(nx, ny, 4) - 1.
if n_elements(panel) EQ 0 then panel = [0.D,0.,1.,1.]
if n_elements(subpanel) EQ 0 then subpanel = [-1.,-1.,-1.,-1.]
subpanel1 = defsubcell(subpanel)
xmarg = subpanel1(0)+(1.-subpanel1(2))
ymarg = subpanel1(1)+(1.-subpanel1(3))
xd = xd * (1. - xmarg)
yd = yd * (1. - ymarg)
xstart = 0.D
for i = 0, nx-1 do begin
xend = xstart + xd(i)
spxstart = 0.
spxend = 1.
if i EQ 0 then xend = xend + subpanel1(0)
if i EQ nx-1 then xend = xend + (1.-subpanel1(2))
if i EQ 0 then spxstart = subpanel1(0)/(xend - xstart)
if i EQ nx-1 then spxend = 1. - (1.-subpanel1(2))/(xend-xstart)
ystart = 0.D
for j = 0, ny-1 do begin
yend = ystart + yd(j)
spystart = 0.
spyend = 1.
if j EQ 0 then yend = yend + subpanel1(1)
if j EQ ny-1 then yend = yend + (1.-subpanel1(3))
if j EQ 0 then spystart = subpanel1(1)/(yend-ystart)
if j EQ ny-1 then spyend = 1. - (1.-subpanel1(3))/(yend-ystart)
newpanels(i,j,*) = subcell([xstart, ystart, xend, yend], panel)
newsubpanels(i,j,*) = [spxstart, spystart, spxend, spyend]
ystart = yend
endfor
xstart = xend
endfor
return
end
pro plotcube, x, y, z, $
xrange=xrange, yrange=yrange, zrange=zrange, $
xtitle=xtitle, ytitle=ytitle, ztitle=ztitle, $
panel=panel, subpanel=subpanel, $
noerase=noerase, $
_EXTRA=extra
;; Default is full-panel
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]
if n_elements(noerase) EQ 0 then noerase=0
if n_elements(xrange) EQ 0 then xrange = [ min(x), max(x) ]
if n_elements(yrange) EQ 0 then yrange = [ min(y), max(y) ]
if n_elements(zrange) EQ 0 then zrange = [ min(z), max(z) ]
if n_elements(xtitle) EQ 0 then xtitle = 'X'
if n_elements(ytitle) EQ 0 then ytitle = 'Y'
if n_elements(ztitle) EQ 0 then ztitle = 'Z'
subcellarray, [1,1,1], [1,1,1,1], newpan, newsub, $
panel=panel, subpanel=subpanel
plotpan, x, z, /xstyle, /ystyle, noerase=noerase, $
xtickformat='(A1)', ytitle=ztitle, $
xrange=xrange, yrange=zrange, $
panel=newpan(1,3,*), subpanel=newsub(1,3,*), _EXTRA=extra
plotpan, z, y, /xstyle, /ystyle, /noerase, $
xtitle=ztitle, ytitle=ytitle, $
xrange=[zrange(1),zrange(0)], yrange=yrange, $
panel=newpan(0,2,*), subpanel=newsub(0,2,*), _EXTRA=extra
plotpan, x, y, /xstyle, /ystyle, /noerase, $
xtickformat='(A1)', ytickformat='(A1)', $
xrange=xrange, yrange=yrange, $
panel=newpan(1,2,*), subpanel=newsub(1,2,*), _EXTRA=extra
plotpan, z, y, /xstyle, /ystyle, /noerase, $
ytickformat='(A1)', xtitle=ztitle, $
xrange=zrange, yrange=yrange, $
panel=newpan(2,2,*), subpanel=newsub(2,2,*), _EXTRA=extra
plotpan, x, z, /xstyle, /ystyle, /noerase, $
xtickformat='(A1)', ytitle=ztitle, $
xrange=xrange, yrange=[zrange(1),zrange(0)], $
panel=newpan(1,1,*), subpanel=newsub(1,1,*), _EXTRA=extra
plotpan, x, y, /xstyle, /ystyle, /noerase, $
xtitle=xtitle, ytitle=ytitle, $
xrange=xrange, yrange=[yrange(1), yrange(0)], $
panel=newpan(1,0,*), subpanel=newsub(1,0,*), _EXTRA=extra
return
end