Stata绘图:绘制桑基图-sankey_plot

发布时间:2022-05-11 阅读 2272

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下载 - 推文合集

作者:强皓凡 (复旦大学)
邮箱:hfqiang21@m.fudan.edu.cn


目录


1. 什么是桑基图

根据百度百科的定义,桑基图 (Sankey diagram),即桑基能量分流图,也叫桑基能量平衡图。它是一种特定类型的流程图,图中延伸的分支的宽度对应数据流量的大小,通常应用于能源、材料成分、金融等数据的可视化分析。因 1898 年 Matthew Henry Phineas Riall Sankey 绘制的 “蒸汽机的能源效率图” 而闻名,此后便以其名字命名为 “桑基图”。

桑基图最明显的特征就是,始末端的分支宽度总和相等,即所有主支宽度的总和应与所有分出去的分支宽度的总和相等,保持能量平衡。本文将着重分享使用 Stata 中的 sankey_plot 命令来制作桑基图的过程。

2. sankey_plot 命令介绍

sankey_plot 命令安装:

net describe http://repec.org/bocode/s/sankey_plot
net install sankey_plot, replace 
net get sankey_plot,     replace  // 获取数据和范例
ssc install palettes,    replace
ssc install colrspace,   replace 

sankey_plot 命令语法:

sankey_plot x0 y0 x1 y1 [if] [in] [, sankey_options twoway_options]

其中,Sankey 坐标选项:

  • x0 y0 x1 y1:必需参数,提供了要绘制的坐标和分组。(x0, y0) 表示原点,(x1 , y1) 表示终点。该值标识节点。X0 和 x1 必须是数值,y0 和 y1 可以是数字或字符串,但不能两者都是。如果它们是字符串,这些值将被用作标签来识别节点;
  • width0(varname):提供一个具有原点 (x0, y0) 的权值或宽度的变量,默认是 0.01;
  • width1(varname):在目标 (x1,y1) 处提供一个具有权值或宽度的变量,默认值是 width0 中的值。

