Ответ 1
Пусть начнется, пытаясь решить путаницу
Я думаю, что мое замешательство сводится к непониманию того, что это на самом деле означает:
Обратите внимание, что указано только одно соединение, но системы образуют схему, поскольку: (1) длины путей оправданы и (2) зеркалирование ориентации и упорядочения потоков.
(2) Ориентация и упорядочение потоков зеркалируются.
То, что вы, вероятно, понимаете неправильно, - это значение зеркального отображения, которое в этом случае действительно запутывает. Можно было бы подумать, что зеркальное отображение равно инвертированному, но это отчасти верно: flows
(или, как вы его называете, в вашем коде: values
) должны быть инвертированы, это вы получили правильно. Поскольку values
соответствуют входам (value > 0
) или выходу (value < 0
). И только выход может быть подключен к входу, и наоборот.
Но orientation
должна быть одинаковой для обоих потоков, которые вы пытаетесь подключить. Этот не инвертирован, но он все равно должен быть "зеркальным". Что с этим связано? Ну, если I/O смотрит в направлении стрелки, из которой он пришел, ему нужно увидеть другой ввод-вывод (как при взгляде в зеркало), только тогда они смогут соединиться. Это не так просто объяснить как не родной оратор, но я попытаюсь проиллюстрировать идею:
Able to connect: Not able to connect: Not able to connect:
I/O Mirror I/O I/O Mirror I/O I/O Mirror I/O
╚══> | >══╝ ╗ | ╔ | ║
║ | ║ ══> | ║
v | ^ | ^
В вашем коде вы перевернули orientation
. Вот почему, например, 3-й поток оранжевой системы находится в верхнем левом углу, а его аналог синей системы находится в правом нижнем углу. Нет никакого способа, чтобы эти входы/выходы могли "видеть" друг друга.
Вы можете вернуть инверсию второй системы, удалив -
которая добавляет ориентацию x
:
orientations=[x["orientation"] for x in system_2]
Вы увидите, что потоки близки друг к другу, но вы находитесь в ситуации, как показано в разделе "Невозможно Not able to connect
-illustration (№ 2). Это означает, что структура вашей диаграммы не сможет работать так. Вы можете сгибать одиночные потоки только в этих трех направлениях: -90 °, 0 ° или 90 °. Какие корреспонденты orientations = -1, 0 or 1
. Единственный способ напрямую подключить эти потоки - установить их orientation=0
, но мне кажется, что это не ваша цель.
Вам нужен новый подход к задаче, поэтому вы не столкнетесь с ситуацией, подобной предыдущей, где больше не сможете подключать потоки. Я изменил ваш код до (возможно?) До цели. Это не выглядит так же, но я думаю, что это хорошее начало, чтобы понять концепцию ориентации и зеркалирования и все такое.
(1) Длины путей оправданы.
Вы увидите, что в моем коде ниже я установил значения для переменной pathlengths
(во второй системе). Я сделал доказательство того, что если у вас слишком много потоков, которые необходимо подключить, matplotlib больше не сможет делать это автоматически.
Код и вывод
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.sankey import Sankey
plt.rcParams["figure.figsize"] = (15,10)
system_1 = [
{"label": "1st", "value": -2.00, "orientation": 1},
{"label": "4th", "value": 0.10, "orientation": 1},
{"label": "2nd", "value": 0.15, "orientation": 1},
{"label": "3rd", "value": 0.60, "orientation": 1},
{"label": "5th", "value": 0.25, "orientation": -1},
{"label": "6th", "value": 0.25, "orientation": -1},
{"label": "7th", "value": 0.25, "orientation": 1},
{"label": "8th", "value": 0.25, "orientation": 1},
{"label": "9th", "value": 0.25, "orientation": 0}
]
system_2 = [
{"label": "1st", "value": 2.00, "orientation": 1},
{"label": "4th", "value": -0.10, "orientation": 1},
{"label": "2nd", "value": -0.15, "orientation": 1},
{"label": "3rd", "value": -0.60, "orientation": 1},
{"label": "new", "value": -0.25, "orientation": 1}
]
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, xticks=[], yticks=[], title="Where are all my cows?")
flows_1 = [x["value"] for x in system_1]
labels_1 = [x["label"] for x in system_1]
orientations_1=[x["orientation"] for x in system_1]
flows_2 = [x["value"] for x in system_2]
labels_2 = [x["label"] for x in system_2]
orientations_2=[x["orientation"] for x in system_2]
sankey = Sankey(ax=ax, unit=None)
sankey.add(flows=flows_1,
labels=labels_1,
label='one',
orientations=orientations_1)
sankey.add(flows=flows_2,
labels=labels_2,
label='two',
orientations=orientations_2,
pathlengths=[0, 0.4, 0.5, 0.65, 1.25],
prior=0,
connect=(0,0))
diagrams = sankey.finish()
diagrams[-1].patch.set_hatch('|')
diagrams[-0].patch.set_hatch('-')
plt.legend(loc='best')
plt.show()