今天下午有个小伙伴问了这样一个问题,他想用 Stata 绘制一幅这样的散点图:
也就是把散点的标签放在图的右侧,然后用线把散点和标签连接起来。
首先我们在 Stata 中输入数据:
clear input str24 省份 float(地区生产总值_亿元 第一产业地区生产总值_亿元 第二产业地区生产总值_亿元) "云南省" 23223.75 3037.62 7961.58 "广东省" 107671.07 4351.26 43546.43 "上海市" 38155.32 103.88 10299.16 "河南省" 54259.2 4635.4 23605.79 "吉林省" 11726.82 1287.32 4134.82 "贵州省" 16769.34 2280.56 6058.45 "辽宁省" 24909.45 2177.77 9531.24 "北京市" 35371.28 113.69 5715.06 "陕西省" 25793.17 1990.93 11980.75 "内蒙古自治区" 17212.53 1863.19 6818.88 "山东省" 71067.53 5116.44 28310.92 "福建省" 42395 2596.23 20581.74 "青海省" 2965.95 301.9 1159.75 "浙江省" 62351.74 2097.38 26566.6 "河北省" 35104.52 3518.44 13597.26 "山西省" 17026.68 824.72 7453.09 "四川省" 46615.82 4807.24 17365.33 "重庆市" 23605.77 1551.42 9496.84 "广西壮族自治区" 21237.14 3387.74 7077.43 "江西省" 24757.5 2057.56 10939.83 "江苏省" 99631.52 4296.28 44270.51 "天津市" 14104.28 185.23 4969.18 "甘肃省" 8718.3 1050.48 2862.42 "黑龙江省" 13612.68 3182.45 3615.21 "安徽省" 37113.98 2915.7 15337.9 "宁夏回族自治区" 3748.48 279.93 1584.72 "海南省" 5308.93 1080.36 1099.03 "湖南省" 39752.12 3646.95 14946.98 "新疆维吾尔自治区" 13597.11 1781.75 4795.5 "西藏自治区" 1697.82 138.19 635.62 "湖北省" 45828.31 3809.09 19098.62 end
|
然后我们把数据按照第一产业地区生产总值_亿元变量进行排序:
为了把散点标签放置在图的右侧,我们需要给每个标签生成一个坐标,在此之前我们先绘制一个不带标签的图:
tw sc 第一产业地区生产总值_亿元 第二产业地区生产总值_亿元
|
可以看出 x 轴的范围大概是 0~50000 的样子、y 轴的范围大概是 0 ~ 6000 的样子,所以我们给标签生成的纵坐标的范围也是 0 ~ 6000,可以均匀排列:
local delta = (6000-0)/31 gen y = _n * `delta' replace y = y - y[1]/2
|
因为是 31 个观测值,要在 0~6000 均匀分布,间隔就是 delta,然后再乘以 1~31 就得到了标签的 y 坐标。为了让标签居中分布,再减去第一个 y 的一般(这样两侧的距离都是 y[1]/2)。
另外 x = 55000 就挺合适:
使用权重可以设置散点的大小,下面的代码使用散点的大小表示地区生产总值_亿元:
tw sc 第一产业地区生产总值_亿元 第二产业地区生产总值_亿元 [aw = 地区生产总值_亿元], /// xla(0(10000)50000, nogrid) yla(0(1000)6000, nogrid) leg(off) /// m(o) || /// sc y x, mlab(省份) xsc(range(0 65000)) mlabpos(3) m(i) mlabsize(*0.7) || /// pcspike 第一产业地区生产总值_亿元 第二产业地区生产总值_亿元 y x, /// lw(*0.5) /// ti("2019 年各省市第一、第二产业地区生产总值的关系") /// xti("第二产业地区生产总值(亿元)") yti("第一产业地区生产总值(亿元)") /// subti("绘制:微信公众号 RStata") /// caption("数据来源:国家统计局")
|
上面的代码中第一个 sc 是绘制散点图的,第二个 sc 是绘制标签文本的(m(i)表示隐藏散点),pcspike 是用来绘制散点和标签的连接线的。
- xla(0(10000)50000, nogrid):设置 x 轴的标签,不使用网格线;
- yla(0(1000)6000, nogrid):设置 y 轴的标签,不使用网格线;
- leg(off):不显示图例;
- m(o):散点使用圆点;
- xsc(range(0 65000)):设置 x 轴的范围;
- mlabpos(3):设置标签位于散点的方向,3 点钟方向;
- m(i):隐藏散点(第二个 sc 图层);
- mlabsize(*0.7):设置散点标签的大小,0.7 倍的标准大小。
另外如果想把标签标在散点的附近并用线连接,可以这样生成一个微微偏移的标签坐标:
gen y1 = 第一产业地区生产总值_亿元 + 200 gen x1 = 第二产业地区生产总值_亿元 + 1000
tw sc 第一产业地区生产总值_亿元 第二产业地区生产总值_亿元, xla(0(10000)50000, nogrid) yla(0(1000)6000, nogrid) leg(off) m(o) || sc y1 x1, mlab(省份) mlabpos(2) m(i) mlabsize(*0.7) mlabgap(*0.1) || pcspike 第一产业地区生产总值_亿元 第二产业地区生产总值_亿元 y1 x1, lw(*0.5) ti("2019 年各省市第一、第二产业地区生产总值的关系") xti("第二产业地区生产总值(亿元)") yti("第一产业地区生产总值(亿元)") subti("绘制:微信公众号 RStata") caption("数据来源:国家统计局")
|
但是这样得到的标签有重叠问题:
我们可以通过微微调整来缓解部分重叠问题:
gen clock = 2 replace y1 = y1 - 300 if 省份 == "江苏省" replace clock = 3 if 省份 == "江苏省" replace y1 = y1 - 400 if 省份 == "河北省" replace y1 = y1 + 200 if 省份 == "黑龙江省" replace x1 = x1 - 3000 if 省份 == "新疆维吾尔自治区" replace y1 = y1 + 400 if 省份 == "新疆维吾尔自治区" replace clock = 12 if 省份 == "新疆维吾尔自治区" replace y1 = y1 - 200 if 省份 == "甘肃省" replace clock = 3 if 省份 == "甘肃省" replace y1 = y1 - 400 if 省份 == "西藏自治区" replace clock = 3 if 省份 == "西藏自治区" replace y1 = y1 - 300 if 省份 == "北京市" replace clock = 3 if 省份 == "北京市" replace y1 = y1 - 120 if 省份 == "天津市" replace y1 = y1 - 300 if 省份 == "重庆市" replace clock = 3 if 省份 == "重庆市" replace y1 = y1 - 300 if 省份 == "内蒙古自治区" replace clock = 3 if 省份 == "内蒙古自治区" replace y1 = y1 - 300 if 省份 == "陕西省" replace clock = 3 if 省份 == "陕西省" replace x1 = x1 + 1000 if 省份 == "江西省" replace clock = 2 if 省份 == "江西省" replace x1 = x1 - 1200 if 省份 == "海南省" replace clock = 12 if 省份 == "海南省" replace x1 = x1 - 1200 if 省份 == "青海省" replace clock = 12 if 省份 == "青海省"
tw sc 第一产业地区生产总值_亿元 第二产业地区生产总值_亿元, xla(0(10000)50000, nogrid) yla(0(1000)6000, nogrid) leg(off) m(o) || sc y1 x1, mlab(省份) mlabvpos(clock) m(i) mlabsize(*0.7) mlabgap(*0.1) || pcspike 第一产业地区生产总值_亿元 第二产业地区生产总值_亿元 y1 x1, lw(*0.5) ti("2019 年各省市第一、第二产业地区生产总值的关系") xti("第二产业地区生产总值(亿元)") yti("第一产业地区生产总值(亿元)") subti("绘制:微信公众号 RStata") caption("数据来源:国家统计局")
|
其中 clock 变量用以标志每个散点标签的方位:

点击这里跳转到 RStata 短书平台获取附件:Stata 如何创建不重叠标签的散点图 or 将散点标签统一放置在图的右侧并和散点连接起来?
评论