Python 绘制 GIS 地图的常用做法
Python 绘制 GIS 地图的常用做法是:先用 GeoPandas 读取、清洗并重投影矢量数据,再用 Folium 或 Leafmap 输出可缩放的交互式 HTML 地图,或用 Matplotlib + Cartopy/Contextily 生成带投影的静态图。截至2026年11月,Folium 稳定版为 0.20.0、GeoPandas 为 1.2.0、Cartopy 为 0.26.0,均已支持较新的 Python 与依赖。新手优先 GeoPandas 的 .plot()/.explore(),需要仪表板再上 Plotly;旧 Basemap 仅作遗留兼容。基础库概念可先看本站gis Python入门指南,从解析Gis python库开始。

怎么选合适的 Python GIS 绘图库
先明确输出形态:交互网页选 Folium/Leafmap,静态报告或投影分析选 Cartopy + Contextily,数据处理统一用 GeoPandas。下表汇总截至2026年11月的常用组合,便于快速对照。
| 库 | 主要用途 | 最新稳定版 | Python 要求 | 推荐搭配 |
|---|---|---|---|---|
| GeoPandas | 读写矢量、空间运算、静态/.explore 交互 | 1.2.0(2026年9月) | ≥3.11 | matplotlib、contextily、folium |
| Folium | Leaflet 交互地图、GeoJSON、标记、分级设色 | 0.20.0(2025年6月) | ≥3.9 | GeoPandas、xyzservices |
| Cartopy | Matplotlib 地理投影、海岸线与要素叠加 | 0.26.0(2026年9月) | ≥3.11 | matplotlib、shapely、pyproj |
| Contextily | 为 Matplotlib/GeoPandas 轴添加 Web 瓦片底图 | 1.7.1(2026年7月) | ≥3.10 | GeoPandas、xyzservices |
| Leafmap | Jupyter 多后端交互 GIS(默认 ipyleaflet) | 约 0.64.0(2026年10月) | 以官网为准 | folium、geopandas |
| Plotly | 仪表板 choropleth/scatter_map | 7.1.0(约2026年9月) | 以官网为准 | 内置几何或自备 GeoJSON |
新项目优先 GeoPandas + Folium/Cartopy;Basemap 虽有 2.0.0 更新,官方长期建议迁移到 Cartopy。完整环境搭建与库解析可参考gis python 开发入门全解析,gis Python新手指南。
GeoPandas 静态地图怎么画(含底图)
目标:把 shapefile/GeoPackage 画成带图例的静态图,并可选叠加 OpenStreetMap 等瓦片。验收标准:图层与底图对齐、CRS 正确、图例可读、文件可复现。
- 用 conda-forge 建隔离环境(强烈推荐,避免 Windows 上 GDAL/GEOS 冲突):conda create -n geo_env python=3.11 后 conda install -c conda-forge geopandas matplotlib contextily。也可 pip install ‘geopandas[all]’,但优先 conda。
- 读数据并检查 CRS:import geopandas as gpd; gdf = gpd.read_file(“data.gpkg”); print(gdf.crs)。没有 CRS 用 gdf = gdf.set_crs(“EPSG:4326”);需要投影到 Web 墨卡托时 gdf = gdf.to_crs(3857)。
- 基础绘图:ax = gdf.plot(column=”某字段”, cmap=”OrRd”, legend=True, figsize=(10,8))。GeoPandas 1.2.0 起静态绘图系统已重写,分类图例与 colorbar 更稳定。
- 加底图(需网络):先把轴转到 3857,再 import contextily as cx; cx.add_basemap(ax, source=cx.providers.OpenStreetMap.Mapnik)。CartoDB 系列从 xyzservices 2026.9.0 起需要 API key,否则会出现水印,需到 Carto 官网申请免费 key 后传入。
- 保存:ax.figure.savefig(“map.png”, dpi=150, bbox_inches=”tight”)。大数据量时性能通常优于纯 Folium HTML。

Folium 交互式地图怎么快速出图
目标:生成可缩放、可点击的 HTML,方便分享或嵌入。验收标准:浏览器正常打开、瓦片加载、标记/GeoJSON 位置正确、无空白或偏移。
- 安装:pip install folium 或 conda install -c conda-forge folium(依赖 branca、Jinja2、numpy、requests、xyzservices 会自动装)。Python ≥3.9。
- 创建地图:import folium; m = folium.Map(location=[39.9, 116.4], zoom_start=10, tiles=”OpenStreetMap”)。内部统一用 EPSG:4326,坐标顺序为纬度、经度。
- 叠加 GeoPandas 数据:先 gdf = gdf.to_crs(4326),再 folium.GeoJson(gdf, name=”图层”).add_to(m),或用 folium.Choropleth 做分级设色。也可直接加 Marker、Circle。
- 保存并检查:m.save(“map.html”)。Jupyter 中直接显示;本地打开需能访问 Leaflet CDN。自定义 tiles 可参考官方文档与 Folium GitHub。
- 大数据(超过约 1 万点)时 HTML 会变大且卡顿,可改用 Leafmap、抽样,或换到静态方案。
需要更少代码的 Jupyter 交互时,可试 Leafmap(默认 ipyleaflet 后端,也支持 Folium)。若你同时用 QGIS 做验证,可在 QGIS Python 控制台里快速检查图层与 CRS,具体命令见QGIS Python控制台怎么用?常用命令有哪些?。
CRS、底图与性能要注意什么
- CRS 错位:Folium 强制 4326(lat, lon);Contextily 常用 3857。数据与底图 CRS 不一致必然偏移。始终先 print(gdf.crs),用 to_crs() 转换;旧 proj4 字符串可能识别不全,优先 EPSG 或 WKT。
- 瓦片与 API key:OpenStreetMap 一般可直接用。CartoDB Positron 等从 xyzservices 2026.9.0 起需 key,否则显示 “API KEY REQUIRED”。获取后示例:tiles=xyz.CartoDB.Positron.build_url(apikey=’YOUR_KEY’)。
- 空白地图:多为 CDN/防火墙拦 Leaflet 资源,换网络或本地缓存 CSS/JS;检查浏览器控制台报错。
- 安装冲突:Windows 上混用 pip 与 conda 易导致 GDAL 报错,统一用 conda-forge 环境。Cartopy 0.22 起已有 binary wheels,安装门槛降低。
- 投影选择:全球概览用 PlateCarree;区域分析用合适的等积或等角投影。Cartopy 替代旧 Basemap,新项目直接上 Cartopy。
版本与变更可核对 GeoPandas 发布标签;日常以各库官方文档与本站教程为准。

常见问题
地图显示空白或只有灰框怎么办?
多数是 Leaflet/CSS CDN 被墙或防火墙拦截,换网络、开代理,或检查生成的 HTML 里资源链接是否可访问。Folium 依赖在线 CDN,离线环境需自行托管静态资源。
数据画出来整体偏移几公里?
几乎都是 CRS 或坐标顺序错误。确认数据已 to_crs(4326) 且 Folium 传入的是 [纬度, 经度];底图用 Contextily 时轴必须是 3857。用 gdf.total_bounds 与已知点核对。
CartoDB 底图出现 “API KEY REQUIRED”?
xyzservices 从 2026.9.0 起对 CartoDB 瓦片强制 key。到 Carto 官网申请免费非商业 key(额度一般足够学习),再按文档把 key 传入 tiles URL 即可。
安装 GeoPandas 在 Windows 总失败?
优先 conda create -n geo_env 后从 conda-forge 安装整个栈,避免 pip 单独装 GDAL。已混装则删环境重建。Python 要求 ≥3.11(GeoPandas 1.2.0)。
总结:日常流程固定为 GeoPandas 处理数据 → Folium/Leafmap 出交互图或 Cartopy/Contextily 出静态投影图,并始终先核对 CRS。建议立刻用 conda 建一个干净环境装 GeoPandas + Folium + Contextily,拿一份本地 GeoJSON 跑通 .plot() 与 folium.GeoJson;需要更系统的库选型与开发路径时,继续阅读本站入门系列即可。