Issue
I have the geojson data about districts in Mauritius and I want to plot a choropleth map.
The properties of the geojson file are as follows:
{'id_0': 143, 'iso': 'MUS', 'name_0': 'Mauritius', 'id_1': 1, 'name_1': 'Agalega', 'hasc_1': 'MU.AG', 'ccn_1': 0, 'cca_1': None, 'type_1': 'Region', 'engtype_1': 'Region', 'nl_name_1': None, 'varname_1': None}
{'id_0': 143, 'iso': 'MUS', 'name_0': 'Mauritius', 'id_1': 2, 'name_1': 'Black River', 'hasc_1': 'MU.BL', 'ccn_1': 0, 'cca_1': None, 'type_1': 'District', 'engtype_1': 'District', 'nl_name_1': None, 'varname_1': None}
{'id_0': 143, 'iso': 'MUS', 'name_0': 'Mauritius', 'id_1': 3, 'name_1': 'Flacq', 'hasc_1': 'MU.FL', 'ccn_1': 0, 'cca_1': None, 'type_1': 'District', 'engtype_1': 'District', 'nl_name_1': None, 'varname_1': None}
{'id_0': 143, 'iso': 'MUS', 'name_0': 'Mauritius', 'id_1': 4, 'name_1': 'Grand Port', 'hasc_1': 'MU.GP', 'ccn_1': 0, 'cca_1': None, 'type_1': 'District', 'engtype_1': 'District', 'nl_name_1': None, 'varname_1': None}
{'id_0': 143, 'iso': 'MUS', 'name_0': 'Mauritius', 'id_1': 5, 'name_1': 'Moka', 'hasc_1': 'MU.MO', 'ccn_1': 0, 'cca_1': None, 'type_1': 'District', 'engtype_1': 'District', 'nl_name_1': None, 'varname_1': None}
{'id_0': 143, 'iso': 'MUS', 'name_0': 'Mauritius', 'id_1': 6, 'name_1': 'Pamplemousses', 'hasc_1': 'MU.PA', 'ccn_1': 0, 'cca_1': None, 'type_1': 'District', 'engtype_1': 'District', 'nl_name_1': None, 'varname_1': None}
{'id_0': 143, 'iso': 'MUS', 'name_0': 'Mauritius', 'id_1': 7, 'name_1': 'Plaines Wilhems', 'hasc_1': 'MU.PW', 'ccn_1': 0, 'cca_1': None, 'type_1': 'District', 'engtype_1': 'District', 'nl_name_1': None, 'varname_1': None}
{'id_0': 143, 'iso': 'MUS', 'name_0': 'Mauritius', 'id_1': 8, 'name_1': 'Port Louis', 'hasc_1': 'MU.PL', 'ccn_1': 0, 'cca_1': None, 'type_1': 'District', 'engtype_1': 'District', 'nl_name_1': None, 'varname_1': None}
{'id_0': 143, 'iso': 'MUS', 'name_0': 'Mauritius', 'id_1': 9, 'name_1': 'Riviere du Rempart', 'hasc_1': 'MU.RR', 'ccn_1': 0, 'cca_1': None, 'type_1': 'District', 'engtype_1': 'District', 'nl_name_1': None, 'varname_1': None}
{'id_0': 143, 'iso': 'MUS', 'name_0': 'Mauritius', 'id_1': 10, 'name_1': 'Rodrigues', 'hasc_1': 'MU.RO', 'ccn_1': 0, 'cca_1': None, 'type_1': 'Autonomous island', 'engtype_1': 'Autonomous island', 'nl_name_1': None, 'varname_1': 'Rodrigues'}
{'id_0': 143, 'iso': 'MUS', 'name_0': 'Mauritius', 'id_1': 11, 'name_1': 'Saint Brandon', 'hasc_1': 'MU.CC', 'ccn_1': 0, 'cca_1': None, 'type_1': 'Region', 'engtype_1': 'Region', 'nl_name_1': None, 'varname_1': 'Cargados Carajos)'}
{'id_0': 143, 'iso': 'MUS', 'name_0': 'Mauritius', 'id_1': 12, 'name_1': 'Savanne', 'hasc_1': 'MU.SA', 'ccn_1': 0, 'cca_1': None, 'type_1': 'District', 'engtype_1': 'District', 'nl_name_1': None, 'varname_1': None}
The data to be plotted is in a LocationJobCount.csv
file and tab is used as separator:
Location JobCount
0 Moka 55
1 Port Louis 45
2 Pamplemousses 13
3 Savanne 3
4 Riviere du Rempart 8
5 Black River 6
6 Plaines Wilhems 200
The location column contains the district names.
My code
"""
Python : 3.9.7
Plotly : 5.8.0
"""
import pandas as pd
import json
import plotly.express as px
districts = json.load(open("stanford-ph377fn8728-geojson.json", 'r'))
df = pd.read_csv("LocationJobCount.csv", sep='\t')
# map each location in dataframe to location in geojson
district_id_map = {}
for feature in districts['features']:
district_id_map[feature['properties']['name_1']] = feature['properties']['id_1']
df['id'] = df['Location'].apply(lambda x: district_id_map[x])
# create choropleth map
fig = px.choropleth(df, geojson=districts,
locations=df['id'],
color='JobCount',
color_continuous_scale="algae",
range_color=[0, max(df['JobCount'])],
labels={"Value": "Count"}
)
fig.update_layout(geo_scope="world", geo_resolution=50)
# fig.update_geos(fitbounds="locations", visible=False)
fig.show()
After mapping locations between geojson and source file, df
looks like this :
Location JobCount id
0 Moka 55 5
1 Port Louis 45 8
2 Pamplemousses 13 6
3 Savanne 3 12
4 Riviere du Rempart 8 9
5 Black River 6 2
6 Plaines Wilhems 200 7
Result
After I zoomed in to Mauritius I see this:
No district is seen.
What I tried
- Reference 1 : I read this post and ensured that the spelling of districts in the geojson file match that in the dataframe.
- Uncommenting
fig.update_geos(fitbounds="locations", visible=False)
outputs a white screen. - Reference2 : Adding
locationmode='country names'
as parameter does not do anything. - Reference 3 :
fig_map.update_layout(geo_scope="africa", geo_resolution=50)
does not work because the island Mauritius is not found in this scope.
My goal is to create something similar to this :
Solution
The problem in code is due to a wrong geojson object/data-file pairing.
Solution
In my case, I can directly pair the name_1
property in my GeoJSON file to the Location
column in my dataframe.
More info: https://plotly.com/python/choropleth-maps/#indexing-by-geojson-properties
import pandas as pd
import json
import plotly.express as px
import plotly.io as pio
pio.renderers.default = 'browser' # to show geojson map in web browser
districts = json.load(open("stanford-ph377fn8728-geojson.json", 'r'))
df = pd.read_csv("LocationJobCount.csv", sep='\t')
fig = px.choropleth(df, geojson = districts,
featureidkey='properties.name_1',
locations='Location', # column in dataframe which contains districts names
color='JobCount', # data from this column in dataframe is plotted
color_continuous_scale="algae",
)
fig.update_geos(fitbounds="locations")
fig.show()
This worked but some districts where JobCount
is 0 were missing from the map.
I modified my dataframe to include all districts and set 0 as default value :
Location JobCount
Black River 6
Flacq 0
Grand Port 0
Moka 60
Pamplemousses 17
Port Louis 53
Riviere du Rempart 10
Savanne 3
Plaines Wilhems 233
The choropleth map now works:
Answered By - creme332
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.