Sankey 外观选项:

  • sharp(#):使用 # 定义更改连接段或链接的外观,默认是 7,必须大于 0,值为 1 时产生一条直线;
  • adjust:调整 Y 轴坐标以避免节点之间的重叠。请注意,调整后的节点位置仍将保持在原始值的 “附近”;
  • extra:基于 width0 和/或 width1 调整 Y坐标。有了这个选项,节点之间就不会有重叠。可以与 adjust 结合使用,得到更美观的结果;
  • gap(#):与 extra 一起使用。当使用 extra 时,请求在同一级别的节点之间添加一个 “间隙”;
  • noline:请求在没有边框的情况下绘制流线;
  • nobar:请求不绘制连接流线的节点块,即后文实例1中每个节点标签处突出显示的色块。

Sankey bar 和 label 选项:

  • bwidth(#):如果连接流线的节点块 (Bar) 被保留,这可以用来修改其宽度,0.025 为默认值;
  • bheight(#):当使用时,这将修改所有连接流线的节点块 (Bar) 的高度,默认是使用链接总和的高度;
  • bcolor(colorstyle):使用时,可以修改连接流线的节点块 (Bar) 的颜色;
  • label0(varname):给起点坐标打上标签,必须为字符串格式,无默认值,如果 y0 和 y1 是字符串,则不需要;
  • label1(varname):给终点坐标打上标签,必须为字符串格式,如果有,则默认为 label0。如果 y0 和 y1 是字符串,则不需要;
  • labangle(#):当提供了 lable0 时,可以使用这个选项修改标签的角度,默认值为 0;
  • labpos(#):当提供了 lable0 时,可以使用这个选项修改标签的位置。默认是将标签放置在第一级的右边,最后一级的左边;
  • labsize(#):当提供了 lable0 时,可以使用这个选项修改标签文本的大小;
  • labcolor(colorstyle):当提供了 lable0,或者 y0、y1 是字符串时,可以使用这个选项修改标签文本的颜色。

Sankey 颜色/样式选项:

  • pstyle(varname):可以提供一个变量,预先分配样式给特定的片段;
  • color(varname):可以提供一个变量,为特定的连接预先分配颜色,不能与 bcolorfillcolor 选项结合使用;
  • fillcolor(color):可以使用此选项为所有连接定义单一的某种颜色;
  • colorpalette(options):这个选项允许使用 Ben Jann 的 colorpalette,且大多数配色选项都是允许的。但是,透明度选项 opacity() 只会影响连接的流线的透明度深浅,而不会影响连接流线的节点块 (Bar)。

Sankey 实验性选项:

  • wide:这是一个实验性的选择。当数据中的每个变量对应于不同的水平级别时,可以使用它;
  • width(varname):如果使用了 wide 选项,则应该使用该选项定义每个流的权重;
  • tight:如果使用了 wide 选项,则该选项会 “压缩” 类别,以避免来自相同节点的多个流分开出现。

接下来,我们对 sankey_plot 命令进行一些概括描述。sankey_plot 是一个旨在促进在 Stata 中创建 Sankey 图的模块。此命令不进行任何数据处理,并假定数据已准备好。

桑基图的核心就是成对的连接坐标:从 (x0, y0) 到 (x1, y1)。这些点与宽度与 width0width1 成比例的流相连。x0 和 x1 标识绘图的垂直水平,这些变量必须是数字。y0 和 y1 标识级别内的不同组。这些变量可以是字符串的数字,但不能同时是两者。使用字符串变量时,这些值将用作级别内不同组的标签。

调整坐标有两个主要选项:

  • adjust:调整坐标,使组内的流没有重叠;
  • extra:根据 width0width1 调整坐标,使组之间没有重叠。

该命令还允许用户使用命令 colorpalatte 从不同的调色板中进行选择,仅在正确安装时可用。

3. 实例演示

3.1 大陆间移民

在本节,我们将使用 immigration.dta 依次绘制不同样式的桑基图。immigration.dta 数据为跨大陆移民流动的数据,包含 5 个变量,具体如下:

. use immigration, clear
. list in 1/10

     +-------------------------------------------------+
     |            from          to     value   x0   x1 |
     |-------------------------------------------------|
  1. |          Africa      Africa   3.14247    1    2 |
  2. |       East Asia   East Asia     1.631    1    2 |
  3. |      South Asia   East Asia   .525881    1    2 |
  4. | South East Asia   East Asia   .145264    1    2 |
  5. |          Africa      Europe   2.10788    1    2 |
     |-------------------------------------------------|
  6. |       East Asia      Europe   .601265    1    2 |
  7. |          Europe      Europe   2.40148    1    2 |
  8. |   Latin America      Europe   1.76259    1    2 |
  9. |   North America      Europe   1.21593    1    2 |
 10. |         Oceania      Europe    .17037    1    2 |
     +-------------------------------------------------+

首先,绘制最简单版本的桑基图。在以下命令中,x0x1 分别为代表起点和终点的两个数值,而 fromto 则是两个字符串变量,会在绘图时被用作标签。此时绘制的桑基图,只能为读者呈现各个起始点、终止点及彼此间是否有联系的简单信息。

. sankey_plot x0 from x1 to

接下来,我们可以通过 width0 来调整两端连线的宽度,这里设置为默认值 0.01 的 10 倍,即 0.1。

. gen w0 = 0.1
. sankey_plot x0 from x1 to, width0(w0)

当一个终点与多个起点之间发生连接时,会出现肉眼不易识别的交叠现象。为此,可以使用 adjust 选项来避免交叠问题。

. sankey_plot x0 from x1 to, width0(w0) adjust

如果不人为地设置线宽,而是使用本身的流量值 value 来作为线宽,那么所有的流线都会出现交叠,出现严重的无法阅读信息的问题。

. sankey_plot x0 from x1 to, width0(value)

在使用 value 流量值做线宽的情形下,即便使用 adjust 也无法解决可读性问题。

. sankey_plot x0 from x1 to, width0(value) adjust

有一种对上述问题进行边际改进的方法,即使用 extra 来调整坐标位置。

. sankey_plot x0 from x1 to, width0(value) extra

如果在使用 extra 的同时,也使用 adjust,则可进一步改进桑基图的可读性。

. sankey_plot x0 from x1 to, width0(value) extra adjust

接着,可以调整配色方案,便于读者阅读,比如使用全灰色的配色 fillcolor(gs12)

. sankey_plot x0 from x1 to, width0(value) extra adjust fillcolor(gs12)

或者,也可以调整其透明度 fillcolor(%50)

. sankey_plot x0 from x1 to, width0(value) extra adjust fillcolor(%50)

还可以增加节点之间的空隙,比如使用 gap(0.1)

. sankey_plot x0 from x1 to, width0(value) extra adjust fillcolor(%50) gap(0.1)

或许你不满意于默认的配色方案,那么可以使用 colorpalette() 来调配。例如,本例中还使用了透明度调整和不加流线的外框线的设置,来展现更为清晰的流线走向。其中,opacity() 取值为0-100,0 为完全透明,100 为完全不透明。

. sankey_plot x0 from x1 to, width0(value) extra adjust colorpalette(viridis, opacity(40)) gap(0.1) noline

还可以增加两端节点的名称,使用 xlabel() 来加以标注。

. sankey_plot x0 from x1 to, width0(value) extra adjust colorpalette(viridis, opacity(40)) ///
>     gap(0.1) noline xlabel(1 "Source" 2 "Destination", nogrid)

更改一种配色方案、透明度和节点间距。

. sankey_plot x0 from x1 to, width0(value) extra adjust colorpalette(economist, opacity(30)) ///
>     gap(0.15) noline xlabel(1 "Source" 2 "Destination", nogrid)

最后,可以加入图表题 title() 和注释内容 note()

. sankey_plot x0 from x1 to, width0(value) extra adjust colorpalette(HSV intense,opacity(40)) ///
>     gap(0.1) noline xlabel(1 "Source" 2 "Destination", nogrid) title("Migration flows")     ///
>     note("Note: Abel, Guy J (2017) Estimates of Global Bilater tion Flows by Gender between 1960 and 2015")

3.2 就业市场流动

在本节,我们将使用 jobmarket.dta 数据依次绘制不同样式的桑基图。本数据集是就业市场数据,包含数周内就业市场流动的情况,包含 7 个变量,具体如下:

. use jobmarket, clear
. list in 1/10

     +----------------------------------------------------------------------------------+
     | y0   y1   week0   week1                 label0                 label1   candid~s |
     |----------------------------------------------------------------------------------|
  1. |  1    1       0       1     Jobs Applied to 32             Replies 15         15 |
  2. |  1    2       0       1     Jobs Applied to 32           Rejections 5          5 |
  3. |  1    3       0       1     Jobs Applied to 32            No Reply 12         12 |
  4. |  1    1       1       2             Replies 15   Initial Interviews 9          9 |
  5. |  1    2       1       2             Replies 15     Replied too late 6          6 |
     |----------------------------------------------------------------------------------|
  6. |  1    1       2       3   Initial Interviews 9       Task Requested 4          4 |
  7. |  1    2       2       3   Initial Interviews 9     No Task Required 1          1 |
  8. |  1    3       2       3   Initial Interviews 9       Rejected by me 2          2 |
  9. |  1    4       2       3   Initial Interviews 9           Rejections 2          2 |
 1.  |  1    1       3       4       Task Requested 4      Final Interview 5          4 |
     +----------------------------------------------------------------------------------+

首先做出最基本的桑基图,反映每周之间的变化情况。

. sankey_plot week0 y0 week1 y1

若想保持与上面相同的形状,但使用提供的宽度,则可以重新调整 Y0 和 Y1 坐标。

. gen y00=y0*10
. gen y11=y1*10
. sankey_plot week0 y00 week1 y11, width0(candidates) adjust

接下来,可以调整颜色、标签和轴坐标。

. sankey_plot week0 y00 week1 y11, width0(candidates) adjust xlabel(0 " " 1 "Week 1" 2 ///
>     "Week 2" 3 "Week 3" 4 "Week 4" 5 "Week 5" 6 "Week 6", nogrid) fillcolor(gs12%50) ///
>     label0(label0) label1(label1) xsize(10) ysize(6)

最后,使用 extra 命令调整节点的位置,使图形更为紧凑。

. sankey_plot week0 y00 week1 y11, width0(candidates) adjust extra xlabel(0 " " 1 ///
>     "Week 1" 2 "Week 2" 3 "Week 3" 4 "Week 4" 5 "Week 5" 6 "Week 6", nogrid)    ///
>     fillcolor(gs12%50) label0(label0) label1(label1) xsize(10) ysize(6)

3.3 宠物、婚姻和幸福

在本节,我们将使用 dogs_and_happiness.dta 依次绘制不同样式的桑基图。本数据具有与上述内容不同的结构,没有使用一对一的坐标,而是使用变量来识别跨节点的流,这需要稍微不同的语法。本数据集包含 4 个变量,具体如下:

. use dogs_and_happiness, clear
. list

     +------------------------------------------+
     |     married       pet       happy   freq |
     |------------------------------------------|
  1. | Married:Yes   Pet:Yes   Happy:Yes      5 |
  2. | Married:Yes   Pet:Yes   Happy:Yes      4 |
  3. | Married:Yes    Pet:No   Happy:Yes      3 |
  4. |  Married:No   Pet:Yes   Happy:Yes      2 |
  5. |  Married:No    Pet:No    Happy:No      1 |
     +------------------------------------------+

首先,绘制最基本的桑基图,请注意我们此时拥有三个节点,而非两个。

. sankey_plot married pet happy, wide width(freq)

接着,我们调整颜色和节点间距,并且去掉轴坐标。

. sankey_plot married pet happy , wide width(freq) fillcolor(%50) xlabel("", nogrid) gap(0.1)

最后,注意到有 2 组同时连接着 MarriedPetHappy,故而可以使用 tight 命令加以合并,并且添加主标题 title() 、副标题 subtitle() 和注释 note() 等内容。

. sankey_plot married pet happy , wide width(freq) fillcolor(%50) xlabel("",nogrid)          ///
>     gap(0.1) tight title("The Secret to Happyness") subtitle("Have Pets: Nora and Bruce!") ///
>     note("Nora and Bruce belong to my wife and I")

4. 相关推文

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