Search code examples
pandasdataframeplotlymapboxgeojson

Dataframe to geojson for mapbox


I have a dataframe that looks like this

df = pd.DataFrame({
    "zone":["A","B"],
    "boundaries":["POLYGON ((10.90973 43.67753, 10.90903 43.68038, 10.9086 43.68125, 10.90704 43.68265, 10.90669 43.68278, 10.90535 43.68268, 10.90107 43.68175, 10.89998 43.68192, 10.89923 43.68233, 10.89849 43.68327, 10.89833 43.6837, 10.89836 43.68478, 10.899000000000001 43.68691, 10.89894 43.68745, 10.89847 43.68797, 10.89737 43.68856, 10.89346 43.69151, 10.8918 43.69242, 10.889050000000001 43.69501, 10.88766 43.69693, 10.90438 43.69787, 10.90619 43.69598, 10.90562 43.6929, 10.9064 43.68971, 10.91216 43.68904, 10.916830000000001 43.68966, 10.92128 43.69076, 10.92842 43.69053, 10.92963 43.69078, 10.93042 43.69064, 10.94203 43.6923, 10.94295 43.6902, 10.94459 43.68744, 10.94506 43.68587, 10.94609 43.68541, 10.94651 43.685, 10.94663 43.68443, 10.95482 43.67126, 10.95208 43.66827, 10.95141 43.66773, 10.95078 43.66636, 10.95073 43.66561, 10.951 43.66502, 10.95074 43.664320000000004, 10.95039 43.66391, 10.95097 43.66199, 10.95088 43.66131, 10.95061 43.66109, 10.94896 43.66075, 10.94711 43.65881, 10.94394 43.65711, 10.94262 43.65478, 10.94651 43.65139, 10.94552 43.65128, 10.94528 43.65166, 10.94421 43.65139, 10.94421 43.65073, 10.94358 43.65067, 10.94323 43.65091, 10.94205 43.65252, 10.94127 43.65413, 10.94083 43.65445, 10.94026 43.65447, 10.93766 43.65299, 10.93685 43.65318, 10.93622 43.65357, 10.93514 43.65485, 10.9339 43.6575, 10.93215 43.65951, 10.93135 43.65994, 10.93026 43.66023, 10.92908 43.66012, 10.92688 43.65911, 10.92592 43.65895, 10.92496 43.65914, 10.92182 43.66056, 10.920490000000001 43.66171, 10.91842 43.66184, 10.91594 43.66245, 10.91553 43.66279, 10.91455 43.66491, 10.914390000000001 43.66633, 10.91459 43.66701, 10.91588 43.66794, 10.91643 43.6686, 10.916640000000001 43.66894, 10.91663 43.66966, 10.91631 43.67027, 10.91559 43.67091, 10.91468 43.67135, 10.91331 43.67171, 10.9123 43.67174, 10.91123 43.67232, 10.91086 43.67488, 10.91022 43.6761, 10.90973 43.67753))","POLYGON ((10.93576 43.72298, 10.93573 43.72162, 10.935410000000001 43.72111, 10.9369 43.72062, 10.93649 43.72022, 10.93594 43.72001, 10.93603 43.71822, 10.9407 43.71806, 10.94331 43.71781, 10.94353 43.71767, 10.94328 43.71653, 10.94299 43.7165, 10.94146 43.71471, 10.917910000000001 43.71195, 10.9224 43.71636, 10.92303 43.71747, 10.92303 43.71817, 10.92545 43.72305, 10.925650000000001 43.72537, 10.927228530434478 43.72728396815181, 10.927855 43.727009, 10.935086 43.724491, 10.93653252869495 43.72376183626959, 10.93576 43.72298))"]
})

I want to be able to use those polygons in choropleth_mapbox, therefore, I need to transform this dataframe into goejson. I tried in many ways but it seems is not working


Solution

  • There are really two steps needed to achieve this

    1. convert WKT strings to polygons using shapely.wkt.loads()
    2. convert resulting geometry to GeoJSON using geopandas
      • create GeoDataFrame using step 1
      • use __geo_interface__ to get GeoJSON from GeoDataFrame

    full code

    import pandas as pd
    import shapely.wkt
    import geopandas as gpd
    import plotly.express as px
    
    df = pd.DataFrame(
        {
            "zone": ["A", "B"],
            "boundaries": [
                "POLYGON ((10.90973 43.67753, 10.90903 43.68038, 10.9086 43.68125, 10.90704 43.68265, 10.90669 43.68278, 10.90535 43.68268, 10.90107 43.68175, 10.89998 43.68192, 10.89923 43.68233, 10.89849 43.68327, 10.89833 43.6837, 10.89836 43.68478, 10.899000000000001 43.68691, 10.89894 43.68745, 10.89847 43.68797, 10.89737 43.68856, 10.89346 43.69151, 10.8918 43.69242, 10.889050000000001 43.69501, 10.88766 43.69693, 10.90438 43.69787, 10.90619 43.69598, 10.90562 43.6929, 10.9064 43.68971, 10.91216 43.68904, 10.916830000000001 43.68966, 10.92128 43.69076, 10.92842 43.69053, 10.92963 43.69078, 10.93042 43.69064, 10.94203 43.6923, 10.94295 43.6902, 10.94459 43.68744, 10.94506 43.68587, 10.94609 43.68541, 10.94651 43.685, 10.94663 43.68443, 10.95482 43.67126, 10.95208 43.66827, 10.95141 43.66773, 10.95078 43.66636, 10.95073 43.66561, 10.951 43.66502, 10.95074 43.664320000000004, 10.95039 43.66391, 10.95097 43.66199, 10.95088 43.66131, 10.95061 43.66109, 10.94896 43.66075, 10.94711 43.65881, 10.94394 43.65711, 10.94262 43.65478, 10.94651 43.65139, 10.94552 43.65128, 10.94528 43.65166, 10.94421 43.65139, 10.94421 43.65073, 10.94358 43.65067, 10.94323 43.65091, 10.94205 43.65252, 10.94127 43.65413, 10.94083 43.65445, 10.94026 43.65447, 10.93766 43.65299, 10.93685 43.65318, 10.93622 43.65357, 10.93514 43.65485, 10.9339 43.6575, 10.93215 43.65951, 10.93135 43.65994, 10.93026 43.66023, 10.92908 43.66012, 10.92688 43.65911, 10.92592 43.65895, 10.92496 43.65914, 10.92182 43.66056, 10.920490000000001 43.66171, 10.91842 43.66184, 10.91594 43.66245, 10.91553 43.66279, 10.91455 43.66491, 10.914390000000001 43.66633, 10.91459 43.66701, 10.91588 43.66794, 10.91643 43.6686, 10.916640000000001 43.66894, 10.91663 43.66966, 10.91631 43.67027, 10.91559 43.67091, 10.91468 43.67135, 10.91331 43.67171, 10.9123 43.67174, 10.91123 43.67232, 10.91086 43.67488, 10.91022 43.6761, 10.90973 43.67753))",
                "POLYGON ((10.93576 43.72298, 10.93573 43.72162, 10.935410000000001 43.72111, 10.9369 43.72062, 10.93649 43.72022, 10.93594 43.72001, 10.93603 43.71822, 10.9407 43.71806, 10.94331 43.71781, 10.94353 43.71767, 10.94328 43.71653, 10.94299 43.7165, 10.94146 43.71471, 10.917910000000001 43.71195, 10.9224 43.71636, 10.92303 43.71747, 10.92303 43.71817, 10.92545 43.72305, 10.925650000000001 43.72537, 10.927228530434478 43.72728396815181, 10.927855 43.727009, 10.935086 43.724491, 10.93653252869495 43.72376183626959, 10.93576 43.72298))",
            ],
        }
    )
    
    gdf = gpd.GeoDataFrame(
        data=df["zone"], geometry=df["boundaries"].apply(shapely.wkt.loads), crs="epsg:4326"
    )
    c = gdf.geometry.unary_union.centroid
    
    px.choropleth_mapbox(
        df,
        geojson=gdf.set_index("zone").__geo_interface__,
        locations="zone",
        color="zone",
        mapbox_style="carto-positron",
    ).update_layout(mapbox={"center": {"lat": c.y, "lon": c.x}, "zoom": 10})
    

    enter image description here