1、什么是桑吉图?

桑基图 (Sankey Diagram),是一种特定类型的流图,用于描述一组值到另一组值的流向。上图为1869年,查尔斯米纳德(Charles Minard)绘制的1812年拿破仑征俄图(Map of Napolean's Russian Campaign of 1812),这是一个在地图上覆盖桑基图的流程图。1898年爱尔兰人Matthew Henry Phineas Riall Sankey 在土木工程师学会会报纪要的一篇关于蒸汽机能源效率的文章中首次推出了第一个能量流动图,此后便以其名字命名为 Sankey 图,中文音译为桑基图。

图中延伸的分支的宽度对应数据流量的大小。桑基图的特点如下:

  • 起始流量和结束流量相同,所有主支宽度的总和与所有分出去的分支宽度总和相等,保持能量的平衡;
  • 在内部,不同的线条代表了不同的流量分流情况,它的宽度成比例地显示此分支占有的流量;
  • 节点不同的宽度代表了特定状态下的流量大小。

桑基图通常应用于能源、材料成分、金融等数据的可视化分析。

英文名:Sankey Diagram

2、简要画法(这里汇总了三种最简单的桑吉图画法,分别使用excel、matlab、python)

2.1.EXCEL画桑基图

①调出开发工具文件→选项→自定义功能区→勾选【开发工具】→确定

②添加E2D3:加载项开发工具→加载项→应用商店→搜索框中输入【E2D3】→搜索→添加→继续

③生成图表点击左边的图标,可选择不同的图表类别

点击左上角的Recommend,把鼠标移至桑基图上方,然后点击弹出页面中的Visualize

自动生成桑基图及数据源

④套用图表虽然生成了我们想要的图表样式,但数据源不正确,此时可通过以下方式修改

删除数据直接选中多余数据,然后删除,此时图表会自动更新

直接替换数据源中的原始数据,图表也会自动引用更新后的数据

直接新增数据,图表自动更新(如果新增数据后,发现图表未更新,需要手动更改数据区域。先用鼠标选取数据区域,然后点击图表左上角的Reset data area,图表即可重新引用选中的数据区域)

2.2.MATLAB画桑基图

代码如下

function sankeyHdl=sankey2(varargin)
if strcmp(get(varargin{1},'type'),'axes' )ax=varargin{1};
elseax=gca;
end
hold(ax,'on')%若未设置,则图像的初始值==================================================
prop.Color=[0,0,0];
prop.FontSize=10;
prop.FontColor=[0,0,0];
prop.Xlim=[0,1];
prop.YLim=[0,1];
prop.PieceWidth=0.15;
prop.List=[];
prop.Margin=0.05;
prop.Sep=1/8;
prop.EdgeColor=[0 0 0];%从可变长度变量中提取有用信息==============================================
for i=1:length(varargin)tempVar=varargin{i};if ischar(tempVar)&&length(tempVar)>1prop.(tempVar)=varargin{i+1};end
end%流量矩阵构建==============================================================
nameList=unique([prop.List(:,1);prop.List(:,3)],'stable');
blockMat=zeros(length(nameList));
for i=1:size(prop.List,1)s=strcmp(nameList,prop.List(i,1));e=strcmp(nameList,prop.List(i,3));blockMat(s,e)=prop.List{i,2};
end
totalFlow=max([sum(blockMat,1);sum(blockMat,2)'],[],1);%划分桑基图层次============================================================
List_L=prop.List(:,1);
List_R=prop.List(:,3);
prop.layer=[];layerRoot=[];n=1;
for i=length(List_R):-1:1if ~any(strcmp(List_L,List_R{i}))layerRoot=[layerRoot;find(strcmp(nameList,List_R{i}))];end
end
layerRoot=unique(layerRoot,'stable');
while ~isempty(List_L)layer_n=[];for i=length(List_L):-1:1if ~any(strcmp(List_R,List_L{i}))layer_n=[layer_n;find(strcmp(nameList,List_L{i}))];List_L(i)=[];List_R(i)=[];endendlayer_n=unique(layer_n,'stable');prop.layer(length(layer_n),n)=0;prop.layer(1:length(layer_n),n)=layer_n;n=n+1;
end
prop.layer(length(layerRoot),n)=0;
prop.layer(1:length(layerRoot),n)=layerRoot;
prop.layerNum=size(prop.layer,2);%绘制方块==================================================================
baseBlockX=[0,1,1,0];
baseBlockY=[0,0,1,1];
bnul=max(sum(prop.layer~=0,1));   %block number upper limit
baseLenY=(diff(prop.YLim)-2*prop.Margin)/(bnul+(bnul-1)*prop.Sep)*bnul;
baseLenX=(diff(prop.XLim)-2*prop.Margin)/(prop.layerNum-0.5);
colorIndex=1;
for i=1:prop.layerNumtempY=prop.Margin;elemSet=prop.layer(prop.layer(:,i)~=0,i);flowSet=totalFlow(elemSet);offSet=(diff(prop.YLim)-2*prop.Margin-baseLenY/length(elemSet)*((length(elemSet)+(length(elemSet)-1)*prop.Sep)))/2;for j=1:length(elemSet)tempLenY=baseLenY./sum(flowSet).*flowSet(j);sankeyHdl.block(prop.layer(j,i))=...fill(baseBlockX.*prop.PieceWidth+prop.Margin+(i-1)*baseLenX,...baseBlockY.*tempLenY+tempY+offSet,...prop.Color(colorIndex,:),'EdgeColor',prop.EdgeColor);tempY=tempY+tempLenY+baseLenY/length(elemSet)*prop.Sep;colorIndex=mod(colorIndex,size(prop.Color,1))+1;end
end%绘制连接
layerList=prop.layer(:);
for i=1:length(nameList)for j=i:length(nameList)if blockMat(i,j)~=0Hdl_L=sankeyHdl.block(i);Hdl_R=sankeyHdl.block(j);list_L=find(blockMat(i,:)~=0);list_R=find(blockMat(:,j)~=0);[~,pl,~]=intersect(layerList,list_L(:));[~,pr,~]=intersect(layerList,list_R(:));list_L=layerList(sort(pl));list_R=layerList(sort(pr));flow_L=blockMat(i,list_L);flow_R=blockMat(list_R,j);XData_L=Hdl_L.XData;YData_L=Hdl_L.YData;XData_R=Hdl_R.XData;YData_R=Hdl_R.YData;xx=[XData_L(1:2);XData_R(1:2)]';k_L=find(list_L==j);k_R=find(list_R==i);yy=[YData_L(1:2)+(YData_L(3:4)-YData_L(1:2))./sum(flow_L).*sum(flow_L(1:k_L-1));YData_R(1:2)+(YData_R(3:4)-YData_R(1:2))./sum(flow_R).*sum(flow_R(1:k_R-1))]';xxq=XData_L(2):0.01:XData_R(1);yyq=interp1(xx,yy,xxq,'pchip');tempColor=Hdl_L.FaceColor;width=(YData_R(3)-YData_R(1))./sum(flow_R).*flow_R(k_R);sankeyHdl.connect(i,k_L)=...fill([xxq,xxq(end:-1:1)],[yyq,yyq(end:-1:1)+width],tempColor,'EdgeColor','none','FaceAlpha',0.3);end    end
end%绘制文本
for i=1:prop.layerNumtempY=prop.Margin;elemSet=prop.layer(prop.layer(:,i)~=0,i);flowSet=totalFlow(elemSet);offSet=(diff(prop.YLim)-2*prop.Margin-baseLenY/length(elemSet)*((length(elemSet)+(length(elemSet)-1)*prop.Sep)))/2;for j=1:length(elemSet)tempLenY=baseLenY./sum(flowSet).*flowSet(j);sankeyHdl.txt(prop.layer(j,i))=...text(prop.PieceWidth+prop.Margin+(i-1)*baseLenX,tempLenY/2+tempY+offSet,[' ',nameList{elemSet(j)}],...'FontSize',prop.FontSize,'Color',prop.FontColor);tempY=tempY+tempLenY+baseLenY/length(elemSet)*prop.Sep;end
end
sankeyHdl.nameList=nameList';
end

3.3.Python

def get_tu(tablename,df):nodes1,links = get_data(df)sankey = (Sankey(init_opts=opts.InitOpts(width="2000px", height="800px")).add(tablename,nodes1,links,pos_top="10%",node_width = 30,  #每个桑基图矩形的宽度node_gap= 12,  #桑基图中每一列任意两个矩形节点之间的间隔。is_draggable = True,layout_iterations = 5,# focus_node_adjacency=True,itemstyle_opts=opts.ItemStyleOpts(border_width=2, border_color="#aaa"),linestyle_opt=opts.LineStyleOpts(opacity=0.8, curve=0.5, color='source'),label_opts=opts.LabelOpts(position='right'),).set_global_opts(title_opts=opts.TitleOpts(title="XXXX")))return sankeyfile ='XXX.xlsx'
df= pd.read_excel(file,sheet_name='XXXX') ##获得数据
sk1 = get_tu('XXX',df)  ##调用函数画图
sk1.render("XXX.html") #输出网址
print('XXX')

需要注意的是:1、nodes中的"name"不要重复命名;2、links中source和target对应的值一定要在nodes的name对应的值中;3、links中source和target对应的值不能相同

桑基图绘制的简易操作相关推荐

  1. R语言多层桑基图_R语言可视化(二十三):桑基图绘制

    23. 桑基图绘制 清除当前环境中的变量 rm(list=ls()) 设置工作目录 setwd("C:/Users/Dell/Desktop/R_Plots/23sankey/") ...

  2. Extjs 桑基图绘制实现(前端+后端)

    桑基图效果如下: 准备工作: 1.新建 SanKey.aspx.cs ,如下所示,将对于部分删除. 删除多余部分,保留头部如下: 2.新建 SanKey.html 页面,如下所示: 在html页面中添 ...

  3. ggalluvial | 冲击图/ 桑基图绘制

    Alluvial_0 ❝ 小伙伴写的ggalluvial使用指南. ❞ 冲击图是一种对能量分流的可视化展示图,在富集分析中可以用来展示基因在各通路中的富集流向,展示效果类比于弦图. ggalluvia ...

  4. python 桑基图_3行代码基于python的matplotlib绘制桑基图

    背景 桑基图作为1种表达数据流动方向的可视化方式,在商业数据分析,地理可视化,生物医学领域有着广泛应用.比如:在基因组学领域,有研究利用桑基图来表示生物分子之间的调控关系. 目前多数桑基图软件包(如p ...

  5. R画图实战之——桑基图

    之所以会想到写关于桑基图的内容是因为最近工作需要,研究了下桑基图,发现网络上和桑基图相关的真实可用的资料少之又少,所以决定出这篇博客,讲讲如何用R语言绘制桑基图. 什么是桑基图? 它是一种特定类型的流 ...

  6. 【Python基础】用Python制作漂亮的流动桑基图

    来源:Python数据之道 作者:Peter 整理:Lemon 桑基图绘制实践 本文中介绍的是如何制作桑基图,使用的可视化库是强大的 Pyecharts (版本1.7.1,版本一致很重要).文章将从如 ...

  7. 炫酷!用Python制作漂亮的流动桑基图

    作者:Peter 整理:Lemon 桑基图绘制实践 本文中介绍的是如何制作桑基图,使用的可视化库是强大的 Pyecharts (版本1.7.1,版本一致很重要).文章将从如下几个方面进行介绍: 什么是 ...

  8. 桑基图(Echarts)——自定义风格

    桑基图绘制--使用Echarts 桑基图(Sankey diagram),即桑基能量分流图,也叫桑基能量平衡图.它是一种特定类型的流程图,图中延伸的分支的宽度对应数据流量的大小,通常应用于能源.材料成 ...

  9. 可视化神器Plotly玩转桑基图

    公众号:尤而小屋 作者:Peter 编辑:Peter 大家好,我是Peter呀~ 本文介绍的是利用Plotly绘制一种相对少见的可视化图形:桑基图,这个图形可以说是展现数据流动的利器. 虽然桑基图使用 ...

最新文章

  1. ASP.NET 制作让搜索引擎可以友好访问的链接
  2. python教程:模块的作用与说明
  3. Django——WEB三层架构与MVC
  4. 南通工学院计算机97级,2021年南通理工学院录取结果查询网址入口及录取结果公布时间...
  5. 唐敏豪:我给MSU评测打9分
  6. 使用OData服务创建SAP C4C的Lead数据,必须指定Account字段
  7. Hive 中的Mapper Reducer个数 决定因素
  8. 系统学习机器学习之随机场(二)--MEMM
  9. python处理csv文件计算均值_PYTHON实现对CSV文件多维不同单位数据的归一化处理
  10. pom文件各标签解释
  11. aac和mp3在码率压缩的一些事
  12. python的三种基本结构流程图_程序的三种基本结构是什么
  13. c语言的fprintf函数的用法,fprintf 和fscanf 函数
  14. 排错Package restore is disabled by default. To give consent, open the Visual Studio Options dialog
  15. Git Gitosis
  16. 贺泓胜:2.24黄金今日走势分析操作建议,黄金原油解套指导
  17. Docker之工作中常用的命令(二)
  18. 陕西计算机考研难度排行榜,陕西地区计算机考研院校分析「建议收藏」「最全」...
  19. Programming Exercise5:Regularized Linera Regression and Bias v.s Variance
  20. 当前最先进的个人计算机,世界上最先进的计算机量子计算机取得了重大突破

热门文章

  1. 高德地图-缩放比例尺控件
  2. 淘宝宝贝详情页的优化技巧
  3. 前端如何将静态页面部署到服务器,并可以通过公网ip访问。
  4. 数据分析: kaggle比赛 - 销量预测
  5. One PUNCH Man——特征选择
  6. 软件的版权和专利辨析
  7. 面试官:hold住了八股和算法,扫码登录应该怎么实现你总不会了吧
  8. 用皮尔逊相关系数检查特征间的线性相关关系
  9. Chrome 图片批量下载扩展—— zzllrr Imager(小乐图客)
  10. 【问题解决】Springboot中@Value()读取不到配置文件属性解决方法