使用 Stata 绘制堆叠柱状图

今天给大家分享一个 Stata 图表绘制案例,原图是这样的:

下面就让我们用 Stata 来复现下这幅图。

首先设置工作目录和绘图主题:

cd "~/Desktop/使用 Stata 绘制堆叠柱状图/"
set scheme plotplain

plotplain 是 blindschemes 包的主题,可以使用 ssc install blindschemes 安装。

然后读入绘图数据:

use data-B7YJx.dta, clear

为了生成纵轴标签的效果,我们把国家和首都合并起来:

replace country = "{bf:" + country + "}" + " (" + capital + ")"

{bf: ...} 在 Stata 绘图中表示加粗。

堆叠柱状图可以使用多个 rbar 绘制,每个 rbar 都需要 ymin 和 ymax,因此我们生成一些辅助变量:

gen y0 = 0
gen y1 = shareofpopulationthatlivesinthec
gen y2 = y1 + inotherurbanareas
gen y3 = 100
gen yl = -28

其中 yl 是“纵轴标签”的位置,这里之所以加上引号,是因为我们实际上是绘制了一层散点标签图层作为纵轴标签,而 Stata 中自带的纵轴标签没有左对齐的设置。

原图中纵轴标签是按照居住在首都的人口比例排序的,所以我们需要对 country 变量进行有序银子化:

sencode country, gen(x) gsort(y1)

sencode 可以使用 ssc install sencode 安装。

为了让图上的标签放置在柱状图的中间,我们需要对 x 进行微调:

gen x1 = x + 0.08

然后我们就可以绘图了。主图我们使用的是 Rboto 字体,caption 中使用的是思源宋体。这两种字体的安装文件我也放到附件中了。

绘制堆叠柱体:

tw rbar y1 y0 x, color("49 79 105") barwidth(0.8) hori lw(none) || ///
rbar y2 y1 x, color("104 172 150") barwidth(0.8) hori lw(none) || ///
rbar y3 y2 x, color("211 139 40") barwidth(0.8) hori lw(none)

对着图右键选择偏好设置就可以选择字体了:

添加数值标签:

tw rbar y1 y0 x, color("49 79 105") barwidth(0.8) hori lw(none) || ///
rbar y2 y1 x, color("104 172 150") barwidth(0.8) hori lw(none) || ///
rbar y3 y2 x, color("211 139 40") barwidth(0.8) hori lw(none) || ///
sc x1 y0 if x > 7, m(i) mlab(label1) mlabpos(3) mlabsize(*0.7) mlabcolor("white") || ///
sc x1 y1, m(i) mlab(label2) mlabpos(3) mlabsize(*0.7) mlabcolor("white") || ///
sc x1 y2 if x < 16, m(i) mlab(label3) mlabpos(3) mlabsize(*0.7) mlabcolor("white")

这里由于柱体使用了 hori 选项,所以散点标签的 x 和 y 需要反过来。

然后我们隐藏原有的 x 和 y 轴,然后手动绘制一个散点标签图层作为 y 轴标签:

tw rbar y1 y0 x, color("49 79 105") barwidth(0.8) hori lw(none) || ///
rbar y2 y1 x, color("104 172 150") barwidth(0.8) hori lw(none) || ///
rbar y3 y2 x, color("211 139 40") barwidth(0.8) hori lw(none) || ///
sc x1 y0 if x > 7, m(i) mlab(label1) mlabpos(3) mlabsize(*0.7) mlabcolor("white") || ///
sc x1 y1, m(i) mlab(label2) mlabpos(3) mlabsize(*0.7) mlabcolor("white") || ///
sc x1 y2 if x < 16, m(i) mlab(label3) mlabpos(3) mlabsize(*0.7) mlabcolor("white") || ///
sc x yl, m(i) mlab(country) mlabpos(3) mlabsize(*0.8) ///
ysc(off) xsc(off)

再调整下 x 和 y 轴让图更匀称:

tw rbar y1 y0 x, color("49 79 105") barwidth(0.8) hori lw(none) || ///
rbar y2 y1 x, color("104 172 150") barwidth(0.8) hori lw(none) || ///
rbar y3 y2 x, color("211 139 40") barwidth(0.8) hori lw(none) || ///
sc x1 y0 if x > 7, m(i) mlab(label1) mlabpos(3) mlabsize(*0.7) mlabcolor("white") || ///
sc x1 y1, m(i) mlab(label2) mlabpos(3) mlabsize(*0.7) mlabcolor("white") || ///
sc x1 y2 if x < 16, m(i) mlab(label3) mlabpos(3) mlabsize(*0.7) mlabcolor("white") || ///
sc x yl, m(i) mlab(country) mlabpos(3) mlabsize(*0.8) ///
ysc(off) xsc(off) ///
xla(-28(10)100, nogrid) ///
yla(1(1)18, nogrid)

