Sankey 与 Matplotlib

Sankey with Matplotlib

在这个 Senkey 中有两个输入:K 和 S,三个输出:H、F 和 Sp,其余的:x

输入应来自左侧,输出应来自右侧。 其余的将登顶。

from matplotlib.sankey import Sankey
import matplotlib.pyplot as plt

fig = plt.figure(figsize = [10,10])
ax = fig.add_subplot(1,1,1)
ax.set(yticklabels=[],xticklabels=[])
ax.text(-10,10, "xxx")

Sankey(ax=ax,  flows = [ 20400,3000,-19900,-400,-2300,800],
              labels = ['K',   'S', 'H',    'F', 'Sp', 'x'],
        orientations = [ 1,    -1,   1,      0,  -1,  -1 ],
scale=1, margin=100,  trunklength=1.0).finish()

plt.tight_layout() 
plt.show()

我玩了很多方向,但没有任何效果或看起来不错。 而且,有没有办法为每个箭头设置不同的颜色?

Sankey 的 scale 应该是输入流时间尺度约为 1.0,输出流时间尺度约为 -1.0 (see docs)。因此,大约 1/25000 是一个很好的实验起点。 margin 应该是一个小数字,可能在 1 左右,或者将其省略。我认为拥有单独颜色的唯一方法是将多个 Sankeys 链接在一起(使用 add),但这可能不是您想要的。使用 plt.axis("off") 完全抑制轴。

我的测试代码:

from matplotlib.sankey import Sankey
import matplotlib.pyplot as plt

fig = plt.figure(figsize = [10,10])
ax = fig.add_subplot(1,1,1)

Sankey(ax=ax,  flows = [ 20400,3000,-19900,-400,-2300,-800],
              labels = ['K',   'S', 'H',   'F', 'Sp',  'x'],
        orientations = [ 1,    -1,   1,     0,   -1,   -1 ],
        scale=1/25000, trunklength=1,
        edgecolor = '#099368', facecolor = '#099368'
      ).finish()
plt.axis("off")
plt.show()

生成的桑基:

有不同的颜色

from matplotlib.sankey import Sankey
import matplotlib.pyplot as plt
from matplotlib import rcParams

plt.rc('font', family = 'serif')
plt.rcParams['font.size']  = 10
plt.rcParams['font.serif'] = "Linux Libertine"

fig    = plt.figure(figsize = [6,4], dpi = 330)
ax     = fig.add_subplot(1, 1, 1,)
s      = Sankey(ax = ax, scale = 1/40000, unit = 'kg', gap = .4, shoulder = 0.05,)

s.add(
    flows        = [3000,     20700,   -23700,], 
    orientations = [ 1,       1,       0, ],
    labels       = ["S Value", "K Value", None, ],
    trunklength = 1, pathlengths = 0.4, edgecolor = '#000000', facecolor = 'darkgreen', 
    lw = 0.5,
)

s.add(
    flows        = [23700,  -800,  -2400,     -20500],
    orientations = [0,       1,    -1,         0], 
    labels       = [None,   "U Value", "Sp Value",  None],
    trunklength=1.5, pathlengths=0.5, edgecolor = '#000000', facecolor = 'grey',
    prior = 0, connect = (2,0), lw = 0.5,
    )

s.add(
    flows        = [20500,  -20000,    -500],
    orientations = [0,      -1,        -1],
    labels       = [None,   "H Value",  "F Value"],
    trunklength =1, pathlengths = 0.5, edgecolor = '#000000', facecolor = 'darkred',
    prior = 1, connect = (3,0), lw = 0.5,
)

diagrams = s.finish() 

for d in diagrams:
    for t in d.texts:
        t.set_horizontalalignment('left')


diagrams[0].texts[0].set_position(xy = [-0.58,  0.9,]) # S 
diagrams[0].texts[1].set_position(xy = [-1.5,   0.9,]) # K 
diagrams[2].texts[1].set_position(xy = [ 2.35, -1.2,]) # H 
diagrams[2].texts[2].set_position(xy = [ 1.75, -1.2,]) # F 
diagrams[1].texts[2].set_position(xy = [ 0.7,  -1.2])  # Sp
diagrams[1].texts[1].set_position(xy = [ 0.7,   0.9,]) # U 

# print(diagrams[0].texts[0])
# print(diagrams[0].texts[1])
# print(diagrams[1].texts[0])
# print(diagrams[1].texts[1])
# print(diagrams[1].texts[2])
# print(diagrams[2].texts[0])
# print(diagrams[2].texts[1]) 
# print(diagrams[2].texts[2])

plt.axis("off") 
plt.show()