Stata+LaTex:绘制流程图

发布时间:2021-06-08 阅读 3072

Stata连享会   主页 || 视频 || 推文 || 知乎

温馨提示: 定期 清理浏览器缓存,可以获得最佳浏览体验。

New! lianxh 命令发布了:
随时搜索推文、Stata 资源。安装:
. ssc install lianxh
详情参见帮助文件 (有惊喜):
. help lianxh

课程详情 https://gitee.com/lianxh/Course

课程主页 https://gitee.com/lianxh/Course

⛳ Stata 系列推文:

PDF下载 - 推文合集

作者: 袁子晴 (香港大学)
邮箱: yzq0612@foxmail.com


目录


⭕ 随后,可以在 连享会:B站 搜索「Latex 流程图」查看本文的视频版。

1. 问题背景

在研究过程中,我们往往需要借助流程图来直观清楚地展示实验步骤、技术路线、逻辑推演等内容,如下图所示。视频演示一个简化的例子,可以点击 Overleaf的案例1项目地址 查看编译后的流程图。通常来说,利用命令可以精准控制图形的形状和位置,对于结构性较强的图形,利用命令画图比手工绘图更值得推荐。

LaTeX 作为论文排版神器,本身有一些命令可以绘制简单的图形,但绘制复杂图形则需要使用一些宏包,其中 TikZ 是最常用的宏包之一。 但是 LaTex 绘图学习成本高且代码繁琐,所以本文将介绍一个 Stata 命令 flowchart 帮助我们生成可以直接在 LaTex 中编译的流程图文件。

2. Stata 实操

2.1 Stata 外部命令介绍

首先通过 ssc install flowchart 来安装外部命令 flowchart ,使用 flowchart 绘制流程图时,其命令结构如下:

 flowchart [命令] [, 选项]

主要命令

  • init :命令格式为 init using filename.data —— 初始化创建用于存储绘图数据的文件(指定文件名或包含文件路径的文件名),该文件后续由 LaTeX 的 datatool 包用来绘图;

  • writerow(..) :按行 (Row) 来创建流程图中的每个区块 (Block);

  • connect :将流程图中的每个区块箭头连接起来;

  • finalize :按照指定模板,将流程图以 TikZ 代码的形式输出,以便后续 LaTeX 编译;

  • setup:安装其他依赖包 ( texdocsjlatex ) 及辅助文件至当前工作路径来确保命令正常运行,选项 [, update] 用来更新 flowchart 命令的安装;

  • debug:命令格式为 debug, [on off logreset info check tikz] —— 打开或关闭调试功能,并产生一个 DebugLog.log 文件,可以指定选项 tikz,在最终的 TikZ 文件中产生调试字符串。

2.2 命令安装及初始化

首先在 Stata 中运行如下命令:

ssc install flowchart
cd "工作路径"  
flowchart setup  // 辅助文件会自动下载到上述指定的工作路径中

3. Stata 绘制流程图

步骤如下:

  1. 指定存储绘图数据的文件名,文件后缀为 .data,例如 flowchart init using "..\Data\Subanalysis Data\methods--fig-flowchart.data";

  2. 从左到右依次指定该行每个区块的名称和内容,例如 flowchart writerow ...

  3. 将不同区块之间用箭头连接起来,例如 flowchart connect

    有以下几种格式:

    • [rowname_center] --> [rowname_left] :水平箭头连接左右区块
    • [rowname_center] --> [rowname_center] :垂直箭头连接上下区块。
    • [rowname_left] --> [rowname_left] : 垂直箭头连接上下区块。
    • , arrow(angle) :这个选项使箭头成90度角。在空白行中使用这个选项。 用下划线连接每一行的区块,然后用这种方式连接与之对应的列方向。
  4. 将上述绘图输出为以 .tikz 为结尾的文件;

  5. 在 LaTex 中将 .tikz 为结尾的文件进行编译。

案例 1:


* TESTS: This is a barebones test file for running tests. Use this as a template
* of the flowchart syntax to follow.
cd "工作路径"
*------------ 第一步:指定存储绘图数据的文件名,文件后缀为 .data------------------*
flowchart init using "filename.data"


*------------ 第二步:从左到右依次指定该行每个区块的名称和内容---------------------*
* |||||| TEST1: Row with 2 blocks.
flowchart writerow(rownametest1): "lblock1_line1" 46 "This is one line, \\ of a block." ///
	"lblock1_line2" 43 "This is another line, of a block" ///
	"lblock1_line3" 3 "This is another line, of a block", ///
	"rblock1_line1" 97 "This is one line, of a block." ///
	"rblock1_line2" 33 "This is another line, of a block" ///
	"rblock1_line3" 44 "This is another line, of a block"

* |||||| TEST2: Row with No center-block (a center-block appears on the left)
flowchart writerow(rownametest2): Flowchart_Blank, ///
	"rblock1_line1" 97 "This is one line, of a block." ///
	"rblock1_line2" 33 "This is another line, of a block" ///
	"rblock1_line3" 44 "This is another line, of a block"

* |||||| TEST3: Row with No left-block (a left-block appears on the right)
flowchart writerow(rownametest3): "lblock1_line1" 46 "This is one line, \\ of a block." ///
	"lblock1_line2" 43 "This is another line, of a block" ///
	"lblock1_line3" 3 "This is another line, of a block", Flowchart_Blank

* 需要注意的是该行左边是没有区块的,只有右边有区块,所以逗号前面用 flowchart_blank 代表空白
* |||||| TEST4: Row with No center-block and a Singleton Lead-Line in the left-block
flowchart writerow(rownametest4): Flowchart_Blank, "rblock1_line1" 97 "This is one line, \\ of a block."
	
* |||||| TEST5: Row with Singleton Lead-Line in the center-block and No left-block
flowchart writerow(rownametest5): "lblock1_line1" 46 "This is one line, \\ of a block.", Flowchart_Blank

*--------------- 第三步:将不同区块之间用箭头连接起来 ---------------------*
* |||||| CONNECTIONS: Use the block orientation to connect arrows to the appropriate blocks
flowchart connect rownametest1_center rownametest1_left
flowchart connect rownametest1_left rownametest2_left
flowchart connect rownametest1_center rownametest3_center
flowchart connect rownametest3_center rownametest5_center
flowchart connect rownametest2_left rownametest4_left

*--------------- 第四步:将上述绘图输出为以 .tikz 为结尾的文件 ---------------------*
* |||||| FINALIZE: This writes the files and generates the 'tikzpicture'
flowchart finalize, template("figure-flowchart.texdoc") output("figure.tikz")

案例 2:

*------------ 第一步:指定存储绘图数据的文件名,文件后缀为 .data------------------*
flowchart init using "methods--figure-flowchart.data"


*------------ 第二步:从左到右依次指定该行每个区块的名称和内容---------------------*
* 命令格式: flowchart writerow(行名): [区块1] , [区块2],同一行从左到右不同区块之间用逗号隔开
* 区块内部格式: "区块名" n= "区块内文本"

* 首先生成一行,行名为 enrollment;
* 生成该行左边第一个区块,区块名为 referred,后面是该区块内容 Referred (n=173),数字173,最终呈现为 (n=173),在本例中代表子样本容量;
* 用逗号分隔后,生成右边第二个区块,区块名为 referred_excluded, 后面全部是该区块的文本内容,该区块内部由三行组成,分别指定了每行的名称、子样本容量和文本内容。
flowchart writerow(enrollment): ///   
    "referred" 173 "Referred", ///
    "referred_excluded" 17 "Excluded" ///
        "referred_excluded_nopartic" 9 "a) Did not wish to participate" ///
        "referred_excluded_noshow" 5 "b) Did not show for interview" ///
        "referred_excluded_other" 3 "c) Other reasons"
    
flowchart writerow(assessment): ///
    "assessed" 156 "Assessed for Eligibility", ///
    "assessed_excluded" 54 "Excluded" ///
        "assessed_excluded_inclusioncritunmet" 22 "a) Inclusion criteria not met" ///
        "assessed_excluded_exclusioncritmet" 13 "b) Exclusion criteria met" ///
        "assessed_excluded_unsuitedgroup" 7 "c) Not suited for waitlist group" ///
        "assessed_excluded_unsuitedtx" 2 "d) Not suited for intervention" ///
        "assessed_excluded_othertx" 3 "e) Sought other treatment" ///
        "assessed_excluded_other" 7 "f) Other reasons"

flowchart writerow(random): "randomized" 102 "Randomized", flowchart_blank // Blank Row

flowchart writerow(allocgroup): ///
    "alloc_interventiongroup" 51 "Allocated to Intervention group", ///
    "alloc_waitlistgroup" 51 "Allocated to Wait-list control group"

