数学建模——matlab绘制 地图 散点图连线图 (运用plot、scatter、struct、xlsread等函数)【全文8000字】

  因为对matlab绘图函数不熟悉,整整花了6个多小时,才终于绘制出了封面那张理想的图。

文章目录

  • 一、最终的作图成果
  • 二、作图步骤
    • 第一步:读取所有数据
    • 第二步:将数据包装入结构体
    • 第三步:绘制交通路线图(不含散点)
    • 第四步:筛选第一问所要用到的散点数据
    • 第五步:集中绘制散点图
    • 第六步:细节优化→图例修整、坐标说明+标题
      • ①图例修整
      • ②坐标说明+标题
  • 四、总结:
  • 五、完整源码(2022/5/3补充)
  • 六、参考附录:


敲到码穷处,坐看云起时。

数学建模系列文章——总结篇:《数模美一国一退役选手的经验分享[2021纪念版]》.


一、最终的作图成果


在这里插入图片描述
  这是2011年国赛数模B题《交巡警服务平台的设置与调度》,用 第一问 给的数据来作的图。

  接下来我将依次讲解其步骤,作图的 详细说明 在代码的注释里。


二、作图步骤

第一步:读取所有数据


clc,clear,close all;
[all_data_1,QY] = xlsread('cumcm2011B附件2_全市六区交通网路和平台设置的数据表.xls',1,'A2:E583');  % 附件1的数据
all_data_2 = xlsread('cumcm2011B附件2_全市六区交通网路和平台设置的数据表.xls',2,'A2:B929');  % 附件2的数据
all_data_3 = xlsread('cumcm2011B附件2_全市六区交通网路和平台设置的数据表.xls',3,'B2:B81');   % 附件3的数据
all_data_4_1 = xlsread('cumcm2011B附件2_全市六区交通网路和平台设置的数据表.xls',4,'B2:B18');  % 附件4的数据
all_data_4_2 = xlsread('cumcm2011B附件2_全市六区交通网路和平台设置的数据表.xls',4,'C2:C14');  % 附件4的数据

ind = all_data_1(:,1);      % 数据点的编号
zuo_x = all_data_1(:,2);    % 数据点的横坐标
zuo_y = all_data_1(:,3);    % 数据点的纵坐标
QuYu = QY;     % 数据点所在的区域【一共有A、B、...、F七个区域】
FaAnLv = all_data_1(:,5);   % 数据点的发案率

QiDian_ind = all_data_2(:,1);     % 交通道路的起点编号
ZhongDian_ind = all_data_2(:,2);  % 交通道路的终点编号

  说明:①Excel数据 需要放在 matlab当前运行的文件夹里面。
     ②xlsread()函数的用法详见本文最后的 参考附录【5】。
     ③数据 在文章最后的 参考附录【7】 。



第二步:将数据包装入结构体


% 第一种添加结构体成员的方法
t = 1;  % 用 t 来记录结构体的序号
for i = 1:size(ind)
    % Table(t) = struct('ind',ind(i),'ZuoBiao',[zuo_x,zuo_y],'QuYu',QuYu(i),'FaAnLv',FaAnLv(i));
    Table(t) = struct('ind',ind(i),'X',zuo_x(i),'Y',zuo_y(i),'QuYu',QuYu(i),'FaAnLv',FaAnLv(i));
    t = t + 1;
end
%---------------------------------


% 第二种添加结构体成员的方法---------
for i = 1:size(ind)
    Table(i).NextJieDian = [];  % 先初始化
end
for i = 1:size(all_data_2,1)    % 遍历每条边,然后把 起点 和 终点 连起来【双边都要连】
    Table(QiDian_ind(i)).NextJieDian = [Table(QiDian_ind(i)).NextJieDian,ZhongDian_ind(i)];    
    Table(ZhongDian_ind(i)).NextJieDian = [Table(ZhongDian_ind(i)).NextJieDian,QiDian_ind(i)];
end

for i = 1:size(all_data_3) 
    Table(all_data_3(i)).PingTai = 1;    % 是交巡警平台,则标记为1,否则不标记
end

for i = 1:size(all_data_4_1) 
    Table(all_data_4_1(i)).QuanShiQu_ChuRuKou = 1;    % 是全市区出入口,则标记为1,否则不标记
end

for i = 1:size(all_data_4_2) 
    Table(all_data_4_2(i)).A_Qu_ChuRuKou = 1;    % 是A区出入口,则标记为1,否则不标记
end
%---------------------------------

  说明:①结构体 的 详细用法详见本文最后的 参考附录【6】 。
     ②代码里的结构体名为 “Table” ,其封装结果 如下图所示其中,“[ ]” 表示 “空” 。

数学建模——matlab绘制 地图 散点图连线图 (运用plot、scatter、struct、xlsread等函数)【全文8000字】_第1张图片



第三步:绘制交通路线图(不含散点)


hold on;
for i = 1:size(Table,2)  
    if Table(i).QuYu == 'A'   % 如果是 A 区,才执行下面的语句【注:我这里是用"1"来判断的】
        
        for j = 1:length(Table(i).NextJieDian)
            if 1 <= Table(i).NextJieDian(j) && Table(i).NextJieDian(j) <= 92  % 由 Excel附件一 可知,A区的数据点的编号范围为[1,92]
                cur_xx = [Table(i).X,Table(Table(i).NextJieDian(j)).X];       % 获取 起点和终点 的两个数据点的横坐标
                next_yy = [Table(i).Y,Table(Table(i).NextJieDian(j)).Y];      % 获取 起点和终点 的两个数据点的纵坐标
                plot(cur_xx,next_yy,'b-');   % 用蓝色(blue)的短线连接 起点和终点
            end
        end
        
    end
end

  说明:①这里的 plot()函数 的使用和我们往常 使用的角度 不一样。(这两行代码,查了很多资料,调了将近两个小时 )

  因为我画直线的时候是 一根一根地并以离散的形式来 连的【关键点】⭐️⭐️⭐️。

  本文后面还会再强调一次这关键点。

  运行结果如下

数学建模——matlab绘制 地图 散点图连线图 (运用plot、scatter、struct、xlsread等函数)【全文8000字】_第2张图片
  整个图的大致雏形就出来了!



第四步:筛选第一问所要用到的散点数据


p_ZuoBiao = [];        % 交巡警平台的坐标矩阵: 第一列装 数据点的横坐标;第二列装 数据点的纵坐标
A_c_ZuoBiao = [];      % A区出入口的坐标矩阵:  第一列装 数据点的横坐标;第二列装 数据点的纵坐标
A_j_ZuoBiao = [];      % A区交通路口的坐标矩阵:第一列装 数据点的横坐标;第二列装 数据点的纵坐标
for i = 1:size(Table,2) 
    if Table(i).QuYu == 'A'          % 如果是 A 区,才执行下面的语句【注:我这里是用"1"来判断的】    
        
        if Table(i).PingTai == 1   % 如果该数据点是 A区的交巡警平台
            p_ZuoBiao = [ p_ZuoBiao ; [Table(i).X,Table(i).Y] ];
        end  
        
        if Table(i).A_Qu_ChuRuKou == 1   % 如果该数据点是 A区的城区出入口
            A_c_ZuoBiao = [ A_c_ZuoBiao ; [Table(i).X,Table(i).Y] ];
        else      % 否则该数据点就是 A区的交通路口
            A_j_ZuoBiao = [ A_j_ZuoBiao ; [Table(i).X,Table(i).Y] ];
        end 
        
    end
end

  三个散点矩阵的数据如下

数学建模——matlab绘制 地图 散点图连线图 (运用plot、scatter、struct、xlsread等函数)【全文8000字】_第3张图片



第五步:集中绘制散点图


scatter(p_ZuoBiao(:,1),p_ZuoBiao(:,2),60,'ks');    
scatter(A_c_ZuoBiao(:,1),A_c_ZuoBiao(:,2),20,'MarkerEdgeColor','b','MarkerFaceColor','r');
scatter(A_j_ZuoBiao(:,1),A_j_ZuoBiao(:,2),10,'filled','b');
legend('A区交巡警平台','出入A区的路口','A区的交通路口');

  运行结果如下

数学建模——matlab绘制 地图 散点图连线图 (运用plot、scatter、struct、xlsread等函数)【全文8000字】_第4张图片

  为什么 会出现这么多 “data1、data2、…” 的标签呢?❔ ❔ ❔

  因为我们画直线的时候是 一根一根地并以离散的形式来 连的【关键点】⭐️⭐️⭐️。



第六步:细节优化→图例修整、坐标说明+标题

①图例修整

  操作步骤 分3步,如下图所示:

数学建模——matlab绘制 地图 散点图连线图 (运用plot、scatter、struct、xlsread等函数)【全文8000字】_第5张图片



数学建模——matlab绘制 地图 散点图连线图 (运用plot、scatter、struct、xlsread等函数)【全文8000字】_第6张图片

✈️ ✈️ ✈️ ✈️ ✈️ ✈️ ✈️ ✈️ ✈️

数学建模——matlab绘制 地图 散点图连线图 (运用plot、scatter、struct、xlsread等函数)【全文8000字】_第7张图片


②坐标说明+标题

数学建模——matlab绘制 地图 散点图连线图 (运用plot、scatter、struct、xlsread等函数)【全文8000字】_第8张图片

.

  整张图就完成啦 !

  瞧瞧最终的成果图吧!

数学建模——matlab绘制 地图 散点图连线图 (运用plot、scatter、struct、xlsread等函数)【全文8000字】_第9张图片


四、总结:

  第一步:读取所有数据

  第二步:将数据包装入结构体

  第三步:绘制交通路线图(不含散点)

  第四步:筛选第一问所要用到的散点数据

  第五步:集中绘制散点图

  第六步:细节优化→图例修整、坐标说明+标题
      ①图例修整
      ②坐标说明+标题

  最后,我没有详细地阐述其原理,只阐述了有什么用、怎么用。详细原理可以参考本文最后的 参考附录



五、完整源码(2022/5/3补充)

  因为评论区在2022.5.3之前的很多评论 表示无法实现理想效果,故笔者将其源码重新拼接+完善,并贴出如下:

  【数据 在文章最后的 参考附录[7] 。放在与代码同一目录文件夹即可】

  感谢大家对问题的指出!

clc
clear
close all

clc,clear,close all;
[all_data_1,QY] = xlsread('cumcm2011B附件2_全市六区交通网路和平台设置的数据表.xls',1,'A2:E583');  % 附件1的数据
all_data_2 = xlsread('cumcm2011B附件2_全市六区交通网路和平台设置的数据表.xls',2,'A2:B929');  % 附件2的数据
all_data_3 = xlsread('cumcm2011B附件2_全市六区交通网路和平台设置的数据表.xls',3,'B2:B81');   % 附件3的数据
all_data_4_1 = xlsread('cumcm2011B附件2_全市六区交通网路和平台设置的数据表.xls',4,'B2:B18');  % 附件4的数据
all_data_4_2 = xlsread('cumcm2011B附件2_全市六区交通网路和平台设置的数据表.xls',4,'C2:C14');  % 附件4的数据

ind = all_data_1(:,1);      % 数据点的编号
zuo_x = all_data_1(:,2);    % 数据点的横坐标
zuo_y = all_data_1(:,3);    % 数据点的纵坐标
QuYu = QY;     % 数据点所在的区域【一共有A、B、...、F七个区域】
FaAnLv = all_data_1(:,5);   % 数据点的发案率

QiDian_ind = all_data_2(:,1);     % 交通道路的起点编号
ZhongDian_ind = all_data_2(:,2);  % 交通道路的终点编号


% 第一种添加结构体成员的方法
t = 1;  % 用 t 来记录结构体的序号
for i = 1:size(ind)
    % Table(t) = struct('ind',ind(i),'ZuoBiao',[zuo_x,zuo_y],'QuYu',QuYu(i),'FaAnLv',FaAnLv(i));
    Table(t) = struct('ind',ind(i),'X',zuo_x(i),'Y',zuo_y(i),'QuYu',QuYu(i),'FaAnLv',FaAnLv(i));
    t = t + 1;
end
%---------------------------------


% 第二种添加结构体成员的方法---------
for i = 1:size(ind)
    Table(i).NextJieDian = [];  % 先初始化
end
for i = 1:size(all_data_2,1)    % 遍历每条边,然后把 起点 和 终点 连起来【双边都要连】
    Table(QiDian_ind(i)).NextJieDian = [Table(QiDian_ind(i)).NextJieDian,ZhongDian_ind(i)];    
    Table(ZhongDian_ind(i)).NextJieDian = [Table(ZhongDian_ind(i)).NextJieDian,QiDian_ind(i)];
end

for i = 1:size(all_data_3) 
    Table(all_data_3(i)).PingTai = 1;    % 是交巡警平台,则标记为1,否则不标记
end

for i = 1:size(all_data_4_1) 
    Table(all_data_4_1(i)).QuanShiQu_ChuRuKou = 1;    % 是全市区出入口,则标记为1,否则不标记
end

for i = 1:size(all_data_4_2) 
    Table(all_data_4_2(i)).A_Qu_ChuRuKou = 1;    % 是A区出入口,则标记为1,否则不标记
end
%---------------------------------


%---------获取坐标------------------------
p_ZuoBiao = [];        % 交巡警平台的坐标矩阵: 第一列装 数据点的横坐标;第二列装 数据点的纵坐标
A_c_ZuoBiao = [];      % A区出入口的坐标矩阵:  第一列装 数据点的横坐标;第二列装 数据点的纵坐标
A_j_ZuoBiao = [];      % A区交通路口的坐标矩阵:第一列装 数据点的横坐标;第二列装 数据点的纵坐标
for i = 1:size(Table,2) 
    if Table(i).QuYu == 'A'          % 如果是 A 区,才执行下面的语句【注:我这里是用"1"来判断的】    
        if Table(i).PingTai == 1   % 如果该数据点是 A区的交巡警平台
            p_ZuoBiao = [ p_ZuoBiao ; [Table(i).X,Table(i).Y] ];
        end  
   
        if Table(i).A_Qu_ChuRuKou == 1   % 如果该数据点是 A区的城区出入口
            A_c_ZuoBiao = [ A_c_ZuoBiao ; [Table(i).X,Table(i).Y] ];
        else      % 否则该数据点就是 A区的交通路口
            A_j_ZuoBiao = [ A_j_ZuoBiao ; [Table(i).X,Table(i).Y] ];
        end 
        
    end
end
%----------------------------------------

%---------先画散点------------------------
figure(1);hold on;
scatter(p_ZuoBiao(:,1),p_ZuoBiao(:,2),60,'ks');    
scatter(A_c_ZuoBiao(:,1),A_c_ZuoBiao(:,2),20,'MarkerEdgeColor','b','MarkerFaceColor','r');
scatter(A_j_ZuoBiao(:,1),A_j_ZuoBiao(:,2),10,'filled','b');
legend('A区交巡警平台','出入A区的路口','A区的交通路口');
%----------------------------------------

%---------再画连线------------------------
for i = 1:size(Table,2)  
    if Table(i).QuYu == 'A'   % 如果是 A 区,才执行下面的语句【注:我这里是用"1"来判断的】
        
        for j = 1:length(Table(i).NextJieDian)
            if 1 <= Table(i).NextJieDian(j) && Table(i).NextJieDian(j) <= 92  % 由 Excel附件一 可知,A区的数据点的编号范围为[1,92]
                cur_xx = [Table(i).X,Table(Table(i).NextJieDian(j)).X];       % 获取 起点和终点 的两个数据点的横坐标
                next_yy = [Table(i).Y,Table(Table(i).NextJieDian(j)).Y];      % 获取 起点和终点 的两个数据点的纵坐标
                plot(cur_xx,next_yy,'b-');   % 用蓝色(blue)的短线连接 起点和终点
            end
        end
        
    end
end
%----------------------------------------


%---------重画一遍散点(更好看)---------------
scatter(p_ZuoBiao(:,1),p_ZuoBiao(:,2),60,'ks');    
scatter(A_c_ZuoBiao(:,1),A_c_ZuoBiao(:,2),20,'MarkerEdgeColor','b','MarkerFaceColor','r');
scatter(A_j_ZuoBiao(:,1),A_j_ZuoBiao(:,2),10,'filled','b');
legend('A区交巡警平台','出入A区的路口','A区的交通路口');
%------------------------------------------


六、参考附录:

[1] 《MATLAB中scatter函数的用法(绘制散点图)》
这里面有关于 scatter 的详细用法总结
链接: https://blog.csdn.net/xuxinrk/article/details/80212221.

[2] 《MATLAB中关于scatter用法的官方文档》
和参考附录[1]类似,但肯定 官方原版的说明书 更好
链接: https://ww2.mathworks.cn/help/matlab/ref/scatter.html#btrli6p-1.

[3] 《matlab绘制X,Y二维散点图并标出序号》
需要在散点图上标序号时可以参考这篇
链接: https://blog.csdn.net/qq_29596177/article/details/53284364?utm_source=blogxgwz1.

[4] 《用matlab画散点图,并指定点与点之间的连线》
如果作的散点图是 稀疏矩阵 ,可以参考这篇,学用gplot()函数
链接: https://blog.csdn.net/heavenmark/article/details/82794488.

[5] 《MATLAB中关于xlsread用法的官方文档》
链接: https://ww2.mathworks.cn/help/matlab/ref/xlsread.html?searchHighlight=xlsread&s_tid=srchtitle.

[6] 《MATLAB中关于struct用法的官方文档》
链接: https://ww2.mathworks.cn/help/matlab/ref/struct.html?searchHighlight=struct&s_tid=srchtitle.

[7] 《2011高教社杯全国大学生数学建模竞赛赛题 B题 数据》
链接: http://www.mcm.edu.cn/html_cn/node/a1ffc4c5587c8a6f96eacefb8dbcc34e.html.

数学建模系列文章——总结篇:《数模美一国一退役选手的经验分享[2021纪念版]》.


码字 码图不易,多多支持~ ❤️

感谢大家对问题的指出!(特别感谢对于2022.5.3之前的评论主) ⭐️⭐️

你可能感兴趣的:(数学建模,数学建模)