之前一文汇总了数学建模竞赛中几种简单的地理可视化的操作,今天这贴则是专门汇总讲一下Matlab中常见的地理可视化方法

Python、MATLAB和PPT完成数学建模竞赛中的地图绘制-CSDN博客文章浏览阅读1.2k次,点赞12次,收藏16次。参加数学建模比赛时,很多题目往往要求我们制作与地图相关的可视化内容。实际上,有很多方法可以完成论文写作中对可视化图片的需求,如Python、MATLAB、Arcgis、echarts、一些BI平台、Excel甚至PPT。本帖介绍几种博主在本科期间参赛用到的方法~ https://blog.csdn.net/jsl123x/article/details/146363141?spm=1001.2014.3001.5501


在绘制图之前,先准备一下数据。这里博主直接粘上来,各位可以选择用xlsread,也可以直接粘到Matlab的变量区:(降水是2024年春季的,数据不一定准确,只为展示原理

citys latitude longitude population GDP Rain
北京市 39.9042 116.4074 2189 43761 12.7
天津市 39.3434 117.3616 1373 16737 14.7
石家庄市 38.0428 114.5149 1120 7534 33.6
太原市 37.8706 112.5489 530 5574 42
呼和浩特市 40.8423 111.749 350 3802 17.1
沈阳市 41.8057 123.4315 907 8122 29
长春市 43.8171 125.3235 906 7002 21.9
哈尔滨市 45.8038 126.534 1000 5576 600
上海市 31.2304 121.4737 2489 47219 247.5
南京市 32.0603 118.7969 942 17421 272.7
杭州市 30.2741 120.1551 1220 20059 363.7
合肥市 31.8206 117.2272 947 12674 220.7
福州市 26.0745 119.2965 842 12928 166
南昌市 28.682 115.8579 625 7213 549.3
济南市 36.6512 117.1201 920 12757 33.7
郑州市 34.7466 113.6253 1260 13618 80.2
武汉市 30.5928 114.3052 1370 20012 344.1
长沙市 28.2282 112.9388 1005 14332 284.9
广州市 23.1291 113.2644 1868 30356 129.7
南宁市 22.8172 108.366 880 5469 220
海口市 20.044 110.1999 290 2358 83.1
重庆市 29.4316 106.9123 3205 30146 62.5
成都市 30.5728 104.0668 2120 22075 76.8
贵阳市 26.6477 106.6302 610 5155 116.6
昆明市 24.8801 102.8329 850 7865 30.2
拉萨市 29.6539 91.1406 86 835 7.7
西安市 34.3416 108.9398 1300 12011 43.7
兰州市 36.0611 103.8343 438 3487 26.7
西宁市 36.6232 101.7788 248 1801 18.4
银川市 38.4872 106.2309 290 2686 7.9
乌鲁木齐市 43.8256 87.6168 405 4168 65.8
台北市 25.033 121.5654 250 9013 100
香港特别行政区 22.3193 114.1694 747 27805 100
澳门特别行政区 22.1987 113.5439 68 17247 100
data =xlsread('geoTest.xlsx');
lat=data(:,1);%纬度
lon=data(:,2);%经度
population=data(:,3);%人口
GDP=data(:,4);%生产总值
rain=data(:,5);%2024春季降水

tips当然更好用的方法为readtable,但由于本帖基本上不需要用到城市名,这里博主就用xlsread直接读成矩阵了,如果各位想修改也可以,这玩意很基础相信你们都会~

data=readtable('geoTest.xlsx');

一.geoscatter

在地图上绘制散点图,支持颜色和大小参数。

geoscatter(lat,lon,'b','filled')%选择颜色和填充效果
geolimits([3 54], [74 136]); % 设置范围
geobasemap streets % 选择街道图

也可以自定义给城市或者任意一个坐标点添加自行输入的标签

cities={'北京','天津'};
for i = 1:numel(cities)
    text(lat(i), lon(i), cities{i}, 'VerticalAlignment', 'bottom', 'HorizontalAlignment', 'left');
end

二.geoplot

在经纬度坐标系中绘制线、多边形或者点。

geoplot(lat,lon,"B-o","LineWidth",2);%后面几个参数选择线形
geolimits([3 54], [72 136]); % 设置范围
geobasemap streets % 选择街道图

看起来有点四不像,路线的先后顺序好和矩阵中元素的顺序也有关。

三.geobubble

创建气泡地图,用气泡大小和颜色表示数据大小

gb=geobubble(lat,lon,population);%第三个参数为权重,这里即为人口数
gb.BubbleColorList=summer(3);%设置气泡颜色,用summer色阶
geolimits([3 54], [72 136]); % 设置范围
geobasemap streets % 选择街道图

上述情况,博主直接用了summer色条的一种颜色作为所有城市的选择,其实也可以各个城市一个然后单纯用气泡大小来反应数值的大小,这次我们选择几个城市为例(这里粘了一部分构成新的lon1和lat1,各位也可以自行操作):

cities = categorical(["北京", "天津", "石家庄", "太原", "呼和浩特"]);
figure;
geobubble(lat1, lon1, pop1, cities);
geobasemap streets % 选择街道图

除了上面这种用泡泡直径来展示数据大小的方式,还可以用色阶和大小混合的方式。由于这里需要严格使用categorical 类型的参数,需要用到的SourceTable的Severity方法才行,因此需要进行读表操作——也即readtable。重新读取数据这也需要你们和我一样创建geoTest.xlsx文件,把数据粘进去:

data = readtable('geoTest.xlsx');
gb = geobubble(data,'latitude','longitude','SizeVariable','population');
%严格大小写哦!
gb.SourceTable.Severity = discretize(data.population,[0 1000 2000 3000,4000],...
'categorical', {'Low', 'Medium', 'High','exaggerate'});%设置4个区间范围和名称
gb.ColorVariable = 'Severity';
geolimits([3 54], [72 136]); % 设置范围
geobasemap streets % 选择街道图

如下:颜色和大小同时展示着人口数据大小~

当然颜色可以自己定义哦,罗列一下常见的颜色栏,博主本人最喜欢parula

需要说明的是无论是本文所述的geobubble或者普通的bubble亦或heatmap等,往往色阶条会恰恰相反,一般来说越大的数值颜色越深,各位可以翻转一下: 

data = readtable('geoTest.xlsx');
gb = geobubble(data,'latitude','longitude','SizeVariable','population');
%严格大小写哦!
gb.SourceTable.Severity = discretize(data.population,[0 1000 2000 3000,4000],...
'categorical', {'Low', 'Medium', 'High','exaggerate'});%设置4个区间范围和名称
gb.ColorVariable = 'Severity';
gb.BubbleColorList = parula(4);
neworder = {'exaggerate','High','Medium','Low'};
gb.SourceTable.Severity = reordercats(gb.SourceTable.Severity,neworder);
%翻转一下,避免和实际意义相反
geolimits([3 54], [72 136]); % 设置范围
geobasemap streets % 选择街道图

 怎么说?看着还不赖~

四.geodensityplot

绘制地理密度热力图。相比气泡图,密度图更适合小范围的数据展示,这里展示各省会的GDP数值,为了方便展示,随机截取一片地区给各位看一下效果:

geodensityplot(lat,lon,GDP)
geobasemap streets % 选择街道图

另一方面,除了street作为底图,topographic地形底图在一些情景下亦是不错的选择。这里展示一下2024春季各省会的降雨量,同样是截取一部分哦:

geodensityplot(lat,lon,rain)
geobasemap topographic

还有一些可以通过名称-值对(Name-Value pairs)设置的自定义参数,各位自行修改:

  • Radius:核密度估计的半径,决定了密度计算的平滑程度。较小的半径会生成更局部的密度分布,较大的半径会生成更平滑的分布。

  • Units:距离单位,支持 'km'(千米)或 'miles'(英里)。

  • Weights:可以为每个点设置权重,例如人口数量或地震震级。

五.worldmap

worldmap是 MATLAB 中用于创建世界地图或特定区域地图的函数,属于 Mapping Toolbox 的一部分。它可以帮助用户快速设置地图的显示范围,并在地图上绘制地理数据

1.基础形态

worldmap world

可以通过设置经纬度范围调整显示区域:

% 设置地图范围为 [minLat, maxLat] 和 [minLon, maxLon]
latlim = [20 50]; % 纬度范围
lonlim = [70 140]; % 经度范围
worldmap(latlim, lonlim);

也可以绘制某个洲或者某个国家,参数即为标准的英文名称

worldmap Antarctica

2.配合plotm函数

plotm是 MATLAB 中用于在地理坐标系中绘制数据的函数,属于 Mapping Toolbox 的一部分。它类似于标准的plot函数,但专门用于处理地理数据(经纬度坐标)。简单来说,这个函数可以帮助我们添加经纬度的点线面元素

前面的南极洲空空如也,执行如下的代码可以绘制海岸线

% 绘制海岸线
load coastlines
plotm(coastlat, coastlon, 'k');

在地图上可以绘制点:

% 创建地图
worldmap world

% 绘制海岸线
load coastlines
plotm(coastlat, coastlon, 'k');

% 绘制点
lat = [39.9, 31.2, 23.1]; % 北京、上海、广州纬度
lon = [116.4, 121.5, 113.3]; % 经度
plotm(lat, lon, 'go', 'MarkerSize', 10, 'LineWidth', 2);

还可以给这些点设置标签:

% 添加文本标签
textm(lat(1), lon(1), 'Beijing', 'Color', 'red', 'FontSize', 12);
textm(lat(2), lon(2), 'Shanghai', 'Color', 'blue', 'FontSize', 12);
textm(lat(3), lon(3), 'Guangzhou', 'Color', 'green', 'FontSize', 12);

 

然后设置边框和网格:

% 设置地图属性
setm(gca, 'Grid', 'on');
setm(gca, 'Frame', 'on');

 

3.本地的shp文件

SHP 文件(Shapefile)是一种常用的地理信息系统(GIS)数据格式,由 Esri 开发。它用于存储地理矢量数据,包括点、线和多边形等几何形状,以及与之相关的属性数据。一个完整的 Shapefile 通常由多个文件组成,包括:

  • .shp:存储几何形状(如点、线、多边形)。

  • .shx:存储几何形状的索引。

  • .dbf:存储属性数据(如名称、面积、人口等)。

  • 其他可选文件(如 .prj 存储投影信息)。

Shapefile 广泛应用于地图绘制、空间分析和地理数据可视化。

这里罗列几种常用的shp数据:

  • 海岸线数据coastlines.shp
  • 道路数据:roads.shp
  • 世界城市数据:worldcities.shp
  • 大陆数据:landareas.shp
  • 湖泊数据:worldlakes.shp
  • 河流数据:worldrivers.shp 

如果需要更多 SHP 文件,可以从以下来源获取:

4.配合geoshow函数

geoshow是 MATLAB 中用于在地理坐标系中显示地理数据的函数,属于 Mapping Toolbox 的一部分。它可以用来显示栅格数据(如 GeoTIFF 文件)和矢量数据(如 shapefile 文件)。

现在有两种使用shp数据绘图的方式,先给大家梳理一下以防晕菜:

a.load方法

前文已经提到过,用plotm展示海岸线的方式:

worldmap world
load coastlines
plotm(coastlat, coastlon, 'k');
b.shaperead函数

而用geoshow函数则需要先创建一个地图坐标区域,worldmap函数的写法也略有不同:

load coastlines;
worldmap world;
geoshow(coastlat, coastlon, 'Color', 'k'); % 'k' 表示黑色

事实上两者的绘制效果是一样的。


再展示一下陆地、湖泊和海洋的绘制。需要注意的是要首先将地图数据存在ax变量中:

% 创建世界地图
ax=worldmap('world');
%绘制陆地、湖泊、河流
land=shaperead('landareas.shp','UseGeoCoords',true);
geoshow(ax,land,'FaceColor',[0.5,0.7,0.5]);
lakes=shaperead('worldlakes.shp','UseGeoCoords',true);
geoshow(lakes,'FaceColor','blue');
rivers=shaperead('worldrivers.shp','UseGeoCoords',true);
geoshow(rivers,'Color','blue');
% 设置地图属性
setm(gca, 'Grid', 'on');
setm(gca, 'Frame', 'on');

 其他的shp文件不展示了,各位按照需要调整代码即可。 

最后来做一个综合案例——展示黄河流域的著名大坝和发电站:

% 设置地图范围为 [minLat, maxLat] 和 [minLon, maxLon]
latlim = [25 45]; % 纬度范围
lonlim = [80 130]; % 经度范围
ax=worldmap(latlim, lonlim);
%绘制陆地、湖泊、河流
land=shaperead('landareas.shp','UseGeoCoords',true);
geoshow(ax,land,'FaceColor',[0.4,0.8,0.5]);
lakes=shaperead('worldlakes.shp','UseGeoCoords',true);
geoshow(lakes,'FaceColor','cyan');
rivers=shaperead('worldrivers.shp','UseGeoCoords',true);
geoshow(rivers,'Color','blue');
lat = [34.67,34.82982,36.06245,36.0721,34.7783]; % 纬度
lon = [100.70,111.35046,101.26939,100.5506,112.361861]; % 经度
plotm(lat, lon, 'r*', 'MarkerSize', 6, 'LineWidth', 1.5);
% 添加文本标签
textm(lat(1), lon(1), '玛尔挡水电站', 'Color', 'white', 'FontSize', 12);
textm(lat(2), lon(2), ' 三门峡水利枢纽', 'Color', 'white', 'FontSize', 12);
textm(lat(3), lon(3), '拉西瓦水电站', 'Color', 'white', 'FontSize', 12);
textm(lat(4), lon(4), '龙羊峡水电站', 'Color', 'white', 'FontSize', 12);
textm(lat(5), lon(5), '小浪底水利枢纽', 'Color', 'white', 'FontSize', 12);
% 设置地图属性
setm(gca, 'Grid', 'on');
setm(gca, 'Frame', 'on');

出于美观博主自行调整了文字位置(用自由选择工具)。

六.mapshow

mapshow是 MATLAB 中用于在平面坐标系(通常是投影坐标系)中显示地理数据的函数,与geoshow不同,mapshow适用于已经投影到平面坐标系的数据。

这里用Boston城市道路的shp数据演示一下(因为Matlab只自带了波士顿数据作为演示。。。)

% 读取道路数据
roads = shaperead('boston_roads.shp');
% 创建地图窗口
figure;
% 使用 mapshow 绘制道路数据
mapshow(roads, 'Color', 'blue', 'LineWidth', 1.5);
% 设置标题
title('波士顿道路数据');
% 显示网格
grid on;

其他城市的shp数据也可以在网页上下载资源,这里不多展开。 


以上即为常见的地理可视化操作,其实还有诸如geoglobeplot3m之类3维的可视化操作,亦或地图与heatmap混合的操作,由于博主的Matlab版本略有不够,在之后的帖子中会单独出一期有关上述两者的归纳总结。

本帖已燃尽!一般来说,对于非专业的同学,在本科期间接触到的实践应用——如数学建模竞赛,上述的几种制图方式绰绰有余~

Logo

永洪科技,致力于打造全球领先的数据技术厂商,具备从数据应用方案咨询、BI、AIGC智能分析、数字孪生、数据资产、数据治理、数据实施的端到端大数据价值服务能力。

更多推荐