使用 Stata 绘制散点连接图

昨天有个小伙伴问了这样一个问题:

如何在 Stata 中绘制这样的图:

图1

这个图其实很简单,就是 散点图 + 连接图。今天我们就一起来学习下这种图的绘制。

图2

首先我们准备示例数据。

我选择的示例数据是 2018 年到 2019 年部分城市的常住人口和人均 GDP 的变化关系,数据来源于 2019 和 2010 年中国城市统计年鉴。

设定工作目录:

cd "~/Desktop/使用 Stata 绘制连接图"

读取 2019 年统计年鉴的数据(里面实际上是 2018 年的数据):

use 2019地区生产总值.dta, clear
* 保留需要的变量
keep 城市 地区生产总值_当年价格_万元_全市 人均地区生产总值_元_全市
* 常住人口可以用 GDP 除以人均 GDP 得到
gen 常住人口_万人_2018 = 地区生产总值_当年价格_万元_全市 / 人均地区生产总值_元_全市
replace 地区生产总值_当年价格_万元_全市 = 地区生产总值_当年价格_万元_全市 / 10000
ren 地区生产总值_当年价格_万元_全市 地区生产总值_当年价格_亿元_全市_2018
ren 人均地区生产总值_元_全市 人均地区生产总值_元_全市_2018
save temp, replace

再用同样的方法处理 2020 年统计年鉴的数据,然后和上面处理得到的 temp.dta 合并:

use 2020地区生产总值.dta, clear
keep 城市 地区生产总值_当年价格_亿元_全市 人均地区生产总值_元_全市
gen 常住人口_万人_2019 = (地区生产总值_当年价格_亿元_全市 / 人均地区生产总值_元_全市) * 10000
ren 地区生产总值_当年价格_亿元_全市 地区生产总值_当年价格_亿元_全市_2019
ren 人均地区生产总值_元_全市 人均地区生产总值_元_全市_2019
merge 1:1 城市 using temp

保留不缺失的以及删除 _merge 变量:

keep if !missing(地区生产总值_当年价格_亿元_全市_2019) & !missing(地区生产总值_当年价格_亿元_全市_2018)
drop _m

保留 2019 年人均地区生产总值最高的 30 个城市:

gsort -人均地区生产总值_元_全市_2019
keep in 1/30

然后就可以绘图了。

首先我们把两个散点图层画上去:

tw sc 人均地区生产总值_元_全市_2018 常住人口_万人_2018, mc("102 194 165") m(o) msize(*2) || ///
sc 人均地区生产总值_元_全市_2019 常住人口_万人_2019, mc("252 141 98") m(o) msize(*2)
图3

然后再给一些散点标上文本标签(实际上还是添加了两个散点图层,只不过只有 m(i) 隐藏了散点):

tw sc 人均地区生产总值_元_全市_2018 常住人口_万人_2018, mc("102 194 165") m(o) msize(*2) || ///
sc 人均地区生产总值_元_全市_2019 常住人口_万人_2019, mc("252 141 98") m(o) msize(*2) || ///
sc 人均地区生产总值_元_全市_2019 常住人口_万人_2019 ///
if 常住人口_万人_2019 > 1000, m(i) mlab(城市) mlabpos(12) mlabcolor(gray) || ///
sc 人均地区生产总值_元_全市_2019 常住人口_万人_2019 ///
if 常住人口_万人_2019 < 1000 & 人均地区生产总值_元_全市_2019 > 180000, m(i) mlab(城市) mlabpos(3) mlabcolor(gray)
图4

然后使用 pcarrow 图层把连接线绘制上去:

tw sc 人均地区生产总值_元_全市_2018 常住人口_万人_2018, mc("102 194 165") m(o) msize(*2) || ///
sc 人均地区生产总值_元_全市_2019 常住人口_万人_2019, mc("252 141 98") m(o) msize(*2) || ///
sc 人均地区生产总值_元_全市_2019 常住人口_万人_2019 ///
if 常住人口_万人_2019 > 1000, m(i) mlab(城市) mlabpos(12) mlabcolor(gray) || ///
sc 人均地区生产总值_元_全市_2019 常住人口_万人_2019 ///
if 常住人口_万人_2019 < 1000 & 人均地区生产总值_元_全市_2019 > 180000, m(i) mlab(城市) mlabpos(3) mlabcolor(gray) || ///
pcarrow 人均地区生产总值_元_全市_2018 常住人口_万人_2018 人均地区生产总值_元_全市_2019 常住人口_万人_2019, ///
color(gray)
图5

这个时候图例就变得很丑了,我们再把图例设置下:

tw sc 人均地区生产总值_元_全市_2018 常住人口_万人_2018, mc("102 194 165") m(o) msize(*2) || ///
sc 人均地区生产总值_元_全市_2019 常住人口_万人_2019, mc("252 141 98") m(o) msize(*2) || ///
sc 人均地区生产总值_元_全市_2019 常住人口_万人_2019 ///
if 常住人口_万人_2019 > 1000, m(i) mlab(城市) mlabpos(12) mlabcolor(gray) || ///
sc 人均地区生产总值_元_全市_2019 常住人口_万人_2019 ///
if 常住人口_万人_2019 < 1000 & 人均地区生产总值_元_全市_2019 > 180000, m(i) mlab(城市) mlabpos(3) mlabcolor(gray) || ///
pcarrow 人均地区生产总值_元_全市_2018 常住人口_万人_2018 人均地区生产总值_元_全市_2019 常住人口_万人_2019, ///
color(gray) ///
leg(pos(2) row(2) ring(0) order(1 "2018 年" 2 "2019 年"))
图6

然后再修修:

tw sc 人均地区生产总值_元_全市_2018 常住人口_万人_2018, mc("102 194 165") m(o) msize(*2) || ///
sc 人均地区生产总值_元_全市_2019 常住人口_万人_2019, mc("252 141 98") m(o) msize(*2) || ///
sc 人均地区生产总值_元_全市_2019 常住人口_万人_2019 ///
if 常住人口_万人_2019 > 1000, m(i) mlab(城市) mlabpos(12) mlabcolor(gray) || ///
sc 人均地区生产总值_元_全市_2019 常住人口_万人_2019 ///
if 常住人口_万人_2019 < 1000 & 人均地区生产总值_元_全市_2019 > 180000, m(i) mlab(城市) mlabpos(3) mlabcolor(gray) || ///
pcarrow 人均地区生产总值_元_全市_2018 常住人口_万人_2018 人均地区生产总值_元_全市_2019 常住人口_万人_2019, ///
color(gray) ///
leg(pos(2) row(2) ring(0) order(1 "2018 年" 2 "2019 年")) ///
xti("常住人口(万人)") yti("人均地区生产总值(元)") ///
yla(100000 "10万" 120000 "12万" 140000 "14万" ///
160000 "16万" 180000 "18万" 200000 "20万" ///
210000 "21万") ///
ti("中国部分城市人均地区生产总值与常住人口的关系") ///
subti("绘制:微信公众号 RStata") ///
caption("数据来源:中国城市统计年鉴 2019、2020")

这样就把这幅图画好啦!

图7

最后,其实上面的图还使用了自定义主题,主题安装文件也在附件里:

* 安装
* 需要先安装 blindschemes:
ssc install blindschemes
* 然后再:
net install rstata_scheme.pkg, from("/Users/ac/Desktop/使用 Stata 绘制连接图/rstata_scheme/") replace

这里的 "/Users/ac/Desktop/使用 Stata 绘制连接图/rstata_scheme/" 是 rstata_scheme.pkg 文件在我电脑上的文件夹路径,替换成你自己电脑上的即可。

* 设置绘图主题
set scheme lightrstata, perm

自然还有 darkrstata:

图8

在上面的绘图代码结尾添加 sch(darkrstata) 选项即可。

点击这里跳转到 RStata 短书平台获取附件:使用 Stata 绘制散点连接图

评论