Black Lives Matter. Please consider donating to Black Girls Code today.

Choropleth maps with custom geojson

Based on several threads here and elsewhere I think I have almost strung together an example of plotting a Choropleth map with custom geojson. Code runs, and the color bar reflects the fact that the data ranges from 4 – 15, but there are no polygons drawn.

This link

Tips to get a right geojson dict

Says there may be an issue with the ID, I have chased that thread and not found anything obvious

import geopandas as gpd
import pandas as pd
import shapely.geometry
from shapely.geometry import Polygon
import json

import plotly.graph_objects as go

p1 = Polygon([(0, 0), (1, 0), (1, 1)])
p2 = Polygon([(0, 0), (1, 0), (1, 1), (0, 1)])
p3 = Polygon([(2, 0), (3, 0), (3, 1), (2, 1)])

g = gpd.GeoSeries([p1, p2, p3])

poly_json = g.to_json()

data = [[0,10],[1,4],[2,15]]
df = pd.DataFrame(data, columns = ['id','color'])

fig = go.Figure(data = go.Choropleth(
    geojson=poly_json,
    locations=df['id'].astype(str),
    z = df['color'].astype(float)
))
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
fig.layout.template= None
fig.show()

Thanks in advance.

Hi @BrianWalsh

Welcome to Plotly forum!!!

First a few comments:

  • you must set your mapbox token within the dict fig.layout.mapbox.
    To get it you need a Mapbox account. From that account you’ll get a public Mapbox Access Token.
  • your conversion, g.to_json(), yields a string, not a dict:
'{"type": "FeatureCollection", "features": [{"id": "0", "type": "Feature", "properties": {}, "geometry": {"type": "Polygon", "coordinates": [[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]]]}, "bbox": [0.0, 0.0, 1.0, 1.0]}, {"id": "1", "type": "Feature", "properties": {}, "geometry": {"type": "Polygon", "coordinates": [[[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0], [0.0, 0.0]]]}, "bbox": [0.0, 0.0, 1.0, 1.0]}, {"id": "2", "type": "Feature", "properties": {}, "geometry": {"type": "Polygon", "coordinates": [[[2.0, 0.0], [3.0, 0.0], [3.0, 1.0], [2.0, 1.0], [2.0, 0.0]]]}, "bbox": [2.0, 0.0, 3.0, 1.0]}], "bbox": [0.0, 0.0, 3.0, 1.0]}'

To convert this string to a geojson type dict, define:

poly_json = json.loads(g.to_json())
  • go.Chroplethmapbox plots your polygons on a map in a region on the globe around the longitude and latitude read from your polygon coordinates:
import geopandas as gpd
import pandas as pd
import shapely.geometry
from shapely.geometry import Polygon
import json

import plotly.graph_objects as go
mapboxt = open(".mapbox_token").read().rstrip() #my mapbox_access_token 

p1 = Polygon([(0, 0), (1, 0), (1, 1)])
p2 = Polygon([(0, 0), (1, 0), (1, 1), (0, 1)])
p3 = Polygon([(2, 0), (3, 0), (3, 1), (2, 1)])

g = gpd.GeoSeries([p1, p2, p3])

poly_json = json.loads(g.to_json())

data = [[0,10],[1,4],[2,15]]
df = pd.DataFrame(data, columns = ['id','color'])

fig = go.Figure(data=[go.Choroplethmapbox(
                                    geojson=poly_json,
                                    colorscale='matter_r',
                                    locations=df['id'].astype(str),
                                    z = df['color'].astype(float))])

fig.update_layout(width=1000, height=800,
                  mapbox = dict(center= dict(lat=1.5, lon=1.5),  #lat=37, lon=-95          
                                 accesstoken= mapboxt,
                                 zoom=2.5,
                                 style='light'
                               ))
fig.show()

I suspect that you wanted only to plot some filled Shapely polygons, but not located on a map. If this is a case then Choroplethmapbox is not the right choice for this purpose.

@empet,

Thank your for the quick response, and this does work but… You guessed correctly. I am trying to repurpose the choropleth / Choroplethmapbox to plot a set of arbitrary polygons. Coming from a SAS background I was looking for the analog of their sgplot polygon procedure that has the ability to plot data against a predefined defined map.

I am still planning on poking around with this but, perhaps another tack I can explore is getting clever with plotly’s scatter or add_shape to replicate the same effect. I do want to stay in plotly because this will eventually be apart of a dash based dashboard.

Thanks!

1 Like