尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

用Python绘制专属世界地图:geopandas与matplotlib完整指南

用Python绘制专属世界地图:geopandas与matplotlib完整指南 如果你手里只有一台电脑也想画出一张完全属于自己的世界地图不依赖在线地图服务、不交订阅费那这篇文章就是给你准备的。我用了几个晚上把基于Python的矢量地图绘制流程完整跑通了一遍从环境搭建到出图美化每一步都踩过坑也把关键细节都记了下来。整条路线用到的核心库是geopandas、matplotlib和cartopy它们能让你用代码“画”出世界地图——没错不是去地图网站截图而是用几千行坐标数据自己在画布上渲染出陆地边界、海岸线、经纬网格甚至你自己标定的城市点位。这个方案的适用人群很广想在地图上展示统计数据的分析师、做GIS课设的学生、想在朋友圈晒一张风格化地图的Python爱好者都能用上这套方法。而“只属于你自己”这件事恰恰是这套方案最有魅力的地方——从颜色、投影方式到标注信息所有细节都由代码说了算而不是被地图服务商的默认样式牵着走。1. 整体设计与方案拆解为什么选geopandas matplotlib这套组合1.1 核心思路把地图拆成“数据 绘制”两层来看在动手写代码之前我先花了一点时间想清楚一个根本问题一张世界地图本质上到底是什么答案是数据。地球上的陆地、海洋、河流、国界在地理信息领域都被抽象成一组组由经纬度坐标组成的几何对象——多边形polygon、线linestring和点point。世界地图的绘制过程其实就是把这堆坐标数据读进来再用绘图库把它们渲染到画布上。想明白了这一点方案选型就清晰了需要一个能处理地理空间数据的库也就是geopandas还需要一个能把数据画成图片的库也就是matplotlib如果对投影方式有更高要求再加一个cartopy。我见过不少初学者一上来就想到用pyecharts或者folium这类交互式地图库。它们确实方便内置了在线底图和交互组件但对“专属感”这件事帮助不大——底图样式、瓦片来源、缩放行为全都受制于第三方服务。离线矢量绘制则刚好相反所有视觉细节都在你掌控之中甚至地图上每个像素是怎么来的你都一清二楚。考虑到这篇文章的核心是“只属于你自己的世界地图”我最终确定了geopandas matplotlib这条主线。1.2 方案对比离线绘制和在线地图服务的取舍市面上用Python画世界地图的方案大概可以分成三类第一类是folium/pyecharts这类在线交互地图优点是零基础友好、能缩放拖拽缺点是底图来自第三方瓦片服务样式定制能力有限而且部分场景下需要稳定的网络环境第二类是基于plotly的交互式矢量地图优点是内置世界地图数据写几行代码就能出图但默认数据和样式都比较“大众脸”做深度定制时绕不开它的底层数据结构第三类就是我采用的方案——用geopandas读入自然地球Natural Earth开源数据再交给matplotlib渲染必要时用cartopy处理投影变换。这套组合最大的优势是每一层都解耦。数据层、投影层、渲染层各自独立你随时可以把其中一个环节换成自己更顺手的工具。比如数据源可以从Natural Earth换成OSM的导出数据渲染层也可以从matplotlib换成plotly做交互式输出。我在实际使用中体会很深的另一点是geopandas的数据结构是建立在pandas之上的这意味着你可以像处理普通表格一样对地图数据进行筛选、排序、聚合操作。想只画亚洲一条query语句就搞定。想把人口大于1亿的国家高亮出来这也是普通的DataFrame条件筛选而已。这种灵活性在在线地图方案里很难找到。2. 环境准备与依赖安装手把手把绘图环境搭起来2.1 Python环境与核心依赖库的安装细节在动手安装之前我建议你先把Python环境准备好。如果你已经装了Python 3.9及以上版本可以跳过这一步如果你是从零开始建议直接去Python官网下载最新稳定版安装时务必勾选“Add Python to PATH”否则后续在命令行里敲python会提示找不到命令。我自己用的是Python 3.11实测下来geopandas和cartopy对3.11的支持已经很完善了。依赖安装这一步不同系统的体验差异比较大。在Windows上我强烈建议不要直接用pip install geopandas因为geopandas的底层依赖里包括GDAL、Fiona、pyproj这些C扩展库pip在Windows上往往需要本地编译经常报错。我自己最开始就是踩了这个坑后来换成conda环境一次就装好了。如果你不想用conda还有一个折中方案去Christoph Gohlke维护的第三方whl仓库把GDAL、Fiona、pyproj、Shapely、geopandas这几个包手动下载到本地再用pip按顺序安装。macOS用户相对省心一些只要系统里有Xcode Command Line Toolspip install geopandas一般能顺利跑完。Linux用户如果遇到依赖问题可以用apt先装libgdal-dev和libgeos-dev。为了让不同系统的读者都能顺利复现我这里给出一个conda环境的完整安装命令conda create -n mapenv python3.11 conda activate mapenv conda install -c conda-forge geopandas matplotlib cartopy这几条命令执行完之后可以顺手装一个jupyter notebook或者直接用VS Code写脚本。我个人习惯用VS Code的交互式窗口因为地图绘制的代码往往需要反复调整样式参数交互式窗口里每块代码都能独立运行调试效率比完整脚本要高不少。需要提醒的是geopandas和cartopy的版本更新比较频繁为了保证代码运行结果一致建议留意一下conda输出的版本号并记录在自己的项目文档里。2.2 世界地图数据从哪里来Natural Earth数据下载指南有了库还不够我们还需要地图的“原材料”——地理空间数据。我首选Natural Earth这个开源数据项目它提供公共领域的地图数据可以免费用于任何用途而且数据质量非常高。我们需要的文件是“Admin 0 – Countries”也就是国家边界的矢量数据里面包含每个国家的几何形状和名称、ISO编码等属性信息。在Natural Earth官网下载页面选择“Countries”分类找到1:110m110百万分之一比例尺的版本即可。这个比例尺的数据精度对于画整张世界地图已经足够了文件只有几百KB加载速度很快。如果你想画更精细的版本也有1:50m和1:10m两个比例尺可选但文件体积会大不少。需要指出的是我只是把一个通用开源数据集推荐给你数据里呈现的具体国界形状由该数据集的制图规则决定你在复现时根据自己的用途判断数据是否满足需求即可。下载完成后会得到一个.shp后缀的压缩包解压后里面至少有.shp、.shx、.dbf、.prj四个文件这四个文件必须放在同一个目录下一个都不能少。.shp保存几何坐标、.shx是空间索引、.dbf保存属性信息、.prj保存坐标系定义任何一个缺失geopandas都无法正确读取。我从官网下载之后全部放在项目的data目录下路径比较清爽后面写代码时引用也方便。3. 从零开始绘制你的第一张基础世界地图3.1 加载数据与初识GeoDataFrame结构环境准备好之后激动人心的时刻到了——写代码画世界地图。我先把完整的入门代码贴出来然后逐段解释。import geopandas as gpd import matplotlib.pyplot as plt # 读取Natural Earth国家边界数据 world gpd.read_file(data/ne_110m_admin_0_countries.shp) # 创建一个画布 fig, ax plt.subplots(figsize(16, 9)) # 绘制世界地图 world.plot(axax, color#f2efe9, edgecolor#666666, linewidth0.3) # 去掉坐标轴边框 ax.set_axis_off() # 保存图片 plt.savefig(world_map_basic.png, dpi200, bbox_inchestight) plt.show()这段代码的执行过程并不复杂但每一行背后都有值得展开的原理。gpd.read_file读取.shp文件时geopandas会把文件里的几何数据转换成GeoSeries并和属性数据一起组装成一个GeoDataFrame。你可以用world.head()查看数据内容用world.plot()直接绘图——这是geopandas封装好的快捷绘图方法本质上就是调用了matplotlib的plot函数。我在第一次运行代码时看到整张世界地图以米色底和灰色边的形式出现在画布上那种“从数据到图形”的成就感确实很强烈。3.2 掌握基础绘图参数颜色、边界线宽和画布尺寸基础版本的代码虽然能出图但离“只属于你自己”还有很大差距。我们先分析一下绘图参数怎么调才能让地图既专业又有个人风格。首先是color参数它控制的是陆地填充色。这里用了暖色调#f2efe9如果你想要更冷峻的科技感可以换成深色背景亮色陆地的组合比如背景设为#1a1a2e陆地填充设为#e8d5b7。其次是edgecolor它控制国家边界的颜色默认的黑色往往显得生硬换成低饱和度的灰色之后整张图的气质会立刻变得素雅。linewidth则控制边界线的粗细0.3是个比较合适的值——太粗会让地图显得笨重太细在小尺寸屏幕上又看不清。画布尺寸用figsize(16,9)控制这个比例接近常见显示器的宽高比视觉上比较舒服。最后ax.set_axis_off()把坐标轴边框和经纬度刻度全部去掉这一步是必须的——不然图片周围会多出一个难看的白边和刻度标签。保存图片时dpi200能把清晰度拉高用于打印或者发朋友圈都很够用。4. 个性化定制让你的世界地图真正“属于你”4.1 自定义配色方案从默认样式到风格化视觉基础地图跑通之后真正好玩的个性化定制才刚开始。主题色方案是区分“随手画的”和“精心设计的”最直观的分界线。我调试过几套配色方案这里挑三套风格差异比较大的分享给你们。第一套是简洁米色系适合做报告配图。背景用海洋的浅蓝色#cfe3f0陆地用米白色#f5f0e6边界线用淡灰色#9a9a9a。这套的视觉特点是安静、百搭不抢正文的风头。第二套是黑金风格适合做海报或封面。海洋部分我通常用一个彩色地图的辅助色带或者干脆用黑色#0d0d0d陆地用金色#d4af37边界线用暗金色#8a6d1c。这套方案对比度强视觉冲击力拉满。第三套是马卡龙风格适合做儿童教育类内容或者轻松主题的分享。海洋用奶油蓝#cfe8ef陆地用淡粉#f9d5e5边界线直接用白色看起来就像一块甜点。实现的方式很简单就是在world.plot()函数里替换color和edgecolor的值world.plot(axax, color#f9d5e5, edgecolorwhite, linewidth0.4)不过这里要提醒一下配色的核心原则是“海洋颜色要比陆地颜色更安静”因为人的视觉注意力天然会落在面积更小、对比度更高的区域上。如果海洋颜色太跳陆地的存在感就会被削弱整张地图看起来会非常奇怪。我试过把海洋调成明黄色结果地图看起来像一块硫磺皂完全没法用。4.2 添加自定义城市点位与文字标注纯粹的世界地图其实信息量很有限真正让地图“属于你”的是你自己叠加在上面的数据点。比如我想在地图上标出我去过的城市并用不同颜色区分旅行地和计划中的目的地。实现思路是在matplotlib的同一张画布上用scatter函数叠加散点再用annotate函数添加标注。我这里先列坐标数据注意经纬度顺序是经度在前、纬度在后cities { 北京: [116.40, 39.90], 上海: [121.47, 31.23], 伦敦: [-0.13, 51.51], 巴黎: [2.35, 48.86], 东京: [139.69, 35.69], 纽约: [-74.01, 40.71], 悉尼: [151.21, -33.87], } for name, (lon, lat) in cities.items(): ax.scatter(lon, lat, s30, color#d32f2f, zorder5) ax.annotate(name, (lon, lat), textcoordsoffset points, xytext(8, 8), fontsize9)这里的zorder参数值得特别留意。matplotlib的绘图顺序按照zorder的值从小到大叠放值越大的图层在越上层。默认情况下地图多边形的zorder是1如果散点图不设zorder点可能会被陆地边界覆盖住导致看不见。我把zorder设成5确保数据点永远显示在地图图层上方。另一个容易踩坑的点是annotate中的textcoords参数用offset points表示标注文本相对于点的偏移量xytext(8,8)意思是向右上方各偏移8个点。如果不加这个偏移文本会直接压在点上文字和数据点挤成一团非常难看。4.3 用GeoDataFrame筛选高亮特定国家或地区想要让地图更聚焦除了全局展示还有一种很常见的玩法把特定国家或区域高亮出来。因为GeoDataFrame本质上是pandas DataFrame的扩展所以你可以直接使用pandas的条件筛选功能。比如我想把中国、俄罗斯、加拿大这三个面积大国用不同的颜色填充其余国家用统一底色代码可以这么写highlight_names [China, Russia, Canada] highlight_colors [#e74c3c, #2980b9, #27ae60] for name, color in zip(highlight_names, highlight_colors): country world[world[NAME] name] country.plot(axax, colorcolor, edgecolorwhite, linewidth0.4, zorder2)这段代码的关键在于先通过world[NAME] name筛出单个国家的子集再对这个子集调用plot方法。每一个高亮国家的图层zorder设为2大于默认的1所以能覆盖在其他国家之上。需要说明的是不同版本Natural Earth数据的属性字段名可能不同有的是NAME有的是NAME_EN你可以用world.columns查看当前数据的字段列表别想当然地写属性名。另外这里只是举一个技术操作的例子国家名称和颜色都只是演示用途任何超出绘图本身的政治解读都不是这篇文章讨论的范围。5. 进阶玩法分层绘制、投影变换与区域聚焦5.1 什么是分层图绘制把视觉元素拆成独立图层分层图绘制是一个很实用但容易被忽略的概念它的核心思想是把一张地图拆成多个独立的视觉层每一层只负责一个信息维度。这样的好处有三个一是每层可以单独修改和调试不用为了改一个点而重画整张图二是可以灵活控制图层顺序利用zorder实现不同层级之间的遮盖关系三是方便复用——同一份底图数据可以用在十张不同主题的图中只需替换上面的数据层。真实场景中一套典型的分层结构可以是这样的第一层是海洋底图用整个axes的背景色填充第二层是陆地多边形包含所有国家的边界第三层是高亮图层只显示你重点关注的国家或区域第四层是数据图层可以是散点、热力图或者统计图表最后一层是标注图层放置文本说明、指北针、比例尺。我在做的“足迹地图”就是按这个思路搭建的改配色只需要动第一层和第三层的代码加新的旅行地点只需要操作第四层的数据整体灵活度比把所有元素写在一段代码里高得多。5.2 用Cartopy更换投影方式从“平面世界”到“球面视角”如果只是用geopandas的默认绘图方式纬度线是直线经度线也是直线这种投影叫等距圆柱投影它最大的问题是高纬度地区的面积会被严重拉伸格陵兰岛看起来和非洲差不多大。如果想打破这种视觉定式让地图呈现出更科学或者更有艺术感的形态就需要引入cartopy来更换投影方式。cartopy是专门处理地图投影的Python库它支持几十种投影方式我推荐三个比较有代表性的第一个是等距圆柱投影PlateCarree适合数据分析和科研绘图因为经纬度就是线性坐标不会引入变形误差这也是很多专业论文的默认选择。第二个是罗宾逊投影Robinson视觉上非常平衡国家形状变形小适合做展示图和封面图。第三个是北极正射投影NorthPolarStereo适合极地主题的内容能展现高纬度的空间关系。代码实现方式是以cartopy的GeoAxes作为画布再把geopandas的数据用to_crs做坐标转换import cartopy.crs as ccrs fig plt.figure(figsize(14, 8)) ax plt.axes(projectionccrs.Robinson(central_longitude0)) # 将geopandas数据转换为罗宾逊投影 world_robinson world.to_crs(ccrs.Robinson(central_longitude0).proj4_init) world_robinson.plot(axax, color#f2efe9, edgecolor#666666, linewidth0.3) ax.stock_img() # 这一行会导致底图冲突实际使用时不建议 ax.set_global()需要特别提醒的是cartopy和geopandas在版本更新中交互方式有一些变化。在cartopy 0.21及以上版本to_crs方法接受一个CRS对象代码写法略有不同。如果遇到报错检查一下两个库的版本再去官方文档确认对应写法即可。另外cartopy本身自带地形、海岸线等数据你可以用ax.add_feature(cfeature.LAND)直接添加但这种方式和geopandas绘制的多边形可能会在边缘处有细微缝隙混用时需要仔细检查效果。5.3 聚焦特定区域从世界地图到区域裁剪很多时候我们需要的不一定是整个世界而是某个大洲或者某个区域。geopandas做区域裁剪有两种常见思路。第一种是直接筛选用bbox坐标范围把地图数据裁出来比如我只想画东亚就选经度在100到150之间、纬度在20到50之间的国家。第二种是更优雅的做法用一个矩形几何对象做空间裁剪利用geopandas的clip函数实现。这里的原理是先构造一个目标区域的边界框bounding box然后用clip函数把所有与这个边界框相交的几何对象裁切出来最后只绘制落在框内的部分。我实际用得比较多的是第一种思路因为简单直接east_asia world.cx[100:150, 20:50] east_asia.plot(axax, color#f2efe9, edgecolor#666666, linewidth0.3)cx属性是GeoDataFrame的一个便利索引器它允许你按坐标范围直接筛选数据。第一次用的时候我被这个用法惊艳到了——一行代码就把世界地图裁剪成了东亚地图。需要注意cx的参数顺序是经度区间在前纬度区间在后和坐标习惯的(x, y)对应。如果发现筛选出来的区域和自己想的不一样优先检查是不是把经纬度顺序写反了。6. 常见问题与避坑指南我踩过的那些坑6.1 中文标注和负号显示乱码问题用matplotlib绘制地图时中文乱码问题几乎人人都会遇到。具体表现是图上的中文城市名显示为一个个方框。原因是matplotlib默认字体不包含中文字形。解决方法是把绘图字体设置为系统里的中文字体。Windows系统通常有微软雅黑或宋体macOS有苹方Linux则要看你装了什么中文字体。我还发现一个细节点坐标轴上的负号也会因为字体设置而变成方块所以用rcParams做全局设置时要把axes.unicode_minus也设为False才能让负号正常显示。import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [Microsoft YaHei, SimHei, PingFang SC] plt.rcParams[axes.unicode_minus] False这段设置放在脚本开头一次设置全局生效。不过要注意如果系统里没有列表中的这些字体matplotlib还是会回退到默认字体依然显示方框。此时需要用font_manager手动注册字体文件路径这也是一个比较常见的进阶需求。6.2 输出图片只有地图没有海洋背景有朋友照着教程跑完代码之后发现生成的图片周围是一片空白而不是预期的海洋蓝色。其实这个现象很正常因为matplotlib的画布默认就是白色它并不会自动把“海洋”渲染成一种颜色。所谓海洋颜色要么是通过fig.patch.set_facecolor设置整个画布的背景要么是绘制一个覆盖全图的矩形并指定颜色。我个人的经验是用fig.patch.set_facecolor因为它只管画布背景不影响地图图层的渲染逻辑fig plt.figure(figsize(16, 9), facecolor#cfe3f0)当然这样设置之后海洋和陆地的接缝处可能会有细小的白色间隙因为陆地多边形和画布边缘之间是分离的。如果想要更精细的效果可以用cartopy的海洋要素数据或者自己绘制一个全图范围的海洋多边形这里就不展开讲了。6.3 geopandas读取文件报错或性能卡顿怎么办读取.shp文件时最常见的报错是“No features found”和“CPLE_OpenFailedError”。前者通常是因为文件路径不对我建议尽量用绝对路径或者提前用os.chdir切换到数据目录避免相对路径在不同环境下解析出错。后者往往是因为缺失了.prj等辅文件回到2.2节确认文件完整性。性能方面如果地图数据用1:10m的比例尺绘制时图层数量多渲染耗时会明显上升。此时的处理方式是把数据做个简化用world.simplify(tolerance0.01)在损失可控的范围内减少多边形顶点数绘图速度可以提升好几倍。我在绘制全国地市级别数据时尝试过效果非常明显。6.4 快速故障排查参考表为了让你在遇到问题时能快速定位我把最容易出现的几类问题整理成表格方便对照排查症状可能原因解决思路中文标题/标注显示方框matplotlib缺少中文字体设置rcParams字体参数或在环境中安装中文字体图片整体没有海洋颜色未设置画布背景色用fig.patch.set_facecolor指定海洋色数据点被地图盖住zorder未设置或值太小把散点图的zorder设为明显高于地图的层级读取.shp时报错文件路径错误或缺少辅文件检查路径和.shp同目录下的四个文件绘制范围与预期不符cx索引经纬度顺序写反确认经度在前、纬度在后罗宾逊投影to_crs报错geopandas/cartopy版本不匹配查看版本并根据官方文档调整写法图形卡顿严重数据精度太高用simplify减少多边形顶点数7. 项目扩展与灵感参考让地图应用场景更丰富7.1 在地图上叠加热力图展示统计数据的分布世界地图做出来之后自然想叠加真实的数据信息让地图“说话”。一个很常见的应用是热力图比如我想展示某品牌全球各门店的数量分布可以用每个国家作为统计单元把门店数量映射到颜色深浅上。实现方式是在GeoDataFrame里新增一列数据然后在plot函数中用column参数指定这一列用cmap参数指定颜色映射。# 假设world数据里新增一列store_count表示每个国家的门店数量 world.plot(axax, columnstore_count, cmapOrRd, edgecolorwhite, linewidth0.3, legendTrue)这段代码跑通之后你会得到一个带图例的填色地图门店数量越多的国家颜色越深。这种图在业务分析、市场报告里非常实用而且因为数据列完全由你控制今天可以放门店数量明天可以换成销量、人口密度、森林覆盖率一套代码通吃。需要留意的一点是当数据有缺失值时geopandas默认会把对应区域画成灰色这是正常现象也可以手动指定missing_kwds参数来控制缺失值的表现样式。7.2 从静态到动态用Matplotlib生成GIF动画地图静态地图之外很多读者会期待地图“动起来”。比如展示一家公司五年间门店数量变化的动态地图或者展示候鸟在不同月份迁移路线的动画。matplotlib本身不支持直接输出GIF但我们可以配合pillow库把一帧一帧的PNG图片合成动画。基本思路是写一个循环每次更新要展示的年份数据重新绘制当前年份的地图并保存为PNG循环结束后用pillow把所有PNG读进来保存为GIF。from PIL import Image import glob frames [] for img_path in sorted(glob.glob(frames/frame_*.png)): frames.append(Image.open(img_path)) frames[0].save(world_map_animation.gif, save_allTrue, append_imagesframes[1:], duration500, loop0)这段代码我实测下来能稳定工作生成的GIF大约是每500毫秒切换一帧视觉上类似于一个简易的新闻数据播报。需要提醒的是帧率设置要合理太快看不清信息太慢又显得拖沓。还有一点生成动画之前所有帧的图片尺寸必须一致所以绘图时figsize和dpi参数要全程保持一致。比如每年的人口数据变化或者每季度的气候数据变化都可以延用这个方法方案。7.3 添加比例尺与指北针让地图看起来更像专业作品一张地图如果只有陆地多边形和城市标注严格来说还不够完整。专业的制图规范里比例尺和指北针是基础的地理信息要素。虽然matplotlib没有内置这两个组件但我们可以用简单的坐标轴操作手动加上去。比例尺的常规做法是用ax.plot画一段表示实际距离的横线再用ax.text标注长度单位比如“2000 km”。指北针则是画一条带箭头的竖线上方标注“N”。# 在左下角添加比例尺 ax.plot([-170, -120], [-55, -55], colorblack, linewidth2) ax.text(-145, -58, 3000 km, hacenter, fontsize10) # 在右下角添加指北针 ax.annotate(N, xy(160, -40), xytext(160, -55), arrowpropsdict(arrowstyle-), fontsize14, hacenter)比例尺的长度需要根据实际纬度来估算因为在等距圆柱投影下1度经度的实际地面距离约等于111公里乘以纬度的余弦。我在-55度纬度线上画的这段60度经度跨度乘以111再乘以cos(-55度)大约是3800公里。上面的示例代码是我随手取的数值实际使用时需要根据你关注区域所在纬度重新计算以免比例尺失真。想做好这一步其实也是理解地图投影原理的一次很好的练习。7.4 自定义数据来源用本国或本地数据替换Natural Earth当你掌握这套流程后大概率不会满足于只有Natural Earth这一种数据源。一个自然的延伸是使用更高精度的本国或本地行政区划数据。这类数据通常由测绘部门或开放数据平台发布常见的格式还包括GeoJSON和TopoJSON。geopandas同样支持直接读取GeoJSON格式一条gpd.read_file就能搞定。拿到本地数据之后的处理流程和上面完全一致读取、筛选、投影、绘制、叠加数据。我自己的经验是处理本地数据时精度问题会变得更加敏感——乡镇级别的边界数据文件动辄几十MB一定要先做simplify简化多边形顶点否则绘图时的内存占用和渲染时间会非常难看。另外本地数据的属性字段经常是中文字段名比如“省”、“市”、“区”在代码里写筛选条件时小心别用错字段名。8. 写在最后的经验之谈整套流程走下来我最想跟读者分享的一句话是画世界地图真正难的不是库的用法而是你想清楚“这张地图画出来要传达什么”。如果只是照着教程跑一遍代码那它只是一张数据可视化作品如果带着“把我去过的城市标出来”“把产品销量分布展示给团队看”这样的明确目标那地图才真正变成了“只属于你自己的世界地图”。我在调试配色和投影方式的时候反复调整了几十次有时候只是为了把某一处标注挪开几毫米但这种“非标准答案”的尝试也正是手工绘制的乐趣所在。希望这个项目也能成为你探索地理可视化的起点——下次当你想展示一组有地理属性的数据时不妨想想能不能用这套方案画出一张属于你自己的地图。
返回列表