本篇以2020年数学建模美赛D题的足球传球网络可视化为例,分三大步骤来简单讲解一下matlab在图与网络可视化方面的应用:
Step1 构图:
首先根据输入数据构造邻接矩阵,然后调用matlab中的graph(无向图)或digraph(有向图)函数进行构图。
构图函数有两种常见的使用方法:
G = digraph(A) %其中A是图的邻接矩阵表示,该函数返回digraph对象G
G = digraph(EdgeTable,NodeTable) %利用边信息表和节点信息表构图
其中,EdgeTable一般包含边所连接的两个节点以及边的权重等信息,NodeTable一般包含节点的标号以及节点的度等信息
Step2 创建Graphplot对象:
调用plot函数返回一个Graphplot对象,Graphplot对象包含线型、标号、颜色、坐标等多种属性,我们可以通过后续调整Graphplot对象的相关属性来改变图像的显示效果。
p = plot(G) %返回一个Graphplot对象p
Step3 调整Graphplot对象的相关属性
(1)指定线条与点的颜色与类型
p=plot(H1,'-b')%指定线条的类型,'-'为线条形状,'b'为线条颜色
p.Marker = 's';%指定节点的形状为正方形
p.NodeColor = 'r';%指定节点的颜色为红色
p.MarkerSize =10;%指定节点的大小为10
(2)自定义节点标号
Labels1={'F1','F2','D1','D2','D3','D4','D6','M1','M2','M3','M4','M6','M7','G1'};
p.NodeLabel=Labels1;
(3)指定图像布局
p=plot(H1,'-b','Layout','circle')%指定Layout为circle来更改图像布局
(4)使边的粗细反映边的权重
LWidths1 = 10*H1.Edges.Weight/max(H1.Edges.Weight);
p.LineWidth = LWidths1;
(5)使节点的大小与颜色反映节点的度数
改变节点的属性需要重新构图,因为如果我们直接使用邻接矩阵来构图的话,NodeTable一般是空的,既不含有节点标签信息也不含有节点的度数,所以我们要首先计算每个节点的度数并将其与节点标签对应建立新的NodeTable,然后重新调用diagraph函数进行构图。
%增加节点信息重新构图
EdgeTable=H1.Edges;
NodeWeight=indegree(H1)+outdegree(H1);
Labels1={'F1','F2','F3','D1','D2','D3','D4','D5','M1','M2','M3','M4','M5','G1'}';
NodeTable=table(Labels1,NodeWeight);
H2=digraph(EdgeTable,NodeTable);
...
...
...
p.MarkerSize = log(H2.Nodes.NodeWeight+1.1)*15;%节点大小
p.NodeCData=H2.Nodes.NodeWeight; %节点颜色
colorbar %显示颜色样条
(6)添加坐标
p.XData=meanx;
p.YData=meany;
%限定坐标系范围
xlim([0 100])
ylim([0 100])
%指定坐标刻度
xticks(0:10:100);
yticks(0:10:100);
(7)添加背景底图
%背景
img = imread('BackGround.jpg');
% 设置图片在绘制时的尺寸
min_x = 0;
max_x = 100;
min_y = 0;
max_y = 100;
%插入背景图
imagesc([min_x max_x],[min_y max_y], flipdim(img,1));
hold on;
(8)将图像输出并保存
%打开图窗
f1=figure(1)
%输出保存
print(f1,'-djpeg',sprintf('Distance%d.jpg',order))
可视化部分代码:
clc,clear
order=1;
A=xlsread(sprintf('passinginfo_%d.xlsx',order));
%输入节点个数
m=14;
num=size(A,1);
H1=zeros(m,m);
meanx=zeros(1,m);
meany=zeros(1,m);
count=zeros(1,m);
%构建传球网络有向图的邻接矩阵
for i=1:num
if A(i,4)~=1
if A(i,1)==1
if A(i,2)==A(i,3)
H1(A(i,2),A(i,3))=0;
else
H1(A(i,2),A(i,3))=H1(A(i,2),A(i,3))+1;
end
meanx(A(i,2))=meanx(A(i,2))+A(i,7);
meany(A(i,2))=meany(A(i,2))+A(i,8);
meanx(A(i,3))=meanx(A(i,3))+A(i,9);
meany(A(i,3))=meany(A(i,3))+A(i,10);
count(A(i,2))=count(A(i,2))+1;
count(A(i,3))=count(A(i,3))+1;
end
end
end
for i=1:m
meanx(i)=meanx(i)/count(i);
meany(i)=meany(i)/count(i);
end
meanx(find(isnan( meanx)==1)) = 0
meany(find(isnan(meany)==1)) = 0
H1=digraph(H1);
EdgeTable=H1.Edges;
NodeWeight=indegree(H1)+outdegree(H1);
Labels1={'F1','F2','F3','D1','D2','D3','D4','D5','M1','M2','M3','M4','M5','G1'}';
NodeTable=table(Labels1,NodeWeight);
H2=digraph(EdgeTable,NodeTable);
%打开图窗
f1=figure(1)
%背景
img = imread('BackGround.jpg');
% 设置图片在绘制时的尺寸
min_x = 0;
max_x = 100;
min_y = 0;
max_y = 100;
%插入背景图
imagesc([min_x max_x],[min_y max_y], flipdim(img,1));
hold on;
%绘制网络
LWidths1 = 10*H2.Edges.Weight/max(H2.Edges.Weight);
p = plot(H2,'-w','LineWidth',LWidths1)
p.NodeLabel=H2.Nodes.Labels1
p.MarkerSize = log(H2.Nodes.NodeWeight+1.1)*15;
p.NodeCData=H2.Nodes.NodeWeight;
p.LineWidth=LWidths1;
p.XData=meanx;
p.YData=meany;
%限定坐标系范围
xlim([0 100])
ylim([0 100])
%指定坐标刻度
xticks(0:10:100);
yticks(0:10:100);
colorbar
print(f1,'-djpeg',sprintf('Distance%d.jpg',order))
更多matlab图与网络相关请参考mathworks官网:
https://ww2.mathworks.cn/help/matlab/graph-and-network-algorithms.html?s_tid=CRUX_lftnav