![使用 Sankey 包绘制闭环流程图](https://linux22.com/image/451431/%E4%BD%BF%E7%94%A8%20Sankey%20%E5%8C%85%E7%BB%98%E5%88%B6%E9%97%AD%E7%8E%AF%E6%B5%81%E7%A8%8B%E5%9B%BE.png)
我想使用 LaTeX Sankey 包绘制以下闭环循环流程图,其中箭头的宽度或厚度表示它们所代表的流量的大小。
Green Plants
主要的挑战是如何从标有、Animals
和Decay
的框中创建闭环Fuel
后退朝向标记CO2 in atmosphere and dissolved in water
为整体闭环系统一部分的框。
上图没有指定每个流的数量,但我需要这样做。一旦确定了每个流的数量,我需要做的就是能够标记每个流(在每个箭头内或旁边)。
一个额外的优点是如果存在一个 GUI 应用程序(在线或桌面 Mac),可以用来创建/生成上述 Sankey 图的 LaTeX 代码,包括闭环流和所有必要的标签。
另一个优点是指定每个 Sankey 箭头/流的颜色,例如,区分材料的相对流量Decay
。例如,我想为从 到 的箭头指定不同的颜色,Green Plants
而不是Animals
延伸Decay
到 的箭头CO2 in atmosphere and dissolved in water
。
数据并非一成不变,会随时间而变化,因此我需要灵活地调整每个桑基箭头以适应数据。根据实际数据可用性,最终桑基图中的桑基箭头可能会比上图所示多出几个/很多。
这是一个很大的要求……它是正在开发的更大信息的一部分,我从未在其他地方看到过。LaTeX 是一个很棒的工具,我想知道我能用它走多远。
PS 我知道 smartdiagram 包会创建圆形闭环图,但是不是使用 Sankey 包的不同宽度箭头。
更新:一名编程缓慢者的道歉……特别是针对 sankey 包的作者 Paul Gaborit。
自从我上次发帖以来,我花了很长时间重新审视简单示例Sankey 包中提供。我不再像以前那么快了(并且没有任何 GUI 应用程序),我花了一些时间来学习 Sankey 代码并应用我所学到的知识。
当我意识到 Gaborit 的 Sankey 包可以提供我所寻找的东西时,我希望提供一个不那么贫乏的解决方案,这样我就可以避免因我的进步而感到尴尬。话虽如此,以下是我迄今为止组装的代码转储(今天我再次登录时才发现 Paul 的代码发布了一个令人惊叹的图形解决方案):
\documentclass{article}
\usepackage{tikz}
\usepackage{sankey}
\begin{document}
\begin{tikzpicture}
\begin{sankeydiagram}[debug=true] %[debug]
\colorlet{cold}[rgb]{cyan!75!blue!50!white}
\colorlet{hot}[rgb]{red!50!orange!75!white}
\sankeyset{ ratio=90pt/6,minimum radius=15pt, start style=simple,end style=simple,
draw/.style={ draw=blue!50!cyan, line width=1pt,line cap=round,line join=round, },
cold/.style={ fill/.style={ draw=cold,line width=0pt,fill=cold, }, },
cold to hot/.style={ fill/.style={ fill=none,top color=cold, bottom color=hot,middle color=yellow, },},
hot/.style={ fill/.style={ draw=hot,line width=0pt,fill=hot, }, }, }
\sankeyset{ debug color/.style={/utils/exec={\colorlet{debug color}{#1}}}, % debug color used by all debug macros
debug color=red!75!black, % debug line between left and right anchors
debug line/.style={overlay,draw=debug color,|-|}, % debug line between center and label
debug normal/.style={overlay,draw=debug color}, % debug node label
debug label/.style={ overlay, draw, font=\ttfamily\tiny,
text=debug color,text opacity=1, inner sep=.1em,
fill=white,fill opacity=1, rounded corners=.1em,
node contents={\name}, }, }
\sankeyset{cold}
\sankeynodestart{name=p0,at={100,0},angle=0,quantity=6}
\sankeyadvance{p0}{50pt}
\sankeyfork{p0}{3/p1,3/p2}
\sankeyturnleft{p1}{90}
\sankeyadvance{p1}{30pt}
\sankeyturnright{p2}{90}
\sankeyadvance{p2}{20pt}
\sankeyfork{p2}{2/p3,1/p4}
\sankeyadvance{p3}{30pt}
\sankeyturnright{p3}{90}
\sankeyadvance{p3}{185pt}
\sankeyfork{p3}{1/p5,1/p6}
\sankeyadvance{p5}{50pt}
\sankeyfork{p1}{1/p8,1/p7,1/p9}
\sankeyadvance{p7}{10pt}
\sankeyadvance{p9}{60pt}
\sankeyturnleft{p9}{90}
\sankeyadvance{p9}{230pt}
\sankeyturnright{p4}{90}
\sankeyadvance{p4}{200pt}
\sankeyadvance{p7}{20pt}
\sankeyturnleft{p7}{90}
\sankeyadvance{p7}{200pt}
\sankeynode{ name=p11,at={[shift={(-20pt,-120pt)}]p7},angle=0,quantity=3, forked={1/p7a,1/p9a,1/p5a}, }
\sankeyoutin{p7}{p7a}
\sankeyoutin{p9}{p9a}
\sankeyoutin{p5}{p5a}
\sankeyadvance{p11}{30pt}
\sankeyend{p11}
\sankeyturnleft{p8}{90}
\sankeyadvance{p6}{43pt}
\sankeyturnright{p6}{75}
\sankeyturnright{p4}{90}
\sankeyset{hot}
\sankeyadvance[cold to hot]{p8}{160pt}
\sankeynode{ name=p10,at={[shift={(-45pt,-140pt)}]p8},angle=0,quantity=3, forked={1/p8a,1/p6a,1/p4a}, }
\sankeyoutin[cold to hot]{p4}{p4a}
\sankeyoutin[cold to hot]{p6}{p6a}
\sankeyoutin{p8}{p8a}
\sankeyadvance{p10}{30pt}
\sankeynode{ name=p12,at={[shift={(+50pt,-22.5pt)}]p11},angle=0,quantity=6, forked={3/p11a,3/p10a}, }
\sankeyoutin[cold to hot]{p10}{p10a}
\sankeyoutin[cold to hot]{p11}{p11a}
\sankeyadvance{p12}{80pt}
\sankeyend{p12}
\end{sankeydiagram}
\end{tikzpicture}
\end{document}
上面的代码为我提供了以下桑基图:
请注意,我没有调整流动颜色,部分是为了将上面的图片链接回简单示例Sankey 包中提供。当我学习如何使用 Paul 的这个神奇包时,我需要一步步地学习。
Paul 针对我最初的问题提供的解决方案代码(他 7 小时前提供的)远远超出了我花很多天编码所能够完成的范围。
感谢 Paul 提供的出色图形包。我需要几天时间才能通读您的代码解决方案,以便将适当的宽度应用于您提供的图形中的每个流程。
答案1
sankey
这是一个使用包和任意值的示例!
\documentclass[tikz]{standalone}
\usepackage{sankey}
\newcommand{\sankeyarrow}[1]{\draw (#1.left) -- ($(#1)!.5!90:(#1.right)$) -- (#1.right);}
\begin{document}
\begin{tikzpicture}
\begin{sankeydiagram}
\sankeynode{name=CO2,quantity=40}
\sankeyfork{CO2}{10/RMGP-e,10/C-e,10/RMA-e,10/D-e}
\sankeyadvance{CO2}{4cm}
\fill[gray](CO2-old.left) rectangle (CO2.right);
\node[align=flush center,text width=3cm] at ($(CO2-old)!.5!(CO2)$) {CO2 in atmosphere and dissolved in water};
\sankeyadvance{CO2}{4cm}
\node[align=flush center,text width=3cm] at ($(CO2-old)!.5!(CO2)$) {Photosynthesis};
\sankeyadvance{CO2}{2cm}
\sankeyarrow{CO2-old}
\sankeyadvance{CO2}{4cm}
\fill[fill=lime!80!black](CO2-old.left) rectangle (CO2.right);
\node[align=flush center,text width=3cm] at ($(CO2-old)!.5!(CO2)$) {Green Plants};
\sankeyfork{CO2}{10/RMGP,10/Fuel,15/Animals,5/DeathGP}
\sankeyturnleft{RMGP}{180}
\sankeyadvance{RMGP}{4cm}
\node[align=flush center,text width=3cm] at ($(RMGP-old)!.5!(RMGP)$) {Respiration \& Metabolism};
\sankeydubins{RMGP}{RMGP-e}
\sankeyarrow{RMGP}
\sankeyadvance{Fuel}{1.5cm}
\sankeyturnleft{Fuel}{90}
\sankeyadvance{Fuel}{3cm}
\sankeyturnleft{Fuel}{90}
\sankeyadvance{Fuel}{4cm}
\fill[fill=orange](Fuel-old.left) rectangle (Fuel.right);
\node[align=flush center,text width=3cm] at ($(Fuel-old)!.5!(Fuel)$) {Fuel};
\sankeyadvance{Fuel}{4cm}
\node[align=flush center,text width=3cm] at ($(Fuel-old)!.5!(Fuel)$) {Combustion};
\sankeyadvance{C-e}{-1.5cm}
\sankeyarrow{C-e}
\sankeyturnleft{C-e}{-90}
\sankeyadvance{C-e}{-3cm}
\sankeyturnleft{C-e}{-90}
\sankeydubins{Fuel}{C-e}
\sankeyarrow{Fuel}
\sankeyadvance{Animals}{1.5cm}
\sankeyturnright{Animals}{90}
\sankeyadvance{Animals}{3cm}
\sankeyturnright{Animals}{90}
\sankeyadvance{Animals}{4cm}
\fill[pink](Animals-old.left) rectangle (Animals.right);
\node[align=flush center,text width=3cm] at ($(Animals-old)!.5!(Animals)$) {Animals};
\sankeyfork{Animals}{10/RMA,5/DeathA}
\sankeyturnright{DeathA}{90}
\sankeyturnleft{DeathA}{90}
\sankeynode{
name=Death,quantity=10,angle=180,
forked={5/DeathA-e,5/DeathGP-e},
fork anchor=DeathA-e.center,
at=DeathA.center,
}
\sankeyturnright{DeathGP}{90}
\sankeydubins{DeathGP}{DeathGP-e}
\sankeyadvance{Death}{3cm}
\node[align=flush center,text width=3cm] at ($(Death-old)!.5!(Death)$) {Death};
\sankeyadvance{Death}{5mm}
\sankeyarrow{Death-old}
\sankeyadvance{Death}{4cm}
\fill[cyan!50!blue!50](Death-old.left) rectangle (Death.right);
\node[align=flush center,text width=3cm] at ($(Death-old)!.5!(Death)$) {Decay};
\sankeydubins{Death}{D-e}
\sankeyadvance*{RMA-e}{1.5cm}
\sankeyarrow{RMA-e}
\sankeyturnright*{RMA-e}{90}
\sankeyadvance*{RMA-e}{4cm}
\sankeyadvance{RMA}{4cm}
\node[align=flush center,text width=3cm] at ($(RMA-old)!.5!(RMA)$) {Respiration \& Metabolism};
\sankeydubins{RMA}{RMA-e}
\sankeyarrow{RMA}
\end{sankeydiagram}
\end{tikzpicture}
\end{document}