Folium is a Python library for creating interactive maps. The plotted markers or polygons can be assigned to individual layers (using folium.FeatureGroup()), which can be switched on and off with a mouse click. 

All the examples I found on the net explicitly define each individual layer with a command like:
feature_group1 = FeatureGroup(name='Foo')
If I have categorical data in a Geopandas.GeoDataFrame, I certainly don’t want to create a layer for each category by hand. Fortunately, we can automate this by simply appending each initialised FeatureGroup to a list. Here’s an example with volcanoes.
A quick look at the data:
volcanoes.info()RangeIndex: 1233 entries, 0 to 1232 Data columns (total 13 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 number 1233 non-null int64 1 name 1233 non-null object 2 country 1233 non-null object 3 vtype 1233 non-null object 4 evidence 1233 non-null object 5 last_eruption 1233 non-null object 6 region 1233 non-null object 7 subregion 1233 non-null object 8 elevation 1233 non-null int64 9 rocks 1198 non-null object 10 tectonic_setting 1230 non-null object 11 last_eruption_int 787 non-null float64 12 geometry 1233 non-null geometry dtypes: float64(1), geometry(1), int64(2), object(9) memory usage: 125.4+ KB 
I want a map grouped by rock type.
grouped = volcanoes.groupby('rocks')
Since Seaborn’s colour palettes are particularly nice, I use them to create a list of colours in hex format (as used by html). The number of colours needed is len(grouped).
import seaborn as sns
pal = sns.color_palette("husl", len(grouped)).as_hex() 
In this example I do not want the base map (the tile layer) to be displayed in the LayerControl as well. Therefore I initialise the map without tiles and add a TileLayer with control=False:
m = folium.Map(tiles=None)
folium.TileLayer('cartodbpositron', control=False).add_to(m)
Now we iterate through the grouped GeoDataFrame. For each category a FeatureGroup is created, which is appended to the list f_groups. Then markers for corresponding volcanoes are added to the last initialised FeatureGroup.
f_groups = []
for group_name, group_data in grouped:
    f_groups.append(folium.FeatureGroup(group_name))
    color = pal.pop()
    
    for i in range(0,len(group_data)):
        # html for popup of markers
        html=f"""
            <h2>  {group_data.iloc[i]['name']} </h2>
            <small>
            <p> Country: {group_data.iloc[i]['country']}  <br/>
            Elevation: {group_data.iloc[i]['elevation']}  <br/>
            Last Eruption: 
            {group_data.iloc[i]['last_eruption']}  <br/>
            Rocks: {group_data.iloc[i]['rocks']}  <br/>
            Tectonic Setting: 
            {group_data.iloc[i]['tectonic_setting']}  </p>
            </small>
            """
        iframe = folium.IFrame(html=html, width=300, height=200)
        popup = folium.Popup(iframe, max_width=650)
        # Add markers to last FeatureGroup    
        folium.CircleMarker(
            location=[group_data.iloc[i].geometry.y, 
                      group_data.iloc[i].geometry.x],
            radius=5,
            popup=popup,
            tooltip=group_data.iloc[i]['name'],
            fill_color=color,
            stroke = False, 
            fill_opacity = 1,
        ).add_to(f_groups[-1])
    # Add last featureGroup to Map
    f_groups[-1].add_to(m)
folium.LayerControl().add_to(m)
m