最近有个小伙伴遇到了这样的一个问题,她在使用 Stata 绘制漏斗图时想要设置散点的颜色却不知如何设置。今天我们就一起看一下这个问题。
由于我对 Meta 分析也不是很了解,所以这里就不再讲解漏斗图的制作和解读了。
首先我们绘制一个漏斗图:
use smoking, clear network setup d n, studyvar(study) trtvar(trt) network convert pairs netfunnel _y _stderr _t1 _t2, random bycomp addplot(lfit _stderr _ES_CEN) noalpha scatteroptions(leg(pos(6)))
|

这幅图的散点颜色是由主题设定的,那么该如何自己设置呢?
最开始我猜想或许可以在 scatteroptions() 里面设置,例如:
netfunnel _y _stderr _t1 _t2, random bycomp /// addplot(lfit _stderr _ES_CEN) noalpha /// scatteroptions(leg(pos(6)) /// mc("102 194 165" "252 141 98" /// "141 160 203" "231 138 195" /// "166 216 84" "255 217 47"))
|
但是并没有任何效果。
因此我们得深入 netfunnel 的源代码,研究这个图是如何绘制的。
运行 adoedit netfunnel 打开 netfunnel 的源代码:
可以看到绘图代码在 205 行:
twoway `_scat`=`_nc''' , yscale(rev) mc(black) xtitle(`xtitle') ytitle(`ytitle') xline(0, lcol(red)) ylab(`ylabel') xlab(`xlabel') `scatteroptions'|| `_lines' || `addplot'
|
而散点图生成的代码是在 112~114 行,是通过一个循环生成的。
因此这个图的绘制代码是类似 tw scatter … || scatter … || scatter … 这样的结构,所以直接在最后的选项里添加 mcolors() 是无效的,需要分别在每个图层里面设置。
因此这里我们需要获取绘图数据和完整的代码,进行修改之后再重新绘图。
复制 netfunnel 的代码,在工作目录下面新建一个 netfunnel2.ado 文件。把 205 行附近的代码改成下面的内容:
cap{ twoway `_scat`=`_nc''' , yscale(rev) mc(black) xtitle(`xtitle') ytitle(`ytitle') xline(0, lcol(red)) ylab(`ylabel') xlab(`xlabel') `scatteroptions' || `_lines' || `addplot' save graphdata, replace file open myfile using "plotcode.do", write file write myfile `"twoway `_scat`=`_nc''' , yscale(rev) mc(black) xtitle(`xtitle') ytitle(`ytitle') xline(0, lcol(red)) ylab(`ylabel') xlab(`xlabel') `scatteroptions' || `_lines' || `addplot'"' _n file close myfile }
|
记得文件开头的 program netfunnel, eclass 也要改成 program netfunnel2, eclass。
这里 save graphdata, replace 用于保存绘图所需的数据,下面的 file 代码则是为了把绘图代码保存到 plotcode.do 文件中。
运行下面的代码:
netfunnel2 _y _stderr _t1 _t2, random bycomp /// addplot(lfit _stderr _ES_CEN) noalpha /// scatteroptions(leg(pos(6)))
|
然后我们就可以在附件中看到 plotcode.do 文件,内容如下:
use graphdata.dta, clear twoway sc __000002 __00000O if _dc1==1 & __000000==1 ||sc __000002 __00000O if _dc2==1 & __000000==1 ||sc __000002 __00000O if _dc3==1 & __000000==1 ||sc __000002 __00000O if _dc4==1 & __000000==1 ||sc __000002 __00000O if _dc5==1 & __000000==1 ||sc __000002 __00000O if _dc6==1 & __000000==1 , yscale(rev) mc(black) xtitle(Effect size centred at comparison-specific pooled effect ({it:y{sub:iXY}-{&mu}{sub:XY}})) ytitle(Standard error of effect size) xline(0, lcol(red)) ylab(0(0.5)1.5) xlab() || function y=abs(x/1.96),range(-2.94 2.94) legend(order( 1 "A vs B" 2 "A vs C" 3 "A vs D" 4 "B vs C" 5 "B vs D" 6 "C vs D" ) col(6)) lcol(black) lpat(dash) || lfit _stderr _ES_CEN
|
直接全选、运行这段代码会报错,大致原因是因为这种 __ 开头的变量导致的,所以我们把所有变量前面都加个 m:
use graphdata.dta, clear foreach i of varlist _all { ren `i' m`i' }
|
然后绘图代码也调整下:
twoway /// sc m__000002 m__00000O if m_dc1==1 & m__000000==1 || /// sc m__000002 m__00000O if m_dc2==1 & m__000000==1 || /// sc m__000002 m__00000O if m_dc3==1 & m__000000==1 || /// sc m__000002 m__00000O if m_dc4==1 & m__000000==1 || /// sc m__000002 m__00000O if m_dc5==1 & m__000000==1 || /// sc m__000002 m__00000O if m_dc6==1 & m__000000==1 , /// yscale(rev) mc(black) /// xtitle(Effect size centred at comparison-specific pooled effect ({it:y{sub:iXY}-{&mu}{sub:XY}})) /// ytitle(Standard error of effect size) /// xline(0, lcol(red)) ylab(0(0.5)1.5) xlab() || /// function y=abs(x/1.96), range(-2.94 2.94) /// legend(order( 1 "A vs B" 2 "A vs C" /// 3 "A vs D" 4 "B vs C" 5 "B vs D" /// 6 "C vs D" ) col(6) pos(6)) /// lcol(black) lpat(dash) || /// lfit m_stderr m_ES_CEN
|
可以看到开头部分的代码其实很容易通过循环生成。下面我们就通过循环生成这部分代码,然后再在每个图层设置颜色:
use graphdata.dta, clear foreach i of varlist _all { ren `i' m`i' }
local cmd = "tw" local colors = `""102 194 165" "252 141 98" "141 160 203" "231 138 195" "166 216 84" "255 217 47""' forval i = 1/6 { local tempcolor: word `i' of `colors' local cmd = `"`cmd' (sc m__000002 m__00000O if m_dc`i' == 1 & m__000000 == 1, mc("`tempcolor'"))"' } `cmd', yscale(rev) xtitle(Effect size centred at comparison-specific pooled effect ({it:y{sub:iXY}-{&mu}{sub:XY}})) ytitle(Standard error of effect size) xline(0, lcol(red)) ylab(0(0.5)1.5) xlab() || function y=abs(x/1.96), range(-2.94 2.94) legend(order( 1 "A vs B" 2 "A vs C" 3 "A vs D" 4 "B vs C" 5 "B vs D" 6 "C vs D" ) col(6) pos(6)) lcol(black) lpat(dash) || lfit m_stderr m_ES_CEN
gr export pic2.png, width(4800) replace
|

这样我们就完成了颜色的设置和更改。
点击这里跳转到 RStata 短书平台获取附件:深入源码解决问题——Stata 绘制漏斗图时如何设置散点颜色
评论