<jupyter_start><jupyter_text>Geospatial Analysis with US Presidential Election Data Election data downloaded from the MIT Election Lab: https://electionlab.mit.edu/dataState Shape data downloaded from the US Census website: https://www.census.gov/geographies/mapping-files/time-series/geo/carto-boundary-file.html  import libraries<jupyter_code># download libraries to then use in google colab

# Important library for many geopython libraries
!apt install gdal-bin python-gdal python3-gdal
 
# Install rtree - Geopandas requirment
!apt install python3-rtree

# Install Geopandas
!pip install git+git://github.com/geopandas/geopandas.git

# Install descartes - Geopandas requirment
!pip install descartes 

# Install Folium for Geographic data visualization
!pip install folium

# Install mapclassify for geospatial data viz
!pip install mapclassify
# import libraries for data analysis
import pandas as pd

# for geo analysis
import geopandas as gpd
import mapclassify

# for data viz
import plotly.express as px
import matplotlib.pyplot as plt
%matplotlib inline

# to export files
from google.colab import files<jupyter_output><empty_output><jupyter_text>import data<jupyter_code># eleection data
df_election = pd.read_csv("https://raw.githubusercontent.com/jhu-business-analytics/geospatial-analysis-election-data/main/original_data_files/1976-2016-president.csv")
# preview
df_election.head()
# check data types
df_election.info()<jupyter_output><class 'pandas.core.frame.DataFrame'>
RangeIndex: 3740 entries, 0 to 3739
Data columns (total 14 columns):
 #   Column          Non-Null Count  Dtype  
---  ------          --------------  -----  
 0   year            3740 non-null   int64  
 1   state           3740 non-null   object 
 2   state_po        3740 non-null   object 
 3   state_fips      3740 non-null   int64  
 4   state_cen       3740 non-null   int64  
 5   state_ic        3740 non-null   int64  
 6   office          3740 non-null   object 
 7   candidate       3474 non-null   object 
 8   party           3404 non-null   object 
 9   writein         3740 non-null   bool   
 10  candidatevotes  3740 non-null   int64  
 11  totalvotes      3740 non-null   int64  
 12  version         3740 non-null   int64  
 13  notes           0 non-null      float64
dtypes: bool(1), float64(1), int64(7), object(5)
memory usage: 383.6+ KB<jupyter_text>__NOTE__: Before you can import the shapefile data, you'll need to manually upload the unzipped files from the US State Shapefile from the [US Census](https://www.census.gov/geographies/mapping-files/time-series/geo/carto-boundary-file.html) (the first file download under the __State__ header)<jupyter_code># import geospatial data
gdf_states = gpd.read_file("cb_2018_us_state_500k.shp")
gdf_states.head()
# look at info
gdf_states.info()<jupyter_output><class 'geopandas.geodataframe.GeoDataFrame'>
RangeIndex: 56 entries, 0 to 55
Data columns (total 10 columns):
 #   Column    Non-Null Count  Dtype   
---  ------    --------------  -----   
 0   STATEFP   56 non-null     object  
 1   STATENS   56 non-null     object  
 2   AFFGEOID  56 non-null     object  
 3   GEOID     56 non-null     object  
 4   STUSPS    56 non-null     object  
 5   NAME      56 non-null     object  
 6   LSAD      56 non-null     object  
 7   ALAND     56 non-null     int64   
 8   AWATER    56 non-null     int64   
 9   geometry  56 non-null     geometry
dtypes: geometry(1), int64(2), object(7)
memory usage: 4.5+ KB<jupyter_text>Merge State Polygon Shape Data onto the Election Data<jupyter_code># convert geo df fips column into an interger so we can merge later
gdf_states["STATEFP"] = gdf_states["STATEFP"].astype(int)
# creating a new gdf of polygon and election data
# merge state data onto the elction data on the column contining the fips code
gdf_election = gdf_states.merge(df_election,
                                how = "right",
                                left_on = "STATEFP",
                                right_on = "state_fips")
gdf_election.head()
# create a new column that is the percent of votes for each party
gdf_election["percent_votes"] = (gdf_election["candidatevotes"]/gdf_election["totalvotes"])*100<jupyter_output><empty_output><jupyter_text>2016 US State Election Maps  data cleaning<jupyter_code># create gdf of only 2016 and one party to make easier for data viz
gdf_election_2016 = gdf_election[(gdf_election["year"] == 2016) & (gdf_election["party"] == "republican")]
# preview the data
gdf_election_2016.head()<jupyter_output><empty_output><jupyter_text>create a map with geopandas<jupyter_code># choropleth maps

# define the figure and the legend
fig, ax = plt.subplots(figsize= (50, 10))

# plot with gdf
gdf_election_2016.plot(column = "percent_votes",
                       ax = ax,
                       legend = True,
                       cmap = "hot",
                       scheme = "User_Defined",
                       classification_kwds = dict(bins = [10, 20, 30, 40, 50, 60, 70,80,90,100]))

# add a title
plt.title("Distribution of Dem/Rep Votes in US Presidential Election, 2016")<jupyter_output><empty_output><jupyter_text>create a map with plotly express<jupyter_code># make a choropleth with plotly express

choropleth_election_2016 = px.choropleth(gdf_election_2016,
                                         locationmode = "USA-states",
                                         locations = "state_po",
                                         color = "percent_votes",
                                         color_continuous_scale = [(0, "blue"), (0.5, "purple"), (1, "red")],
                                         range_color = (0, 100),
                                         labels = {"state_po": "State", "percent_votes": "Percent Republican Votes"})
choropleth_election_2016.update_layout(geo_scope = "usa",
                                       title = "Distribution of Dem/Rep Votes in US Presidential Election, 2016")<jupyter_output><empty_output><jupyter_text>Choropleth Animation with Plotly Express<jupyter_code># preview gdf of election data
gdf_election.head()
# filter the data to include only republican votes
gdf_election_rep = gdf_election[gdf_election["party"] == "republican"]
#preview data
gdf_election_rep.head()
# make a choropleth with plotly express

choropleth_election_animation = px.choropleth(gdf_election_rep,
                                         locationmode = "USA-states",
                                         locations = "state_po",
                                         color = "percent_votes",
                                         color_continuous_scale = [(0, "blue"), (0.5, "purple"), (1, "red")],
                                         range_color = (0, 100),
                                         labels = {"state_po": "State", "percent_votes": "Percent Republican Votes"},
                                         animation_frame = "year")

choropleth_election_animation.update_layout(geo_scope = "usa",
                                       title = "Distribution of Dem/Rep Votes in US Presidential Election, 1976-2016")<jupyter_output><empty_output><jupyter_text>export the animation as a html file<jupyter_code># save as an html to share animation
choropleth_election_animation.write_html("chroropleth_us_prez_election_animation.html")
# download the file from google colab
files.download("chroropleth_us_prez_election_animation.html")<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.0871313672922252, 'fraction_numerical': 0.036327077747989274, 'mean_word_length': 2.5613365155131267, 'pattern_counts': {'":': 4, '<': 37, '<?xml version=': 0, '>': 37, 'https://': 4, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 36, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '434361', 'license': 'MIT', 'n_tokens_mistral': 2425, 'n_tokens_neox': 2169, 'n_words': 631, 'path': '12_05_2020_geospatial_analysis_us_elections_melanieshimano.ipynb', 'repo_name': 'melanieshimano/geospatial-analysis-election-data', 'size': '7460'}