詳解Matlab如何繪制?;鶊D
這次主要是分享自己寫的一個(gè)函數(shù),用來(lái)繪制?;鶊D,效果大概是下面這樣子:



先說(shuō)明函數(shù)(sankey2)怎么用,函數(shù)完整代碼放在博客最后
詳細(xì)用法
1 使用示例
新建一個(gè)m文件,運(yùn)行如下代碼
List={'a1',1,'A';
'a2',1,'A';
'a3',1,'A';
'a3',0.5,'C';
'b1',1,'B';
'b2',1,'B';
'b3',1,'B';
'c1',1,'C';
'c2',1,'C';
'c3',1,'C';
'A',2,'AA';
'A',1,'BB';
'B',1.5,'BB';
'B',1.5,'AA';
'C',3.5,'BB';
};
axis([0,2,0,1])
sankeyHdl=sankey2([],'XLim',[0,2],'YLim',[0,1],'PieceWidth',0.15,'List',List,'Color',[0.3,0.3,0.7])

2 輸入?yún)?shù)
2.1 必要輸入?yún)?shù)
必要參數(shù)一共有四個(gè),第一個(gè)就是流量表(‘List’),可以從excel里導(dǎo)入,也可以像下圖這樣直接寫在cell數(shù)組里:
List={'a1',1,'A';
'a2',1,'A';
'a3',1,'A';
'a3',0.5,'C';
'b1',1,'B';
'b2',1,'B';
'b3',1,'B';
'c1',1,'C';
'c2',1,'C';
'c3',1,'C';
'A',2,'AA';
'A',1,'BB';
'B',1.5,'BB';
'B',1.5,'AA';
'C',3.5,'BB';
};另外三個(gè)參數(shù)為,x軸范圍(‘xLim’),y軸范圍(‘YLim’),以及函數(shù)第一個(gè)參數(shù),要繪制圖像的axes,要畫在當(dāng)前窗口可以將第一個(gè)參數(shù)寫作[]或者gca
2.2 修飾參數(shù)
主要有以下幾個(gè),不寫時(shí)用省缺值替換
- Color 方塊顏色
- EdgeColor 方塊邊緣顏色
- FontSize 字號(hào)
- FontColor 字體顏色
- PieceWidth 方塊寬度
- Margin ?;鶊D距離邊緣距離
- Sep 縱向空白占方塊總長(zhǎng)度比例
其中Color可以是個(gè)nx3大小的矩陣,矩陣中數(shù)值范圍為[0,1],例如:
List={'a1',1,'A';
'a2',1,'A';
'a3',1,'A';
'a3',0.5,'C';
'b1',1,'B';
'b2',1,'B';
'b3',1,'B';
'c1',1,'C';
'c2',1,'C';
'c3',1,'C';
'A',2,'AA';
'A',1,'BB';
'B',1.5,'BB';
'B',1.5,'AA';
'C',3.5,'BB';
};
axis([0,2,0,1])
colorList=[0.4600 0.5400 0.4600
0.5400 0.6800 0.4600
0.4100 0.4900 0.3600
0.3800 0.5300 0.8400
0.4400 0.5900 0.8700
0.5800 0.7900 0.9300
0.6500 0.6400 0.8400
0.6300 0.6300 0.8000
0.5600 0.5300 0.6700
0.7600 0.8100 0.4300
0.5600 0.8600 0.9700
0.7800 0.5900 0.6500
0.8900 0.9100 0.5300
0.9300 0.5600 0.2500];
sankeyHdl=sankey2([],'XLim',[0,2],'YLim',[0,1],'PieceWidth',0.15,'List',List,'Color',colorList)
3 輸出
函數(shù)的輸出如下:

