Search code examples
geopandasfolium

Add location marker on plotted Geopandas Dataframe using Folium


Context

I have an merged geodataframe of 1). Postalcode areas and 2). total amount of deliveries within that postalcode area in the city of Groningen called results. The geodataframe includes geometry that include Polygons and Multiploygons visualizing different Postal code areas within the city.

result geopandas.geodataframe

I am new to GeoPandas and therefore I've tried different tutorials including this one from the geopandas official website wherein I got introduced into interactive Folium maps, which I really like. I was able to plot my geodataframe using result.explore(), which resulted in the following map

enter image description here

The problem

So far so good, but now I want to simply place an marker using the folium libarty with the goal to calculate the distance between the marker and the postalcode areas. After some looking on the internet I found out in the quickstart guild that you need to create an folium.Map, then you need folium.Choropleth for my geodataframe and folium.Marker and add them to the folium.Map.

m = folium.Map(location=[53.21917, 6.56667], zoom_start=15)

folium.Marker(
    [53.210903, 6.598276], 
    popup="My marker"
).add_to(m)

folium.Choropleth(results, data=results, columns="Postcode", fill_color='OrRd', name="Postalcode areas").add_to(m)
folium.LayerControl().add_to(m)
m

But when try to run the above code I get the following error:

enter image description here

What is the (possible) best way?

Besides my failing code (which would be great if someone could help me out). I am curious if this is the way to do it (Folium map + marker + choropleth). Is it not possible to call geodataframe.explore() which results into the map in second picture and then just add an marker on the same map? I have the feeling that I am making it too difficult, there must be an better solution using Geopandas.


Solution

    • you have not provided the geometry. Have found postal districts of Netherlands and used that
    • explore() supports will draw a point as a marker with appropriate parameters
    • hence two layers,
      • one is postal areas coloured using number of deliveries
      • second is point, with distance to each area calculated
    import geopandas as gpd
    import shapely.geometry
    import pandas as pd
    import numpy as np
    
    geo_url = "https://geodata.nationaalgeoregister.nl/cbsgebiedsindelingen/wfs?request=GetFeature&service=WFS&version=2.0.0&typeName=cbs_provincie_2017_gegeneraliseerd&outputFormat=json"
    
    gdf = gpd.read_file(geo_url).assign(
        deliveries=lambda d: np.random.randint(10**4, 10**6, len(d))
    )
    
    p = gpd.GeoSeries(shapely.geometry.Point(6.598276, 53.210903), crs="epsg:4386")
    
    # calc distances to point
    gdf["distance"] = gdf.distance(p.to_crs(gdf.crs).values[0])
    
    # dataframe of flattened distances
    dfp = pd.DataFrame(
        [
            "<br>".join(
                [f"{a} - {b:.2f}" for a, b in gdf.loc[:, ["statcode", "distance"]].values]
            )
        ],
        columns=["info"],
    )
    
    # generate colored choropleth
    m = gdf.explore(
        column="deliveries", categorical=True, legend=False, height=400, width=400
    )
    # add marker with distances
    gpd.GeoDataFrame(
        geometry=p,
        data=dfp,
    ).explore(m=m, marker_type="marker")
    

    enter image description here