👇 连享会 · 推文导航 |
www.lianxh.cn
🍓 课程推荐:
连享会:2025 寒假班
嘉宾:连玉君(初级|高级);杨海生(前沿)
时间:2025 年 1 月 13-24 日
咨询:王老师 18903405450(微信)
作者
:李亭 (山东大学)
邮箱
:[email protected]
温馨提示:
文中链接在微信中无法生效。请点击底部
「阅读原文」
。或直接长按/扫描如下二维码,直达原文:
编者按
:本文主要摘译自下文,特此致谢!
Source:
Rice, Kenneth, and Thomas Lumley. Effective graphs for data display: recommendations for authors. 2015.
-PDF-
-Replication-
-Stata codes-
-R codes-
目录
1. 数据说明
2. 单变量图形绘制
3. 双变量图形绘制
3.1 连续—分类变量
3.2 连续—连续变量
3.3 分类—分类变量
3.4 分类—连续变量
4. 多变量图形绘制
5. 结语
6. 相关推文
在论文写作中,图形在呈现研究数据方面起着关键的作用,并有助于验证数据分析的结果。然而,图形可能有时绘制不当,无法准确表达作者的观点,因此需要在发表之前进行反复修改。为此,本文将通过对 Rice 等 (2015) 的介绍,来帮助大家更好理解 Stata 绘图以及实证写作。
1. 数据说明
本文使用的案例数据均来自于「国家健康和营养检查调查数据集 (NHANES)」,我们从中选取了大小分别为 30 (小)、200 (中) 和 1000 (大) 的随机子集。其中变量如下:
race_ethc
:种族,编码为西班牙裔、非西班牙裔白人、非西班牙裔黑人和其他;
dr1tfola
:叶酸摄入量 (μg/day);
在正式开始之前,我们需要安装以下命令:
. 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