I’m trying to add a color bar for median income (per county) in a choropleth.
When I add a ColorBar to the below, I get the error:
TypeError: Object of type 'range' is not JSON serializable
When I remove the Color Bar code, the chart renders properly.
Any push in the right direction is appreciated.
My colorscl array looks like:
[[0, '#ffffe0'],
[1, '#fffddb'],
[2, '#fffad7'],
[3, '#fff7d1'],
[4, '#fff5cd']]
...
[[96, '#94010e'],
[97, '#91000a'],
[98, '#8e0006'],
[99, '#8b0000'],
[100, '#8b0000']]
The Code
import plotly.plotly as py
from plotly.graph_objs import *
import pandas as pd
def popup_text(row):
val = '''{0}<br>\
Total Profit: ${1:,.0f}<br>\
{2}, {3}<br>\
ShipToZip: {4}<br>\
CityPop: {5:,.0f}<br>\
CityGrowth: {6:.0%}<br>\
Density: {7:,.0f}<br>\
County Density: {8:,.0f}<br>\
Households: {9:,.0f}<br>\
AvgIncome: ${10:,.0f}<br>\
CountyAvgIncome: ${11:,.0f}<br>\
White: {12:.0%}<br>\
FEMA Disaster Count: {13:,.0f}<br>\
Bldg Valuation Growth: {14:.0%}'''.format(
row['Company'],
pd.to_numeric(row['Profit_sum'],errors='coerce'),
row['City'], row['State'], row['ShipToLocZip'],
row['CityPop2016'], row['CityPopGrowth'], row['Density'],
row['County_PopDensity'], row['Households'], row['AvgIncome'],
row['County_MedianHouseoldIncome'], row['PopulationRaceWhite'],
row['DisasterCount'], row['ValuationGrowth'])
return val.replace('\\','').strip()
def f(df, start_year, end_year, client_count, mytitle):
# Set range
df = df[df.OrderDate.dt.year.between(start_year, end_year)]
# Add Profit Total for Every Client
df['Profit_sum'] = df.groupby('Company')['Profit'].transform(sum)
df = df.sort_values(['Profit_sum', 'Company'], ascending=[False, False])
# Entire Sales History
plotly_df = df[[
'Company', 'ShipToLocZip', 'City', 'State', 'Population', 'Density',
'CityPop2016', 'CityPopGrowth', 'AvgIncome',
'County_MedianHouseoldIncome', 'County_PopDensity', 'DisasterCount',
'ValuationGrowth', 'PopulationRaceWhite', 'Households', 'Latitude',
'Longitude', 'Profit_sum'
]]
# plotly_df.head(1)
plotly_df['Text'] = plotly_df.apply(lambda row: popup_text(row), axis=1)
# 20 best clients
bestclient_df = (plotly_df.groupby('Company').agg({
'Profit_sum':
'min',
'Latitude':
lambda x: x.value_counts().index[0],
'Longitude':
lambda x: x.value_counts().index[0],
'Text':
'min'
}).reset_index().sort_values('Profit_sum',
ascending=False)[0:client_count])
# bestclient_df.head(1)
data = graph_objs.Data([
# All Sales
Scattermapbox(
lat=list(plotly_df.Latitude),
lon=list(plotly_df.Longitude),
mode='markers',
marker=Marker(
size=4,
#color=colors,
opacity=0.7),
text=list(plotly_df.Text),
hoverinfo='text',
showlegend=False),
# Best Clients
Scattermapbox(
lat=list(bestclient_df.Latitude),
lon=list(bestclient_df.Longitude),
mode='markers',
marker=Marker(size=12, color='rgb(50, 255, 100)', opacity=0.8),
text=list(bestclient_df.Text),
hoverinfo='text',
showlegend=False),
# Color Bar for Census Data
Scattermapbox(
lat = [0],
lon = [0],
marker = graph_objs.Marker(
cmax=100,
cmin=0,
colorscale = colorscl,
showscale = True,
autocolorscale=False,
color=range(0,101),
colorbar= graph_objs.ColorBar(len = .89)
),
mode = 'markers')
])
layout = graph_objs.Layout(
title= '{0} and {1} Best Clients ({2}-{3})'.format(
mytitle, client_count, start_year, end_year),
autosize=True,
hovermode='closest',
mapbox=dict(
layers=[
dict(sourcetype = 'geojson',
source =sources[k],
below="water",
type = 'fill',
color = sources[k]['features'][0]['properties']['Color'],
opacity=0.5,
) for k in range(len(sources))
],
accesstoken=MAPBOX_API_KEY,
bearing=0,
center=dict(lat=38, lon=-94),
pitch=0,
zoom=3.6,
style='light'
)
)
fig = dict(data=data, layout=layout)
return py.iplot(fig, filename='Affinity Sales')
f(af_df, start_year=2013, end_year=2016, client_count=30, mytitle='Sales over Median Income')`
Error Dump
TypeError Traceback (most recent call last)
<ipython-input-229-73b59cacc0ad> in <module>()
137 # profit_df= pd.read_pickle(url)
138 # profit_df.columns
--> 139 f(af_df, start_year=2013, end_year=2016, client_count=30, mytitle='Sales over Median Income')
<ipython-input-229-73b59cacc0ad> in f(df, start_year, end_year, client_count, mytitle)
131 # image_filename='MytestwithColorBar')
132
--> 133 return py.iplot(fig, filename='Affinity Sales')
134
135
//anaconda/envs/OSMNX/lib/python3.6/site-packages/plotly/plotly/plotly.py in iplot(figure_or_data, **plot_options)
133 if 'auto_open' not in plot_options:
134 plot_options['auto_open'] = False
--> 135 url = plot(figure_or_data, **plot_options)
136
137 if isinstance(figure_or_data, dict):
//anaconda/envs/OSMNX/lib/python3.6/site-packages/plotly/plotly/plotly.py in plot(figure_or_data, validate, **plot_options)
226 data = fig.get('data', [])
227 plot_options['layout'] = fig.get('layout', {})
--> 228 response = v1.clientresp(data, **plot_options)
229
230 # Check if the url needs a secret key
//anaconda/envs/OSMNX/lib/python3.6/site-packages/plotly/api/v1/clientresp.py in clientresp(data, **kwargs)
27 payload = {
28 'platform': 'python', 'version': version.__version__,
---> 29 'args': _json.dumps(data, **dumps_kwargs),
30 'un': creds['username'], 'key': creds['api_key'], 'origin': 'plot',
31 'kwargs': _json.dumps(kwargs, **dumps_kwargs)
//anaconda/envs/OSMNX/lib/python3.6/json/__init__.py in dumps(obj, skipkeys, ensure_ascii, check_circular, allow_nan, cls, indent, separators, default, sort_keys, **kw)
236 check_circular=check_circular, allow_nan=allow_nan, indent=indent,
237 separators=separators, default=default, sort_keys=sort_keys,
--> 238 **kw).encode(obj)
239
240
//anaconda/envs/OSMNX/lib/python3.6/site-packages/plotly/utils.py in encode(self, o)
134
135 # this will raise errors in a normal-expected way
--> 136 encoded_o = super(PlotlyJSONEncoder, self).encode(o)
137
138 # now:
//anaconda/envs/OSMNX/lib/python3.6/json/encoder.py in encode(self, o)
197 # exceptions aren't as detailed. The list call should be roughly
198 # equivalent to the PySequence_Fast that ''.join() would do.
--> 199 chunks = self.iterencode(o, _one_shot=True)
200 if not isinstance(chunks, (list, tuple)):
201 chunks = list(chunks)
//anaconda/envs/OSMNX/lib/python3.6/json/encoder.py in iterencode(self, o, _one_shot)
255 self.key_separator, self.item_separator, self.sort_keys,
256 self.skipkeys, _one_shot)
--> 257 return _iterencode(o, 0)
258
259 def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
//anaconda/envs/OSMNX/lib/python3.6/site-packages/plotly/utils.py in default(self, obj)
202 except NotEncodable:
203 pass
--> 204 return _json.JSONEncoder.default(self, obj)
205
206 @staticmethod
//anaconda/envs/OSMNX/lib/python3.6/json/encoder.py in default(self, o)
178 """
179 raise TypeError("Object of type '%s' is not JSON serializable" %
--> 180 o.__class__.__name__)
181
182 def encode(self, o):
TypeError: Object of type 'range' is not JSON serializable