Plotly:如何使用 pandas 数据框定义桑基图的结构?
Plotly: How to define the structure of a sankey diagram using a pandas dataframe?
这听起来像是一个非常宽泛的问题,但如果你让我描述一些细节,我可以向你保证它非常具体.以及令人沮丧、沮丧和愤怒。
以下情节描述了一次苏格兰选举,并基于 plot.ly 中的代码:
地块 1:
数据集 1:
data = [['Source','Target','Value','Color','Node, Label','Link Color'],
[0,5,20,'#F27420','Remain+No – 28','rgba(253, 227, 212, 0.5)'],
[0,6,3,'#4994CE','Leave+No – 16','rgba(242, 116, 32, 1)'],
[0,7,5,'#FABC13','Remain+Yes – 21','rgba(253, 227, 212, 0.5)'],
[1,5,14,'#7FC241','Leave+Yes – 14','rgba(219, 233, 246, 0.5)'],
[1,6,1,'#D3D3D3','Didn’t vote in at least one referendum – 21','rgba(73, 148, 206, 1)'],
[1,7,1,'#8A5988','46 – No','rgba(219, 233, 246,0.5)'],
[2,5,3,'#449E9E','39 – Yes','rgba(250, 188, 19, 1)'],
[2,6,17,'#D3D3D3','14 – Don’t know / would not vote','rgba(250, 188, 19, 0.5)'],
[2,7,2,'','','rgba(250, 188, 19, 0.5)'],
[3,5,3,'','','rgba(127, 194, 65, 1)'],
[3,6,9,'','','rgba(127, 194, 65, 0.5)'],
[3,7,2,'','','rgba(127, 194, 65, 0.5)'],
[4,5,5,'','','rgba(211, 211, 211, 0.5)'],
[4,6,9,'','','rgba(211, 211, 211, 0.5)'],
[4,7,8,'','','rgba(211, 211, 211, 0.5)']
]
地块的搭建方式:
我从各种来源获取了一些关于桑基图行为的重要细节,例如:
挑战:
正如您将在下面的详细信息中看到的那样,节点、标签和颜色未按照与源数据框的结构顺序相同的顺序应用于图表。 其中一些 非常合理,因为您有各种元素描述相同的节点,如颜色、目标、值和 link 颜色。一个节点 'Remain+No – 28'
看起来像这样:
数据集的伴随部分如下所示:
[0,5,20,'#F27420','Remain+No – 28','rgba(253, 227, 212, 0.5)'],
[0,6,3,'#4994CE','Leave+No – 16','rgba(242, 116, 32, 1)'],
[0,7,5,'#FABC13','Remain+Yes – 21','rgba(253, 227, 212, 0.5)'],
所以这部分源描述了一个节点 [0]
和三个对应的目标 [5, 6, 7]
和三个 link 的值 [20, 3, 5]
。 '#F27420'
是节点的橙色(左右)颜色,颜色 'rgba(253, 227, 212, 0.5)'
、'rgba(242, 116, 32, 1)'
和 'rgba(253, 227, 212, 0.5)'
描述了节点中 link 的颜色到一些目标。到目前为止,上面示例中尚未使用的信息是:
数据样本2(部分)
[-,-,--'-------','---------------','-------------------'],
[-,-,-,'#4994CE','Leave+No – 16','-------------------'],
[-,-,-,'#FABC13','Remain+Yes – 21','-------------------'],
并且该信息用于介绍图表的其余元素。
那么,问题是什么?在下面的进一步详细信息中,您将看到只要数据集中的新数据行插入一个新的 link 并且对其他元素(颜色、标签)进行其他更改(如果该信息具有),一切都有意义尚未使用。我将使用我制作的设置中的两个屏幕截图更加具体,左边是绘图,右边是代码:
以下数据示例按照上面描述的逻辑生成下图:
数据样本3
data = [['Source','Target','Value','Color','Node, Label','Link Color'],
[0,5,20,'#F27420','Remain+No – 28','rgba(253, 227, 212, 0.5)'],
[0,6,3,'#4994CE','Leave+No – 16','rgba(242, 116, 32, 1)'],
[0,7,5,'#FABC13','Remain+Yes – 21','rgba(253, 227, 212, 0.5)'],
[1,5,14,'#7FC241','Leave+Yes – 14','rgba(219, 233, 246, 0.5)'],
[1,6,1,'#D3D3D3','Didn’t vote in at least one referendum – 21','rgba(73, 148, 206, 1)']]
屏幕截图 1 - 数据样本 3 的部分图
问题:
在数据集中添加行 [1,7,1,'#8A5988','46 – No','rgba(219, 233, 246,0.5)']
在源 [5]
和目标 [7]
之间生成一个新的 link,但 将颜色和标签应用于同时瞄准5。我认为下一个应用于图表的标签是 'Remain+Yes – 21'
,因为它还没有被使用过。但是这里发生的是标签 '46 – No'
应用于目标 5。为什么?
屏幕截图 2 - 包含数据样本 3 + [1,7,1,'#8A5988','46 – No','rgba(219, 233, 246,0.5)']
:
的部分图
你如何根据该数据框辨别什么是源,什么是目标?
我知道这个问题既奇怪又难以回答,但我希望有人能提出建议。我也知道数据框可能不是桑基图的最佳来源。也许 json 而不是?
用于 Jupyter Notebook 的简单复制和粘贴的完整代码和数据示例:
import pandas as pd
import numpy as np
import plotly.graph_objs as go
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
init_notebook_mode(connected=True)
# Original data
data = [['Source','Target','Value','Color','Node, Label','Link Color'],
[0,5,20,'#F27420','Remain+No – 28','rgba(253, 227, 212, 0.5)'],
[0,6,3,'#4994CE','Leave+No – 16','rgba(242, 116, 32, 1)'],
[0,7,5,'#FABC13','Remain+Yes – 21','rgba(253, 227, 212, 0.5)'],
[1,5,14,'#7FC241','Leave+Yes – 14','rgba(219, 233, 246, 0.5)'],
[1,6,1,'#D3D3D3','Didn’t vote in at least one referendum – 21','rgba(73, 148, 206, 1)'],
[1,7,1,'#8A5988','46 – No','rgba(219, 233, 246,0.5)'],
[2,5,3,'#449E9E','39 – Yes','rgba(250, 188, 19, 1)'],
[2,6,17,'#D3D3D3','14 – Don’t know / would not vote','rgba(250, 188, 19, 0.5)'],
[2,7,2,'','','rgba(250, 188, 19, 0.5)'],
[3,5,3,'','','rgba(127, 194, 65, 1)'],
[3,6,9,'','','rgba(127, 194, 65, 0.5)'],
[3,7,2,'','','rgba(127, 194, 65, 0.5)'],
[4,5,5,'','','rgba(211, 211, 211, 0.5)'],
[4,6,9,'','','rgba(211, 211, 211, 0.5)'],
[4,7,8,'','','rgba(211, 211, 211, 0.5)']
]
headers = data.pop(0)
df = pd.DataFrame(data, columns = headers)
scottish_df = df
data_trace = dict(
type='sankey',
domain = dict(
x = [0,1],
y = [0,1]
),
orientation = "h",
valueformat = ".0f",
node = dict(
pad = 10,
thickness = 30,
line = dict(
color = "black",
width = 0
),
label = scottish_df['Node, Label'].dropna(axis=0, how='any'),
color = scottish_df['Color']
),
link = dict(
source = scottish_df['Source'].dropna(axis=0, how='any'),
target = scottish_df['Target'].dropna(axis=0, how='any'),
value = scottish_df['Value'].dropna(axis=0, how='any'),
color = scottish_df['Link Color'].dropna(axis=0, how='any'),
)
)
layout = dict(
title = "Scottish Referendum Voters who now want Independence",
height = 772,
font = dict(
size = 10
),
)
fig = dict(data=[data_trace], layout=layout)
iplot(fig, validate=False)
这个问题看起来很奇怪,但前提是你要分析 plotly
中的桑基图是如何创建的:
当您创建桑基图时,您发送给它:
- 节点列表
- 链接列表
这些列表彼此绑定。当您创建 5 长度的节点列表时,任何边缘都将在其开始和结束时知道 0,1,2,3,4
。在您的程序中,您错误地创建了节点 - 您创建了 link 的列表,然后遍历它并创建节点。看看你的图表。它有两个黑色节点,里面有 undefined
。你的数据集的长度是多少……是的,5
。您的节点索引以 4
结束,并且没有真正定义目标节点。您将第六个列表添加到您的数据集中 - 宾果游戏! - 有 nodes[5]
个存在!只需尝试在您的数据集中添加另一条新行:
[1,7,1,'#FF0000','WAKA','rgba(219, 233, 246,0.5)']
你会看到另一个黑条变成了红色。您有五个节点(因为您有 5 个 link 并且您通过迭代 link 列表来创建节点),但是 link 的目标索引是 5,6,7
。您可以通过两种方式修复它:
- 将数据集中的
Target
更改为 2,3,4
- 分别创建节点和link(正确的方式)
我希望我帮助你解决了你的问题和情节创作的理解(在我看来更重要的是什么)。
编辑: 这里是单独创建 nodes/links 的例子(注意 data_trace
中的 node
部分仅使用 nodes_df
数据,data_trace
中的link
部分仅使用links_df
数据且nodes_df
和links_df
长度不相等):
import pandas as pd
import numpy as np
import plotly.graph_objs as go
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
init_notebook_mode(connected=True)
nodes = [
['ID', 'Label', 'Color'],
[0,'Remain+No – 28','#F27420'],
[1,'Leave+No – 16','#4994CE'],
[2,'Remain+Yes – 21','#FABC13'],
[3,'Leave+Yes – 14','#7FC241'],
[4,'Didn’t vote in at least one referendum – 21','#D3D3D3'],
[5,'46 – No','#8A5988']
]
links = [
['Source','Target','Value','Link Color'],
[0,3,20,'rgba(253, 227, 212, 0.5)'],
[0,4,3,'rgba(242, 116, 32, 1)'],
[0,2,5,'rgba(253, 227, 212, 0.5)'],
[1,5,14,'rgba(219, 233, 246, 0.5)'],
[1,3,1,'rgba(73, 148, 206, 1)'],
[1,4,1,'rgba(219, 233, 246,0.5)'],
[1,2,10,'rgba(8, 233, 246,0.5)'],
[1,3,5,'rgba(219, 77, 246,0.5)'],
[1,5,12,'rgba(219, 4, 246,0.5)']
]
nodes_headers = nodes.pop(0)
nodes_df = pd.DataFrame(nodes, columns = nodes_headers)
links_headers = links.pop(0)
links_df = pd.DataFrame(links, columns = links_headers)
data_trace = dict(
type='sankey',
domain = dict(
x = [0,1],
y = [0,1]
),
orientation = "h",
valueformat = ".0f",
node = dict(
pad = 10,
thickness = 30,
line = dict(
color = "black",
width = 0
),
label = nodes_df['Label'].dropna(axis=0, how='any'),
color = nodes_df['Color']
),
link = dict(
source = links_df['Source'].dropna(axis=0, how='any'),
target = links_df['Target'].dropna(axis=0, how='any'),
value = links_df['Value'].dropna(axis=0, how='any'),
color = links_df['Link Color'].dropna(axis=0, how='any'),
)
)
layout = dict(
title = "Scottish Referendum Voters who now want Independence",
height = 772,
font = dict(
size = 10
),
)
fig = dict(data=[data_trace], layout=layout)
iplot(fig, validate=False)
编辑 2: 让我们更深入地探讨 :)
桑基图中的节点和 link 几乎完全独立。限制它们的唯一信息 - link 中源目标中的索引。所以我们可以创建很多节点,并且没有 links 给它们(只需用它替换 Edit1 代码中的 nodes/links):
nodes = [
['ID', 'Label', 'Color'],
[0,'Remain+No – 28','#F27420'],
[1,'Leave+No – 16','#4994CE'],
[2,'Remain+Yes – 21','#FABC13'],
[3,'Leave+Yes – 14','#7FC241'],
[4,'Didn’t vote in at least one referendum – 21','#D3D3D3'],
[5,'46 – No','#8A5988'],
[6,'WAKA1','#8A5988'],
[7,'WAKA2','#8A5988'],
[8,'WAKA3','#8A5988'],
[9,'WAKA4','#8A5988'],
[10,'WAKA5','#8A5988'],
[11,'WAKA6','#8A5988'],
]
links = [
['Source','Target','Value','Link Color'],
[0,3,20,'rgba(253, 227, 212, 0.5)'],
[0,4,3,'rgba(242, 116, 32, 1)'],
[0,2,5,'rgba(253, 227, 212, 0.5)'],
[1,5,14,'rgba(219, 233, 246, 0.5)'],
[1,3,1,'rgba(73, 148, 206, 1)'],
[1,4,1,'rgba(219, 233, 246,0.5)'],
[1,2,10,'rgba(8, 233, 246,0.5)'],
[1,3,5,'rgba(219, 77, 246,0.5)'],
[1,5,12,'rgba(219, 4, 246,0.5)']
]
并且这些节点不会出现在图表中。
我们只能创建 link 个没有节点:
nodes = [
['ID', 'Label', 'Color'],
]
links = [
['Source','Target','Value','Link Color'],
[0,3,20,'rgba(253, 227, 212, 0.5)'],
[0,4,3,'rgba(242, 116, 32, 1)'],
[0,2,5,'rgba(253, 227, 212, 0.5)'],
[1,5,14,'rgba(219, 233, 246, 0.5)'],
[1,3,1,'rgba(73, 148, 206, 1)'],
[1,4,1,'rgba(219, 233, 246,0.5)'],
[1,2,10,'rgba(8, 233, 246,0.5)'],
[1,3,5,'rgba(219, 77, 246,0.5)'],
[1,5,12,'rgba(219, 4, 246,0.5)']
]
我们将只有 link 从无处到无处。
如果你想添加 (1) 一个带有 link 的新源,你应该在 nodes
中添加一个新列表,计算它的索引(这就是为什么我有 ID 列)并在 links
中添加一个新列表,其中 Source
等于节点索引。
如果您想为现有节点添加 (2) 新目标 - 只需在 links
中添加一个新列表并写入其 Source
和Target
正确:
[1,100500,10,'rgba(219, 233, 246,0.5)'],
[1,100501,10,'rgba(8, 233, 246,0.5)'],
[1,100502,10,'rgba(219, 77, 246,0.5)'],
[1,100503,10,'rgba(219, 4, 246,0.5)']
(这里我为 4 个新目标创建了 4 个新的 link。源是索引为 1
的节点)。
(3+4): 桑基图不区分来源和目标。所有这些都只是 Sankey 的节点。每个节点既可以是源也可以是目标。看看吧:
nodes = [
['ID', 'Label', 'Color'],
[0,'WAKA WANNA BE SOURCE','#F27420'],
[1,'WAKA WANNA BE TARGET','#4994CE'],
[2,'WAKA DON\'T KNOW WHO WANNA BE','#FABC13'],
]
links = [
['Source','Target','Value','Link Color'],
[0,1,10,'rgba(253, 227, 212, 1)'],
[0,2,10,'rgba(242, 116, 32, 1)'],
[2,1,10,'rgba(253, 227, 212, 1)'],
]
在这里您将看到 3 列桑基图。 0 节点是源,1 是目标,2 节点是源1 和 2 的目标。
这听起来像是一个非常宽泛的问题,但如果你让我描述一些细节,我可以向你保证它非常具体.以及令人沮丧、沮丧和愤怒。
以下情节描述了一次苏格兰选举,并基于 plot.ly 中的代码:
地块 1:
数据集 1:
data = [['Source','Target','Value','Color','Node, Label','Link Color'],
[0,5,20,'#F27420','Remain+No – 28','rgba(253, 227, 212, 0.5)'],
[0,6,3,'#4994CE','Leave+No – 16','rgba(242, 116, 32, 1)'],
[0,7,5,'#FABC13','Remain+Yes – 21','rgba(253, 227, 212, 0.5)'],
[1,5,14,'#7FC241','Leave+Yes – 14','rgba(219, 233, 246, 0.5)'],
[1,6,1,'#D3D3D3','Didn’t vote in at least one referendum – 21','rgba(73, 148, 206, 1)'],
[1,7,1,'#8A5988','46 – No','rgba(219, 233, 246,0.5)'],
[2,5,3,'#449E9E','39 – Yes','rgba(250, 188, 19, 1)'],
[2,6,17,'#D3D3D3','14 – Don’t know / would not vote','rgba(250, 188, 19, 0.5)'],
[2,7,2,'','','rgba(250, 188, 19, 0.5)'],
[3,5,3,'','','rgba(127, 194, 65, 1)'],
[3,6,9,'','','rgba(127, 194, 65, 0.5)'],
[3,7,2,'','','rgba(127, 194, 65, 0.5)'],
[4,5,5,'','','rgba(211, 211, 211, 0.5)'],
[4,6,9,'','','rgba(211, 211, 211, 0.5)'],
[4,7,8,'','','rgba(211, 211, 211, 0.5)']
]
地块的搭建方式:
我从各种来源获取了一些关于桑基图行为的重要细节,例如:
挑战:
正如您将在下面的详细信息中看到的那样,节点、标签和颜色未按照与源数据框的结构顺序相同的顺序应用于图表。 其中一些 非常合理,因为您有各种元素描述相同的节点,如颜色、目标、值和 link 颜色。一个节点 'Remain+No – 28'
看起来像这样:
数据集的伴随部分如下所示:
[0,5,20,'#F27420','Remain+No – 28','rgba(253, 227, 212, 0.5)'],
[0,6,3,'#4994CE','Leave+No – 16','rgba(242, 116, 32, 1)'],
[0,7,5,'#FABC13','Remain+Yes – 21','rgba(253, 227, 212, 0.5)'],
所以这部分源描述了一个节点 [0]
和三个对应的目标 [5, 6, 7]
和三个 link 的值 [20, 3, 5]
。 '#F27420'
是节点的橙色(左右)颜色,颜色 'rgba(253, 227, 212, 0.5)'
、'rgba(242, 116, 32, 1)'
和 'rgba(253, 227, 212, 0.5)'
描述了节点中 link 的颜色到一些目标。到目前为止,上面示例中尚未使用的信息是:
数据样本2(部分)
[-,-,--'-------','---------------','-------------------'],
[-,-,-,'#4994CE','Leave+No – 16','-------------------'],
[-,-,-,'#FABC13','Remain+Yes – 21','-------------------'],
并且该信息用于介绍图表的其余元素。
那么,问题是什么?在下面的进一步详细信息中,您将看到只要数据集中的新数据行插入一个新的 link 并且对其他元素(颜色、标签)进行其他更改(如果该信息具有),一切都有意义尚未使用。我将使用我制作的设置中的两个屏幕截图更加具体,左边是绘图,右边是代码:
以下数据示例按照上面描述的逻辑生成下图:
数据样本3
data = [['Source','Target','Value','Color','Node, Label','Link Color'],
[0,5,20,'#F27420','Remain+No – 28','rgba(253, 227, 212, 0.5)'],
[0,6,3,'#4994CE','Leave+No – 16','rgba(242, 116, 32, 1)'],
[0,7,5,'#FABC13','Remain+Yes – 21','rgba(253, 227, 212, 0.5)'],
[1,5,14,'#7FC241','Leave+Yes – 14','rgba(219, 233, 246, 0.5)'],
[1,6,1,'#D3D3D3','Didn’t vote in at least one referendum – 21','rgba(73, 148, 206, 1)']]
屏幕截图 1 - 数据样本 3 的部分图
问题:
在数据集中添加行 [1,7,1,'#8A5988','46 – No','rgba(219, 233, 246,0.5)']
在源 [5]
和目标 [7]
之间生成一个新的 link,但 将颜色和标签应用于同时瞄准5。我认为下一个应用于图表的标签是 'Remain+Yes – 21'
,因为它还没有被使用过。但是这里发生的是标签 '46 – No'
应用于目标 5。为什么?
屏幕截图 2 - 包含数据样本 3 + [1,7,1,'#8A5988','46 – No','rgba(219, 233, 246,0.5)']
:
你如何根据该数据框辨别什么是源,什么是目标?
我知道这个问题既奇怪又难以回答,但我希望有人能提出建议。我也知道数据框可能不是桑基图的最佳来源。也许 json 而不是?
用于 Jupyter Notebook 的简单复制和粘贴的完整代码和数据示例:
import pandas as pd
import numpy as np
import plotly.graph_objs as go
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
init_notebook_mode(connected=True)
# Original data
data = [['Source','Target','Value','Color','Node, Label','Link Color'],
[0,5,20,'#F27420','Remain+No – 28','rgba(253, 227, 212, 0.5)'],
[0,6,3,'#4994CE','Leave+No – 16','rgba(242, 116, 32, 1)'],
[0,7,5,'#FABC13','Remain+Yes – 21','rgba(253, 227, 212, 0.5)'],
[1,5,14,'#7FC241','Leave+Yes – 14','rgba(219, 233, 246, 0.5)'],
[1,6,1,'#D3D3D3','Didn’t vote in at least one referendum – 21','rgba(73, 148, 206, 1)'],
[1,7,1,'#8A5988','46 – No','rgba(219, 233, 246,0.5)'],
[2,5,3,'#449E9E','39 – Yes','rgba(250, 188, 19, 1)'],
[2,6,17,'#D3D3D3','14 – Don’t know / would not vote','rgba(250, 188, 19, 0.5)'],
[2,7,2,'','','rgba(250, 188, 19, 0.5)'],
[3,5,3,'','','rgba(127, 194, 65, 1)'],
[3,6,9,'','','rgba(127, 194, 65, 0.5)'],
[3,7,2,'','','rgba(127, 194, 65, 0.5)'],
[4,5,5,'','','rgba(211, 211, 211, 0.5)'],
[4,6,9,'','','rgba(211, 211, 211, 0.5)'],
[4,7,8,'','','rgba(211, 211, 211, 0.5)']
]
headers = data.pop(0)
df = pd.DataFrame(data, columns = headers)
scottish_df = df
data_trace = dict(
type='sankey',
domain = dict(
x = [0,1],
y = [0,1]
),
orientation = "h",
valueformat = ".0f",
node = dict(
pad = 10,
thickness = 30,
line = dict(
color = "black",
width = 0
),
label = scottish_df['Node, Label'].dropna(axis=0, how='any'),
color = scottish_df['Color']
),
link = dict(
source = scottish_df['Source'].dropna(axis=0, how='any'),
target = scottish_df['Target'].dropna(axis=0, how='any'),
value = scottish_df['Value'].dropna(axis=0, how='any'),
color = scottish_df['Link Color'].dropna(axis=0, how='any'),
)
)
layout = dict(
title = "Scottish Referendum Voters who now want Independence",
height = 772,
font = dict(
size = 10
),
)
fig = dict(data=[data_trace], layout=layout)
iplot(fig, validate=False)
这个问题看起来很奇怪,但前提是你要分析 plotly
中的桑基图是如何创建的:
当您创建桑基图时,您发送给它:
- 节点列表
- 链接列表
这些列表彼此绑定。当您创建 5 长度的节点列表时,任何边缘都将在其开始和结束时知道 0,1,2,3,4
。在您的程序中,您错误地创建了节点 - 您创建了 link 的列表,然后遍历它并创建节点。看看你的图表。它有两个黑色节点,里面有 undefined
。你的数据集的长度是多少……是的,5
。您的节点索引以 4
结束,并且没有真正定义目标节点。您将第六个列表添加到您的数据集中 - 宾果游戏! - 有 nodes[5]
个存在!只需尝试在您的数据集中添加另一条新行:
[1,7,1,'#FF0000','WAKA','rgba(219, 233, 246,0.5)']
你会看到另一个黑条变成了红色。您有五个节点(因为您有 5 个 link 并且您通过迭代 link 列表来创建节点),但是 link 的目标索引是 5,6,7
。您可以通过两种方式修复它:
- 将数据集中的
Target
更改为2,3,4
- 分别创建节点和link(正确的方式)
我希望我帮助你解决了你的问题和情节创作的理解(在我看来更重要的是什么)。
编辑: 这里是单独创建 nodes/links 的例子(注意 data_trace
中的 node
部分仅使用 nodes_df
数据,data_trace
中的link
部分仅使用links_df
数据且nodes_df
和links_df
长度不相等):
import pandas as pd
import numpy as np
import plotly.graph_objs as go
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
init_notebook_mode(connected=True)
nodes = [
['ID', 'Label', 'Color'],
[0,'Remain+No – 28','#F27420'],
[1,'Leave+No – 16','#4994CE'],
[2,'Remain+Yes – 21','#FABC13'],
[3,'Leave+Yes – 14','#7FC241'],
[4,'Didn’t vote in at least one referendum – 21','#D3D3D3'],
[5,'46 – No','#8A5988']
]
links = [
['Source','Target','Value','Link Color'],
[0,3,20,'rgba(253, 227, 212, 0.5)'],
[0,4,3,'rgba(242, 116, 32, 1)'],
[0,2,5,'rgba(253, 227, 212, 0.5)'],
[1,5,14,'rgba(219, 233, 246, 0.5)'],
[1,3,1,'rgba(73, 148, 206, 1)'],
[1,4,1,'rgba(219, 233, 246,0.5)'],
[1,2,10,'rgba(8, 233, 246,0.5)'],
[1,3,5,'rgba(219, 77, 246,0.5)'],
[1,5,12,'rgba(219, 4, 246,0.5)']
]
nodes_headers = nodes.pop(0)
nodes_df = pd.DataFrame(nodes, columns = nodes_headers)
links_headers = links.pop(0)
links_df = pd.DataFrame(links, columns = links_headers)
data_trace = dict(
type='sankey',
domain = dict(
x = [0,1],
y = [0,1]
),
orientation = "h",
valueformat = ".0f",
node = dict(
pad = 10,
thickness = 30,
line = dict(
color = "black",
width = 0
),
label = nodes_df['Label'].dropna(axis=0, how='any'),
color = nodes_df['Color']
),
link = dict(
source = links_df['Source'].dropna(axis=0, how='any'),
target = links_df['Target'].dropna(axis=0, how='any'),
value = links_df['Value'].dropna(axis=0, how='any'),
color = links_df['Link Color'].dropna(axis=0, how='any'),
)
)
layout = dict(
title = "Scottish Referendum Voters who now want Independence",
height = 772,
font = dict(
size = 10
),
)
fig = dict(data=[data_trace], layout=layout)
iplot(fig, validate=False)
编辑 2: 让我们更深入地探讨 :) 桑基图中的节点和 link 几乎完全独立。限制它们的唯一信息 - link 中源目标中的索引。所以我们可以创建很多节点,并且没有 links 给它们(只需用它替换 Edit1 代码中的 nodes/links):
nodes = [
['ID', 'Label', 'Color'],
[0,'Remain+No – 28','#F27420'],
[1,'Leave+No – 16','#4994CE'],
[2,'Remain+Yes – 21','#FABC13'],
[3,'Leave+Yes – 14','#7FC241'],
[4,'Didn’t vote in at least one referendum – 21','#D3D3D3'],
[5,'46 – No','#8A5988'],
[6,'WAKA1','#8A5988'],
[7,'WAKA2','#8A5988'],
[8,'WAKA3','#8A5988'],
[9,'WAKA4','#8A5988'],
[10,'WAKA5','#8A5988'],
[11,'WAKA6','#8A5988'],
]
links = [
['Source','Target','Value','Link Color'],
[0,3,20,'rgba(253, 227, 212, 0.5)'],
[0,4,3,'rgba(242, 116, 32, 1)'],
[0,2,5,'rgba(253, 227, 212, 0.5)'],
[1,5,14,'rgba(219, 233, 246, 0.5)'],
[1,3,1,'rgba(73, 148, 206, 1)'],
[1,4,1,'rgba(219, 233, 246,0.5)'],
[1,2,10,'rgba(8, 233, 246,0.5)'],
[1,3,5,'rgba(219, 77, 246,0.5)'],
[1,5,12,'rgba(219, 4, 246,0.5)']
]
并且这些节点不会出现在图表中。
我们只能创建 link 个没有节点:
nodes = [
['ID', 'Label', 'Color'],
]
links = [
['Source','Target','Value','Link Color'],
[0,3,20,'rgba(253, 227, 212, 0.5)'],
[0,4,3,'rgba(242, 116, 32, 1)'],
[0,2,5,'rgba(253, 227, 212, 0.5)'],
[1,5,14,'rgba(219, 233, 246, 0.5)'],
[1,3,1,'rgba(73, 148, 206, 1)'],
[1,4,1,'rgba(219, 233, 246,0.5)'],
[1,2,10,'rgba(8, 233, 246,0.5)'],
[1,3,5,'rgba(219, 77, 246,0.5)'],
[1,5,12,'rgba(219, 4, 246,0.5)']
]
我们将只有 link 从无处到无处。
如果你想添加 (1) 一个带有 link 的新源,你应该在 nodes
中添加一个新列表,计算它的索引(这就是为什么我有 ID 列)并在 links
中添加一个新列表,其中 Source
等于节点索引。
如果您想为现有节点添加 (2) 新目标 - 只需在 links
中添加一个新列表并写入其 Source
和Target
正确:
[1,100500,10,'rgba(219, 233, 246,0.5)'],
[1,100501,10,'rgba(8, 233, 246,0.5)'],
[1,100502,10,'rgba(219, 77, 246,0.5)'],
[1,100503,10,'rgba(219, 4, 246,0.5)']
(这里我为 4 个新目标创建了 4 个新的 link。源是索引为 1
的节点)。
(3+4): 桑基图不区分来源和目标。所有这些都只是 Sankey 的节点。每个节点既可以是源也可以是目标。看看吧:
nodes = [
['ID', 'Label', 'Color'],
[0,'WAKA WANNA BE SOURCE','#F27420'],
[1,'WAKA WANNA BE TARGET','#4994CE'],
[2,'WAKA DON\'T KNOW WHO WANNA BE','#FABC13'],
]
links = [
['Source','Target','Value','Link Color'],
[0,1,10,'rgba(253, 227, 212, 1)'],
[0,2,10,'rgba(242, 116, 32, 1)'],
[2,1,10,'rgba(253, 227, 212, 1)'],
]
在这里您将看到 3 列桑基图。 0 节点是源,1 是目标,2 节点是源1 和 2 的目标。