plotly / orca

Command line application for generating static images of interactive plotly charts
MIT License
293 stars 40 forks source link

chropleth map code used to work, now it doesn't #329

Open FlorinAndrei opened 4 years ago

FlorinAndrei commented 4 years ago

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[ ]: