控制Sankey关系图连接

2024-05-19 20:12:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图使用Matplotlib Sankey图控制哪些流相互连接。我在修改基本的两个系统的例子。在

我想我的困惑归结为误解了这实际上意味着什么:

Notice that only one connection is specified, but the systems form a circuit since: (1) the lengths of the paths are justified and (2) the orientation and ordering of the flows is mirrored.

我做了一个玩具示例,它使用单个数据集,然后为第二个系统修改它,以确保所有数字都匹配。在

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":  0},
    {"label": "2nd",  "value":  0.15, "orientation": -1},
    {"label": "3rd",  "value":  0.60, "orientation": -1},
    {"label": "4th",  "value": -0.10, "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": -1}
]

system_2 = system_1[:4]
system_2.append({"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  = [x["value"] for x in system_1]
labels = [x["label"] for x in system_1]
orientations=[x["orientation"] for x in system_1]
sankey = Sankey(ax=ax, unit="cow")
sankey.add(flows=flows, 
           labels=labels,
           label='one',
           orientations=orientations)

sankey.add(flows=[-x["value"] for x in system_2], 
           labels=[x["label"] for x in system_2],
           label='two',
           orientations=[-x["orientation"] for x in system_2], 
           prior=0, 
           connect= (0,0)
          )

diagrams = sankey.finish()
diagrams[-1].patch.set_hatch('/')
plt.legend(loc='best')


plt.show()

这给了我:

A sankey diagram that doesn't really work

它应该用匹配的标签连接流。在

我读过this和{a3},但它们不能帮助我理解实际发生了什么。在


Tags: theinimportforlabelsvaluepltax
1条回答
网友
1楼 · 发布于 2024-05-19 20:12:24

让我们从解决困惑开始

I think my confusion comes down to misunderstanding what this actually means:

Notice that only one connection is specified, but the systems form a circuit since: (1) the lengths of the paths are justified and (2) the orientation and ordering of the flows is mirrored.

(2)反映流的方向和顺序。

你可能理解错误的是镜像的含义,这在本例中确实令人困惑。有人会认为,镜像等于反转,但这只是部分正确:
flows(或者你在代码中称之为:values)必须颠倒,这个你说对了。因为values对应于输入(value > 0)或输出(value < 0)。只有输出可以连接到输入,反之亦然。在

但是对于您尝试连接的两个流,orientation必须相同。这个不是倒置的,但它仍然需要“镜像”。这是什么意思?好吧,如果一个I/O朝着箭头的方向看,它需要看到另一个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。这就是为什么橙色系统的第三个流程在左上角,而蓝色系统的对应流程在右下角。不可能,这些I/O将永远能够“看到”彼此。在

您可以通过删除-来恢复第二个系统的反转,该x在方向中前置:

^{pr2}$

您将看到现在流彼此接近,但您处于一个类似于Not able to connect-插图(第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()

Output

相关问题 更多 >