orca
orca copied to clipboard
chropleth map code used to work, now it doesn't
The code below worked fine two weeks ago. Meanwhile I've seen some Plotly updates via conda. Anyway, now the saved image is empty - it only has a color bar, but the map is missing. In Jupyter, however, the map is shown correctly.
No error messages anywhere.
Import this code in a Jupyter notebook on Windows:
#!/usr/bin/env python
# coding: utf-8
# In[1]:
import requests
import json
import os
import pandas as pd
import plotly.express as px
import copy
# get GeoJSON for counties
# https://eric.clst.org/tech/usgeojson/
geofile = 'gz_2010_us_050_00_5m.json'
geourl = 'https://eric.clst.org/assets/wiki/uploads/Stuff/' + geofile
if not os.path.exists(geofile):
req = requests.get(geourl)
with open(geofile, 'wb') as f:
f.write(req.content)
with open(geofile) as f:
counties = json.load(f)
# add geo id field compatible with the data format
for c in counties['features']:
c['id'] = c['properties']['GEO_ID'][-5:]
#counties
# In[2]:
# get unemployment data
unempfile = 'fips-unemp-16.csv'
unempurl = 'https://raw.githubusercontent.com/plotly/datasets/master/' + unempfile
if not os.path.exists(unempfile):
req = requests.get(unempurl)
with open(unempfile, 'wb') as f:
f.write(req.content)
unemp = pd.read_csv(unempfile,
dtype={"fips": str})
#unemp
# In[3]:
# now look for missing FIPS codes in data, and backfill them in from GeoJSON
# data will be all 0 for the backfilled rows
# without this, the map has holes in it
allcodes = [c['id'] for c in counties['features']]
for c in allcodes:
if c not in unemp['fips'].tolist():
newrow = {}
newrow.update({'fips': c})
for col in unemp.columns.tolist()[1:]:
newrow.update({col: 0})
unemp = unemp.append(newrow, ignore_index=True)
# In[4]:
# get GeoJSON data for states
# https://eric.clst.org/tech/usgeojson/
geostatefile = 'gz_2010_us_040_00_5m.json'
geostateurl = 'https://eric.clst.org/assets/wiki/uploads/Stuff/' + geostatefile
if not os.path.exists(geostatefile):
req = requests.get(geostateurl)
with open(geostatefile, 'wb') as f:
f.write(req.content)
with open(geostatefile) as f:
jstates = json.load(f)
#jstates
# In[5]:
# convert states from Polygon to LineString
states = copy.deepcopy(jstates)
for k, feat in enumerate(jstates['features']):
if feat['geometry']['type']=='Polygon':
states['features'][k]['geometry']['type']='LineString'
states['features'][k]['geometry']['coordinates']=feat['geometry']['coordinates'][0]
elif feat['geometry']['type']=='MultiPolygon':
states['features'][k]['geometry']['type']='MultiLineString'
states['features'][k]['geometry']['coordinates']=[linea[0]
for linea in feat['geometry']['coordinates']]
else:
raise ValueError('geom-type is not polygon or multipolygon')
#states
# In[6]:
fig = px.choropleth_mapbox(unemp,
geojson=counties,
locations='fips',
color='unemp',
color_continuous_scale="Inferno",
center={'lat': 38.5, 'lon': -95.77 },
zoom=4.42,
mapbox_style='carto-positron',
)
fig.update_layout(
title_text='<b>US unemployment</b>',
title_y=0.97,
title_font_size=32,
width=1920,
height=1080,
coloraxis_colorbar = {
'tickmode': 'array',
# fake nonlinear scale, just for testing
'tickvals': [0, 5, 10, 15, 20, 25],
'ticktext': [0, 0.5, 1, 3, 10, 25],
'title': 'unemployment',
},
margin={"r":0,"t":0,"l":0,"b":0},
mapbox_layers = [dict(sourcetype = 'geojson',
source = states,
color='#ffffff',
type = 'line',
line=dict(width=1)
)]
)
fig.write_image('bigmap.png', scale=1.0)
fig.show()
# In[ ]: