Search code examples
pythonleafletfolium

Setting a color using an attribute, folium, python dataframe


I would like CircleMarker to set the color using an argument, is there such a possibility? I have dataframe something like this below:

lon     lat  segment
ABMF00GLP  -61.528  16.262       41
ABPO00MDG   47.229 -19.018       71
ACRG00GHA   -0.207   5.641       16
AGGO00ARG  -58.140 -34.874        4
AIRA00JPN  130.600  31.824       20
...            ...     ...      ...
YKRO00CIV   -5.240   6.871       16
ZAMB00ZMB   28.311 -15.426       90
ZECK00RUS   41.565  43.788       67
ZIM200CHE    7.465  46.877       81
ZIM300CHE    7.465  46.877       81   

I can add markers with the same color like below, unfortunately I don't know how to make it segment dependent.

for x in df.index:
    folium.CircleMarker(list(np.array(df.loc[x])),
                      popup=x,
                      radius=3,
                      color = "red",
                      ).add_to(m)

Solution

  • Introduce a continuous colormap and set minimum and maximum values in segment columns. Takes a segment value as an argument in the marker color setting. See this for more information about colormaps.

    import pandas as pd
    import numpy as np
    import io
    import folium
    import branca.colormap as cm
    
    data = '''
    id lon     lat  segment
    ABMF00GLP  -61.528  16.262       41
    ABPO00MDG   47.229 -19.018       71
    ACRG00GHA   -0.207   5.641       16
    AGGO00ARG  -58.140 -34.874        4
    AIRA00JPN  130.600  31.824       20
    YKRO00CIV   -5.240   6.871       16
    ZAMB00ZMB   28.311 -15.426       90
    ZECK00RUS   41.565  43.788       67
    ZIM200CHE    7.465  46.877       81
    '''
    
    df = pd.read_csv(io.StringIO(data), delim_whitespace=True)
    
    linear = cm.LinearColormap(["green", "yellow", "red"], vmin=df['segment'].min(), vmax=df['segment'].max())
    
    m = folium.Map([df['lat'].mean(), df['lon'].mean()], tiles="cartodbpositron", zoom_start=2)
    
    for _, row in df.iterrows():
        folium.CircleMarker([row.lat, row.lon],
                          popup=row.id,
                          radius=3,
                          color = linear(row.segment),
                          ).add_to(m)
    
    m
    

    enter image description here