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

本文详细介绍了如何使用MATLAB从Excel数据读取并绘制交通路线图,包括散点图和连线,涉及数据结构、scatter函数和plot函数的使用。作者通过一步步的代码解释,展示了数据处理和作图的全过程,适合初学者参考。
摘要由CSDN通过智能技术生成

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


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

数学建模系列文章——总结篇《数模美一国一退役选手的经验分享[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” ,其封装结果 如下图所示其中,“[ ]” 表示 “空” 。

在这里插入图片描述



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


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()函数 的使用和我们往常 使用的角度 不一样。(这两行代码,查了很多资料,调了将近两个小时 🍋)

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

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

  运行结果如下

在这里插入图片描述
  整个图的大致雏形就出来了! 😲



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


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

  三个散点矩阵的数据如下

在这里插入图片描述



第五步:集中绘制散点图


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区的交通路口');

  运行结果如下

在这里插入图片描述

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

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



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

①图例修整

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

在这里插入图片描述

🐟 🐟 🐟 🐟 🐟 🐟 🐟 🐟 🐟

在这里插入图片描述

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

在这里插入图片描述
🚁 🚁 🚁 🚁 🚁 🚁 🚁 🚁 🚁

②坐标说明+标题

第三张图

.

  整张图就完成啦 ! 😲 😲 😲

  瞧瞧最终的成果图吧!😲 😲 😲

在这里插入图片描述


四、总结:

  第一步:读取所有数据

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

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

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

  第五步:集中绘制散点图

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

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



五、完整源码(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之前的评论主) ⭐️⭐️

评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一支王同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值