.- help for ^hidlin^ and ^altitude^ (STB-45: gr30) .- 3D-routines ----------- These graphing routines provide two different representations of a 3D-surface defined by a function ^func^ of the form z=f(x,y) declared in a separate ado file (see example below). The name of this file is ^hlfunc.ado^, where func is any name of your choosing (max 6 characters). The naming convention is the same as for Stata's ^nl^ (nonlinear estimation). The two programs share most of their information and store in the same macros and matrices, whose names all are prefixed by ^hl^. These are kept after the graph completes, thus permitting a replay any time later in the same Stata session. User data are cleared. Both ^hidlin^ and ^altitude^ can only represent a function, not data. However, the auxiliary program @makfun@.ado may be used to "make" a function summarizing real data, with which either graphing routine can then produce its 3D representation. ^hidlin^ shows 3D-surfaces with hidden-line removal ------------------------------------------------- ^hidlin^ func [ ^,^ ^x^info^(^ # [^,^] # [^,^] # ^)^ ^y^info^(^ # [^,^] # [^,^] # ^)^ ^n^eg ^xm^argin^(^ # ^)^ ^ym^argin^(^ # ^)^ ^t^ext ^tm^ag^(^ # ^)^ ^sav^ing^(^ filename ^)^ ^e^ye^(^ # [^,^] # [^,^] # ^)^ ^l^ines^(^[x][y]^)^ ^b^ox ^c^oo ] The function is calculated on the grid defined by ^xinfo^(xlow xhigh xstep), ^yinfo^(ylow yhigh ystep) and viewed from a position declared by ^eye^(xpos ypos zpos); this is not a perspective view. Grid and eye position are required. The object is presented such that the lowest 2D-corner (projection) is "in front". ^altitude^ shows pseudo-contour lines of 3D-surfaces -------------------------------------------------- ^altitude^ func [^,^ ^x^info^(^ # [^,^] # [^,^] # ^)^ ^y^info^(^ # [^,^] # [^,^] # ^)^ ^n^eg ^xm^argin^(^ # ^)^ ^ym^argin^(^ # ^)^ ^t^ext ^tm^ag^(^ # ^)^ ^sav^ing^(^ filename ^)^ ^nq^uant^(^ # ^)^ ^s^ymb^(^ # ^)^ ] The function is calculated on the grid defined by ^xinfo^(xlow xhigh xstep), ^yinfo^(ylow yhigh ystep), which are required. The computed z-value (altitude) is then devided into ^nquant^ quantiles, which are displayed on the grid using symbol ^symb^. The successive quantile levels are represented with different colors and increasing sizes of the symbol, so that the appearance truly yields contour effects. The legend relative to quantile colors and sizes is shown in the right margin. Options ------- 1. Common options ----------------- ^xinfo^ and ^yinfo^ must be known. They define x (range and step) and y (range and step) of the grid over which the function is evaluated. All specified values may be separated by commas and they may be expressions, e.g. x( -_pi, _pi _pi/90 ) going from -pi to pi in 180 steps. ^neg^ requests that -z be plotted rather than z (upside-down view) ^xmargin^ and ^ymargin^ specify the sizes of the margins around the plot. They are expressed as a percentage of the graphing area. Default margins are 10 for both x and y (i.e. 10%). ^text^ requests that stored texts be displayed This option invokes the auxiliary program @hltex@.ado ^tmag^ asks for a text magnification, the default being 100. This magnification applies only to texts added by hltex. ^saving^ stores the graph in which must be a new file. 2. Specific ^hidlin^ options -------------------------- ^eye^ must be known. it defines the eye (x- y- z- directions), i.e. the position from where the surface is viewed. ^lines^ requests that only x-curves be drawn when x is specified, or only y-curves when y is specified. More precisely, lines(x) asks to see the curves z=f(x,y0), where x varies at each succesive level y0 of y. Similarly, lines(y) requests the curves z=f(x0,y) where y varies at succesive levels of x. When ^lines^ is omitted or when both x and y are specified, the default is to draw both sets of curves. ^box^ asks that the surface be represented as a chunk of a solid 3D object ^coo^ asks that the coordinates of the "corners" of the surface be displayed 3. Specific ^altitude^ options ---------------------------- ^nquant^ declares the desired number quantiles (max 20) The default is set to 16 because 8 pens are used (i.e. 8 colors), thus providing two full pencolor-cycles. ^symb^ specifies the choice of graphing symbol numbered as for @gph@. 0= dot 1= large circle 4= small circle 2= square 5= diamond (not translucid) 3= triangle 6= plus the default is 4 The lowest quantile is always represented by a dot so you always know where the surface is at its minimum Example of a ^func^ declaration ----------------------------- Below is a program defining the bivariate normal (bivnor) density surface It generates the data, not the graph syntax: hlbivnor x y z [in #/#] (x,y any two existing variables, z created/replaced as necessary) Remarks: - lines preceding the actual declaration appear in any hlfunc z=f(x,y) (no checking but program is for use only and speed is important) - any parameter you wish to easily access should be declared in a global macro in the present function the correlation rho between x & y is needed and the program assumes independence (rho=0) if $rho is empty - MUST have parens in line marked !!! ( for instance, 1- -.8^^2 would be 1.64) *---------------- prog def hlbivnor *---------------- loc x `1' loc y `2' loc z `3' cap confirm var `z' if _rc {qui gen `z'=.} mac shift 3 loc in "opt" parse "`*'" *--- actual start of function declaration --- if "$rho"=="" { glo rho 0 } loc r = 1 - ($rho)^^2 /* !!! need parentheses */ loc c = 2 * _pi * sqrt(`r') #delimit ; qui replace `z'= exp( -(`x'^^2 -2*$rho*`x'*`y'+`y'^^2) / (2*`r') )/ `c' `in' ; #delimit cr end *------- The hidden-line-representation may be obtained, for instance, by . ^glob rho .9^ . ^hidlin bivnor, x(-3 3 .2) y(-3 3 .3) e(2 -3 .1) b c^ You need to explore to find a "nice" place to sit, that is ^e(^# # #^)^, after which you can modify stepsizes to your liking. Warning: When the stepsizes are very small, in other words if the number of grid-points becomes huge, say 500 by 500 (which is visually much too dense anyway and is the maximum allowed), graphing will become annoyingly slow if your function is very wavy or bumpy. It is better to start with large steps until a satisfactory viewpoint has been found. A 30 by 20 grid as in the example above is very fast and generally yields satisfactory insight on the studied surface. Similarly, the altitude-representation may be obtained for example by ^altitude bivnor, x(-3 3 .06) y(-3 3 .12) s(5)^ Usually, satisfactory stepsizes are 100 steps along x and 50 steps along y, which, with the ranges of the example above, might have been written x(-3 3 6/100) y(-3 .3 6/50) since expressions are permitted. Details ------- All information regarding the call to ^hidlin^ or ^altitude^ is stored in globals and matrices, allowing a replay later in in the same session. Either command submitted with no arguments reproduces exactly the same graph. However, if some options are specified (e.g. ^hidlin, b^ or ^altitude , s(5)^, note that the function name may be omitted for it too is hlsomething), then indicators such as box, coo, neg, tex are reset before the new options are parsed, so that the graph only shows the newly requested ones. Remark: Stata's ^clear^ does erase matrices but not the globals. Therefore, residual memory usage is negligeable after a clear. Matrices are recomputed from scratch on each call to hidlin or altitude. If you want to remove all these macros and matrices later in the session without having to ^clear^ you can type either ^hidlin clean^ or ^altitude clean^. Details on the geometry for ^hidlin^ ---------------------------------- In order to keep the number of drawing points reasonably low it is required that the ratio of the x and y components of the eye position be the same as the ratio of xstep to ystep. Thus it is required that: xstep / ystep = xeye / yeye (ignoring signs). However, If the information provided by the user does not satisfy that condition the program adapts the x- and y-step to meet the requirement, so that the user actually does not have to worry with this limitation. The reason for implementing such constraint is that all 2D-projected points now have fixed horizontal-axis coordinates (i.e. all points on the screen align on verticals). As a consequence, the next point to be drawn is easily identified as visible or invisible according to its position with respect to the current upper and lower edges of the graphed portion. These edges are permenantly updated as new points are computed and, because they have fixed horizontal-coordinates, their storage is very economical. There are indeed Nx + Ny +1 fixed coordinates, where Nx is the number of steps along x (i.e xrange/xstep) and Ny he number of steps along y in 3D. So, even on a 500 x 500 grid, there are only 1001 points to memorize for the lower edge and 1001 for the upper edge! When a curve becomes invisible a partial segment is drawn from the last visible point to the approximate position where it disappears. This position is obtained, via linear interpolation, as the intersection of the previous visible edge and the segment joining te last point to the next (invisible) one. Naturally, a similar interpolation is performed when the curve goes from invisible to visible. Known bugs with ^hidlin^ ---------------------- Of course, when the surface is very bumpy or very steep and the steps are too large, then the interpolation may become esthetically unsatisfactory. Futhermore, and along the same lines, if the last drawn point was visible and the next one to be drawn is also visible, it is assumed that the entire segment is visible, which is not always true. In particular, when the function is very steep a very small stepsize will be needed to avoid this "error", but when the function actually is vertical there is no remedy. For each line to be drawn the program is set up to use the fast function whenever possible, i.e. for visible portions of the line. However, when a line becomes invisible the program goes step by step until either the end of the line or a visible portion is encountered. It is well known that such stepping is slow in Stata and ^hidlin^ may possibly be improved there. Author ------ Guy D. van Melle University of Lausanne, Switzerland guy.van-melle@@inst.hospvd.ch Also see -------- STB: gr30 (STB-45), gr20 (STB-34) manual: [R] gph on-line: ^help^ for @gph@