Announcing Dash Bio 1.0.0 🎉 : a one-stop-shop for bioinformatics and drug development visualizations.

Empty cloropeth map with geojson file

I am trying to create a cloropleth map of provinces in the Netherlands, using a JSON file I download through an API (https://geodata.nationaalgeoregister.nl/).

The following code just gives me an empty map. I’ve been going through the documentation and some threads on here, but I cant seem to work it out. Does anyone know what the problem is?

After I get the map to draw I also want to fill it data from a dataframe, but first things first.

import urllib.request
import json
import plotly.express as px

geo_url = 'https://geodata.nationaalgeoregister.nl/cbsgebiedsindelingen/wfs?request=GetFeature&service=WFS&version=2.0.0&typeName=cbs_provincie_2017_gegeneraliseerd&outputFormat=json'

def read_geojson(url):
    with urllib.request.urlopen(url) as url:
        jdata = json.loads(url.read().decode())
    return jdata

jdata = read_geojson(geo_url) # keys are: dict_keys(['type', 'id', 'geometry', 'geometry_name', 'properties'])

fig = px.choropleth(geojson=jdata)
fig.show()

@thijmen

Mapbox cannot process your geojson data because its CRS (Coordinate Reference System) is different from that used at Mapbox.
For a geojson file that can be read by Mapbox, it should look like this one:

jdata['crs']={'type': 'name', 'properties': {'name': 'urn:ogc:def:crs:OGC:1.3:CRS84'}}

while your file has:

jdata['crs']={"type":"name","properties":{"name":"urn:ogc:def:crs:EPSG::28992"}}

These CRS codes do not say too much at the first sight, but there is another way to realise why your file does not encode mapbox readable data: the geographical coordinates in its geometry description are very big numbers, not just lon, and lat that take values in the interval (-180, 180], respectively in [-90, 90].

Hence you should find an online tool to convert the geojson file to one readable by Mapbox.

1 Like

Thanks so much @empet. I’ve converted the file to the appropriate CRS encoding and now the map is not empty anymore, but still not showing up correctly. Could there still be something wrong with the file or could there be some error in my code?

import json
import urllib.request
import plotly.express as px
import pandas as pd

# I converted above file (at https://mygeodata.cloud/converter/) and saved it on my github 
geo_url = 'https://raw.githubusercontent.com/Thijmen-data/geojson-data/main/web_provincie_geodata.geojson'

def read_geojson(url):
    with urllib.request.urlopen(url) as url:
        jdata = json.loads(url.read().decode())
    return jdata 

jdata = read_geojson(geo_url)

jdata['crs'] # {'type': 'name', 'properties': {'name': 'urn:ogc:def:crs:OGC:1.3:CRS84'}}: exactly as you said it should be
jdata['features'][0].keys() # dict_keys(['type', 'geometry_name', 'id', 'properties', 'geometry'])

# making a dataset where provincie will be the location key (corresponding to properties.statnaam) and counts the value used to fill
df = pd.DataFrame.from_dict({'provincie': ['Drenthe', 'Flevoland', 'Friesland', 'Gelderland', 'Groningen', 'Limburg', 'Noord-Brabant', 'Noord-Holland', 'Overijssel', 'Utrecht', 'Zeeland', 'Zuid-Holland'],
 'counts': [2, 20, 28, 154, 12, 71, 355, 125, 189, 58, 5, 123]})

fig = px.choropleth(df, geojson=jdata, color="counts",
                    locations="provincie", featureidkey="properties.statnaam",
                    projection="mercator"
                   )
fig.update_geos(fitbounds="locations", visible=False)
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
fig.show()

As you can see it is not showing up correctly. Only one province shows up and the rest is purple. The funny thing is the plotly hover functionality is working for the other provinces too. I’ve been spending so much time on this. Really appreciate your help.

Could you provide a link to the new geojson file?

Sorry, just uploaded it to my Github. I have edited my above post with code that downloads it from there.

Link is: https://raw.githubusercontent.com/Thijmen-data/geojson-data/main/web_provincie_geodata.geojson

Your code is good, but geojson file is corrupted (the coordinates of its geometry have been saved in a wrong format during conversion). I found out this geojson https://www.webuildinternet.com/articles/2015-07-19-geojson-data-of-the-netherlands/provinces.geojson that works.

You have only to change the DataFrame definition to:

df = pd.DataFrame.from_dict({'provincie': ['Drenthe', 'Flevoland', 'Friesland (Fryslân)', 'Gelderland', 'Groningen', 'Limburg', 'Noord-Brabant', 'Noord-Holland', 'Overijssel', 'Utrecht', 'Zeeland', 'Zuid-Holland'],
 'counts': [2, 20, 28, 154, 12, 71, 355, 125, 189, 58, 5, 123]})

because Friesland has two names.
One more change:

featureidkey="properties.name"

The link you’ve send works, but doesn’t show the internal borders correctly. I’ve converted the data with QGIS program and now i’ve got a working multipolyon GEOJSON file. Graph is looking sick.

Thanks for your help and showing me the problem was with the data file / conversion.