*! dashgph - program to add dashed lines to scatterplots *! NJGW 1.0.1 12-2-2000 * * 1.0.1 fixes casewise deletion * program define dashgph version 6.0 **************** * Alter not to drop casewise - this messes up multiple-line graphs! **************** qui syntax varlist(min=2 max=21) [if] [in] [aw iw fw], [ Dash(numlist) SPACe(numlist) SAving(string) /* */ Connect(string) PEn(string) /* */ HIstogram Matrix Oneway Box STar BAr Pie /* */ RScale(string) Jitter(integer 0) Rescale XReverse * ] if "`histogr'"!="" | "`matrix'"!="" | "`oneway'"!="" | "`box'"!="" | "`star'"!="" /* */ | "`bar'"!="" | "`pie'"!="" { di in red "dashgph only works for scatterplots" error 198 } if "`jitter'"!="0" { di in red "jitter() option invalid with dashgph" error 198 } if "`xreverse'"!="" { di in red "xreverse option invalid with dashgph" error 198 } if "`rscale'"!="" { di in blue "Warning: dashed line(s) will only be correct if it applies to the" di in blue " variable on the right-hand scale" local rscale "rscale(`rscale')" } if "`rescale'"!="" { di in blue "Warning: dashed line(s) will only be correct if it applies to the" di in blue " variable on the right-hand scale" } if "`if'"!="" { preserve qui keep `if' } if "`in'"!="" { preserve qui keep `in' } if "`weight'"!="" { local weight "[`weight'`exp']" } local ndash : word count `dash' local nspace : word count `space' if `ndash'>1 | `nspace'>1 { local i 1 local n 0 while `i'<=length("`connect'") { local n=`n'+ (substr("`connect'",`i',1)=="D") local i=`i'+1 } if `n'!=`ndash' & `ndash'!=0 & `ndash'!=1 { di in red "Must specify a single dash(), or one per variable" error 198 } if `n'!=`nspace' & `nspace'!=0 & `nspace'!=1 { di in red "Must specify a single space(), or one per variable" error 198 } } if "`dash'"!="" { local dlist "dlist(`dash')" } if "`space'"!="" { local slist "slist(`space')" } if `"`saving'"'!="" { if index(`"`saving'"',"replace")==0 { if index(`"`saving'"',".gph") { confirm new file `"`saving'"' } else { confirm new file `"`saving'.gph"' } } local saving `"saving(`saving')"' } local nvars : word count `varlist' local xvar : word `nvars' of `varlist' if length("`pen'")<`nvars'-1 { local pen="`pen'"+substr("2345678923456789234",length("`pen'")+1,`nvars'-1-length("`pen'")) } local Dpos=index("`connect'","D") while `Dpos'!=0 { if `Dpos'<`nvars' { /* don't deal with extras */ local Dv : word `Dpos' of `varlist' local Dvars "`Dvars' `Dv'" local Dpen="`Dpen'"+substr("`pen'",`Dpos',1) } local connect=substr("`connect'",1,`Dpos'-1)+"."+substr("`connect'",`Dpos'+1,.) local Dpos=index("`connect'","D") } if "`connect'"!="" { local connect "connect(`connect')" } graph `varlist' `weight', `connect' pen(`pen') `options' `rscale' `rescale' if "`Dvars'"!="" { DoDash `Dvars' `xvar' , `dlist' `slist' pen(`Dpen') `saving' } end program define DoDash version 6.0 syntax varlist , pen(string) [ dlist(numlist) slist(numlist) SAving(string) ] if `"`saving'"'!="" { local saving `"saving(`saving')"' } local nvars : word count `varlist' local xvar : word `nvars' of `varlist' sort `xvar' local ndash : word count `dlist' if `ndash'==0 { local dsize 200 local i 1 while `i' < `nvars' { /* skip xvar... */ local dlist "`dlist' `dsize'" local dsize=`dsize'+200 local i=`i'+1 } } else if `ndash'==1 { local dsize "`dlist'" local dlist local i 1 while `i' < `nvars' { local dlist "`dlist' `dsize'" local i=`i'+1 } } if "`slist'"=="" { local slist "100" } local nspace : word count `slist' if `nspace'==1 { local ssize "`slist'" local slist local i 1 while `i' < `nvars' { /* skip xvar... */ local slist "`slist' `ssize'" local i=`i'+1 } } local ay=`r(ay)' local by=`r(by)' local ax=`r(ax)' local bx=`r(bx)' local obs=_N gph open, `saving' graph local j 1 while `j' < `nvars' { local yvar : word `j' of `varlist' local curpen=substr("`pen'",`j',1) gph pen `curpen' local dash : word `j' of `dlist' local space : word `j' of `slist' local i 1 while `i' < `obs' { local next 1 while (`xvar'[`i'+`next']==. | `yvar'[`i'+`next']==.) & (`i'+`next'<=`obs') { local next=`next'+1 } if `xvar'[`i'+`next']!=. { /* deal with missing at end */ local x0=`xvar'[`i'] local x1=`xvar'[`i'+`next'] local y0=`yvar'[`i'] local y1=`yvar'[`i'+`next'] local r0 = `ay'*`y0' + `by' local c0 = `ax'*`x0' + `bx' local r1 = `ay'*`y1' + `by' local c1 = `ax'*`x1' + `bx' local slope = (`r1'-`r0')/(`c1'-`c0') if `slope'<. { local xstep=sqrt(`dash'^2/((`slope')^2+1)) local ystep=`xstep'*`slope' } else { local xstep 0 if `r1'<`r0' { local ystep=(-1)*(`dash') } else { local ystep=`dash' } } local curr `r0' local curc `c0' local signr=sign(`r1'-`r0') local signc=sign(`c1'-`c0') while (`curr'<=max(`r0',`r1')) & (`curr'>=min(`r0',`r1')) & /* */ (`curc'<=max(`c0',`c1')) & (`curc'>=min(`c0',`c1')) { local nextc = min(`curc' + `xstep',`c1') if `slope'< 0 | (`slope'==. & `r1'<`r0') { local nextr = max(`curr' + `ystep',`r1') } else { local nextr = min(`curr' + `ystep',`r1') } if min(`curr',`nextr',`curc',`nextc')>=0 & max(`curr',`nextr')<=23063 & /* */ max(`curc',`nextc')<=32000 { gph line `curr' `curc' `nextr' `nextc' } local curr=`curr' + (1+(`space')/100)*(`ystep') local curc=`curc' + (1+(`space')/100)*(`xstep') } } local i=`i'+`next' } local j=`j'+1 } gph close end