10万以内点位优先选folium+markercluster,因它真能跑起来;超2万必须用fastmarkercluster防白屏,初始化需设prefer_canvas=true避免dom爆炸。

用 folium 快速渲染万级经纬度点,别碰 plotly.express.scatter_mapbox 的默认设置
直接上结论:10 万以内点位优先选 folium + MarkerCluster,不是因为更炫,而是它真能跑起来;plotly 默认用 scatter_mapbox 渲染 5 万点会卡死浏览器,除非你手动关掉 hover 交互、禁用动画、改用 go.Scattermapbox(mode="markers") 并设 hoverinfo="skip"。
实操建议:
-
folium.Map初始化时务必加prefer_canvas=True,否则大量Marker会触发 DOM 节点爆炸,页面直接无响应 - 点数超 2 万,必须套
MarkerCluster—— 它不是“锦上添花”,是防止地图白屏的刚需 - 避免对每个点都调用
folium.Marker:改用folium.plugins.FastMarkerCluster,底层用 Canvas 批量绘制,性能提升 3–5 倍 - 如果数据含中文地址字段,别在 popup 里直接塞整行文本,用
folium.Popup(..., max_width=200)控制宽度,否则弹窗撑爆地图容器
用 geopandas + contextily 出静态图时,底图坐标系错位怎么调?
常见错误现象:gdf.plot() 出来的点全挤在香港或赤道附近,或者整个地图偏移几百公里——大概率是 CRS(坐标系)没对齐。
关键判断:你的经纬度是 WGS84(EPSG:4326)没错,但 contextily 加的底图默认是 Web Mercator(EPSG:3857),两者不能直接叠。
正确做法:
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
- 确保原始
GeoDataFrame的crs显式设为"EPSG:4326":gdf = gpd.GeoDataFrame(df, geometry=gpd.points_from_xy(df.lon, df.lat), crs="EPSG:4326") - 绘图前必须重投影:
gdf_3857 = gdf.to_crs("EPSG:3857"),再调gdf_3857.plot(ax=ax) - 加底图用
contextily.add_basemap(ax, crs="EPSG:3857", source=contextily.providers.OpenStreetMap.Mapnik),crs参数不能省,且必须和gdf_3857一致 - 别用
plt.show()直接看——保存为.png再打开,matplotlib 默认显示可能因 DPI 导致底图模糊或错位
kepler.gl 本地启动后加载大文件失败,报 RangeError: Invalid array length
这不是内存不够,是 JavaScript 引擎对数组长度的硬限制(约 2³²−1),当你的 CSV 有 100 万行、又含非数值字段(如带逗号的地址描述),kepler.gl 解析时会尝试建超长字符串数组,直接崩。
绕过方法很实际:
- 预处理 CSV:用
pandas.read_csv(..., usecols=["lat", "lon", "category"])只读必要列,删掉所有文本描述字段 - 强制类型转换:
df["lat"] = pd.to_numeric(df["lat"], errors="coerce"),把脏数据转为NaN,否则 kepler 会卡在类型推断阶段 - 导出前采样或聚合:
df_sampled = df.sample(n=50000, random_state=42),或按网格聚合(用geopandas.clip+groupby统计密度) - 启动 kepler 时加参数:
keplergl --data your_cleaned.csv --port 8081,别拖文件进网页,本地 CLI 模式更稳
为什么用 datashader 渲染千万级点仍卡顿?关键在 Canvas 尺寸和聚合方式
datashader 不是银弹。它快的前提是:你给的画布尺寸合理、聚合函数选对、输出没额外加滤镜。
容易被忽略的坑:
-
Canvas.points()的plot_width和plot_height别照着显示器分辨率设(比如 1920×1080)——设成 800×600 足够,分辨率越高,内部栅格计算量指数增长 - 默认用
count()聚合,但如果你只关心热力分布,改用ds.count_cat("category")或ds.mean("value"),比纯 count 多一步分类/计算,但视觉信息更准,且不会因重复坐标导致密度失真 - 别在
tf.shade()后链式调tf.spread(...)或tf.set_background(...):每加一个就多一次 CPU 光栅遍历,1000 万点下耗时翻倍 - 输出存 PNG 就行,别导成交互式 HTML——
export_image(agg, "heatmap", background="black")这句之后直接退出 Python,别留着 kernel 等交互
真正难的从来不是“怎么画出来”,而是你得提前知道哪一层计算在拖慢整个流程——Canvas 尺寸、CRS 对齐、JS 数组限制、聚合粒度,这些点不抠清楚,工具再强也白搭。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










