MATLAB | 全网最详细网络图(图论图)绘制教程

一篇超超超长,超超超全面网络图绘制教程,本篇基本能讲清楚所有绘制要点,当然图论与网络优化的算法一篇不可能完全讲清楚,未来如果看的人多可以适当更新,同时做部分网络图绘图复刻。

以下是本篇绘图实验效果:

1 网络图创建

可以通过 graph 函数创建无向图,通过 digraph 创建有向图,其中网络创建可以使用起始终止点数组、邻接矩阵、EdgeTable等几种方式。

1.1 起始终止点数组

不点名布局时它会自动选择比较清晰的布局方式,怎么改布局之后再说,以下两个图连线情况都是一样的,不过有向图为了更好展示方向箭头自动用了不同的布局。

s=[1 1 1 1 1 1 1 9 9 9 9 9 9 9];
t=[2 3 4 5 6 7 8 2 3 4 5 6 7 8];
G=graph(s,t);
plot(G)

s=[1 1 1 1 1 1 1 9 9 9 9 9 9 9];
t=[2 3 4 5 6 7 8 2 3 4 5 6 7 8];
G=digraph(s,t);
plot(G)


1.2 邻接矩阵

无向图邻接矩阵必须是对称的,但是可以通过设置lower或upper属性使用下三角或上三角矩阵。

s=[1 1 1 1 1 1 1 9 9 9 9 9 9 9];
t=[2 3 4 5 6 7 8 2 3 4 5 6 7 8];
A=zeros(max(s));
for i=1:length(s)
    A(s(i),t(i))=1;
    A(t(i),s(i))=1;
end
% A = [0     1     1     1     1     1     1     1     0
%      1     0     0     0     0     0     0     0     1
%      1     0     0     0     0     0     0     0     1
%      1     0     0     0     0     0     0     0     1
%      1     0     0     0     0     0     0     0     1
%      1     0     0     0     0     0     0     0     1
%      1     0     0     0     0     0     0     0     1
%      1     0     0     0     0     0     0     0     1
%      0     1     1     1     1     1     1     1     0];
G=graph(A);
plot(G)

通过设置upper属性使用上三角矩阵:

s=[1 1 1 1 1 1 1 9 9 9 9 9 9 9];
t=[2 3 4 5 6 7 8 2 3 4 5 6 7 8];
A=zeros(max(s));
for i=1:length(s)
    A(min(s(i),t(i)),max(s(i),t(i)))=1;
end
% A = [0     1     1     1     1     1     1     1     0
%      0     0     0     0     0     0     0     0     1
%      0     0     0     0     0     0     0     0     1
%      0     0     0     0     0     0     0     0     1
%      0     0     0     0     0     0     0     0     1
%      0     0     0     0     0     0     0     0     1
%      0     0     0     0     0     0     0     0     1
%      0     0     0     0     0     0     0     0     1
%      0     0     0     0     0     0     0     0     0];
G=graph(A,'upper');
plot(G)

有向图第 i 行第 j 列有数值就说明有从 i 流向 j 的箭头。此处不要求对称矩阵啦。

s=[1 1 1 1 1 1 1 9 9 9 9 9 9 9];
t=[2 3 4 5 6 7 8 2 3 4 5 6 7 8];
A=zeros(max(s));
for i=1:length(s)
    A(s(i),t(i))=1;
end

G=digraph(A);
plot(G,'Layout','layered')

如果矩阵是对称的就说明流动是双向的:

s=[1 1 1 1 1 1 1 9 9 9 9 9 9 9];
t=[2 3 4 5 6 7 8 2 3 4 5 6 7 8];
A=zeros(max(s));
for i=1:length(s)
    A(s(i),t(i))=1;
    A(t(i),s(i))=1;
end

G=digraph(A);
plot(G,'Layout','layered')


1.3 EdgeTable

先展示一下最简单的啥都没有的网络图,之后会给出边表中增添权重,增添标签名称啥的方法的!

s=[1 1 1 2 3];
t=[2 3 4 3 4];
EdgeTable=table([s' t'],'VariableNames',{'EndNodes'});
% EdgeTable =
%
%   5×1 table
%     EndNodes
%     ________
%      1    2 
%      1    3 
%      1    4 
%      2    3 
%      3    4 
G=graph(EdgeTable);
plot(G)

s=[1 1 1 2 3];
t=[2 3 4 3 4];
EdgeTable=table([s' t'],'VariableNames',{'EndNodes'});
G=digraph(EdgeTable);
plot(G)


1.4 指定节点数量

通过如下方式可以设置节点总数:

s=[1 1 1 1 1 1 1 9 9 9 9 9 9 9];
t=[2 3 4 5 6 7 8 2 3 4 5 6 7 8];
G=graph(s,t,[],21);
plot(G)


