Folium世界地图批量标记点位报错KeyError: 'lat,lon'求助
解决Folium批量绘制标记时的KeyError: 'lat,lon'问题
错误原因
你遇到的KeyError: 'lat,lon',大概率是这两个问题之一:
- 你的DataFrame里没有单独的
lat(纬度)和lon(经度)列,反而把经纬度合并成了一个名为lat,lon的列; - 调用Folium方法时,错误地用
'lat,lon'作为列名参数,而实际DataFrame里的列名是分开的lat和lon。
下面针对你提到的两种数据来源方式,分别给出正确的实现步骤:
方式一:字典创建DataFrame批量加标记
确保字典里的lat和lon是独立的键,对应各自的数值列表,不要合并在一起:
import folium import pandas as pd # 构造正确格式的数据源 person_data = { '姓名': ['张三', '李四', '王五'], '职位': ['后端工程师', 'UI设计师', '产品经理'], '年龄': [28, 32, 29], 'lat': [39.9042, 31.2304, 23.1291], # 单独的纬度列 'lon': [116.4074, 121.4737, 113.2644] # 单独的经度列 } # 转成DataFrame df = pd.DataFrame(person_data) # 初始化地图(中心设为中国区域,可按需调整) world_map = folium.Map(location=[30, 110], zoom_start=4) # 循环遍历每一行数据,添加标记和弹窗 for _, row in df.iterrows(): # 构造弹窗内容,用HTML换行更清晰 popup_text = f""" 姓名: {row['姓名']}<br> 职位: {row['职位']}<br> 年龄: {row['年龄']} """ # 创建标记并添加到地图 folium.Marker( location=[row['lat'], row['lon']], popup=folium.Popup(popup_text, max_width=300) # 设置弹窗宽度避免内容截断 ).add_to(world_map) # 保存地图为HTML文件 world_map.save('birth_place_map.html')
方式二:读取CSV文件批量加标记
情况1:CSV里已有单独的lat和lon列
如果你的CSV结构是这样的(列名分别为姓名、职位、年龄、lat、lon):
姓名,职位,年龄,lat,lon 张三,后端工程师,28,39.9042,116.4074 李四,UI设计师,32,31.2304,121.4737 王五,产品经理,29,23.1291,113.2644
直接读取后,用和上面一样的循环添加标记即可:
import folium import pandas as pd # 读取CSV df = pd.read_csv('birth_data.csv') # 初始化地图 world_map = folium.Map(location=[30, 110], zoom_start=4) # 批量添加标记(代码和方式一的循环部分完全一致) for _, row in df.iterrows(): popup_text = f""" 姓名: {row['姓名']}<br> 职位: {row['职位']}<br> 年龄: {row['年龄']} """ folium.Marker( location=[row['lat'], row['lon']], popup=folium.Popup(popup_text, max_width=300) ).add_to(world_map) world_map.save('birth_place_map.html')
情况2:CSV里经纬度是合并在一个列里
如果你的CSV里经纬度是合并成一个列(比如列名叫lat_lon,内容格式为39.9042,116.4074),需要先拆分列:
import folium import pandas as pd df = pd.read_csv('birth_data.csv') # 拆分合并的经纬度列,生成单独的lat和lon列 df[['lat', 'lon']] = df['lat_lon'].str.split(',', expand=True) # 把字符串类型的经纬度转成数值类型 df['lat'] = pd.to_numeric(df['lat']) df['lon'] = pd.to_numeric(df['lon']) # 后续添加标记的代码和上面一致 world_map = folium.Map(location=[30, 110], zoom_start=4) for _, row in df.iterrows(): popup_text = f""" 姓名: {row['姓名']}<br> 职位: {row['职位']}<br> 年龄: {row['年龄']} """ folium.Marker( location=[row['lat'], row['lon']], popup=folium.Popup(popup_text, max_width=300) ).add_to(world_map) world_map.save('birth_place_map.html')
额外提示
如果你用的是Folium的批量插件(比如FastMarkerCluster),一定要指定正确的列名参数,比如:
from folium.plugins import FastMarkerCluster # 用zip把lat和lon打包成坐标列表,再传入插件 FastMarkerCluster( data=list(zip(df['lat'], df['lon'])), popup=folium.Popup("弹窗内容", max_width=300) ).add_to(world_map)
内容的提问来源于stack exchange,提问作者Lambohihi
相关产品推荐
相关产品推荐