nameList就是每一個(gè)元素的名稱,block是每一個(gè)方塊的圖形對(duì)象,connect是每一個(gè)連接的圖形對(duì)象,txt是每一個(gè)標(biāo)簽的文本對(duì)象,我們可以做出以下操作:
圖形對(duì)象和文本對(duì)象原本自帶的屬性依舊可以用(顏色,位置,透明度,邊緣粗細(xì)等等)
假設(shè)我們編寫了如下代碼的基礎(chǔ)上,我們嘗試對(duì)對(duì)象進(jìn)行操作:
List={'a1',1,'A';
'a2',1,'A';
'a3',1,'A';
'a3',0.5,'C';
'b1',1,'B';
'b2',1,'B';
'b3',1,'B';
'c1',1,'C';
'c2',1,'C';
'c3',1,'C';
'A',2,'AA';
'A',1,'BB';
'B',1.5,'BB';
'B',1.5,'AA';
'C',3.5,'BB';
};
axis([0,2,0,1])
sankeyHdl=sankey2([],'XLim',[0,2],'YLim',[0,1],'PieceWidth',0.15,'List',List,'Color',colorList)
操作1 把第四個(gè)方塊顏色變?yōu)榧t色
sankeyHdl.block(4).FaceColor=[0.8,0.3,0.3];

操作2 把第10個(gè)方塊的第一個(gè)連接變?yōu)榧t色
sankeyHdl.connect(10,1).FaceColor=[0.8,0.3,0.3];

操作3 把第11個(gè)標(biāo)簽文本放大
sankeyHdl.txt(11).FontSize=40;

函數(shù)完整代碼
function sankeyHdl=sankey2(varargin)
if strcmp(get(varargin{1},'type'),'axes' )
ax=varargin{1};
else
ax=gca;
end
hold(ax,'on')
%若未設(shè)置,則圖像的初始值==================================================
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];
%從可變長(zhǎng)度變量中提取有用信息==============================================
for i=1:length(varargin)
tempVar=varargin{i};
if ischar(tempVar)&&length(tempVar)>1
prop.(tempVar)=varargin{i+1};
end
end
%流量矩陣構(gòu)建==============================================================
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:1
if ~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:1
if ~any(strcmp(List_R,List_L{i}))
layer_n=[layer_n;find(strcmp(nameList,List_L{i}))];
List_L(i)=[];
List_R(i)=[];
end
end
layer_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.layerNum
tempY=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)~=0
Hdl_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.layerNum
tempY=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
使用示例代碼
List={'零食',300,'食品開銷';
'飲料',150,'食品開銷';
'水果',250,'食品開銷';
'食堂',600,'食品開銷';
'外賣',400,'食品開銷';
'水費(fèi)',90,'住宿開銷';
'電費(fèi)',90,'住宿開銷';
'網(wǎng)費(fèi)',120,'住宿開銷';
'食品開銷',1700,'開銷';
'住宿開銷',300,'開銷'};
axis([0,2,0,1])
sankeyHdl=sankey2([],'XLim',[0,2],'YLim',[0,1],'PieceWidth',0.15,'List',List,'Color',colorList)
sankeyHdl.block(4).FaceColor=[0.8,0.3,0.3];
sankeyHdl.txt(4).FontSize=40;

試試證明還是方塊畫細(xì)一點(diǎn)顯得高級(jí),修飾一下:


以上就是詳解Matlab如何繪制桑基圖的詳細(xì)內(nèi)容,更多關(guān)于Matlab桑基圖的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Matlab實(shí)現(xiàn)貪吃蛇小游戲的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用Matlab實(shí)現(xiàn)貪吃蛇小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
C++使用boost::lexical_cast進(jìn)行數(shù)值轉(zhuǎn)換
這篇文章介紹了C++使用boost::lexical_cast進(jìn)行數(shù)值轉(zhuǎn)換的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06
從匯編看c++函數(shù)的默認(rèn)參數(shù)的使用說(shuō)明
本篇文章介紹了,在c++中函數(shù)的默認(rèn)參數(shù)的使用說(shuō)明分析。需要的朋友參考下2013-05-05
C語(yǔ)言判斷數(shù)是否為素?cái)?shù)與素?cái)?shù)輸出
大家好,本篇文章主要講的是C語(yǔ)言判斷數(shù)是否為素?cái)?shù)與素?cái)?shù)輸出,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12

