Python做交互地图用啥?Folium还是PyDeck?
Python做交互地图用啥?Folium还是PyDeck? 这是很多 GIS 学生、数据分析师和 Python GIS 初学者在做地图可视化时最常遇到的选择题:一个上手快、适合 Leaflet 风格的二维地图;另一个更偏向大数据量、三维视角和 WebGL 渲染。本文不做抽象评测,而是从真实 GIS 工作流出发,帮你判断什么时候用 Folium,什么时候用 PyDeck。
引言:先看你的交互地图到底要解决什么问题
在 Python GIS 项目里,交互地图通常不是为了“好看”而存在,而是为了快速查看空间数据、展示分析结果、检查点线面位置是否正确,或者把成果交给非 GIS 背景的同事浏览。
如果你的需求是把 GeoDataFrame、CSV 经纬度点、行政区面数据做成一个可以缩放、点击、弹窗查看属性的网页地图,Folium 往往更合适。如果你要展示几十万点、轨迹流向、三维柱状图、密度聚合或大规模 WebGL 图层,PyDeck 通常更有优势。
简单判断:Folium 更像“Python 里调用 Leaflet 做交互地图”,PyDeck 更像“Python 里配置 deck.gl 做高性能空间可视化”。

背景:Folium 和 PyDeck 分别是什么
Folium:适合常规 WebGIS 浏览和轻量交互
Folium 是 Python 对 Leaflet.js 的封装。Leaflet 是经典的前端二维 WebGIS 地图库,适合做底图加载、点线面展示、弹窗、图层控制、分级设色图和简单交互。
对 GIS 用户来说,Folium 的优势在于理解成本低。你可以在 Jupyter Notebook 中直接预览,也可以导出 HTML 文件发给别人打开。它特别适合以下任务:
- 把一批经纬度点显示在地图上。
- 制作行政区分级设色图。
- 给点位加弹窗,查看名称、编号、指标值。
- 叠加 GeoJSON 边界、线状路线、缓冲区结果。
- 快速检查坐标是否落在正确位置。
PyDeck:适合大数据量、三维和 WebGL 图层
PyDeck 是 deck.gl 的 Python 接口。deck.gl 是基于 WebGL 的可视化框架,常用于大规模空间数据渲染,比如海量点、轨迹线、热力图、三维柱状图和复杂图层叠加。
PyDeck 更适合需要视觉冲击力和渲染性能的场景。例如城市 POI 密度、出租车轨迹、OD 流向、栅格统计结果的 3D 柱状展示,以及面向仪表盘或数据产品的交互可视化。
- 点数量较大,普通 Marker 渲染明显卡顿。
- 需要三维柱状图、弧线、流向线、热力图。
- 希望利用 GPU 加速渲染。
- 结果将嵌入 Streamlit、Jupyter 或数据看板。
- 需要更强的视觉表达,而不只是传统 GIS 查询浏览。
原理:为什么同样是 Python 交互地图,性能和体验差很多
Folium 和 PyDeck 的差异,本质上来自前端渲染方式不同。
Folium 输出的是 Leaflet 地图。Leaflet 很适合传统二维地图交互,但如果你把几万甚至几十万个独立 Marker 直接加进去,浏览器需要维护大量 DOM 或 SVG 元素,缩放和拖动就容易变慢。
PyDeck 背后是 deck.gl,依赖 WebGL 渲染。WebGL 可以利用 GPU 绘制大量图形元素,因此在点云、轨迹、三维可视化方面更强。但它的参数配置更像“图层声明”,对初学者来说不如 Folium 直观。
| 维度 | Folium | PyDeck |
|---|---|---|
| 底层技术 | Leaflet.js | deck.gl / WebGL |
| 学习难度 | 较低 | 中等 |
| 典型地图 | 二维浏览地图、专题图 | 大规模点线面、三维可视化 |
| 数据量适应性 | 中小数据量更稳 | 较大数据量更有优势 |
| GIS 属性查询 | 弹窗、图层控制很方便 | Tooltip 可用,但配置更偏可视化 |
| 导出 HTML | 非常方便 | 可以导出,常用于 Notebook 或看板 |
步骤:用实际需求判断 Folium 还是 PyDeck
步骤 1:先判断地图是不是传统二维 GIS 浏览
如果你的目标是“把结果放到地图上看一看”,例如检查点位、查看行政区属性、叠加边界和缓冲区,那么优先选 Folium。
典型场景包括:
- 地理编码结果检查:确认地址点是否落在正确城市。
- 采样点展示:点击点位查看样本编号和监测值。
- 行政区专题图:按人口、面积、产值等字段分级设色。
- 空间分析结果展示:叠加缓冲区、裁剪结果、相交结果。
一个最小 Folium 示例:
import folium
m = folium.Map(
location=[31.2304, 121.4737],
zoom_start=10,
tiles="OpenStreetMap"
)
folium.Marker(
location=[31.2304, 121.4737],
popup="上海市中心示例点",
tooltip="点击查看属性"
).add_to(m)
m.save("folium_map.html")
这个示例适合快速输出一个 HTML 地图。对于 GIS 初学者来说,它的好处是结构清楚:创建地图、添加图层、保存 HTML。
步骤 2:如果你要做分级设色图,Folium 通常更直接
Folium 对 GeoJSON 和 Choropleth 分级设色支持比较顺手。如果你已经有行政区边界和统计字段,Folium 可以较快做出专题图。
import folium
import geopandas as gpd
gdf = gpd.read_file("districts.geojson")
m = folium.Map(location=[30.6, 114.3], zoom_start=8)
folium.Choropleth(
geo_data=gdf,
data=gdf,
columns=["name", "value"],
key_on="feature.properties.name",
fill_color="YlOrRd",
fill_opacity=0.7,
line_opacity=0.3,
legend_name="指标值"
).add_to(m)
m.save("choropleth_map.html")
这里要注意,key_on 必须和 GeoJSON 属性字段对应,否则分级设色可能不生效。很多 Folium 专题图失败,并不是代码语法错,而是属性连接字段不匹配。
步骤 3:如果点很多,不要直接用 Folium Marker 硬堆
Folium 可以显示点,但不建议把大量点全部做成普通 Marker。几千个点通常还能接受,点数继续增加后,浏览器会明显卡顿。
如果仍想用 Folium,可以考虑:
- 使用 CircleMarker 代替 Marker。
- 使用 MarkerCluster 做聚合显示。
- 先按网格、行政区或六边形聚合数据。
- 只展示当前分析所需的字段,不把所有属性塞进弹窗。
- 把大 GeoJSON 简化后再加载。
如果你的核心问题就是大数据量点渲染,那么更应该考虑 PyDeck。
步骤 4:需要 WebGL、大规模点和三维效果时选 PyDeck
PyDeck 更适合“空间数据可视化产品”而不是“传统 GIS 图层浏览”。例如你有大量经纬度点,并希望按照数值字段控制颜色、半径、高度,PyDeck 的 ScatterplotLayer 或 ColumnLayer 会更合适。
import pandas as pd
import pydeck as pdk
df = pd.DataFrame({
"lng": [121.47, 121.50, 121.42],
"lat": [31.23, 31.20, 31.26],
"value": [10, 30, 20]
})
layer = pdk.Layer(
"ScatterplotLayer",
data=df,
get_position=["lng", "lat"],
get_radius=500,
get_fill_color=[255, 100, 80, 160],
pickable=True
)
view_state = pdk.ViewState(
longitude=121.47,
latitude=31.23,
zoom=10,
pitch=0
)
r = pdk.Deck(
layers=[layer],
initial_view_state=view_state,
tooltip={"text": "值:{value}"}
)
r.to_html("pydeck_map.html")
这个例子里,PyDeck 用图层的方式描述数据如何渲染。你不再是一个点一个点添加 Marker,而是把数据表交给图层,由 WebGL 批量绘制。
步骤 5:如果要做三维柱状图,PyDeck 更自然
城市热度、人口密度、POI 数量、网格统计值,经常需要用高度表达指标大小。Folium 也可以通过插件做一些效果,但 PyDeck 的 ColumnLayer 更直接。
import pandas as pd
import pydeck as pdk
df = pd.DataFrame({
"lng": [116.40, 116.42, 116.38],
"lat": [39.90, 39.92, 39.88],
"count": [120, 300, 180]
})
layer = pdk.Layer(
"ColumnLayer",
data=df,
get_position=["lng", "lat"],
get_elevation="count",
elevation_scale=20,
radius=300,
get_fill_color=[80, 160, 255, 180],
pickable=True,
auto_highlight=True
)
view_state = pdk.ViewState(
longitude=116.40,
latitude=39.90,
zoom=11,
pitch=45,
bearing=0
)
deck = pdk.Deck(
layers=[layer],
initial_view_state=view_state,
tooltip={"text": "数量:{count}"}
)
deck.to_html("column_map.html")
如果你的文章、报告或看板需要展示“空间分布 + 数值强弱 + 三维高度”,PyDeck 往往比 Folium 更省事。
常见坑:选择 Folium 或 PyDeck 时最容易踩的坑
坑 1:经纬度顺序写反
Folium 的位置通常写成 [纬度, 经度],例如 [31.23, 121.47]。PyDeck 的位置通常写成 [经度, 纬度],例如 ["lng", "lat"]。
这是从 Folium 切到 PyDeck 时最常见的问题。点位如果跑到海里、国外或完全看不到,先检查经纬度顺序。
坑 2:坐标系不是 WGS84 经纬度
Web 地图常用经纬度坐标。很多 GIS 数据来自 CGCS2000 高斯投影、地方坐标、Web Mercator 或 UTM。如果你直接把投影坐标当经纬度传给 Folium 或 PyDeck,地图一定会错位。
使用 GeoPandas 时,通常可以这样转换:
import geopandas as gpd
gdf = gpd.read_file("data.shp")
gdf = gdf.to_crs(epsg=4326)
转换前要确保原始数据的 CRS 正确。如果原始 CRS 本身缺失或定义错误,直接 to_crs 也无法得到正确结果。
坑 3:把大 GeoJSON 直接塞进浏览器
无论 Folium 还是 PyDeck,浏览器端都有承载上限。行政区边界过细、线段节点太多、属性字段太多,都会让 HTML 文件变大、加载变慢。
建议先做这些处理:
- 删除不用于展示的字段。
- 对面或线数据进行适度简化。
- 按地图缩放级别准备不同精度数据。
- 大数据量优先考虑矢量瓦片或服务端接口。
坑 4:忽视底图访问限制
Folium 和 PyDeck 都可能使用在线底图。不同底图服务有访问限制、密钥要求和网络可用性问题。如果地图空白,不一定是代码错,也可能是底图加载失败。
- 检查浏览器开发者工具里的网络请求。
- 确认底图 URL 是否可访问。
- 避免在正式项目中随意使用无授权底图。
- 内网环境要考虑离线瓦片或自建地图服务。
坑 5:把 PyDeck 当成完整 GIS 软件
PyDeck 强在可视化,不是完整的 GIS 分析软件。缓冲区、叠加分析、空间连接、投影转换等操作,仍建议在 GeoPandas、Shapely、PostGIS、QGIS 或 ArcGIS Pro 中完成,然后把结果交给 PyDeck 展示。
方法比较:不同 GIS 场景下怎么选
| 使用场景 | 推荐工具 | 原因 |
|---|---|---|
| 教学演示一个点位地图 | Folium | 代码短,上手快,HTML 导出方便 |
| 行政区分级设色图 | Folium | GeoJSON 和 Choropleth 工作流成熟 |
| 空间分析结果快速检查 | Folium | 适合查看点线面位置和属性弹窗 |
| 几万到几十万点可视化 | PyDeck | WebGL 渲染更适合大数据量 |
| 三维柱状图和空间热度展示 | PyDeck | ColumnLayer、HeatmapLayer 更自然 |
| 轨迹、流向、弧线可视化 | PyDeck | deck.gl 图层表达能力更强 |
| 发给领导或同学直接打开 HTML | Folium | 简单、稳定、文件交付友好 |
| 嵌入 Streamlit 数据看板 | PyDeck | 与数据产品和交互看板结合更常见 |
如果只能记一个结论:常规 GIS 展示优先 Folium,高性能空间可视化优先 PyDeck。
检查清单:开始写代码前先回答这 8 个问题
- 数据类型是什么? 点、线、面、网格、轨迹,还是 OD 流向。
- 数据量多大? 几百条、几千条、几万条,还是几十万条以上。
- 是否需要属性弹窗? 需要大量字段查询时,Folium 更直观。
- 是否需要三维效果? 需要高度、倾斜视角、柱状图时,优先 PyDeck。
- 坐标系是否为 EPSG:4326? 不是就先转换或确认底图坐标要求。
- 最终交付形式是什么? Notebook、HTML 文件、Streamlit 看板,还是正式 WebGIS 系统。
- 底图是否可稳定访问? 正式环境要考虑授权和网络条件。
- 是否真的需要交互? 如果只是论文插图,静态地图可能用 GeoPandas、QGIS 或 Matplotlib 更合适。
FAQ:关于 Python 交互地图 Folium 和 PyDeck 的常见问题
Python 做交互地图初学者先学 Folium 还是 PyDeck?
建议先学 Folium。它更接近传统 WebGIS 地图思路,创建地图、添加点线面、设置弹窗和导出 HTML 都比较直观。掌握 Folium 后,再学习 PyDeck 的图层配置和 WebGL 可视化会更顺。
Folium 能不能处理大数据量点位?
可以处理一定规模的点,但不建议直接用大量普通 Marker。点位较多时应考虑 MarkerCluster、CircleMarker、数据抽稀、网格聚合或面聚合。如果数据量很大,并且主要目标是流畅渲染,PyDeck 更合适。
PyDeck 能不能像 Folium 一样做行政区分级设色图?
可以,但配置方式不同。PyDeck 可以使用 GeoJsonLayer 展示面数据,并根据属性字段设置颜色。不过如果只是常规行政区 Choropleth 图,Folium 通常更容易上手。
Folium 和 PyDeck 输出的地图能发给别人打开吗?
两者都可以输出 HTML。Folium 的 HTML 交付体验通常更简单。PyDeck 也可以导出 HTML,但如果涉及外部底图、脚本资源或数据文件,仍要检查目标电脑是否能正常访问相关资源。
为什么我的 Folium 或 PyDeck 地图点位偏移很大?
优先检查两个问题:第一,经纬度顺序是否写反;第二,坐标系是否已经转换为 WGS84 经纬度。Folium 常用 [lat, lon],PyDeck 常用 [lon, lat]。如果原始数据是投影坐标,需要先用 GeoPandas、QGIS 或 ArcGIS Pro 做坐标转换。
Python GIS 项目里 Folium 和 PyDeck 可以一起用吗?
可以。一个常见做法是:用 Folium 做常规成果浏览和属性检查,用 PyDeck 做大规模点、热力、轨迹和三维展示。它们不是互相替代的关系,而是适合不同展示任务。
结论:Folium 解决常规地图展示,PyDeck 解决高性能可视化
回到标题里的问题:Python做交互地图用啥?Folium还是PyDeck? 如果你的核心需求是快速制作二维交互地图、显示点线面、弹窗查看属性、输出 HTML 给别人浏览,选 Folium 更稳。如果你的核心需求是大数据量、三维柱状、轨迹流向、热力效果和 WebGL 渲染,选 PyDeck 更合适。
实际项目中,不要只按工具热度选择,而要按数据量、交互方式、交付形式和性能要求选择。对于 GIS 学习和日常分析,Folium 是更友好的起点;对于空间数据产品和高级可视化,PyDeck 是值得掌握的进阶工具。