0
votes

I am using the Folium package to build a "Choropleth" map with python. The data that is displayed is pulled from an API that keeps track of the most recent Covid-19 infected rates per country. A column shared between the countries.geojson file (a json file of a world map) and the data that I pulled is the name of the country. Most of the countries are shaded in with color (successfully), while some of the countries are not identical and therefore is shaded with grey, for example "US" in the pandas dataframe and "United States of America" in the .geojson file doesnt match, and therefore doesn't display their data on the map.

covid_data = requests.get('https://covid2019-api.herokuapp.com/v2/current')
covid_data = covid_data.json()
covid_data = pd.DataFrame.from_dict(covid_data['data'])
location  confirmed  deaths  recovered  active
US     636350   28326      52096  555928
Spain     177644   18708      70853   88083

The way I'm storing the API data is within a pandas DataFrame, because it works best with Folium. My hacky way of transforming the data from the country names that arent identical is with the code: covid_data.location[covid_data.location=='US'] = 'United States of America'

By doing this, the country name is now the same on both the .geojson file and the DataFrame

location  confirmed  deaths  recovered  active
United States of America     636350   28326      52096  555928
Spain     177644   18708      70853   88083

is now the same as

{ "type": "Feature", "properties": { "ADMIN": "United States of America", "ISO_A3": "USA"} "geometry": {}}     (countries.geojson)

Before editing the dataframe, the map was rendered, but when US is changed to United States of America, it throws an error

return color_range[color_idx], fill_opacity IndexError: list index out of range

So that means that im setting the Choropleth threshold_scale to 636,360 (which is the highest # in the 'confirmed' column) but theres no data to match that # to. Therefore if I change the threshold_scale down to the next highest number, 177,644 (which is Italy) I get the error

ValueError: All values are expected to fall into one of the provided bins (or to be Nan). Please check > the bins parameter and/or your data.

Heres the rest of the code to help resolve this issue,

#this variable is to get the highest value of the rates as the max threshold used for coloring
covid_data_max = covid_data['confirmed'].max()
covid_data_max = covid_data_max.item()
world_geo = r'countries.geojson'
world_map = folium.Map(location=[4.68, 8.33],
                    tiles='Mapbox Bright', zoom_start=3)
world_map = folium.Choropleth(
    geo_data=world_geo,
    name='choropleth',
    data=covid_data,
    columns=['location','confirmed'],
    key_on='properties.ADMIN',
    threshold_scale = [0,int((covid_data_max/15)),int((covid_data_max/10)),int((covid_data_max/4)),covid_data_max],
    fill_color='BuPu',
    fill_opacity=0.7,
    line_opacity=0.2,
    legend_name='Number of deaths per country',
    highlight=True,
    line_color='black'
    ).add_to(world_map)

folium.LayerControl().add_to(world_map)
world_map.save(r'./templates/map.html')

You can see the image of the map (for some reason the threshold includes the USA #'s):

enter image description here

Let me know if theres anything else I can provide!

2
stackoverflow.com/questions/60815295/… This question is similar, and maybe I'm failing to convert the new location string to the same type as the .geojson ADMIN stringmlabenski
Please, provide the geojson file as well. Thanks.sentence
datahub.io/core/geo-countries @sentence thanks for your time reading my question!mlabenski

2 Answers

0
votes

So I was able to display the color by editing the json file before it was converted to a pandas frame. I would still love an explaination of why editing a pandasFrame directly doesnt work. Maybe it has something to do with the error

A value is trying to be set on a copy of a slice from a DataFrame

Therefore I coded a for loop that edits the specific country and changed it to "United States of America" to match the .geojson entry for "United States of America"

for data, values in covid_data.items():
    if data == 'data':
        for country in values:
            if country['location'] == 'US':
                country['location']='United States of America'
0
votes

As suggested by the error:

IndexError: list index out of range

the problem is in:

threshold_scale = [0,int((covid_data_max/15)),int((covid_data_max/10)),int((covid_data_max/4)),covid_data_max],

You can simply add 1 to covid_data_max:

threshold_scale = [0,int((covid_data_max/15)),int((covid_data_max/10)),int((covid_data_max/4)),covid_data_max+1],

and you get your map:

enter image description here

Please, note that threshold_scale parameter is now deprecated in favor of the bins parameter.