使用 Sankey 包绘制闭环流程图

使用 Sankey 包绘制闭环流程图

我想使用 LaTeX Sankey 包绘制以下闭环循环流程图,其中箭头的宽度或厚度表示它们所代表的流量的大小。

Green Plants主要的挑战是如何从标有、AnimalsDecay的框中创建闭环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}

在此处输入图片描述

相关内容