Folium Choropleth无颜色变化及GeoJSON匹配报错求助
Folium绘制Choropleth地图匹配失败问题
问题场景
我用以下代码尝试用Folium绘制Choropleth地图:
DF = pd.DataFrame({'REGION_ID':list(range(0,88)), 'share': list(map(lambda x: x* 5.3, list(range(0,88))))}) m = folium.Map(location=[63.391522, 96.328125], zoom_start=3) rel_ = folium.Choropleth( geo_data = './admin_level_4.geojson', name = 'Имя', data = DF, columns=['REGION_ID', 'share'], key_on='id', bins = 10, fill_color='BuGn', nan_fill_color='darkblue', nan_fill_opacity=0.5, fill_opacity=0.7, line_opacity=0.2, legend_name= 'Легенда', highlight = True, show = False ) rel_.add_to(m)
教程说明REGION_ID需要和GeoJSON中的对应字段匹配,但我用GeoPandas查看GeoJSON的属性列后,未找到REGION_ID或id字段:
gpd.read_file('./admin_level_4.geojson').columns.values # 输出结果: array(['flag', 'ref', 'name', 'note', 'is_in', 'koatuu', 'place', 'ref:en', 'ref:ru', 'ref:uk', 'source', 'int_ref', 'name:ab', 'name:af', 'name:ar', 'name:av', 'name:az', 'name:ba', 'name:be', 'name:bg', 'name:bs', 'name:ca', 'name:ce', 'name:cs', 'name:cu', 'name:cv', 'name:cy', 'name:da', 'name:de', 'name:el', 'name:en', 'name:eo', 'name:es', 'name:et', 'name:eu', 'name:fa', 'name:fi', 'name:fr', 'name:fy', 'name:ga', 'name:he', 'name:hi', 'name:hr', 'name:hu', 'name:hy', 'name:id', 'name:is', 'name:it', 'name:ja', 'name:ka', 'name:kk', 'name:ko', 'name:ku', 'name:kv', 'name:ky', 'name:la', 'name:lb', 'name:lt', 'name:lv', 'name:mk', 'name:mn', 'name:mr', 'name:ms', 'name:nb', 'name:nl', 'name:nn', 'name:no', 'name:oc', 'name:os', 'name:pl', 'name:pt', 'name:ro', 'name:ru', 'name:se', 'name:sh', 'name:sk', 'name:sl', 'name:sq', 'name:sr', 'name:su', 'name:sv', 'name:sw', 'name:ta', 'name:tg', 'name:tl', 'name:tr', 'name:tt', 'name:ug', 'name:uk', 'name:ur', 'name:uz', 'name:vi', 'name:yi', 'name:zh', 'alt_name', 'website', 'boundary', 'int_name', 'name:aba', 'name:ace', 'name:ast', 'name:atv', 'name:bxr', 'name:crh', 'name:dsb', 'name:hak', 'name:hsb', 'name:inh', 'name:kaa', 'name:kbd', 'name:koi', 'name:krc', 'name:krl', 'name:lbe', 'name:lez', 'name:lrc', 'name:mhr', 'name:mrj', 'name:myv', 'name:nog', 'name:pam', 'name:pnb', 'name:sah', 'name:sco', 'name:szl', 'name:tyv', 'name:tzl', 'name:udm', 'name:vep', 'name:war', 'name:xal', 'name_int', 'old_name', 'timezone', 'wikidata', 'ISO3166-2', 'ssrf:code', 'wikipedia', 'cladr:code', 'oktmo:user', 'omkte:code', 'addr:region', 'population', 'short_name', 'source:url', 'admin_level', 'alt_name:ca', 'alt_name:de', 'alt_name:en', 'alt_name:fr', 'alt_name:nl', 'alt_name:ru', 'alt_name:sl', 'alt_name:vi', 'border_type', 'name:az-cyr', 'old_name:en', 'old_name:eo', 'old_name:fr', 'old_name:os', 'old_name:vi', 'addr:country', 'addr:postcode', 'cadaster:code', 'name:be-x-old', 'gis-lab:status', 'wikipedia:ru', 'wikipedia:uk', 'is_in:country', 'official_name', 'gost_7.67-2003', 'name:be-tarask', 'is_in:continent', 'name:zh-min-nan', 'official_name:av', 'official_name:az', 'official_status', 'old_alt_name:vi', 'population:date', 'official_name:ca', 'official_name:ce', 'official_name:de', 'official_name:en', 'official_name:es', 'official_name:fr', 'official_name:it', 'official_name:ru', 'official_name:lez', 'official_name:tt', 'official_name:bxr', 'official_name:udm', 'population:source', 'is_in:country_code', 'geometry'], dtype=object)
当前遇到的问题:
- 地图可视化时区域间无颜色差异
- 手动用GeoPandas给GeoJSON添加
id列后,出现错误:ValueError: key_on 'id' not found in GeoJSON
问题原因与解决方法
1. 初始无颜色差异的原因
你的Choropleth配置中key_on='id',但原GeoJSON既没有顶级id字段,属性里也没有匹配REGION_ID的字段,Folium无法建立数据与地理区域的映射关系,因此无法给区域上色。
2. 添加id列后报错的原因
用GeoPandas给GeoDataFrame添加id列后,导出的GeoJSON中该id是属性字段(位于properties对象内),但你设置的key_on='id'指向的是GeoJSON中每个Feature对象的顶级id字段(与properties、geometry同级),两者路径不匹配,导致Folium找不到对应字段。
正确解决步骤
步骤1:选择匹配字段
从GeoJSON的属性列中挑选一个能与DF['REGION_ID']匹配的字段,比如koatuu、ssrf:code这类编码字段(需确认字段值的格式、范围与REGION_ID一致)。
步骤2:修改key_on参数
若选择koatuu作为匹配字段,key_on需写成feature.properties.koatuu,格式必须遵循feature.properties.xxx(指向属性内的字段路径)。
示例代码(以koatuu匹配为例)
# 确保DF的REGION_ID与GeoJSON的koatuu字段格式一致(比如统一为字符串/数字) DF['REGION_ID'] = DF['REGION_ID'].astype(str) rel_ = folium.Choropleth( geo_data = './admin_level_4.geojson', name = 'Имя', data = DF, columns=['REGION_ID', 'share'], key_on='feature.properties.koatuu', # 修正为属性字段的完整路径 bins = 10, fill_color='BuGn', nan_fill_color='darkblue', nan_fill_opacity=0.5, fill_opacity=0.7, line_opacity=0.2, legend_name= 'Легенда', highlight = True, show = False )
若必须使用顶级id字段的处理方式
如果一定要用key_on='id',需要在导出GeoJSON时将id设置为Feature的顶级字段:
gdf = gpd.read_file('./admin_level_4.geojson') # 添加id列(可使用索引或匹配的字段值) gdf['id'] = gdf.index.astype(str) # 导出时指定id字段为顶级 gdf.to_file('./admin_level_4_with_id.geojson', driver='GeoJSON', id_field='id') # 后续Choropleth配置修改路径与key_on rel_ = folium.Choropleth( geo_data = './admin_level_4_with_id.geojson', key_on='id', # 其他参数保持不变 )
内容的提问来源于stack exchange,提问作者Dmitry Sokolov
相关产品推荐
相关产品推荐

