Python做交互地图用啥?Folium还是PyDeck?

GIS基础理论
Dr.GIS
wowwwai GIS研习社 · 工具流程与项目排障

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 做高性能空间可视化”。

Python交互地图 Folium还是PyDeck 对比工作流
Folium 和 PyDeck 的核心差异:一个偏 Leaflet 二维网页地图,一个偏 deck.gl WebGL 高性能可视化。

背景: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 是值得掌握的进阶工具。