1.5 节点及边的增添

实际上是使用,以下的 addnode 及 addedge 函数实现的:

s=[1 1 1 1 1 1 1 9 9 9 9 9 9 9];
t=[2 3 4 5 6 7 8 2 3 4 5 6 7 8];
G=digraph(s,t); 

G=G.addnode(5);
plot(G)

G=G.addedge(10,14);
plot(G)


1.6 边数量说明

两点之间不仅仅只能有两条边。

s=ones(1,15);
t=2.*ones(1,15);
G=digraph(s,t); 
plot(G)

自己到自己的边也是可以有且能有很多条的:

s=ones(1,10);
t=ones(1,10);
G=digraph(s,t); 
plot(G)


2 标签添加

2.1 权重添加及节点命名

对于由起始终止点数组创建的图:

s=[1 1 1 2 2 3 3 4 5 5 6 7];
t=[2 4 8 3 7 4 6 5 6 8 7 8];
weights=[10 10 1 10 1 10 1 1 12 12 12 12];
names={'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H'};
G=graph(s,t,weights,names);
plot(G,'EdgeLabel',weights)

对于边表创建时增添权重及节点名称:

s=[1 1 1 2 2 3 3 4 5 5 6 7];
t=[2 4 8 3 7 4 6 5 6 8 7 8];
weights=[10 10 1 10 1 10 1 1 12 12 12 12];
names={'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H'};
EdgeTable=table([s' t'],weights','VariableNames',{'EndNodes' 'Weights'});
NodeTable=table(names','VariableNames',{'Name'});
% EdgeTable =
% 
%   12×2 table
%     EndNodes    Weights
%     ________    _______
%      1    2       10   
%      1    4       10   
%      1    8        1   
%     ...  ...     ...   
%      6    7       12   
%      7    8       12   
G=graph(EdgeTable,NodeTable);
plot(G,'EdgeLabel',weights)


2.2 权重标签及节点标签修改

s=[1 1 1 2 2 3 3 4 5 5 6 7];
t=[2 4 8 3 7 4 6 5 6 8 7 8];
weights=[10 10 1 10 1 10 1 1 12 12 12 12];
names={'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H'};
codeW={'10S','10S','1S','10S','1S','10S','1S','1S','12S','12S','12S','12S'};
codeN={'AAA' 'BBB' 'CCC' 'DDD' 'EEE' 'FFF' 'GGG' 'HHH'};
G=graph(s,t,weights,names);
plot(G,'EdgeLabel',codeW,'NodeLabel',codeN)

当然可以仅仅为部分添加:

s=[1 1 2 2 3 4 5 5];
t=[2 3 3 4 4 5 1 2];
G=digraph(s,t);
h=plot(G);
labelnode(h,[1 2],{'source' 'target'})
labeledge(h,1,2,'lalalalala')


2.3 highlight

比如说把如下点和边标为红色:

G=digraph(bucky);
h=plot(G);

highlight(h,[8,7,6,1,2,3,4,5,54,55],'NodeColor','red','MarkerSize',5)
highlight(h,[8,7,6,1,2,3,4,5,54,55],'EdgeColor','red','LineWidth',3)

axis tight equal

但其实最好用边表来增添高亮,很多图论与网络优化官方函数的返回值都是边表:

G=digraph(bucky);
h=plot(G);
[mf,GF]=maxflow(G,1,56);

highlight(h,GF,'EdgeColor','red','LineWidth',3)

axis tight equal


3 基础属性

以下操作在如下例子的基础上进行:

s=[1 1 1 2 2 3 3 4 5 5 6 7];
t=[2 4 8 3 7 4 6 5 6 8 7 8];
weights=[10 10 1 10 1 10 1 1 12 12 12 12];
names={'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H'};
codeW={'10S','10S','1S','10S','1S','10S','1S','1S','12S','12S','12S','12S'};
codeN={'AAA' 'BBB' 'CCC' 'DDD' 'EEE' 'FFF' 'GGG' 'HHH'};
G=digraph(s,t,weights,names);
h=plot(G,'EdgeLabel',codeW,'NodeLabel',codeN,'Layout','subspace');


3.1 线条属性

线条粗细:

h.LineWidth=weights;

线条颜色:

h.EdgeColor=[0,0,0];

线条颜色映射:

h.EdgeCData=weights;
colormap(winter)

线条样式:

h.LineStyle=':';

透明度:

h.EdgeAlpha=.1;


3.2 节点属性

节点大小:

h.MarkerSize=(1:8).*3;

节点颜色:

h.NodeColor='red';%[1,0,0]

节点颜色映射:

h.NodeCData=1:8;

节点形状:

h.Marker="^";


3.3 标签属性

标签各个属性名就加个Node或者Edge即可:

h.NodeFontName='Cambria';
h.NodeFontSize=15;
h.NodeLabelColor=[0,0,.8];

h.EdgeFontName='Cambria';
h.EdgeFontSize=13;
h.EdgeLabelColor=[.8,0,0];


3.4 箭头属性

箭头大小:

h.ArrowSize=15;

箭头位置,范围0-1比例,0时代表在末尾,1时代表在头部

h.ArrowPosition=1;

h.ArrowPosition=.2;


3.5 类比plot函数

老版本就可以像正常plot函数一样设置属性,属性设置可以写的比较随意,而且和普通plot含函数绘图非常类似,甚至这样都行:

G=graph(bucky);
plot(G,'-.dr','NodeLabel',{})
axis tight equal

G=graph(bucky);
G.Edges.Weight=rand(size(G.Edges.Weight));

plot(G,'NodeLabel',{},'EdgeCData',G.Edges.Weight,'LineWidth',G.Edges.Weight.*8)
colormap(winter)
axis tight equal


4 网络图布局

4.1 circle布局

就是节点均匀分布在圆上:

A=rand(16)>.7;
G=digraph(A);
plot(G,'Layout','circle')
axis tight equal

把节点1放在中央:

A=rand(16)>.7;
G=digraph(A);
plot(G,'Layout','circle','Center',1)
axis tight equal


4.2 force布局

在相邻节点之间使用引力,在远距离节点之间使用斥力:

s=[1 1 1 1 1 6 6 6 6 6 11 11 11];
t=[2 3 4 5 6 7 8 9 10 11 12 13 14];
G=graph(s,t);
plot(G,'Layout','force');

增添权重影响,权重越大的边越长:

s=[1 1 1 1 1 6 6 6 6 6 11 11 11];
t=[2 3 4 5 6 7 8 9 10 11 12 13 14];
weights=randi([1 20],1,13);

G=graph(s,t,weights);
plot(G,'Layout','force','WeightEffect','direct');

通过调整’Iterations’改变引力模拟迭代次数,以下举迭代10次和迭代1000次例子(迭代的初始X,Y坐标可通过’XStart’及’YStart’属性设置以保证每次实验结果相同,此处不再赘述):

% 随便生成一组最小生成树
A=rand(60)>.7;
G=graph(A,'upper');
T=minspantree(G);

plot(T,'Layout','force','Iterations',10);

plot(T,'Layout','force','Iterations',1000);

围绕原点:

% 随便生成一组最小生成树
A=rand(60)>.7;
G=graph(A,'upper');
T=minspantree(G);

plot(T,'Layout','force','UseGravity',true);
axis tight equal

给个更直观的例子:

s=[1 3 5 7 7 10:100];
t=[2 4 6 8 9 randi([10 100],1,91)];
G=graph(s,t,[],150);

plot(G,'Layout','force','UseGravity',true);
axis tight equal


4.3 layered布局

有层次的树状布局:

% 随便生成一组最小生成树
A=rand(30)>.7;
G=graph(A,'upper');
T=minspantree(G)

plot(T,'Layout','layered')

通过设置’Direction’ 设置方向,可选为’down’ | ‘up’ | ‘left’ | ‘right’

plot(T,'Layout','layered','Direction','right')

'Sources’属性可用来设置哪些点在第一层,'Sinks’属性可用来设置哪些点在最后一层:

plot(T,'Layout','layered','Sources',[1,2,4])

‘AssignLayers’属性可用来设置层分配方法,可选为’auto’ | ‘asap’ | ‘alap’

  • auto: 节点分配使用 ‘asap’ 或 ‘alap’,以两者中更紧凑者为准。
  • asap: 在分配节点时,在满足该节点所有前趋节点都必须在其之前的层的约束条件下,将其分配到尽可能靠前的层。
  • alap: 在分配节点时,在满足其所有后继节点都必须在其之后的层的约束条件下,将其分配到尽可能后的层。
plot(T,'Layout','layered','AssignLayers','asap')

plot(T,'Layout','layered','AssignLayers','alap')


4.4 subspace布局

在高维嵌入式子空间中绘制图节点,然后将位置投影回二维。默认情况下,子空间维度是100或节点总数(以两者中较小者为准):

s=[1 1 1 2 2 3 3 4 5 5 6 7];
t=[2 4 8 3 7 4 6 5 6 8 7 8];

G=graph(s,t);
plot(G,'Layout','subspace');

通过’Dimension’设置高维空间维数。

XYZW=(abs(dec2bin(0:2^4-1))-48.5).*2;
IPT=tril(XYZW*(XYZW'));
[rows,cols]=find(IPT==2);

G=graph(rows,cols);
plot(G,'Layout','subspace');

plot(G,'Layout','subspace','Dimension',5)


4.5 force3布局

与force布局可设置属性几乎完全一样不过是三维的:

A=rand(30)>.7;
G=graph(A,'upper');
T=minspantree(G);

plot(T,'Layout','force3','UseGravity',true);
axis tight equal

4.6 subspace3布局

与subspace布局可设置属性几乎完全一样不过是三维的:

XYZW=(abs(dec2bin(0:2^4-1))-48.5).*2;
IPT=tril(XYZW*(XYZW'));
[rows,cols]=find(IPT==2);

G=graph(rows,cols);
plot(G,'Layout','subspace3','Dimension',13);

4.7 自定义X,Y坐标布局

弄个心形:

posXY=[-0.1598   -0.0682; 0.3117   -0.0060;-0.0389    0.4154;-0.1874    0.5155;
       -0.3877    0.5691;-0.6693    0.5397;-0.8092    0.2599;-0.7522   -0.0959;
       -0.5915   -0.3515;-0.4465   -0.5294;-0.2668   -0.6503;-0.0060   -0.7867;
        0.2202   -0.6503; 0.4275   -0.5173; 0.5933   -0.3515; 0.7228   -0.1563;
        0.8040    0.1045; 0.7642    0.3653; 0.5259    0.5622; 0.2323    0.5121];

A=ones(20)>0;
[s,t]=find(A);

G=graph(s,t);
plot(G,'XData',posXY(:,1),'YData',posXY(:,2))

A=ones(10)>0;
[s,t]=find(A);

T=linspace(0,2*pi,6);T(end)=[];
X=[cos(T+pi/2),cos(T+pi/2+pi/10).*.5];
Y=[sin(T+pi/2),sin(T+pi/2+pi/10).*.5];

G=graph(s,t);
plot(G,'XData',X,'YData',Y)
axis tight equal


5 修饰案例

其实也算是给出一些好看的绘图模板叭,喜欢看的人多以后可以单独出几期绘图复刻啥的。

5.1 conncomp分类

s=[randi([1 50],1,40),randi([51 60],1,5),61:120];
t=[randi([1 50],1,40),randi([51 60],1,5),randi([61,120],1,60)];
G=graph(s,t,[],150);

% 分割,并将孤立点归为一类
bins=conncomp(G);
newBins=bins;
tb=tabulate(bins);
[~,ind]=sort(tb(:,2),'descend');
nV=tb(ind,1);
nS=tb(ind,2);
for i=1:length(ind)
    if nS(i)>1
        newBins(bins==nV(i))=i;
    else
        newBins(bins==nV(i))=0;
    end
end
newBins=newBins+1;
% 基础绘图
G=digraph(s,t,[],150);
h=plot(G,'Layout','force','UseGravity',true);
axis tight equal
% 属性修饰
h.NodeCData=newBins;
h.EdgeColor=[0,0,0];
h.EdgeAlpha=.3;
h.LineWidth=2;
h.MarkerSize=6+(newBins>1).*3;
CM=[0.4000    0.7608    0.6471
    0.9882    0.5529    0.3843
    0.5529    0.6275    0.7961
    0.9059    0.5412    0.7647
    0.6510    0.8471    0.3294
    1.0000    0.8510    0.1843
    0.8980    0.7686    0.5804
    0.7020    0.7020    0.7020];
CM=[CM;CM.*.6];
CM=[.8,.8,.8;CM];
colormap(CM(1:max(newBins),:))


5.2 圆形网络图

% 先仅节点无边绘制带引力图记录X,Y坐标用于之后绘图
A=zeros(120);
G=digraph(A);
H=plot(G,'Layout','force','UseGravity',true);
X=H.XData;Y=H.YData;delete(H)
% 随机生成数据
A1=rand(20)>.92;
A2=rand(20)>.92;
A3=rand(20)>.92;
A5=zeros(20);
A=blkdiag(A1,A5,A2,A5,A3,A5);
[~,ind]=sort(rand(1,120));
A=A(ind,ind);
G=graph(A+A');
% 分割,并将孤立点归为一类
% 仅仅是示例,要有更好的分类算法或者早就分好类建议直接用
bins=conncomp(G);
newBins=bins;
tb=tabulate(bins);
[~,ind]=sort(tb(:,2),'descend');
nV=tb(ind,1);
nS=tb(ind,2);
for i=1:length(ind)
    if nS(i)>1
        newBins(bins==nV(i))=i;
    else
        newBins(bins==nV(i))=0;
    end
end
newBins=newBins+1;
% 绘图
G=digraph(A+A');
h=plot(G,'XData',X,'YData',Y);
axis tight equal
% 属性修饰
h.NodeCData=newBins;
h.EdgeCData=newBins(G.Edges.EndNodes(:,1));
h.EdgeAlpha=.4;
h.LineWidth=1;
h.MarkerSize=9;
CM=[0.4000    0.7608    0.6471
    0.9882    0.5529    0.3843
    0.5529    0.6275    0.7961
    0.9059    0.5412    0.7647
    0.6510    0.8471    0.3294
    1.0000    0.8510    0.1843
    0.8980    0.7686    0.5804
    0.7020    0.7020    0.7020];
CM=[CM;CM.*.6];
CM=[.8,.8,.8;CM];
colormap(CM(1:max(newBins),:))
set(gca,'XTick',[],'YTick',[])


5.3 多彩的树状图

n=120;
A=rand(120)>.7;
G=graph(A,'upper');
T=minspantree(G,'Root',1);
L=zeros(1,n);
for i=1:n
    L(i)=length(shortestpath(T,1,i));
end
T=digraph(T.Edges.EndNodes(:,2),T.Edges.EndNodes(:,1));
% 基础绘图
h=plot(T,'Layout','force','Iterations',5);
h.MarkerSize=((max(L)-L)./max(L).*10./4+1).^2;
h.LineWidth=(max(L(2:end))-L(2:end))./max(L(2:end)).*3+.1;
h.ArrowSize=(max(L(2:end))-L(2:end))./max(L(2:end)).*10+10; 
h.ArrowPosition=1;
% 设置配色
h.EdgeCData=T.Edges.EndNodes(:,1);
h.NodeCData=1:n;
CM=[0.4000    0.7608    0.6471
    0.9882    0.5529    0.3843
    0.5529    0.6275    0.7961
    0.9059    0.5412    0.7647
    0.6510    0.8471    0.3294
    1.0000    0.8510    0.1843
    0.8980    0.7686    0.5804
    0.7020    0.7020    0.7020];
colormap(CM)

修改一下配色:

n=120;
A=rand(120)>.7;
G=graph(A,'upper');
T=minspantree(G,'Root',1);
L=zeros(1,n);
for i=1:n
    L(i)=length(shortestpath(T,1,i));
end
T=digraph(T.Edges.EndNodes(:,2),T.Edges.EndNodes(:,1));
% 基础绘图
h=plot(T,'Layout','force','Iterations',5);
h.MarkerSize=10;
h.LineWidth=(max(L(2:end))-L(2:end))./max(L(2:end)).*3+.1;
h.ArrowSize=(max(L(2:end))-L(2:end))./max(L(2:end)).*10+10; 
h.ArrowPosition=1;
% 设置配色
h.EdgeColor=[0,0,0];
h.NodeCData=mod(L,2)+1;
CM=[.8,.8,.8
    0.4000    0.7608    0.6471];
colormap(CM)

CM=[152,210,195
    254,237,119]./255;
colormap(CM)


5.4 Watts-Strogatz 小世界图形

Watts-Strogatz 模型是一个包含小世界网络属性(例如集群和平均短路径长度)的随机图形。详细介绍请见:
https://ww2.mathworks.cn/help/matlab/math/build-watts-strogatz-small-world-graph-model.html

创建 Watts-Strogatz 图形包含以下两个基本步骤:

  • 创建一个环形网格,其中包含 N N N 个平均出入度为 2 K 2K 2K 的节点。每个节点都与任一侧的 K K K 个最近邻点相连。
  • 对于图中的每条边,重新连接概率为 β \beta β的目标节点。重新连接的边不能是重复或自环的。

执行第一步操作之后,图形将是一个完美的环形网格。因此当 β = 0 \beta=0 β=0时,不会重新连接任何边,并且该模型会返回一个环形网格。而如果 β = 1 \beta=1 β=1,则所有边都将重新连接,并且环形网格会变成随机图形。

文件 WattsStrogatz.m 对无向图实现该图算法。根据上面的算法说明,输入参数为 N、K 和 beta。

% Copyright 2015 The MathWorks, Inc.

function h = WattsStrogatz(N,K,beta)
% H = WattsStrogatz(N,K,beta) returns a Watts-Strogatz model graph with N
% nodes, N*K edges, mean node degree 2*K, and rewiring probability beta.
%
% beta = 0 is a ring lattice, and beta = 1 is a random graph.

% Connect each node to its K next and previous neighbors. This constructs
% indices for a ring lattice.
s = repelem((1:N)',1,K);
t = s + repmat(1:K,N,1);
t = mod(t-1,N)+1;

% Rewire the target node of each edge with probability beta
for source=1:N    
    switchEdge = rand(K, 1) < beta;
    
    newTargets = rand(N, 1);
    newTargets(source) = 0;
    newTargets(s(t==source)) = 0;
    newTargets(t(source, ~switchEdge)) = 0;
    
    [~, ind] = sort(newTargets, 'descend');
    t(source, switchEdge) = ind(1:nnz(switchEdge));
end

h = graph(s,t);
end

构建图,并圆形布局,重新连接概率为0:

h=WattsStrogatz(50,15,0);
plot(h,'NodeColor','k','Layout','circle');
axis tight equal

提高重新连接概率并计算出入度:

h2=WattsStrogatz(500,25,0.65);
H=plot(h2,'NodeColor','k','EdgeAlpha',0.1);
axis tight equal
H.EdgeColor=[0,0,0];
deg=degree(h2);
H.MarkerSize=2*sqrt(deg-min(deg)+0.2);
H.NodeCData=deg;
colormap(winter)


5.5 PageRank 算法对网站进行排名

又是官网的一个例子:
在 PageRank 算法的每一步中,每个网页的得分都会根据以下公式更新:
r = (1-P)/n + P*(A’*(r./d) + s/n)

  • r 是 PageRank 得分的向量。
  • P 是标量阻尼因子(通常为 0.85),这是随机浏览者点击当前网页上的链接而不是在另一随机网页上继续点击的概率。
  • A’ 是图形的邻接矩阵的转置。
  • d 是包含图形中每个节点的出度的向量。对于没有外向边的节点,d 设置为 1。
  • n 是图形中节点的标量数量。
  • s 是无链接的网页的 PageRank 得分的标量总和。

换言之,每个网页的排名很大程度上基于与之链接的网页的排名。项 A’*(r./d) 会挑选出链接到图形中每个节点的源节点的得分,而得分按这些源节点的出站链接总数进行归一化。这确保了 PageRank 得分的总和始终为 1。例如,如果节点 1 链接到节点 2、3 和 4,则它会在算法的每次迭代期间向其中的每一个节点传送 1/3 的 PageRank 得分。

s = {'a' 'a' 'a' 'b' 'b' 'c' 'd' 'd' 'd'};
t = {'b' 'c' 'd' 'd' 'a' 'b' 'c' 'a' 'b'};
G = digraph(s,t);
labels = {'a/3' 'a/3' 'a/3' 'b/2' 'b/2' 'c' 'd/3' 'd/3' 'd/3'};
p = plot(G,'Layout','layered','EdgeLabel',labels);
highlight(p,[1 1 1],[2 3 4],'EdgeColor','g')
highlight(p,[2 2],[1 4],'EdgeColor','r')
highlight(p,3,2,'EdgeColor','m')
title('PageRank Score Transfer Between Nodes')

加载 mathworks100.mat 中的数据,并查看邻接矩阵 A。这些数据是使用自动网页趴chong程序在 2015 年生成的。网页趴chong程序从 https://www.mathworks.com 开始,然后是指向后续网页的链接,直到邻接矩阵包含 100 个唯一网页连接的相关信息。

load mathworks100.mat 
spy(A)

绘制网络图:

load mathworks100.mat 
G=digraph(A,U);
plot(G,'NodeLabel',{},'NodeColor',[0.93 0.78 0],'Layout','force');
axis tight equal

MATLAB自带centrality函数可以计算重要性:

load mathworks100.mat 
G=digraph(A,U);
pr = centrality(G,'pagerank','MaxIterations',200,'FollowProbability',0.85);
G.Nodes.PageRank = pr;
G.Nodes.InDegree = indegree(G);
G.Nodes.OutDegree = outdegree(G);

H=subgraph(G,find(G.Nodes.PageRank > 0.005));
h=plot(H,'NodeLabel',{},'NodeCData',H.Nodes.PageRank,'Layout','force');
colormap(parula(32))
colorbar
axis tight equal

修改配色:

h.EdgeColor=[0,0,0];
h.EdgeAlpha=.3;
h.NodeColor=[185,67,69]./255;
colorbar('off')


5.6 神经网络图

最多只能三层。三层往上建议自己写个函数。

layer=[5,8,7];
sumlayer=[0,cumsum(layer)];

S=[];T=[];
for i=1:length(layer)-1
    [tS,tT]=meshgrid(1:layer(i),1:layer(i+1));
    S=[S;tS(:)+sumlayer(i)];
    T=[T;tT(:)+sumlayer(i+1)]; 
end
G=digraph(S,T);
h=plot(G,'Layout','layered','Sources',1:layer(1),'AssignLayers','asap',...
    'Sinks',sumlayer(end-1)+1:sumlayer(end),'Direction','right');
h.ArrowPosition=1;
h.LineWidth=1;
h.EdgeColor=[0,0,0];
h.EdgeAlpha=.3;
h.ArrowSize=12;
h.MarkerSize=16;
h.NodeColor=[.8,.8,.8];
h.NodeFontSize=14;
h.NodeFontName='Cambria';


5.7 随便的一个树状图

E1=[ones(60,1),(2:61)'];
E2=[E1(randi([1,60],[90,1]),2),(62:151)'];
E3=[E2(randi([1,90],[150,1]),2),(152:301)'];
s=[E1(:,1);E2(:,1);E3(:,1)];
t=[E1(:,2);E2(:,2);E3(:,2)];
% 绘图
G=graph(s,t,t.*0+1);
h=plot(G,'Layout','force','WeightEffect','direct');
axis tight equal
% 修饰
h.EdgeColor=[0,0,0];
h.EdgeAlpha=.6;
h.MarkerSize=3;
h.NodeColor=[185,67,69]./255;


5.8 Delaunay 三角剖分

X=rand([200,1]);
Y=rand([200,1]);
% delaunay三角形生成
Tri=delaunay(X,Y);
S=[Tri(:,1);Tri(:,2);Tri(:,3)];
T=[Tri(:,2);Tri(:,3);Tri(:,1)];
% 绘图
G=digraph(S,T);
h=plot(G,'XData',X,'YData',Y);
% 修饰
axis equal
set(gca,'XLim',[0,1],'YLim',[0,1],'XTick',[],'YTick',[])
h.EdgeColor=[0,0,0];
h.EdgeAlpha=.6;
h.MarkerSize=4;
h.LineWidth=.5;
h.NodeColor=[185,67,69]./255;


又是一篇大长文结束
攒着想写的文章总算又干掉一篇
网络图绘制技能树get
编写不易希望大家多多点赞!!

全部代码mlx文件请以下gitee仓库获取:

https://gitee.com/slandarer/matlab-graph-plot

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/2721.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java中的String类

String类1.String类1.1 特性1.2 面试题1.3 常用方法1.4 String与其他类型之间的转换2. StringBuilder类、StringBuffer类&#xff1a;可变字符序列1.String类 1.1 特性 String类为final类&#xff0c;不可被继承&#xff0c;代表不可变的字符序列&#xff1b; 实现了Serializ…

webpack——使用、分析打包代码

世上本无nodejs js最初是在前端浏览器上运行的语言&#xff0c;js代码一旦脱离了浏览器环境&#xff0c;就无法被运行。直到nodejs的出现&#xff0c;我们在电脑上配置了node环境&#xff0c;就可以让js代码脱离浏览器&#xff0c;在node环境中运行。 浏览器不支持模块化 nodej…

STL—vector

vector介绍在C标准库中&#xff0c;vector是一个常用的序列式容器&#xff08;线性结构&#xff09;&#xff0c;它就好比c语言中的数组&#xff0c;但是vector有一些数组没有的功能&#xff0c;是一个封装好了的类。想要使用vector需要先引入头文件&#xff1a;#include<ve…

【C陷阱与缺陷】----语法陷阱

&#x1f4af;&#x1f4af;&#x1f4af; 要理解一个C程序&#xff0c;必须理解这些程序是如何组成声明&#xff0c;表达式&#xff0c;语句的。虽然现在对C的语法定义很完善&#xff0c;几乎无懈可击&#xff0c;大门有时这些定义与人们的直觉相悖&#xff0c;或容易引起混淆…

【机器学习】综述:机器学习中的模型评价、模型选择与算法选择

文章目录一、前言二、论文摘要三、简介&#xff1a;基本的模型评估项和技术3.1 性能评估&#xff1a;泛化性能 vs. 模型选择四、Bootstrapping 和不确定性五、交叉验证和超参数优化一、前言 最近在做实验的时候&#xff0c;发现树模型有过拟合的情况发生&#xff0c;为此&…

蓝桥杯每日一真题—— [蓝桥杯 2021 省 AB2] 完全平方数(数论,质因数分解)

文章目录[蓝桥杯 2021 省 AB2] 完全平方数题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1样例 #2样例输入 #2样例输出 #2提示思路&#xff1a;理论补充&#xff1a;完全平方数的一个性质&#xff1a;完全平方数的质因子的指数一定为偶数最终思路&#xff1a;小插曲&am…

直面风口,未来不仅是中文版ChatGPT,还有AGI大时代在等着我们

说到标题的AI2.0这个概念的研究早在2015年就研究起步了&#xff0c;其实大家早已知道&#xff0c;人工智能技术必然是未来科技发展战略中的重要一环&#xff0c;今天我们就从AI2.0入手&#xff0c;以GPT-4及文心一言的发布为切入角度&#xff0c;来谈一谈即将降临的AGI时代。 关…

Linux搭建GitLab私有仓库,并内网穿透实现公网访问

文章目录前言1. 下载Gitlab2. 安装Gitlab3. 启动Gitlab4. 安装cpolar5. 创建隧道配置访问地址6. 固定GitLab访问地址6.1 保留二级子域名6.2 配置二级子域名7. 测试访问二级子域名前言 GitLab 是一个用于仓库管理系统的开源项目&#xff0c;使用Git作为代码管理工具&#xff0c…

基于Springboot实现商务安全邮箱邮件收发 源码+论文展示

基于Springboot实现商务安全邮箱邮件收发 源码论文开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Ma…

【多线程】定时器和线程池

✨个人主页&#xff1a;bit me&#x1f447; ✨当前专栏&#xff1a;Java EE初阶&#x1f447; ✨每日一语&#xff1a;种一棵树最好的时间是十年前&#xff0c;其次是现在。 目 录⌚️一. 定时器&#x1f4c4;1. 定时器是什么&#x1f4c3;2. 标准库中的定时器&#x1f4d1;3.…

【C语言初阶】初识C语言 | C语言知识预览

文章目录&#x1f490;专栏导读&#x1f490;文章导读&#x1f337;什么是C语言&#xff1f;&#x1f337;第一个C语言程序&#x1f337;数据类型&#x1f337;变量、常量、字符串&#x1f33a;定义变量的方法&#x1f33a;变量的分类&#x1f33a;变量的使用&#x1f33a;变量…

DJ2-5 DNS:Internet 的目录服务

目录 1. DNS 简介 2. DNS 服务器提供的功能 3. 分布式、层次数据库 4. DNS 查询方法 5. DNS 缓存和权威 DNS 服务器记录更新 6. DNS 记录 7. DNS 报文 8. 在 DNS 数据库中插入记录 9. DNS 攻击 1. DNS 简介 名称&#xff1a;Domain Name System DNS 是&#xff1a; …

vue面试题(day06)

文章目录前言请谈谈WXML与标准的html的异同&#xff1f;请谈谈WXSS和CSS的异同&#xff1f;请谈谈微信小程序主要目录和文件的作用&#xff1f;请谈谈小程序的双向绑定和vue的异同&#xff1f;简单描述下微信小程序的相关文件类型&#xff1f;微信小程序有哪些传值(传递数据)方…

【新星计划2023】SQL SERVER (01) -- 基础知识

【新星计划2023】SQL SERVER -- 基础知识1. Introduction1.1 Official Website1.2 Conn Tool2. 基础命令2.1 建库建表2.2 Alter2.3 Drop2.3 Big Data -- Postgres3.Awakening1. Introduction 1.1 Official Website 官方文档&#xff08;小技巧&#xff09; Officail Website: …

十个Python图像处理工具,不可不知

这些Python库提供了一种简单直观的方法来转换图像并理解底层数据。 今天的世界充满了数据&#xff0c;图像是这些数据的重要组成部分。但是&#xff0c;在使用它们之前&#xff0c;必须对这些数字图像进行处理 - 分析和操作&#xff0c;以提高其质量或提取一些可以使用的信息。…

【C++学习】继承

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《C学习》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; C是面向对象的编程语言&#xff0c;它有很多的特性&#xff0c;但是最重要的就是封装&#xff0c;继承…

【3DoF算法】

VR 3DoF算法介绍 核心&#xff1a;3DoF算法应用场景&#xff0c;在VIO应用中&#xff0c;当只有测量没有观测的情况下&#xff0c;6DoF算法的预测会退化成一个只有测量的3DoF算法&#xff0c;这时候需要使用3DoF算法&#xff0c;来更加稳定准确的获取3DoF位姿&#xff0c;直到…

【VSCode】Windows 下搭建 Fortran 环境

文章目录Part.I 预备知识Part.II 安装与配置Chap.I 编译环境Chap.II 插件Part.III 测试Chap.I 一个示例Chap.II 注意事项Part.I 预备知识 Fortran 是一种比较古老的语言了&#xff0c;当时作为一种科学计算工具&#xff0c;还是比较火的&#xff0c;因为很多有名的软件都是基于…

LFM雷达实现及USRP验证【章节2:LFM雷达测距】

目录 1. 参数设计 几个重要的约束关系 仿真参数设计 2. matlab雷达测距代码 完整源码 代码分析 回顾&#xff1a;LFM的基本原理请详见第一章 本章节将介绍LFM雷达测距的原理及实现 1. 参数设计 几个重要的约束关系 带通采样定理&#xff1a; 因此如果我们B80MHz时&a…

SQL优化13连问,收藏好!

1.日常工作中&#xff0c;你是怎么优化SQL的&#xff1f; 大家可以从这几个维度回答这个问题&#xff1a; 分析慢查询日志 使用explain查看执行计划 索引优化 深分页优化 避免全表扫描 避免返回不必要的数据&#xff08;如select具体字段而不是select*&#xff09; 使用…