How to add categorical layered data to LayerControl() in python Folium map?

Viewed 884

I have this categorical dataset in which I will like each category/group to be a layer I can turn ON/OFF.

Am able to add the groups on 'LayerControl', but it doesn't work properly as expected.

import folium

m = folium.Map(location=[39.712183, -104.998424], zoom_start=5)

data = [(36.314292, -117.517516, 'P1'),
             (40.94859, -116.15316, 'P2'),
             (34.14757, -119.81985, 'P3'),
             (46.31292, -117.57516, 'P4'),
             (41.04159, -116.15316, 'P2'),
             (44.22093, -119.821985,'P2'), 
             (42.25308, -117.27589, 'P3'),
             (41.60302, -115.97012, 'P4'),
             (44.35519, -117.94183, 'P4'),
             (44.02027, -117.22198, 'P1'),
             (45.91613, -113.05364, 'P5'),
             (48.17537, -117.90075, 'P1'),
             (37.65961, -117.61321, 'P1')]


for x in range(0, len(data)):
    
    point_layer = folium.FeatureGroup(name = latLong[x][2])

    for lat,lng,nameP in latLong:
        point_layer.add_child(folium.CircleMarker(location=[lat, lng], radius=10,
            popup=str(nameP) + " Lat: " + str(lat) + " , Long: " + str(lng), 
            tooltip=str(nameP) + " Lat: " + str(lat) + " , Long: " + str(lng),
            fill=True,  # Set fill to True
            color='red',
            fill_opacity=1.0)).add_to(m)

    
    m.add_child(point_layer)


m.add_child(folium.LayerControl(collapsed=False))  
m.save("Map1.html")

enter image description here

As you see from above, the buttons are off yet the points/circles still display on the map. Any idea to fixing this?

1 Answers

To associate a marker with a layer, create a point group and set the marker to belong to it. You can then add the point group to the map. The code in the question creates a point group in a loop process, but we can change the process to create a point group in advance and then add it to the map.

import folium

m = folium.Map(location=[39.712183, -104.998424], zoom_start=5)

latLong = [(36.314292, -117.517516, 'P1'),
             (40.94859, -116.15316, 'P2'),
             (34.14757, -119.81985, 'P3'),
             (46.31292, -117.57516, 'P4'),
             (41.04159, -116.15316, 'P2'),
             (44.22093, -119.821985,'P2'), 
             (42.25308, -117.27589, 'P3'),
             (41.60302, -115.97012, 'P4'),
             (44.35519, -117.94183, 'P4'),
             (44.02027, -117.22198, 'P1'),
             (45.91613, -113.05364, 'P5'),
             (48.17537, -117.90075, 'P1'),
             (37.65961, -117.61321, 'P1')]

# point_layer name list
all_gp = []
for x in range(len(latLong)):
    pg = latLong[x][2]
    all_gp.append(pg)

# Create point_layer object
unique_gp = list(set(all_gp))
vlist = []
for i,k in enumerate(unique_gp):
    locals()[f'point_layer{i}'] = folium.FeatureGroup(name=k)
    vlist.append(locals()[f'point_layer{i}'])

# Creating list for point_layer
pl_group = []
for n in all_gp:
    for v in vlist: 
        if n == vars(v)['layer_name']:
            pl_group.append(v)

for (lat,lng,nameP),pg in zip(latLong, pl_group):
    folium.CircleMarker(location=[lat, lng], radius=10,
        popup=str(nameP) + " Lat: " + str(lat) + " , Long: " + str(lng), 
        tooltip=str(nameP) + " Lat: " + str(lat) + " , Long: " + str(lng),
        fill=True,  # Set fill to True
        color='red',
        fill_opacity=1.0).add_to(pg)
    pg.add_to(m)

m.add_child(folium.LayerControl(collapsed=False))  
#m.save("Map1.html")
m

enter image description here

Related