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")
问题原因分析
- 图层覆盖问题:循环中每次都将完整的GeoJSON图层添加到地图,后添加的图层会完全覆盖之前的图层,最终仅显示最后一次循环生成的图层。
- Lambda变量捕获陷阱:循环中的变量
i在lambda函数执行时,已经指向循环的最后一个值,导致所有图层的判断逻辑都只针对最后一个部门。 - 样式参数错误:
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")
修复说明
- 一次性加载GeoJSON:不再循环添加图层,仅加载一次完整的GeoJSON,避免图层覆盖。
- 独立颜色映射函数:将颜色判断逻辑封装成
get_color函数,代码更清晰易维护。 - 正确的样式参数:统一设置边界颜色和透明度,根据部门名称从字典中获取数值,动态匹配填充颜色。
- 避免Lambda陷阱:直接在style函数中通过
feature['properties']['nom']获取当前部门名称,无需依赖循环变量。
内容的提问来源于stack exchange,提问作者newtiban
相关产品推荐
相关产品推荐

