Search code examples
pythonpython-3.xleafletfoliumchoropleth

how to hide python folium choropleth legend


I have created a folium map with two choropleths layers:

https://ghana.deta.dev/

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:

enter image description here

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.


Solution

  • 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