Предполагая, что ваши входные значения являются показанными процентами, ваша цель может быть достигнута путем добавления этой информации вручную к каждой метке. Используйте '\n'
, когда вам нужна новая строка, используйте da sh ' – '
или двоеточие при записи процентов в одной строке. Вам нужно будет сбросить параметры format
и unit
в санкее, чтобы предотвратить добавление процента во второй раз.
Поскольку санкей все еще пишет пустой формат и единицу, текст можно обновить, чтобы удалить пустую строку и получить правильное вертикальное центрирование.
from matplotlib import pyplot as plt
from matplotlib.sankey import Sankey
from random import randint
Input = 240.1
L0 = 140.1
F9 = 21.1
L = [randint(1,300) for _ in range(9)]
norm_factor = (Input - L0 - F9) / sum(L)
flows_s2 = [Input - L0] + [-l * norm_factor for l in L] + [-F9]
labels_s2 = ['Input 2', 'Loss 1', 'Loss 2', 'Loss 3', 'Loss 4', 'Loss 5', 'Loss 6', 'Loss 7', 'Loss 8', 'Loss 9',
'Output']
labels_s2_long = [f'{label}\n{flow} %' for label, flow in zip(labels_s2[:1], flows_s2)]
labels_s2_long += [f'{label} – {-flow:.1f} %' for label, flow in zip(labels_s2[1:], flows_s2[1:])]
fig = plt.figure(figsize=(8.3, 11.7))
ax = fig.add_subplot(1, 1, 1)
plt.axis('off')
sankey = Sankey(ax=ax,
scale=2 / Input,
offset=0.6,
head_angle=135,
shoulder=0,
gap=0.2,
radius=0.1,
format='%.1f',
unit='%')
s0 = sankey.add(flows=[Input, -L0, -(Input - L0)],
labels=['Input 1', 'Loss 0', ''],
orientations=[0, 1, 0],
trunklength=1,
rotation=-90,
fc='crimson', alpha=0.8)
sankey.format = ''
sankey.unit = ''
s1 = sankey.add(flows=flows_s2,
labels=labels_s2_long,
orientations=[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
trunklength=1,
rotation=-90,
prior=0, connect=(2, 0),
fc='tomato', alpha=0.6)
diagrams = sankey.finish()
for d in diagrams:
for t in d.texts:
text = t.get_text()
if text[-1] == '\n': # remove empty line at the end, needed for centering
t.set_text(text[:-1])
t.set_fontsize(10)
t.set_verticalalignment('center')
if text[:4] == 'Loss' and text[:6] != 'Loss 0': # align all loss labels except loss 0
t.set_horizontalalignment('left')
xy = t.get_position()
t.set_position(xy=(0.18, xy[1]))
else:
t.set_horizontalalignment('center')
#t.set_bbox(dict(facecolor='red', alpha=0.5, edgecolor='blue'))
diagrams[0].texts[0].set_position(xy=(0, 0.42)) # adjust position of input 1
diagrams[0].texts[1].set_position(xy=(1.75, diagrams[0].texts[1].get_position()[1])) # adjust pos. of loss 0
diagrams[0].texts[2].set_text('') # remove output 1 as it coincides with input 2
diagrams[1].texts[-1].set_position(xy=(diagrams[1].texts[-1].get_position()[0], -5)) # adjust pos. of output
plt.tight_layout()
plt.show()