Folium:将 GeoJson 添加到地图时的颜色映射
Folium: color mapping when adding GeoJson to the map
我的 python 代码中有一个循环,它向我的 folium 地图添加了特征。每个功能都保存在一个字典(称为产品)中,每个功能都有一个参数字典(GeoJson 字符串和属性)。我想根据其中一个参数为特征着色。
我首先为参数创建一个唯一值列表。然后我将颜色映射到每个唯一值:
orb_list = [value['relativeorbitnumber'] for key, value in products.items()]
orb_list = list(set(orb_list))
color_cycle = cycler(color=['#8e0038', '#8e0073', '#59008e'], fillColor=['#8e0038', '#8e0073', '#59008e'])
orb_colors=dict([[i, sty] for i, sty in zip(orb_list, cycle(color_cycle))])
接下来,我创建了一个循环,在其中检索与特征参数值对应的颜色和填充颜色,并在 style_function 中使用它:
for key,value in products.items():
footprint = json.dumps(wkt.loads(products[key]['footprint']))
fillColor = orb_colors[products[key]['relativeorbitnumber']]['fillColor']
color = orb_colors[products[key]['relativeorbitnumber']]['color']
feat = folium.GeoJson(footprint,
style_function=lambda x: {'fillColor':fillColor,'color':color},
highlight_function=lambda feature: {'fillcolor':'green','color':'green'},
name='Footprint')
feat.add_to(mapa)
我认为这可行,但所有功能似乎都被我循环中的最后一个 "fillColor" 和 "color" 着色了。谁能解释这是为什么?我假设在所有循环完成之前不会呈现这些功能,因此 "color" 和 "fillColor" 的最后一个值用于所有功能。你能建议我的代码应该如何修改来解决这个问题吗?或许我的做法完全错误,您可以建议一种更简洁的方法吗?
您遇到了 Python closures
的常见陷阱
您传递给的函数,例如style_function
在循环中不是立即执行,而是稍后执行。那时,fillColor
将从外部作用域中检索(因为它没有在 lambda
表达式创建的内部作用域中定义),此时它将具有最后一个值。
演示正在发生的事情:
In [1]: out = []
...: for k in ('a', 'b', 'c'):
...: l = lambda: k
...: out.append(l)
...: [l() for l in out]
Out[1]: ['c', 'c', 'c']
为了防止这种情况,您可以将变量的(当前)值作为 default argument 传递给 lambda 表达式创建的函数,以便稍后执行该函数时使用该值:
In [2]: out = []
...: for k in ('a', 'b', 'c'):
...: l = lambda k=k: k
...: out.append(l)
...: [l() for l in out]
Out[2]: ['a', 'b', 'c']
或者在您的代码中:
for key, value in products.items():
footprint = json.dumps(wkt.loads(products[key]["footprint"]))
fillColor = orb_colors[products[key]["relativeorbitnumber"]]["fillColor"]
color = orb_colors[products[key]["relativeorbitnumber"]]["color"]
feat = folium.GeoJson(
footprint,
style_function=lambda x, fillColor=fillColor, color=color: {
"fillColor": fillColor,
"color": color,
},
highlight_function=lambda feature: {"fillcolor": "green", "color": "green"},
name="Footprint",
)
feat.add_to(mapa)
这应该可以解决问题。
我的 python 代码中有一个循环,它向我的 folium 地图添加了特征。每个功能都保存在一个字典(称为产品)中,每个功能都有一个参数字典(GeoJson 字符串和属性)。我想根据其中一个参数为特征着色。
我首先为参数创建一个唯一值列表。然后我将颜色映射到每个唯一值:
orb_list = [value['relativeorbitnumber'] for key, value in products.items()]
orb_list = list(set(orb_list))
color_cycle = cycler(color=['#8e0038', '#8e0073', '#59008e'], fillColor=['#8e0038', '#8e0073', '#59008e'])
orb_colors=dict([[i, sty] for i, sty in zip(orb_list, cycle(color_cycle))])
接下来,我创建了一个循环,在其中检索与特征参数值对应的颜色和填充颜色,并在 style_function 中使用它:
for key,value in products.items():
footprint = json.dumps(wkt.loads(products[key]['footprint']))
fillColor = orb_colors[products[key]['relativeorbitnumber']]['fillColor']
color = orb_colors[products[key]['relativeorbitnumber']]['color']
feat = folium.GeoJson(footprint,
style_function=lambda x: {'fillColor':fillColor,'color':color},
highlight_function=lambda feature: {'fillcolor':'green','color':'green'},
name='Footprint')
feat.add_to(mapa)
我认为这可行,但所有功能似乎都被我循环中的最后一个 "fillColor" 和 "color" 着色了。谁能解释这是为什么?我假设在所有循环完成之前不会呈现这些功能,因此 "color" 和 "fillColor" 的最后一个值用于所有功能。你能建议我的代码应该如何修改来解决这个问题吗?或许我的做法完全错误,您可以建议一种更简洁的方法吗?
您遇到了 Python closures
的常见陷阱您传递给的函数,例如style_function
在循环中不是立即执行,而是稍后执行。那时,fillColor
将从外部作用域中检索(因为它没有在 lambda
表达式创建的内部作用域中定义),此时它将具有最后一个值。
演示正在发生的事情:
In [1]: out = []
...: for k in ('a', 'b', 'c'):
...: l = lambda: k
...: out.append(l)
...: [l() for l in out]
Out[1]: ['c', 'c', 'c']
为了防止这种情况,您可以将变量的(当前)值作为 default argument 传递给 lambda 表达式创建的函数,以便稍后执行该函数时使用该值:
In [2]: out = []
...: for k in ('a', 'b', 'c'):
...: l = lambda k=k: k
...: out.append(l)
...: [l() for l in out]
Out[2]: ['a', 'b', 'c']
或者在您的代码中:
for key, value in products.items():
footprint = json.dumps(wkt.loads(products[key]["footprint"]))
fillColor = orb_colors[products[key]["relativeorbitnumber"]]["fillColor"]
color = orb_colors[products[key]["relativeorbitnumber"]]["color"]
feat = folium.GeoJson(
footprint,
style_function=lambda x, fillColor=fillColor, color=color: {
"fillColor": fillColor,
"color": color,
},
highlight_function=lambda feature: {"fillcolor": "green", "color": "green"},
name="Footprint",
)
feat.add_to(mapa)
这应该可以解决问题。