I have created a folium map with two choropleths layers:
As you can see in the picture, only one layer is right now selected (green). Yet, the legend is shown for both (blue and green).
Is there a way to sync it with the layer control?
Instead of my code, I am linking the folium Choropleth tutorial to make it more usable for everyone:
source: https://python-visualization.github.io/folium/quickstart.html#Choropleth-maps As you can see, regardless of the layer control, the legend is always on.
r-beginners
provided the clue to this solution in their comment. A few additional re-works were necessary so I consider it worth adding the code for future reference.
Explaining the solution briefly, the branca color map is first removed to then be re-added to the map binded to the choropleth layer itself thanks to a custom macro element.
from branca.element import MacroElement
from jinja2 import Template
import pandas as pd
class BindColormap(MacroElement):
"""Binds a colormap to a given layer.
Parameters
----------
colormap : branca.colormap.ColorMap
The colormap to bind.
"""
def __init__(self, layer, colormap):
super(BindColormap, self).__init__()
self.layer = layer
self.colormap = colormap
self._template = Template(u"""
{% macro script(this, kwargs) %}
{{this.colormap.get_name()}}.svg[0][0].style.display = 'block';
{{this._parent.get_name()}}.on('overlayadd', function (eventLayer) {
if (eventLayer.layer == {{this.layer.get_name()}}) {
{{this.colormap.get_name()}}.svg[0][0].style.display = 'block';
}});
{{this._parent.get_name()}}.on('overlayremove', function (eventLayer) {
if (eventLayer.layer == {{this.layer.get_name()}}) {
{{this.colormap.get_name()}}.svg[0][0].style.display = 'none';
}});
{% endmacro %}
""") # noqa
url = (
"https://raw.githubusercontent.com/python-visualization/folium/master/examples/data"
)
state_geo = f"{url}/us-states.json"
state_unemployment = f"{url}/US_Unemployment_Oct2012.csv"
state_data = pd.read_csv(state_unemployment)
m = folium.Map(location=[48, -102], zoom_start=3)
c = folium.Choropleth(
geo_data=state_geo,
name="choropleth",
data=state_data,
columns=["State", "Unemployment"],
key_on="feature.id",
fill_color="YlGn",
fill_opacity=0.7,
line_opacity=0.2,
legend_name="Unemployment Rate (%)",
)
for key in c._children:
if key.startswith('color_map'):
branca_color_map = c._children[key]
del(c._children[key])
m.add_child(c)
m.add_child(folium.map.LayerControl())
m.add_child(branca_color_map)
m.add_child(BindColormap(c, branca_color_map))
m