Stata绘图:如何更高效的绘制图形

发布时间:2022-05-16 阅读 3605

Stata连享会   主页 || 视频 || 推文 || 知乎 || Bilibili 站

温馨提示: 定期 清理浏览器缓存,可以获得最佳浏览体验。

New! lianxh 命令发布了:
随时搜索推文、Stata 资源。安装:
. ssc install lianxh
详情参见帮助文件 (有惊喜):
. help lianxh
连享会新命令:cnssc, ihelp, rdbalance, gitee, installpkg

课程详情 https://gitee.com/lianxh/Course

课程主页 https://gitee.com/lianxh/Course

⛳ Stata 系列推文:

PDF下载 - 推文合集

作者:李亭 (山东大学)
邮箱17863116708@163.com

编者按:本文主要摘译自下文,特此致谢!
Source: Rice, Kenneth, and Thomas Lumley. Effective graphs for data display: recommendations for authors. 2015. -PDF- -Replication- -Stata codes- -R codes-


目录


在论文写作中,图形在呈现研究数据方面起着关键的作用,并有助于验证数据分析的结果。然而,图形可能有时绘制不当,无法准确表达作者的观点,因此需要在发表之前进行反复修改。为此,本文将通过对 Rice 等 (2015) 的介绍,来帮助大家更好理解 Stata 绘图以及实证写作。

1. 数据说明

本文使用的案例数据均来自于「国家健康和营养检查调查数据集 (NHANES)」,我们从中选取了大小分别为 30 (小)、200 (中) 和 1000 (大) 的随机子集。其中变量如下:

  • bpxsar:收缩压 (mmHg);
  • bpxdar:舒张压 (mmHg);
  • bpsdi1 bpxdi2:两类舒张压读数;
  • race_ethc:种族,编码为西班牙裔、非西班牙裔白人、非西班牙裔黑人和其他;
  • dr1tfola:叶酸摄入量 (μg/day);
  • riagendr:性别,编码为男/女;
  • bmxbmi:体重指数 (kg/m^2);
  • ridagey:年龄 (years)。

在正式开始之前,我们需要安装以下命令:

. ssc install vioplot, replace
. ssc install stripplot, replace
. ssc install spineplot, replace

2. 单变量图形绘制

2.1 连续变量

在绘制小样本 (即 n<30) 连续变量的图形时,我们建议使用点图 (Dot Plot)。点图类似于条形图,区别在于点图用点来显示数据。此外建议使用空的圆符号而不是填充的圆,因为当附近有多个点时,空圆能够更好地区分单个点。例如在下图中,我们展示了样本中人们收缩压值的分布。

. insheet using "http://faculty.washington.edu/kenrice/heartgraphs/nhanessmall.csv", clear
. label variable bpxsar "Systolic Blood Pressure (mmHg)" 
. stripplot bpxsar  // 绘制点图

但是有时数据可能会重叠,比如样本中可能存在收缩压相同的数据。当重叠值存在时,可以使用堆叠点图 (Stacked Dot Chart)。堆叠点图通过把相同的观测值垂直堆叠起来,清楚地显示了样本数据的分布。

. stripplot bpxsar, stack center   // 绘制堆叠点图

点图适用于中等大小以下的数据集,对于更大的样本量,点图可能会变得十分混乱。在大的样本量下,个体值不太可能影响整体数据的解释。因此,直接表示数据的范围和分布就已足够。在这种情况下,我们推荐使用小提琴图 (Violin Plot)。

. insheet using http://faculty.washington.edu/kenrice/heartgraphs/nhaneslarge.csv, clear
. label variable bpxsar "Systolic Blood Pressure (mmHg)"
. vioplot bpxsar, horizontal //绘制小提琴图

2.2 分类变量

对于分类变量,表格足以简明的记录数据,例如男性和女性的数量。但是,如果表中的信息足够重要,那么以图形方式对其呈现可能是更好的选择。无论样本量如何,对于分类变量只有两组 (如 1/0,或是/否) 的类型,我们建议使用柱状图。

. insheet using http://faculty.washington.edu/kenrice/heartgraphs/nhaneslarge.csv, clear
. generate normotens = bpxsar <= 140
. label define normotensl 1 "<= 140 mmHg" 0 "> 140 mmHg",replace 
. label values normotens normotensl
. generate sample = 1
. graph hbar (percent) sample, over(normotens) asyvars stack // 绘制柱状图

对于三个或更多组别的分类变量的图形表示,我们同样建议使用堆叠柱状图。下图显示了不同种族 (西班牙裔、非西班牙裔白人、非西班牙裔黑人和其他) 所占比例。

. insheet using http://faculty.washington.edu/kenrice/heartgraphs/nhaneslarge.csv, clear
. generate sample = 1
. graph hbar (percent) sample, over(race_ethc) asyvars stack  // 绘制堆叠柱状图

3. 双变量图形绘制

3.1 连续—分类变量

绘制连续结果变量 (纵轴为连续变量) 与分类协变量 (横轴为分类变量) 组合图时,我们建议小样本 (n=30)、中等样本 (n=200)、大样本 (n=1000) 数据分别使用点图、堆叠点图和小提琴图来呈现。图中直观的揭示了男性和女性每天在叶酸摄入量的差异。

 insheet using http://faculty.washington.edu/kenrice/heartgraphs/nhanessmall.csv, clear
. label variable dr1tfola "Folate intake (ug/day)"
. label values riagendr sexl
. stripplot dr1tfola, vertical over(riagendr) name(g1, replace) // 绘制点图

. insheet using http://faculty.washington.edu/kenrice/heartgraphs/nhanesmedium.csv, clear
. label variable dr1tfola "Folate intake (ug/day)"
. label values riagendr sexl
. stripplot dr1tfola, width(20) vertical stack center over(riagendr) name(g2, replace) // 绘制堆叠点图

. insheet using http://faculty.washington.edu/kenrice/heartgraphs/nhaneslarge.csv, clear
. label variable dr1tfola "Folate intake (ug/day)"
. label values riagendr sexl
. vioplot dr1tfola, vertical over(riagendr) ytitle("Folate intake (ug/day)") name(g3, replace) // 绘制小提琴图

.  gr combine g1 g2 g3, rows(1)

3.2 连续—连续变量

绘制连续变量与连续变量组合图时,对于小的或中等的样本量,我们建议使用散点图。与点图一样,我们建议散点图使用空心圆而不是填充的圆来表示,以便于更好地区分单个点。

. insheet using http://faculty.washington.edu/kenrice/heartgraphs/nhanesmedium.csv, clear
. label variable bpxsar "Systolic Blood Pressure (mmHg)"
. label variable ridageyr "Age (years)"
. twoway (scatter bpxsar ridageyr, msymbol(Oh)) (lfitci bpxsar ridageyr), ///
>     legend(off) ytitle("Systolic Blood Pressure (mmHg)") 

此外当观测结果不是唯一时 (即当观测结果具有相同的 X 和 Y 值时),那么在这些点上添加少量的 “抖动”,足以使单个点可区分,同时也可以保留原始数据的整体模式。

3.3 分类—分类变量

列联表可能足以描述两个分类变量之间的关系。但对于多分类变量统计会很复杂。为了绘制任何样本大小下分类变量的分类结果,我们建议使用马赛克图 (Mosaic Plot)。马赛克图也叫做不等宽柱状图 (Marimekko Chart),可以直观显示多变量每种取值组合的观测个数和比例。根据不同变量,矩形方块会被填充不同的颜色,以区分数据。

. insheet using http://faculty.washington.edu/kenrice/heartgraphs/nhaneslarge.csv, clear
. egen sbpcut = cut(bpxsar), at(0 110 140 250) label
. encode race_ethc, generate(race_ethc2)
. label variable sbpcut "Category of Sys Blood Pressure"
. label variable race_ethc2 "Race/Ethnicity"
. spineplot sbpcut race_ethc2, xlabel(, angle(v) axis(2))

在马赛克图中,协变量 (横轴) 和结果变量 (纵轴) 分别决定了矩形的宽度和矩形的高度。然而对于图表是要说明两个变量之间一致或不一致的情况,这种区别是不合适的,我们建议使用波动图 (fluctuation diagram)。

具体如下图所示。图中比较了第一次和第二次舒张压测量值的分布。在这里,每个变量组合对应的方块面积与其观测值数量成正比。图中 45 度线周围的对称性表明,没有强有力的证据表明第一次和第二次舒张压测量值之间存在系统差异。

. insheet using http://faculty.washington.edu/kenrice/heartgraphs/nhaneslarge.csv, clear
. egen dbpcut1 = cut(bpxdi1), at(0 60 70 80 120) label
. egen dbpcut2 = cut(bpxdi2), at(0 60 70 80 120) label
. generate x=1
. collapse (count) x, by(dbpcut1 dbpcut2) 
. twoway (scatter dbpcut1 dbpcut2 [weight=x], msize(1.5) msymbol(S)) ///
>     (function y=x, range(-1 4) ), aspectratio(1) ///
>     xlabel(0 "0-" 1 "60-" 2 "70-" 3 "80-")       ///
>     ylabel(0 "0-" 1 "60-" 2 "70-" 3 "80-")       /// 
>     xscale( range(-1 4)) yscale( range(-1 4))    ///
>     xtitle("Category of Dias BP, Measure #2")    ///
>     ytitle("Category of Dias BP, Measure #1")    ///
>     legend(off)

3.4 分类—连续变量

绘制连续协变量 (横轴为连续变量) 与分类结果变量 (纵轴为分类变量) 组合图时,当分类变量只有两个分组 (如1/0,或是/否) 时,散点图可以显示每个样本数据,尽管可能需要调整来减少附近或连接点的过度绘制。

当兴趣是任一分组在横轴不同区域所占比例时,可以通过叠加来自逻辑回归或其类似分析的拟合均值,在散点图上显示该比例。下图给出了示例,图中直观的展示了舒张压与年龄的关系,随着年龄的增大,样本中舒张压的拟合均值也不断增加。

. insheet using http://faculty.washington.edu/kenrice/heartgraphs/nhanesmedium.csv, clear
. generate htn = bpxdar > 70
. label variable ridageyr "Age (years)"
. label variable htn "Diastolic BP (mmHg)/Proportion"
. label define htnl 1 "> 70 mmHg" 0 "<= 70 mmHg" 
. label values htn htnl
. logistic htn ridageyr
. predict fitted, xb
. predict fitted_se, stdp
. generate est = exp(fitted)/(1+exp(fitted))
. generate hici = exp(fitted+fitted_se*1.96)/(1+exp(fitted+fitted_se*1.96))
. generate loci = exp(fitted-fitted_se*1.96)/(1+exp(fitted-fitted_se*1.96))
. sort ridageyr
. stripplot ridageyr, stack center over(htn) 
. graph addplot rarea hici loci ridageyr
. graph addplot line est ridageyr, yscale( range(0 1)) ylabel(0 "<= 70mmHg 0" 0.5 1 ">70mmHg 1")

对于较大的数据集,可以向散点图添加平滑器,并在这些线周围添加 95% 置信区间的区域,以增加数据拟合的优度。

. insheet using http://faculty.washington.edu/kenrice/heartgraphs/nhanesmedium.csv, clear
. generate htn = bpxdar > 70
. label variable ridageyr "Age (years)"
. label variable htn "Dichotomized Diastolic BP (mmHg), Proportion"
. label define htnl 1 "> 70 mmHg" 0 "<= 70 mmHg" 
. label values htn htnl
. mkspline spage = ridageyr, cubic
. quietly logistic htn spage*
. predict fitted, xb
. predict fitted_se, stdp
. generate est = exp(fitted)/(1+exp(fitted))
. generate hici = exp(fitted+fitted_se*1.96)/(1+exp(fitted+fitted_se*1.96))
. generate loci = exp(fitted-fitted_se*1.96)/(1+exp(fitted-fitted_se*1.96))
. sort ridageyr
. stripplot ridageyr, stack center over(htn) 
. graph addplot rarea hici loci ridageyr
. graph addplot line est ridageyr, yscale( range(0 1)) ylabel(0 "<= 70mmHg 0" 0.5 1 ">70mmHg 1")

4. 多变量图形绘制

当要表示连续结果变量和连续协变量之间的关系如何取决于第三个连续变量时,三维绘图变得很有吸引力。但由于期刊文章必须打印在二维纸上,因此无法准确传达三维图形的含义。相反,根据第三个变量对数据进行分层可能是有效的。下图中给出了一个示例,分层的概念也可用于小提琴图、条形图和其他图表,从而能够根据一个协变量的值显示结果/协变量关系。

. insheet using http://faculty.washington.edu/kenrice/heartgraphs/nhaneslarge.csv, clear
. egen agecut = cut(ridageyr), at(0 30 55 100) label
. label variable bmxbmi "BMI (kg/m^2)"
. twoway (scatter bpxsar bmxbmi, msymbol(o) mcolor(gs14) subtitle("Age Category:", prefix)) ///
>     (lowess bpxsar bmxbmi if riagendr==1, lwidth(thick))                                  ///
>     (lowess bpxsar bmxbmi if riagendr==2, lwidth(thick) lpattern(dash)),                  ///
>     by(agecut, cols(3) compact note(""))                                                  ///
>     ytitle("Systolic Blood Pressure (mmHg)") legend(order(2 "Male" 3 "Female"))

5. 结语

简单的可视化技术可以用来加强科学数据的交流。为了有效地呈现变量之间的关系,我们推荐了一些简单的图,并且可以在 Stata 软件中生成。在论文手稿中,糟糕的图表和写作阻碍了问题的发现和学者间的交流。因此,我们希望本文中的建议可以为读者提供高效的绘图方法。

6. 相关推文

Note:产生如下推文列表的 Stata 命令为:
lianxh 绘图, m
安装最新版 lianxh 命令:
ssc install lianxh, replace

相关课程

免费公开课

最新课程-直播课

专题 嘉宾 直播/回看视频
最新专题 文本分析、机器学习、效率专题、生存分析等
研究设计 连玉君 我的特斯拉-实证研究设计-幻灯片-
面板模型 连玉君 动态面板模型-幻灯片-
面板模型 连玉君 直击面板数据模型 [免费公开课,2小时]
  • Note: 部分课程的资料,PPT 等可以前往 连享会-直播课 主页查看,下载。

课程主页

课程主页

关于我们

  • Stata连享会 由中山大学连玉君老师团队创办,定期分享实证分析经验。
  • 连享会-主页知乎专栏,700+ 推文,实证分析不再抓狂。直播间 有很多视频课程,可以随时观看。
  • 公众号关键词搜索/回复 功能已经上线。大家可以在公众号左下角点击键盘图标,输入简要关键词,以便快速呈现历史推文,获取工具软件和数据下载。常见关键词:课程, 直播, 视频, 客服, 模型设定, 研究设计, stata, plus, 绘图, 编程, 面板, 论文重现, 可视化, RDD, DID, PSM, 合成控制法

连享会小程序:扫一扫,看推文,看视频……

扫码加入连享会微信群,提问交流更方便

✏ 连享会-常见问题解答:
https://gitee.com/lianxh/Course/wikis

New! lianxhsongbl 命令发布了:
随时搜索连享会推文、Stata 资源,安装命令如下:
. ssc install lianxh
使用详情参见帮助文件 (有惊喜):
. help lianxh