添加脚注:

tw rbar y1 y0 x, color("49 79 105") barwidth(0.8) hori lw(none) || ///
rbar y2 y1 x, color("104 172 150") barwidth(0.8) hori lw(none) || ///
rbar y3 y2 x, color("211 139 40") barwidth(0.8) hori lw(none) || ///
sc x1 y0 if x > 7, m(i) mlab(label1) mlabpos(3) mlabsize(*0.7) mlabcolor("white") || ///
sc x1 y1, m(i) mlab(label2) mlabpos(3) mlabsize(*0.7) mlabcolor("white") || ///
sc x1 y2 if x < 16, m(i) mlab(label3) mlabpos(3) mlabsize(*0.7) mlabcolor("white") || ///
sc x yl, m(i) mlab(country) mlabpos(3) mlabsize(*0.8) ///
ysc(off) xsc(off) ///
xla(-28(10)100, nogrid) ///
yla(1(1)18, nogrid) ///
note(`" The UN defines "Urban" differently for each country. To count as "urban", Japanese settlements need to have at least "' ///
`" 50,000 inhabitants. In Iceland, 200 inhabitants are enough."', ///
justification(left) size(*0.6))

这里再 note 前面添加空格是为了调整脚注和 “y 轴标签对齐”。

然后是设置图例:

tw rbar y1 y0 x, color("49 79 105") barwidth(0.8) hori lw(none) || ///
rbar y2 y1 x, color("104 172 150") barwidth(0.8) hori lw(none) || ///
rbar y3 y2 x, color("211 139 40") barwidth(0.8) hori lw(none) || ///
sc x1 y0 if x > 7, m(i) mlab(label1) mlabpos(3) mlabsize(*0.7) mlabcolor("white") || ///
sc x1 y1, m(i) mlab(label2) mlabpos(3) mlabsize(*0.7) mlabcolor("white") || ///
sc x1 y2 if x < 16, m(i) mlab(label3) mlabpos(3) mlabsize(*0.7) mlabcolor("white") || ///
sc x yl, m(i) mlab(country) mlabpos(3) mlabsize(*0.8) ///
ysc(off) xsc(off) ///
xla(-28(10)100, nogrid) ///
yla(1(1)18, nogrid) ///
note(`" The UN defines "Urban" differently for each country. To count as "urban", Japanese settlements need to have at least "' ///
`" 50,000 inhabitants. In Iceland, 200 inhabitants are enough."', ///
justification(left) size(*0.6)) ///
leg(order(1 "Share of population that lives in the capital" ///
2 "in other urban areas" 3 "in rural areas") size(*0.8) ///
row(1) pos(11) symysize(1.5pt) symxsize(1.5pt) colgap(0.5pt) ///
alignment(middle) keygap(0.3pt))

最后再设置下 title、subtitle 和 caption:

tw rbar y1 y0 x, color("49 79 105") barwidth(0.8) hori lw(none) || ///
rbar y2 y1 x, color("104 172 150") barwidth(0.8) hori lw(none) || ///
rbar y3 y2 x, color("211 139 40") barwidth(0.8) hori lw(none) || ///
sc x1 y0 if x > 7, m(i) mlab(label1) mlabpos(3) mlabsize(*0.7) mlabcolor("white") || ///
sc x1 y1, m(i) mlab(label2) mlabpos(3) mlabsize(*0.7) mlabcolor("white") || ///
sc x1 y2 if x < 16, m(i) mlab(label3) mlabpos(3) mlabsize(*0.7) mlabcolor("white") || ///
sc x yl, m(i) mlab(country) mlabpos(3) mlabsize(*0.8) ///
ysc(off) xsc(off) ///
xla(-28(10)100, nogrid) ///
yla(1(1)18, nogrid) ///
note(`" The UN defines "Urban" differently for each country. To count as "urban", Japanese settlements need to have at least "' ///
`" 50,000 inhabitants. In Iceland, 200 inhabitants are enough."', ///
justification(left) size(*0.6)) ///
leg(order(1 "Share of population that lives in the capital" ///
2 "in other urban areas" 3 "in rural areas") size(*0.8) ///
row(1) pos(11) symysize(1.5pt) symxsize(1.5pt) colgap(0.5pt) ///
alignment(middle) keygap(0.3pt)) ///
ti(" Population by Urban/Rural Areas", justification(left) bexpand) ///
subti(" Share of population that lives in the capital, in urban areas and in rural areas, of selected countries," " 2014.", justification(left) bexpand size(*0.8)) ///
caption(`" {fontface "SourceHanSerifSC-Medium":绘制:微信公众号 RStata}"', size(*0.6))
gr export "pic.png", replace width(4800)

这样我们就在 Stata 中基本复现了这幅图~

点击这里跳转到 RStata 短书平台获取附件:使用 Stata 绘制堆叠柱状图

评论