import pandas as pd
from census import Census
import geopandas as gpd
import numpy as np
import plotly.io as pio
import plotly.express as px
pio.renderers.default='browser'
file_path = "Path"
# Load Census Median Age by District Data
c = Census("KEY")
district_df = c.acs1.state_congressional_district(['NAME', 'B01002_001E'], '*', '*')
district_df = pd.DataFrame(district_df)
district_df.rename(columns={'B01002_001E': 'median_age'},
inplace=True)
district_df['GEOID'] = district_df['state'] district_df['congressional district']
district_df.sort_values(by=['GEOID'], ascending=True)
district_df['id'] = np.arange(1,438)
# Import District Geojson
geojson_path = 'https://raw.githubusercontent.com/CivilServiceUSA/us-house/master/us-house/geojson/us-house.geojson'
geojson_file = gpd.read_file(geojson_path)
# Transformations
# Fill at-large districts nans with 0 to align with census
geojson_file[['district']] = geojson_file[['district']].fillna(value=0)
geojson_file['district'] = geojson_file.district.astype(float)
# drop congressional districts that have no voting power (State Number 98)
district_df['congressional district'] = district_df['congressional district'].astype(float)
# district_df = district_df.loc[district_df['state'] != 98]
# Create index state_name to inner join
new = district_df['NAME'].str.split(", ", n = 1, expand = True)
district_df['district_name'] = new[0]
district_df['state_name'] = new[1]
district_df.drop(columns = 'NAME', inplace = True)
# Inner Join
merged_data = pd.merge(district_df, geojson_file,
left_on=['state_name', 'congressional district'],
right_on=['state_name', 'district'])
# Plot
fig = px.choropleth(merged_data,
geojson=merged_data.geometry,
locations=merged_data.index,
color='median_age',
color_continuous_scale='Viridis',
scope='usa',
projection='mercator',
basemap_visible=True)
fig.update_geos(fitbounds="locations", visible=True)
fig.update_layout(title_text='Map')
fig.show()
When I run this code, I get the following error
Traceback:
Traceback (most recent call last):
File "/Users/colby/Desktop/Colby's Folder/Congressional Demo ETL Project/scripts/etl.py", line 81, in <module>
fig.show()
File "/Users/colby/opt/anaconda3/lib/python3.8/site-packages/plotly/basedatatypes.py", line 3398, in show
return pio.show(self, *args, **kwargs)
File "/Users/colby/opt/anaconda3/lib/python3.8/site-packages/plotly/io/_renderers.py", line 404, in show
renderers._perform_external_rendering(fig_dict, renderers_string=renderer, **kwargs)
File "/Users/colby/opt/anaconda3/lib/python3.8/site-packages/plotly/io/_renderers.py", line 341, in _perform_external_rendering
renderer.render(fig_dict)
File "/Users/colby/opt/anaconda3/lib/python3.8/site-packages/plotly/io/_base_renderers.py", line 747, in render
html = to_html(
File "/Users/colby/opt/anaconda3/lib/python3.8/site-packages/plotly/io/_html.py", line 141, in to_html
jdata = to_json_plotly(fig_dict.get("data", []))
File "/Users/colby/opt/anaconda3/lib/python3.8/site-packages/plotly/io/_json.py", line 124, in to_json_plotly
return json.dumps(plotly_object, cls=PlotlyJSONEncoder, **opts)
File "/Users/colby/opt/anaconda3/lib/python3.8/json/__init__.py", line 234, in dumps
return cls(
File "/Users/colby/opt/anaconda3/lib/python3.8/site-packages/_plotly_utils/utils.py", line 59, in encode
encoded_o = super(PlotlyJSONEncoder, self).encode(o)
File "/Users/colby/opt/anaconda3/lib/python3.8/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/Users/colby/opt/anaconda3/lib/python3.8/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "/Users/colby/opt/anaconda3/lib/python3.8/site-packages/_plotly_utils/utils.py", line 136, in default
return _json.JSONEncoder.default(self, obj)
File "/Users/colby/opt/anaconda3/lib/python3.8/json/encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type MultiPolygon is not JSON serializable
Solutions that I have tried:
1: I have also tried using geojson=geometry and locations=index based on the