flowchart writerow(allocdetails): ///
    "intervention_received" 49 "Received intervention" ///
        "intervention_unreceived" 2 "Did not receive intervention" ///
        "intervention_unreceived_exclusioncrit" 1 "With exclusionary criteria" ///
        "intervention_unreceived_notime" 1 "Could not find time to participate", ///
    "waitlist_stayedon" 48 "Stayed on wait-list" ///
        "waitlist_didnotstay" 3 "Did not stay on wait-list" ///
        "waitlist_didnotstay_selfinduced" 2 "Lost motivation" ///
        "waitlist_didnotstay_leftarea" 1 "Was offered treatment elsewhere"
    
flowchart writerow(postmeasurement): ///
    "postintervention_lost" 5 "Post-intervention measurement" ///
        "postintervention_lost_droppedout" 2 "Dropped out of the intervention" ///
        "postintervention_lost_nomeasurement" 3 "Did not complete measurement", ///
    "postwaitlist_lost" 6 "Post-wait-list measurement" ///
        "postwaitlist_lost_droppedout" 3 "Dropped out of the wait-list" ///
        "postwaitlist_lost_nomeasurement" 3 "Did not complete measurement" ///
    
flowchart writerow(wlistintervention): flowchart_blank, /// 
    "postwaitlist_intervention_allocated" 48 "Allocated to intervention" ///
        "postwaitlist_intervention_received" 46 "Received intervention" ///
        "postwaitlist_intervention_didnotreceive" 2 "Did not receive intervention" ///
        "postwaitlist_intervention_dnr_lowmotivation" 1 "Reported low motivation" ///
        "postwaitlist_intervention_dnr_notime" 1 "Could not find time to participate"
    
flowchart writerow(measurement3monpostint): ///
    "intervention_3monthfollowup" 9 "3-months follow-up measurement: \\ \h Loss to follow-up", ///
    "postwaitlist_postintervention_losstofollowup" 5 "Post-intervention measurement: \\ \h Loss to follow-up" ///
        "postwaitlist_postintervention_losstofollowup_droppedout" 2 "Dropped out of the intervention" ///
        "postwaitlist_postintervention_losstofollowup_incomplete" 3 "Did not complete measurement"

* 需要注意的是该行左边是没有区块的,只有右边有区块,所以逗号前面用 flowchart_blank 代表空白
flowchart writerow(wlist3mon): flowchart_blank, ///
    "postwaitlist_3monthfollowup" 2 "3-months follow-up measurement \\ \h Did not complete measurement"
    
flowchart writerow(analyzed): ///
    "intervention_analyzed" 51 "Analyzed in Intervention group", ///
    "postwaitlist_analyzed" 51 "Analyzed in Wait-list control group"

*--------------- 第三步:将不同区块之间用箭头连接起来 ---------------------*
flowchart connect enrollment_center enrollment_left
flowchart connect enrollment_center assessment_center
flowchart connect assessment_center assessment_left
flowchart connect assessment_center random_center
flowchart connect random_center allocgroup_center
flowchart connect random_center allocgroup_left, arrow(angled)
flowchart connect allocgroup_center allocdetails_center
flowchart connect allocgroup_left allocdetails_left
flowchart connect allocdetails_center postmeasurement_center
flowchart connect allocdetails_left postmeasurement_left
flowchart connect postmeasurement_center measurement3monpostint_center
flowchart connect measurement3monpostint_center analyzed_center
flowchart connect postmeasurement_left wlistintervention_left
flowchart connect wlistintervention_left measurement3monpostint_left
flowchart connect measurement3monpostint_left wlist3mon_left
flowchart connect wlist3mon_left analyzed_left 

*--------------- 第四步:将上述绘图输出为以 .tikz 为结尾的文件 ---------------------*
flowchart finalize, template("figure-flowchart.texdoc") output("methods--figure-flowchart.tikz")

4. Latex 编译流程图

在进行 LaTex 编译之前,我们需要做以下准备工作:

  • LaTex 工作路径下需要放置:绘图文件 methods--figure-flowchart.tikz,以及 LaTex 在使用 datatool 宏包编译的过程中还需要的 methods--figure-flowchart.data
  • LaTex 编译的主文件 main.tex 里面在正文开始前需要加载相应的宏包以便后续调用
  • LaTex 在 figure 环境中加载以 .tikz 结尾的绘图文件

Latex 编译过程中整体的文件结果如下:

  • main.tex 主要编译文件,在此基础上进行编译;
    • methods--figure-flowchart.tex 编译子文件,在 figure 环境中加载以 .tikz 结尾的绘图文件;
      • methods--figure-flowchart.tikz Stata 输出的绘图文件;
      • methods--figure-flowchart.data Stata 存储绘图数据的文件,在LaTex 使用datatool 宏包编译的过程中需要。

案例 1:

  • main.tex 是用于编译的主文档
\documentclass{article}
%---------- 加载所需宏包及自定义命令------------------%
%% Package Declarations
\usepackage[utf8]{inputenc} % Document Encoding
	\renewcommand{\rmdefault}{ppl}	% Font Changes - PPL = Palatino
% Layout Management 排版管理宏包
\usepackage[left=2cm,right=2cm,top=2cm,bottom=2cm]{geometry}
\usepackage{multicol}
% Design 版面设计宏包
\usepackage{xcolor}		% Design - Custom Colors
\usepackage{graphicx} 	% Design - Graphics Packages
% 	Figures, Diagrams, and Other Graphics 生成图表所需宏包
\usepackage{tikz}		% TikZ Package - Generates graphics (i.e., flowcharts)
	\usetikzlibrary{shapes,arrows}
	\newcommand*{\h}{\hspace{5pt}}% For indentation
	\newcommand*{\hh}{\h\h}% Double indentation
\usepackage{datatool}	% DataTool Package - Loads Subanalysis Data to generate flowchart 数据工具包--加载子分析数据以生成流程图
	\DTLsetseparator{ = }% Delimiter
\newcommand{\symbcomma}{,}	% Work-Around: Put a comma into a number with \symbcomma without breaking the Stata code
% Biostatistics 生物统计学宏包
\usepackage{amsmath} 	% Equations - Handler
	\usepackage{amsfonts} 	% Equations - Display
	\usepackage{amssymb} 	% Equations - Symbols
\usepackage{fontenc}
%-------------------------------------------%
\title{LaTex-flowchart 演示}
\author{}
\date{}

%----------------- 正文 --------------------%
\begin{document}

% 插入流程图子文件
\input{figure.tex}   


\end{document}
  • Figure.tex 是包含了绘图文件和绘图数据的子文档,这里需要修改两个地方,一是加载的数据文件,即filename.data,二是 LaTeX 的 input 命令插入的流程图文件 figure.tikz
\begin{figure}
\begin{center}
%% Load Subanalysis Data for Figure into \figvalue{} commands
\DTLloaddb[noheader, keys={subanakey,subanavalue}]{subanalysis-flowchart}{"filename.data"}
\newcommand{\figvalue}[1]{\DTLfetch{subanalysis-flowchart}{subanakey}{#1}{subanavalue}}
  % Style - Setting the typeface to sans serif and the font size to small
  % 	(the scope of this style is local to the environment)
  \sffamily
  \footnotesize
  \input{figure.tikz}
  \caption{Subject disposition flowchart of analytic sample data.} \label{fig:StudyFlowchart}
\end{center}
\end{figure}
  • 最后,在 main.tex 文档上进行编译,可以点击 Overleaf 的案例1项目地址 查看编译后的流程图,即文章开头演示的流程图。

案例 2:

此外,作者提供的案例2的编译过程在此不再赘述,可以直接点击浏览该项目,最终的流程图如下图所示:

5. 参考文献

6. 相关推文

Note:产生如下推文列表的 Stata 命令为:
lianxh latex
安装最新版 lianxh 命令:
ssc install lianxh, replace

相关课程

免费公开课

最新课程-直播课

专题 嘉宾 直播/回看视频
最新专题 文本分析、机器学习、效率专题、生存分析等
研究设计 连玉君 我的特斯拉-实证研究设计-幻灯片-
面板模型 连玉君 动态面板模型-幻灯片-
面板模型 连玉君 直击面板数据模型 [免费公开课,2小时]
  • Note: 部分课程的资料,PPT 等可以前往 连享会-直播课 主页查看,下载。

课程主页

课程主页

关于我们

  • Stata连享会 由中山大学连玉君老师团队创办,定期分享实证分析经验。
  • 连享会-主页知乎专栏,400+ 推文,实证分析不再抓狂。直播间 有很多视频课程,可以随时观看。
  • 公众号关键词搜索/回复 功能已经上线。大家可以在公众号左下角点击键盘图标,输入简要关键词,以便快速呈现历史推文,获取工具软件和数据下载。常见关键词:课程, 直播, 视频, 客服, 模型设定, 研究设计, stata, plus, 绘图, 编程, 面板, 论文重现, 可视化, RDD, DID, PSM, 合成控制法

连享会小程序:扫一扫,看推文,看视频……

扫码加入连享会微信群,提问交流更方便

✏ 连享会-常见问题解答:
https://gitee.com/lianxh/Course/wikis

New! lianxh 命令发布了:
随时搜索连享会推文、Stata 资源,安装命令如下:
. ssc install lianxh
使用详情参见帮助文件 (有惊喜):
. help lianxh