桑基图不是特别常见的图表,一般是用于具有流向关系的数据可视化,比如购买链路/路径,可以清晰地知道顾客一二三四单分别买了什么;
桑基图需要两组数据
数据节点(nodes),数据格式如下:
[
{"name": "category1"},
{"name": "category2"},
{"name": "category3"},
{"name": "category4"},
{"name": "category5"},
{"name": "category6"},
]
当然你还可以在此单独定义每个数据项的样式,如:
[
{"name": "category1", , itemStyle={"color": '#78b4ff'}},
{"name": "category2"},
{"name": "category3"},
{"name": "category4", , itemStyle={"opacity": 0.3}},
{"name": "category5"},
{"name": "category6"},
]
节点之间的关系(links),数据格式如下:
[
{"source": "category1", "target": "category2", "value": 10},
{"source": "category2", "target": "category3", "value": 15},
{"source": "category3", "target": "category4", "value": 20},
{"source": "category5", "target": "category6", "value": 25},
]
通过命名其实就可以看出来,source
表示源头,target
表示目标,value
表示数值大小;
桑基图支持的参数如下:
def add(
# 系列名称,用于 tooltip 的显示,legend 的图例筛选。
series_name: str,
nodes: Sequence,
links: Sequence,
# 是否选中图例
is_selected: bool = True,
# Sankey 组件离容器左侧的距离。
pos_left: types.Union[str, types.Numeric] = "5%",
# Sankey 组件离容器上侧的距离。
pos_top: types.Union[str, types.Numeric] = "5%",
# Sankey 组件离容器右侧的距离。
pos_right: types.Union[str, types.Numeric] = "20%",
# Sankey 组件离容器下侧的距离。
pos_bottom: types.Union[str, types.Numeric] = "5%",
# 桑基图中每个矩形节点的宽度。
node_width: Numeric = 20,
# 桑基图中每一列任意两个矩形节点之间的间隔。
node_gap: Numeric = 8,
# 桑基图中节点的对齐方式,默认是双端对齐,可以设置为左对齐或右对齐,对应的值分别是:
# justify: 节点双端对齐。
# left: 节点左对齐。
# right: 节点右对齐。
node_align: str = "justify",
# 布局的迭代次数,用来不断优化图中节点的位置,以减少节点和边之间的相互遮盖。
# 默认布局迭代次数:32。
# 注: 布局迭代次数不要低于默认值。
layout_iterations: types.Numeric = 32,
# 桑基图中节点的布局方向,可以是水平的从左往右,也可以是垂直的从上往下。
# 对应的参数值分别是 horizontal, vertical。
orient: str = "horizontal",
# 控制节点拖拽的交互,默认开启。开启后,用户可以将图中任意节点拖拽到任意位置。若想关闭此交互,只需将值设为 false 就行了。
is_draggable: bool = True,
# 鼠标 hover 到节点或边上,相邻接的节点和边高亮的交互,默认关闭,可手动开启。
# false:hover 到节点或边时,只有被 hover 的节点或边高亮。
# true:同 'allEdges'。
# 'allEdges':hover 到节点时,与节点邻接的所有边以及边对应的节点全部高亮。hover 到边时,边和相邻节点高亮。
# 'outEdges':hover 的节点、节点的出边、出边邻接的另一节点 会被高亮。hover 到边时,边和相邻节点高亮。
# 'inEdges':hover 的节点、节点的入边、入边邻接的另一节点 会被高亮。hover 到边时,边和相邻节点高亮。
focus_node_adjacency: types.Union[bool, str] = False,
# 桑基图每一层的设置。可以逐层设置
levels: types.SankeyLevel = None,
# 标签配置项,参考 `series_options.LabelOpts`
label_opts: Union[opts.LabelOpts, dict] = opts.LabelOpts(),
# 线条样式配置项,参考 `series_options.LineStyleOpts`
linestyle_opt: Union[opts.LineStyleOpts, dict] = opts.LineStyleOpts(),
# 提示框组件配置项,参考 `series_options.TooltipOpts`
tooltip_opts: Union[opts.TooltipOpts, dict, None] = None,
)
可以针对桑基图的每一层进行样式配置,支持的配置项如下:
class SankeyLevelsOpts(
# 指定设置的是桑基图哪一层,取值从 0 开始。
depth: Numeric = None,
# 桑基图指定层节点的样式。参考 `global_opts.ItemStyleOpts`
itemstyle_opts: Union[ItemStyleOpts, dict, None] = None,
# 桑基图指定层出边的样式。
# 其中 lineStyle.color 支持设置为'source'或者'target'特殊值,此时出边会自动取源节点或目标节点的颜色作为自己的颜色。
# 参考 `global_opts.LineStyleOpts`
linestyle_opts: Union[LineStyleOpts, dict, None] = None,
)
In [1]:
import pandas as pd
import numpy as np
from pyecharts import options as opts
from pyecharts.charts import Sankey
data = pd.read_excel(r'D:\Sone\CODE\sankey\sankey.xlsx')
# 生成nodes
nodes = []
data1=np.append(data["品类1"],data["品类2"])
for i in set(data1):
nodes.append({
'name':i
})
# 生成links
links = []
for a,b,c in zip(data["品类1"],data["品类2"],data["人数"]):
links.append({
"source":a,
"target":b,
"value":c
})
c = (
Sankey(init_opts=opts.InitOpts(width="1200px", height="800px",theme='westeros'))
.add(
"",
nodes=nodes,
links=links,
focus_node_adjacency=True, #是否高亮
linestyle_opt=opts.LineStyleOpts(opacity=0.2, curve=0.5, color="source"),
label_opts=opts.LabelOpts(position="right"),
)
.set_global_opts(title_opts=opts.TitleOpts(title="桑基图"))
.render("D:\Sone\CODE\sankey\test.html")
)
Out [1]: