Search code examples
pythonjsongeojsonplotly-python

Plotly px.choropleth not drawing data from json file


I have a CSV file with the following structure

cardodb_id,CONCELHO,LAT,LONG,DATA,INC 225,Abrantes,39.466667,-8.2,2020-03-25,1000

And a Json file with the following structure:

{"type":"FeatureCollection", "features": [ {"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-8.163874,39.626553],[-8.164286,39.626686],[-8.165384,39.626633],*(more coordinates' pairs)*,[-8.163874,39.626553]]]},"properties":{"cartodb_id":225,"id_2":225,"id_1":16,"id_0":182,"varname_2":null,"nl_name_2":null,"engtype_2":"Municipality","type_2":"Concelho","name_2":"Abrantes","name_1":"Santarém","name_0":"Portugal","iso":"PRT","split_id":"1"}} ]}

Both the CSV and the json file here are part of a larger set but this will do as an example

My code is as follows

import json
with open('abrantes.json') as json_file:
    abr = json.load(json_file)

import pandas as pd

df = pd.read_csv("abrantes.csv")

import plotly.express as px

fig = px.choropleth(df, geojson=abr, locations='cardodb_id', color='INC',
                           color_continuous_scale="Viridis",
                           range_color=(0, 5000),
                           labels={'INC':'Incidência'}
                          )

fig.show()

The end result is an empty map with the scale from 0 to 5000 on the right side, when I was expecting the polygon to be filled with the color correspondent to "INC", i.e., "1000".

What am I doing wrong? Thank you in advance for all the help you can provide.


Solution

  • To draw a map, px.choropleth() must match IDs of your dataframe with IDs of your GeoJSON. With the parameter locations you specify the column with the IDs in your dataframe. What you are missing is the parameter featureidkey to specify the same IDs in the GeoJSON. Alternatively, you can omit featureidkey but then the features in your GeoJSON need a parameter id.

    Then you have to pay attention to spelling. Your csv file has a column cardodb_id, your GeoJSON a parameter cartodb_id.

    And since the polygon you provided is quite small, it is not visible on a world map. Thus, I recommend to add fig.update_geos(fitbounds="locations") to zoom the map to the area of interest.

    import json
    import pandas as pd
    import plotly.express as px
    
    with open('abrantes.json') as json_file:
        abr = json.load(json_file)
    
    df = pd.read_csv("abrantes.csv")
    
    fig = px.choropleth(df, geojson=abr, locations='cardodb_id', color='INC',
                               color_continuous_scale="Viridis",
                               featureidkey="properties.cartodb_id",
                               range_color=(0, 5000),
                               labels={'INC':'Incidência'}
                              )
    fig.update_geos(fitbounds="locations")                        
    fig.show()