You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Folium地图按部门数值着色异常问题求助

问题:Folium地图仅显示最后一个部门颜色,无法按字典值批量着色

我和三位同学在课程项目中使用Folium绘制法国部门地图时遇到问题:我们希望根据departements字典中的数值为各部门设置对应颜色,但目前地图仅显示最后一个部门的颜色,推测问题可能与部门边界处理有关,现有教程无法解决,请求修复代码或提供建议。

原代码

import folium
import json

departements = {
    'Ain':37 ,'Aisne':42 ,'Allier':34 ,'Alpes-de-Haute-Provence':47 ,'Hautes-Alpes':45 ,'Alpes-Maritimes':73 ,'Ardèche':36 ,'Ardennes':38,
    'Ariège':40,'Aube':51,'Aude':48,'Aveyron':26,'Bouches-du-Rhône':77,'Calvados':38,'Cantal':23,'Charente':40,'Charente-Maritime':50,
    'Cher':40,'Corrèze':31,'Côte-d\'Or':41,'Côtes-d\'Armor':33,'Creuse':23,'Dordogne':28,'Doubs':45,'Drôme':51,'Eure':37,
    'Eure-et-Loir':38,'Finistère':36,'Gard':54,'Haute-Garonne':64,'Gers':27,'Gironde':53,'Hérault':65,'Ille-et-Vilaine':37,
    'Indre':34,'Indre-et-Loire':42,'Isère':56,'Jura':33,'Landes':40,'Loir-et-Cher':38,'Loire':46,'Haute-Loire':29,
    'Loire-Atlantique':54,'Loiret':47,'Lot':34,'Lot-et-Garonne':38,'Lozère':26,'Maine-et-Loire':36,'Manche':23,'Marne':54,
    'Haute-Marne':41,'Mayenne':31,'Meurthe-et-Moselle':47,'Meuse':37,'Morbihan':34,'Moselle':40,'Nièvre':37,'Nord':43,
    'Oise':50,'Orne':36,'Pas-de-Calais':45,'Puy-de-Dôme':39,'Pyrénées-Atlantiques':37,'Hautes-Pyrénées':42,
    'Pyrénées-Orientales':55,'Bas-Rhin':39,'Haut-Rhin':38,'Rhône':50,'Haute-Saône':36,'Saône-et-Loire':35,'Sarthe':39,
    'Savoie':50,'Haute-Savoie':43,'Paris':59,'Seine-Maritime':46,'Seine-et-Marne':59,'Yvelines':39,'Deux-Sèvres':30,
    'Somme':45,'Tarn':35,'Tarn-et-Garonne':42,'Var':59,'Vaucluse':55,'Vendée':33,'Vienne':40,'Haute-Vienne':33,
    'Vosges':33,'Yonne':56,'Territoire de Belfort':44,'Essonne':53,'Hauts-de-Seine':64,'Seine-Saint-Denis':85,
    'Val-de-Marne':63,'Val-d\'Oise':59
}

# 加载geojson文件
geo = json.load(open("departements.geojson"))
# 创建地图
map = folium.Map(location = [48.856578, 2.351828], zoom_start = 6)
# 部门着色
for i in departements:
    if departements[i] <=30:
        folium.GeoJson(geo,style_function =lambda feature: {'fillColor':"#25fde9",'fillOpacity': 1,'opacity': 1 if (feature['properties']['nom']==i) else 'White'}).add_to(map)
    elif departements[i] <=45 and departements[i]>30:
        folium.GeoJson(geo,style_function =lambda feature: {'fillColor':"#85bd87",'fillOpacity': 1,'opacity': 1 if (feature['properties']['nom']==i) else 'White'}).add_to(map)
    elif departements[i] <=60 and departements[i]>45:
        folium.GeoJson(geo,style_function =lambda feature: {'fillColor':"#ff8800",'fillOpacity': 1,'opacity': 1 if (feature['properties']['nom']==i) else 'White'}).add_to(map)
    elif departements[i] <=75 and departements[i]>60:
        folium.GeoJson(geo,style_function =lambda feature: {'fillColor':"#cc0002",'fillOpacity': 1,'opacity': 1 if (feature['properties']['nom']==i) else 'White'}).add_to(map)
    elif departements[i]>75:
        folium.GeoJson(geo,style_function =lambda feature: {'fillColor':"#000000",'fillOpacity': 1,'opacity': 1 if (feature['properties']['nom']==i) else 'White'}).add_to(map)
# 保存地图
map.save("folium_map.html")

