*! 1.2.4 NJC 27 January 2004 *! 1.2.3 NJC 28 June 2000 * 1.2.2 NJC 24 November 1999 * 1.2.1 NJC 28 March 1999 * 1.1.0 NJC 6 May 1998 program def triplot6 version 6.0 #delimit ; syntax varlist(min=3 max=3) [if] [in] [, Max(real 1) LAbel(numlist miss) Vertices(real 1) Y SAving(str) Symbol(str) PTSize(int 275) PEn(str) FONTR(int 570) FONTC(int 290) Connect(str) Group(varname) AHL(int 300) LText(str) RText(str) BText(str) BLText(str) BRText(str) TText(str) TItle(str) T1title(str) Key(varname) KEYCol(int 24000) KEYRow(int 4000) KEYText(varname) ] ; #delimit cr if "`connect'" != "" { if "`connect'" != "l" & "`connect'" != "a" { di in r "invalid connect( ) option" exit 198 } } marksample touse qui count if `touse' local nuse = r(N) if `nuse' == 0 { di in r "no observations" exit 2000 } tokenize `varlist' args a b c loc i 1 while `i' <= 3 { capture assert ``i'' >= 0 & ``i'' <= `max' if `touse' if _rc { di in r "``i'' has values outside [0, `max']" exit 198 } loc i = `i' + 1 } if "`symbol'" != "" { tokenize "`symbol'", parse("[] ") local i = 1 while "`1'" != "" { if "`1'" == "[" { mac shift local sy`i' "`1'" if "`1'" != "_n" { capture confirm variable `1' if _rc { di in r "symbol( ) invalid: `1' not variable" exit 198 } * avoid confusion between variables named * i and invisible point symbol local varsy`i' `1' local sy`i' "var" } local st`i' 1 local i = `i' + 1 mac shift 2 } else if "`1'" == "]" { di in r "symbol( ) invalid" exit 198 } else { local l = length("`1'") local j = 1 while `j' <= `l' { local sy`i' = substr("`1'",`j',1) Gphtrans `sy`i'' local sy`i' "$S_1" local st`i' 0 local i = `i' + 1 local j = `j' + 1 } mac shift } } local nsy = `i' - 1 } else { local sy1 "4" local nsy = 1 local st1 = 0 } if `max' <= 0 { di in r "maximum must be positive" exit 198 } if "`key'" != "" { local keylab : value label `key' local keyvar 1 } else local keyvar 0 if "`group'" == "" { tempvar group gen byte `group' = 1 } tempvar order Key first left right bot qui { gen long `order' = _n sort `touse' `key' `group' `order' by `touse' `key' : gen byte `Key' = _n == 1 if `touse' gen byte `first' = `Key' replace `Key' = sum(`Key') loc nkey = `Key'[_N] sort `touse' `group' `key' `order' } if `nkey' > `nsy' { if `nsy' == 1 { local i = 2 while `i' <= `nkey' { local st`i' = `st1' local sy`i' "`sy1'" local i = `i' + 1 } } else { di in r "insufficient symbols specified" exit 198 } } if "`pen'" == "" { loc pen "2" } loc len = length("`pen'") if `nkey' > `len' { if `len' == 1 { loc pen : di _dup(`nkey') "`pen'" } else { di in r "insufficient pens specified" exit 198 } } qui { gen `left' = `a' gen `right' = `b' if `max' != 1 { replace `left' = `left' / `max' replace `right' = `right' / `max' } } loc htfact = sqrt(3)/2 /* sin _pi/3 = 60 deg */ loc xL 6000 /* triangle coordinates */ loc xR 26000 loc xT = (`xL' + `xR') / 2 loc width = `xR' - `xL' loc height = `width' * `htfact' loc yT 2000 loc yB = `yT' + `height' loc yM = `yT' + `height' / 2 /* position of var text */ loc xltext = `xT' - 0.35 * `width' loc xrtext = `xT' + 0.35 * `width' - 100 loc ybtext = `yB' + 1800 loc yt1 = `yT' - 1200 /* position of titles */ loc ytitle = `yB' + 2800 local yBtext = `yB' + 800 local yTtext = `yT' - 300 loc yblab = `yB' + 800 /* position of labels */ loc xllab = `xL' - 200 loc xrlab = `xT' - 100 loc xkeysy `keycol' /* key position */ loc xkeysy2 = `keycol' - 200 loc xkeytxt = `xkeysy' + 500 loc ykey `keyrow' loc ykeytxt = `ykey' + 200 loc ykeyst = 1000 + (`ptsize' - 200) * (`ptsize' > 275) loc dotsp 150 /* spacing between dots */ if `"`saving'"' != "" { loc saving `", saving(`saving')"' } gph open `saving' if `vertices' == 1 { gph line `yB' `xL' `yT' `xT' gph line `yT' `xT' `yB' `xR' gph line `yB' `xR' `yB' `xL' } else { local v = `vertices' / 2 local yV = `yT' + (1 - `v') * (`yB' - `yT') local xV = `xL' + `v' * `width' / 2 gph line `yB' `xL' `yV' `xV' local xV = `xL' + `v' * `width' gph line `yB' `xL' `yB' `xV' local xV = `xL' + (1 - `v') * `width' gph line `yB' `xR' `yB' `xV' local xV = `xR' - `v' * `width' / 2 gph line `yB' `xR' `yV' `xV' local xV = `xL' + (1 - `v') * `width' / 2 local yV = `yT' + `v' * (`yB' - `yT') gph line `yT' `xT' `yV' `xV' local xV = `xR' - (1 - `v') * `width' / 2 gph line `yT' `xT' `yV' `xV' } if "`y'" == "y" { local xY1 = (`xL' + `xR') / 2 local yY1 = `yB' - (`yB' - `yT') / 3 local ndots = 1 + (`yB' - `yY1') / `dotsp' loc idot 1 loc ydot `yB' while `idot' <= `ndots' { gph point `ydot' `xY1' `ptsize' 0 loc ydot = `ydot' - `dotsp' loc idot = `idot' + 1 } local xY2 = (`xL' + `xT') / 2 local yY2 = (`yB' + `yT') / 2 local dist = sqrt((`xY2' - `xY1')^2 + (`yY2' - `yY1')^2) local ndots = 1 + `dist' / `dotsp' local idot 1 local ydot `yY1' local xdot `xY1' while `idot' <= `ndots' { gph point `ydot' `xdot' `ptsize' 0 local ydot = `ydot' - `dotsp' / 2 local xdot = `xdot' - `dotsp' * `htfact' local idot = `idot' + 1 } local idot 1 local ydot `yY1' local xdot `xY1' while `idot' <= `ndots' { gph point `ydot' `xdot' `ptsize' 0 local ydot = `ydot' - `dotsp' / 2 local xdot = `xdot' + `dotsp' * `htfact' local idot = `idot' + 1 } } if "`ltext'" != " " { if "`ltext'" == "" { loc ltext : variable label `a' if "`ltext'" == "" { loc ltext "`a'" } } gph text `yM' `xltext' 0 1 `ltext' } if "`rtext'" != " " { if "`rtext'" == "" { loc rtext : variable label `b' if "`rtext'" == "" { loc rtext "`b'" } } gph text `yM' `xrtext' 0 -1 `rtext' } if "`btext'" != " " { if "`btext'" == "" { loc btext : variable label `c' if "`btext'" == "" { loc btext "`c'" } } gph text `ybtext' `xT' 0 0 `btext' } if trim("`ttext'") != "" { gph text `yTtext' `xT' 0 0 `ttext' } if trim("`bltext'") != "" { gph text `yBtext' `xL' 0 0 `bltext' } if trim("`brtext'") != "" { gph text `yBtext' `xR' 0 0 `brtext' } if "`title'" != "" { gph text `ytitle' `xT' 0 0 `title' } if "`t1title'" != "" { gph text `yt1' `xT' 0 0 `t1title' } if "`label'" == "" { if `max' == 100 { loc label "0 20 40 60 80 100" } else loc label "0 .2 .4 .6 .8 1" } numlist "`label'", miss tokenize `r(numlist)' if "`1'" != "." { while "`1'" != "" { loc text "`1'" loc 1 = `1' / `max' loc x = `xllab' + (`width' / 2) * `1' loc y = `yT' + `height' * (1 - `1') gph text `y' `x' 0 1 `text' if `1' != 0 & `1' != 1 { loc xdot = `xL' + (`width' / 2) * `1' loc xdot2 = `xT' + (`width' / 2) * (1 - `1') loc ndots = 1 + (`xdot2' - `xdot') / `dotsp' loc idot 1 loc ydot `y' while `idot' <= `ndots' { gph point `ydot' `xdot' `ptsize' 0 loc xdot = `xdot' + `dotsp' loc idot = `idot' + 1 } } loc x = `xrlab' + (`width' / 2) * `1' loc y = `yT' + `height' * `1' gph text `y' `x' 0 -1 `text' if `1' != 0 & `1' != 1 { loc xdot = `xT' + (`width' / 2) * `1' loc xdot2 = `xL' + `width' * `1' loc dist = sqrt((`xdot2' - `xdot')^2 + (`y' - `yB')^2) loc ndots = 1 + `dist' / `dotsp' loc idot 1 loc ydot `y' while `idot' <= `ndots' { gph point `ydot' `xdot' `ptsize' 0 loc xdot = `xdot' - `dotsp' / 2 loc ydot = `ydot' + `dotsp' * `htfact' loc idot = `idot' + 1 } } loc x = `xR' - `width' * `1' gph text `yblab' `x' 0 0 `text' if `1' != 0 & `1' != 1 { loc xdot = `xR' - `width' * `1' loc xdot2 = `xL' + (`width' / 2) * (1 - `1') loc ydot2 = `yT' + `height' * `1' loc dist = /* */ sqrt((`xdot2' - `xdot')^2 + (`ydot2' - `yB')^2) loc ndots = 1 + `dist' / `dotsp' loc idot 1 loc ydot `yB' while `idot' <= `ndots' { gph point `ydot' `xdot' `ptsize' 0 loc xdot = `xdot' - `dotsp' / 2 loc ydot = `ydot' - `dotsp' * `htfact' loc idot = `idot' + 1 } } mac shift } } loc i = _N - `nuse' + 1 local cg = "`connect'" != "" while `i' <= _N { local k = `Key'[`i'] loc x = `xL' + `width' * (`right'[`i'] + `left'[`i'] / 2) loc y = `yT' + `height' * (1 - `left'[`i']) loc pe = substr("`pen'", `k', 1) gph pen `pe' gph font `fontr' `fontc' if "`sy`k''" != "i" { if `st`k'' { if "`sy`k''" == "_n" { local text = `i' } else local text = `varsy`k''[`i'] gph text `y' `x' 0 0 `text' } else gph point `y' `x' `ptsize' `sy`k'' } if `cg' & ("`prevy'" != "") & (`group'[`i'] == `group'[`i'-1]) { gph line `y' `x' `prevy' `prevx' if "`connect'" == "a" { local sine = `x' - `prevx' local cosine = `prevy' - `y' Atan2 `sine' `cosine' local angle = $S_1 * arrow heads `ahl' long * angle between heads = _pi/3 = 60 deg local ah1y = `y' - `ahl' * cos(`angle' + 5 * _pi / 6) local ah1x = `x' + `ahl' * sin(`angle' + 5 * _pi / 6) local ah2y = `y' - `ahl' * cos(`angle' + 7 * _pi / 6) local ah2x = `x' + `ahl' * sin(`angle' + 7 * _pi / 6) gph line `ah1y' `ah1x' `y' `x' gph line `ah2y' `ah2x' `y' `x' } } if `keyvar' & `first'[`i'] == 1 & `nkey' > 1 & `nkey' < 13 { gph pen `pe' if "`sy`k''" != "i" { if `st`k'' { if "`sy`k''" == "_n" { gph text `ykeytxt' `xkeysy2' 0 1 `text' } else gph text `ykeytxt' `xkeysy2' 0 -1 `text' } else { gph point `ykey' `xkeysy' `ptsize' `sy`k'' } gph pen 1 if "`keytext'" != "" { loc keyval = `keytext'[`i'] } else { loc keyval = `key'[`i'] if "`keylab'" != "" { loc keyval : label `keylab' `keyval' } } gph text `ykeytxt' `xkeytxt' 0 -1 `keyval' loc ykey = `ykey' + `ykeyst' loc ykeytxt = `ykeytxt' + `ykeyst' } } local prevy `y' local prevx `x' loc i = `i' + 1 } gph close end program def Gphtrans /* transliterate ".OSTodp" -> "0123456" */ * 1.0.0 NJC 31 March 1998 loc argin `1' loc length = length("`argin'") loc i 1 while `i' <= `length' { loc `i' = substr("`argin'", `i', 1) if "``i''" == "." { loc `i' 0 } else if "``i''" == "O" { loc `i' 1 } else if "``i''" == "S" { loc `i' 2 } else if "``i''" == "T" { loc `i' 3 } else if "``i''" == "o" { loc `i' 4 } else if "``i''" == "d" { loc `i' 5 } else if "``i''" == "p" { loc `i' 6 } loc argout "`argout'``i''" loc i = `i' + 1 } global S_1 `argout' end program define Atan2 * 1.2.1 NJC 25 March 1999 version 6.0 tempname at local sign1 = sign(`1') local sign2 = sign(`2') if (`sign1' == 1 & `sign2' == 1) | ((`sign1' == 0) & `sign2' == 1) { scalar `at' = atan(`1'/`2') } else if `sign1' == 1 & `sign2' == 0 { scalar `at' = _pi / 2 } else if `sign1' == -1 & `sign2' == 0 { scalar `at' = 3 * _pi / 2 } else if `sign2' == -1 { scalar `at' = _pi + atan(`1'/`2') } else if `sign1' == -1 & `sign2' == 1 { scalar `at' = 2 * _pi + atan(`1'/`2') } global S_1 = `at' end