如果只是想查看某个城市在哪里,Google Maps、OpenStreetMap等在线地图已经足够。但当需求变成制作一张适合海报、文章配图、城市视觉作品或者数据可视化项目的地图时,普通在线地图的默认样式就会显得比较固定。
Prettymaps解决的正是后一类问题。它不是一个导航软件,也不是用来替代在线地图服务,而是一个Python地图绘制库:从OpenStreetMap获取道路、建筑、水域、绿地等地理数据,再通过Matplotlib等工具将这些数据绘制成可以高度自定义的地图。
项目当前GitHub仓库中的setup.py标记版本为v1.4.2,官方文档已经覆盖基础绘图、图层样式、预设、多个区域组合、地形阴影和关键地点等功能。

Prettymaps到底是什么
Prettymaps官方将其定位为一个用于绘制自定义OpenStreetMap地图的轻量Python库。项目主要建立在OSMnx、Matplotlib、Shapely和vsketch等Python工具之上。
这些组件承担的工作并不完全相同。OSMnx负责处理OpenStreetMap相关地理数据,Shapely用于几何对象操作,Matplotlib负责最终的图形绘制,而vsketch则让项目可以进一步输出适合绘图机使用的SVG内容。
因此,Prettymaps更像是在地理数据与视觉设计之间增加了一层方便使用的接口。用户不必从头处理每一条道路和每一个建筑几何对象,而是可以通过较少的Python代码完成数据获取、图层筛选和地图渲染。
它为什么适合制作风格化地图
普通地图服务需要保证道路名称、地点搜索、导航和交互功能,因此视觉设计通常需要服从信息展示。Prettymaps的目标不同,它允许用户把地图中的不同地理对象拆成图层,然后分别决定这些图层应该怎样显示。
例如,同一个城市可以把建筑绘制成几种不同颜色,把道路改成深色线条,把公园设置为绿色,把水域设置为浅蓝色,再改变背景颜色和边界效果。
这种方式适合制作强调视觉表现的城市地图、街区海报、旅游区域插图以及个人地图作品。如果需要的是准确导航、公交路线或者实时交通信息,则不是Prettymaps主要解决的问题。
地图数据和绘图怎样组合
Prettymaps的核心并不是提供一套自己的全球地图数据库,而是使用OpenStreetMap数据。
用户提交地点后,程序会根据配置获取相关地理对象,然后按照不同图层进行组织。官方教程中的示例就包括建筑、道路、森林、水域、停车区域和其他OpenStreetMap标签。
这种设计带来的一个重要特点是,最终地图效果不仅取决于绘图代码,也取决于对应区域在OpenStreetMap中的数据完整程度。
如果某个地区已经拥有比较完整的建筑轮廓、道路和自然地物数据,通常可以绘制出比较丰富的结果;如果原始地图数据本身较少,那么单纯增加Prettymaps样式参数也无法产生不存在的地理信息。
从地址到地图的基本用法
Prettymaps可以直接通过pip安装。当前项目setup.py要求Python 3.12及以上,因此已有旧Python环境的用户需要先检查版本。
pip install prettymaps
官方提供的基础调用方式比较直接:
import prettymaps plot = prettymaps.plot( 'Stad van de Zon, Heerhugowaard, Netherlands' )
绘图查询参数并不局限于地址。根据官方教程,目前可以使用三种主要输入形式:
地点或地址名称。
经纬度坐标。
自定义GeoDataFrame边界。
对于刚开始使用的人,通过地点名称生成地图最容易理解;需要准确控制地图中心点时,可以直接传入经纬度;已经在使用GeoPandas处理空间数据的用户,则可以把自定义边界继续交给Prettymaps处理。
项目还提供Google Colab安装方式,对于暂时不想在本机搭建完整Python环境的用户,可以通过Notebook尝试官方示例。
图层和样式决定视觉效果
真正决定Prettymaps可玩性的,是layers和style两个参数。
layers用于决定获取哪些OpenStreetMap对象。例如可以把building作为建筑图层,把natural为water或bay的对象组成水域图层,再根据highway类型处理不同级别道路。
style则负责这些图层最终怎样呈现。颜色、边框、线宽、透明度以及建筑颜色组合等视觉属性,都可以进一步调整。
这意味着用户并不是简单选择一个现成地图模板,而是可以决定“需要哪些地图对象”和“这些对象应该怎么画”。对于已经熟悉OpenStreetMap标签与Matplotlib的开发者,这种方式提供了比较大的自定义空间。
另一方面,这也意味着想深入使用Prettymaps,最终仍然需要理解一定的Python字典、OSM标签和Matplotlib样式参数。它并不是完全通过拖拽完成地图设计的工具。
预设可以重复使用地图风格
如果每次生成地图都重新填写完整的图层和颜色参数,会让代码变得比较长。Prettymaps因此提供了preset机制,可以把一组配置保存下来重复使用。
官方目前提供default、minimal、macao、tijuca等示例预设,并可以通过相关函数查看已有预设。
plot = prettymaps.plot( 'Stad van de Zon, Heerhugowaard, Netherlands', preset='minimal' )
用户也可以创建自己的preset,将常用图层和视觉参数保存为配置。对于需要连续生成多个城市地图的人,这比每次手工修改所有参数更加方便,也有助于保持不同图片之间的视觉一致性。
绘制结果还能继续加工
调用prettymaps.plot()之后,返回的并不只是一张已经固定好的图片。官方当前将结果封装为Plot数据类,其中包括geodataframes、fig和ax。
geodataframes保存不同图层对应的GeoDataFrame,因此用户可以继续访问建筑等原始空间数据;fig和ax则分别对应Matplotlib的Figure和Axes,可以继续使用Matplotlib接口增加标题、调整背景或者绘制其他元素。
例如制作城市海报时,可以先通过Prettymaps形成主体地图,然后继续利用Matplotlib添加城市名称和其他视觉内容,而不需要把生成结果当作一张无法修改的普通截图。
对于数据分析场景,能够直接访问GeoDataFrame也很有价值。官方教程甚至演示了提取城市建筑轮廓,再单独排列成建筑Footprint图案的方式。
项目还提供多区域绘图能力
Prettymaps并不限制一张画布只能出现一个区域。官方提供multiplot和Subplot,可以把多个地点绘制在同一个画布中,并让不同区域使用各自的图层或样式。
这种功能比较适合制作城市街区对比、多个地点组合海报,或者将不同区域以相同视觉语言放在一张作品中。
它和传统地图软件里的多个地图窗口并不是完全相同的概念,更偏向程序化生成一组最终视觉作品。
新版本扩展了地形绘图能力
项目v1.4版本进一步增加了海洋几何对象自动绘制、hillshade地形阴影、keypoints关键地点以及Streamlit前端等功能,同时对代码进行了重构,并减少了对Overpass API的请求次数。
其中hillshade比较适合山地、岛屿以及地形变化明显的区域,可以为二维地图增加地貌层次。官方教程允许配置光照方位、光照高度、垂直夸张程度和透明度等参数。
keypoints则可以根据OpenStreetMap标签寻找特定地点,例如官方教程使用自然地物标签查找海滩,同时指定山峰等具体对象。
这些功能说明Prettymaps目前已经不只是简单的道路和建筑绘图工具,而是在继续向地形与地点标注等方向扩展。
还可以输出绘图机使用的SVG
Prettymaps提供plotter模式,并结合vsketch生成适合Pen Plotter使用的SVG。
这与普通保存PNG地图有明显区别。绘图机通常需要处理矢量路径,再利用实体笔在纸张上实际绘制线条。对于生成艺术、地图海报以及实体制图实验,这类输出方式比普通位图更加有针对性。
如果只是准备网页配图,通常没有必要使用plotter模式;如果目标是激光切割、绘图机或者后续矢量编辑,则值得进一步研究该功能。
Streamlit前端降低了尝试门槛
当前仓库还包含一个基于Streamlit的前端应用。安装Prettymaps后,可以在项目仓库中运行:
streamlit run app.py
这意味着项目已经不完全局限于Notebook和Python脚本,也提供了浏览器形式的交互入口。
不过它仍然需要用户安装Python环境和项目依赖,并不是访问一个公开网站就能直接使用的在线制图服务。因此,对完全不了解Python环境配置的用户来说,仍然存在一定使用门槛。
使用Prettymaps需要哪些基础
从官方快速示例来看,只生成默认地图并不需要写很多代码。但如果希望真正发挥项目价值,最好具备一些Python和地图数据基础。
至少需要理解Python环境、pip安装和函数参数。如果准备自定义地图,还需要进一步理解Matplotlib样式以及OpenStreetMap标签的组织方式。
项目当前依赖中包括OSMnx、Shapely、Matplotlib、Rasterio、rioxarray、vsketch、Streamlit等多个库。与一个单文件小工具相比,其地理和绘图依赖相对完整,因此安装环境是否兼容也需要关注。
另外,由于地图数据需要从OpenStreetMap相关服务获取,实际生成新区域地图时也依赖网络数据请求。对于大范围区域或复杂图层,请求和处理的数据规模会明显高于绘制一个小街区。
poxiaoxi博客
精彩评论