问题原因分析

  1. 图层覆盖问题:循环中每次都将完整的GeoJSON图层添加到地图,后添加的图层会完全覆盖之前的图层,最终仅显示最后一次循环生成的图层。
  2. Lambda变量捕获陷阱:循环中的变量i在lambda函数执行时,已经指向循环的最后一个值,导致所有图层的判断逻辑都只针对最后一个部门。
  3. 样式参数错误:opacity是控制边界透明度的数值(0-1),原代码中错误地将未匹配部门的opacity设为字符串'White',应该修改为设置fillColor为白色,保持opacity为正常数值。

修复后的代码

import folium
import json

departements = {
    'Ain':37 ,'Aisne':42 ,'Allier':34 ,'Alpes-de-Haute-Provence':47 ,'Hautes-Alpes':45 ,'Alpes-Maritimes':73 ,'Ardèche':36 ,'Ardennes':38,
    'Ariège':40,'Aube':51,'Aude':48,'Aveyron':26,'Bouches-du-Rhône':77,'Calvados':38,'Cantal':23,'Charente':40,'Charente-Maritime':50,
    'Cher':40,'Corrèze':31,'Côte-d\'Or':41,'Côtes-d\'Armor':33,'Creuse':23,'Dordogne':28,'Doubs':45,'Drôme':51,'Eure':37,
    'Eure-et-Loir':38,'Finistère':36,'Gard':54,'Haute-Garonne':64,'Gers':27,'Gironde':53,'Hérault':65,'Ille-et-Vilaine':37,
    'Indre':34,'Indre-et-Loire':42,'Isère':56,'Jura':33,'Landes':40,'Loir-et-Cher':38,'Loire':46,'Haute-Loire':29,
    'Loire-Atlantique':54,'Loiret':47,'Lot':34,'Lot-et-Garonne':38,'Lozère':26,'Maine-et-Loire':36,'Manche':23,'Marne':54,
    'Haute-Marne':41,'Mayenne':31,'Meurthe-et-Moselle':47,'Meuse':37,'Morbihan':34,'Moselle':40,'Nièvre':37,'Nord':43,
    'Oise':50,'Orne':36,'Pas-de-Calais':45,'Puy-de-Dôme':39,'Pyrénées-Atlantiques':37,'Hautes-Pyrénées':42,
    'Pyrénées-Orientales':55,'Bas-Rhin':39,'Haut-Rhin':38,'Rhône':50,'Haute-Saône':36,'Saône-et-Loire':35,'Sarthe':39,
    'Savoie':50,'Haute-Savoie':43,'Paris':59,'Seine-Maritime':46,'Seine-et-Marne':59,'Yvelines':39,'Deux-Sèvres':30,
    'Somme':45,'Tarn':35,'Tarn-et-Garonne':42,'Var':59,'Vaucluse':55,'Vendée':33,'Vienne':40,'Haute-Vienne':33,
    'Vosges':33,'Yonne':56,'Territoire de Belfort':44,'Essonne':53,'Hauts-de-Seine':64,'Seine-Saint-Denis':85,
    'Val-de-Marne':63,'Val-d\'Oise':59
}

# 定义颜色映射函数
def get_color(value):
    if value <= 30:
        return "#25fde9"
    elif 30 < value <= 45:
        return "#85bd87"
    elif 45 < value <= 60:
        return "#ff8800"
    elif 60 < value <= 75:
        return "#cc0002"
    else:
        return "#000000"

# 加载geojson文件
geo = json.load(open("departements.geojson"))
# 创建地图
m = folium.Map(location=[48.856578, 2.351828], zoom_start=6)

# 仅添加一次GeoJSON图层,通过style函数批量处理所有部门
folium.GeoJson(
    geo,
    style_function=lambda feature: {
        'fillColor': get_color(departements.get(feature['properties']['nom'], 0)),
        'fillOpacity': 1,
        'opacity': 1,  # 边界透明度
        'color': 'black'  # 边界颜色
    }
).add_to(m)

# 保存地图
m.save("folium_map.html")

修复说明

  1. 一次性加载GeoJSON:不再循环添加图层,仅加载一次完整的GeoJSON,避免图层覆盖。
  2. 独立颜色映射函数:将颜色判断逻辑封装成get_color函数,代码更清晰易维护。
  3. 正确的样式参数:统一设置边界颜色和透明度,根据部门名称从字典中获取数值,动态匹配填充颜色。
  4. 避免Lambda陷阱:直接在style函数中通过feature['properties']['nom']获取当前部门名称,无需依赖循环变量。

内容的提问来源于stack exchange,提问作者newtiban

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 12:54:55