We give two methods to plot polygons overlaying a mapbox map: the first one is based only on plotly.graph_objects and no other import. The second method involves pandas, geopandas, shapely, json and plotly.express.
Version 1: define each polygon as a mapbox layer, with a given color. The color is not a color corresponding to some value associated to the polygon, and mapped to a colorscale. It is just a color code associated to each polygon:
import plotly.graph_objs as go
def get_polygon(lons, lats, color='blue'):
if len(lons) != len(lats):
raise ValueError('the legth of longitude list must coincide with that of latitude')
geojd = {"type": "FeatureCollection"} #define a geojson type dictionary
geojd['features'] = []
coords = []
for lon, lat in zip(lons, lats):
coords.append((lon, lat))
coords.append((lons[0], lats[0])) #close the polygon
geojd['features'].append({ "type": "Feature",
"geometry": {"type": "Polygon",
"coordinates": [coords] }})
layer=dict(sourcetype = 'geojson',
source = geojd,
below='',
type = 'fill',
color = color)
return layer
#mapbox_t=open(".mapbox_token").read().rstrip() #must be read when using a mapbox style different from carto-positron
fig1 = go.Figure(go.Scattermapbox())# empty scattermapbox; here we are interested only in plotting some polygons
fig1.update_layout(autosize=True,
mapbox = dict(center=dict(lat=62.3833, lon=16.3000),
#accesstoken=mapbox_t,
zoom=4,
style='carto-positron',
),
width=700,
height=600,
title_text = 'Polygons over Sweden map',
title_x=0.5)
mylayers =[]
mylayers.append(get_polygon(lons=[14, 16, 16, 14], lats=[58.55, 58.55, 60.6, 60.6], color='gold'))
mylayers.append(get_polygon(lons=[15, 16., 16.85,], lats=[62, 64, 62.], color='silver'))
fig1.layout.update(mapbox_layers=mylayers)
fig1.show()
Version 2: define polygons via Choroplethmapbox and a dataframe with two columns: 'id' and a numerical column to be mapped to a colorscale. Needs many imports:
import geopandas as gpd
import pandas as pd
import shapely.geometry
from shapely.geometry import Polygon
import plotly.express as px
import json
p1 = Polygon([(14, 58.55), (16, 58.55), (16, 60.6), (14, 60.6)])
p2 = Polygon([(15, 62), (16.0, 64), (16.85, 62.0)])
geojs = gpd.GeoSeries([p1, p2]) #define a geojson dict containing the the two polygons
jdata = json.loads(geojs.to_json())
data = [[0,10],[1,4],[2,15]]
df = pd.DataFrame(data, columns = ['id','color'])
fig2 = px.choropleth_mapbox(df,
geojson=jdata,
locations='id',
color='color',
color_continuous_scale ='matter_r',
center= dict(lat=62.3833,
lon=16.3000),
zoom=4,
mapbox_style='carto-positron')
fig2.update_layout(autosize=True,
width=700,
height=600,
coloraxis_colorbar_thickness=25,
title_text = 'Polygons over Sweden map',
title_x=0.5)
fig2.show()
.