****changelog: * v1.0.3 added option to add other twoway plots * v1.0.2 bugfix * v1.0.1 the symbol_opacity() option was added cap program drop colorscatter program define colorscatter version 11.0 syntax varlist(max=3) [if] [in],[ keeplegend scatter_options(string) symbol_opacity(string) cmin(string) cmax(string) rgb_low(string) rgb_high(string) tw_pre(string) tw_post(string) * ] marksample touse tokenize `varlist' local x "`1'" local y "`2'" local c "`3'" qui sum `c' if `touse' if "`cmin'"=="" { local cmin=r(min) } if "`cmax'"=="" { local cmax=r(max) } if "`symbol_opacity'"=="" { local symbol_opacity 1 } if "`rgb_low'"=="" { local rgb_low 0 0 255 } if "`rgb_high'"=="" { local rgb_high 255 0 0 } local rl1 : word 1 of `rgb_high' local rl2 : word 2 of `rgb_high' local rl3 : word 3 of `rgb_high' local rh1 : word 1 of `rgb_low' local rh2 : word 2 of `rgb_low' local rh3 : word 3 of `rgb_low' tempvar cscaled gen `cscaled' = round(255*(`c'-`cmin')/(`cmax'-`cmin')) qui replace `cscaled'=0 if `cscaled' <0 qui replace `cscaled'=255 if `cscaled'>255 & ! missing(`cscaled') local command tw (`tw_pre') qui levelsof `cscaled' if `touse', local(levels) local i 0 local legend_entry local last : word count `levels' foreach l of local levels { local i = `i'+1 local gradient=`l'/255 local command `command' (scatter `x' `y' if `cscaled'==`l' & `touse', mcolor("`: di round(`gradient'*`rl1' + (1-`gradient')*`rh1')' `: di round(`gradient'*`rl2' + (1-`gradient')*`rh2')' `: di round(`gradient'*`rl3' + (1-`gradient')*`rh3')' `symbol_opacity'") `scatter_options') local label "" if `i'==1 | `i'==`last' { qui sum `c' if `cscaled'==`l' & `touse' qui di `r(N)' local label `: di %12.2g `r(mean)'' } local legend_entry `legend_entry' `i' "`label'" } local command `command' (`tw_post') if ("`keeplegend'"=="") { `command', `options' legend(order(`legend_entry') col(1) symplacement(right) position(3)) } else { `command', `options' } end