In [1]:
import geopandas as gpd
import pandas as pd
import folium
import branca
import requests
import json

from folium.features import GeoJson, GeoJsonTooltip, GeoJsonPopup

In [2]:
print(folium.__version__)


0.10.1+14.gc160388

In [3]:
income = pd.read_csv(r"https://raw.githubusercontent.com/pri-data/50-states/master/data/income-counties-states-national.csv", dtype={"fips":str})
income['income-2015'] = pd.to_numeric(income['income-2015'], errors='coerce')

In [4]:
income.head()


Out[4]:
fips county state income-2015 income-1989a income-1989b change
0 00000 US US 55775.0 28906 53367.28102 4.316843
1 01000 Alabama AL 44833.0 22202 40990.11877 8.571546
2 01001 Autauga County AL 56580.0 26898 49660.04030 12.230399
3 01003 Baldwin County AL 52387.0 24043 44389.03818 15.267074
4 01005 Barbour County AL 31433.0 18673 34474.75398 -9.676945

In [5]:
response = requests.get(r"https://raw.githubusercontent.com/python-visualization/folium/master/examples/data/us-states.json")
data = response.json()
states = gpd.GeoDataFrame.from_features(data, crs='EPSG:4326')

states.head()


Out[5]:
geometry name
0 POLYGON ((-87.35930 35.00118, -85.60667 34.984... Alabama
1 MULTIPOLYGON (((-131.60202 55.11798, -131.5691... Alaska
2 POLYGON ((-109.04250 37.00026, -109.04798 31.3... Arizona
3 POLYGON ((-94.47384 36.50186, -90.15254 36.496... Arkansas
4 POLYGON ((-123.23326 42.00619, -122.37885 42.0... California

In [6]:
response = requests.get('https://gist.githubusercontent.com/tvpmb/4734703/raw/b54d03154c339ed3047c66fefcece4727dfc931a/US%2520State%2520List')
abbrs = pd.read_json(response.text)

abbrs.head(3)


Out[6]:
name alpha-2
0 Alabama AL
1 Alaska AK
2 Arizona AZ

In [7]:
statesmerge = states.merge(abbrs, how='left', left_on='name', right_on='name')
statesmerge['geometry'] = statesmerge.geometry.simplify(.05)

statesmerge.head()


Out[7]:
geometry name alpha-2
0 POLYGON ((-87.35930 35.00118, -85.60667 34.984... Alabama AL
1 MULTIPOLYGON (((-131.60202 55.11798, -131.5691... Alaska AK
2 POLYGON ((-109.04250 37.00026, -109.04798 31.3... Arizona AZ
3 POLYGON ((-94.47384 36.50186, -90.15254 36.496... Arkansas AR
4 POLYGON ((-123.23326 42.00619, -120.00186 41.9... California CA

In [8]:
income.groupby(by="state")[['state','income-2015']].median().head()


Out[8]:
income-2015
state
AK 62561.5
AL 38721.5
AR 37890.0
AZ 43810.0
CA 53341.0

In [9]:
statesmerge['medianincome'] = statesmerge.merge(income.groupby(by="state")[['state','income-2015']].median(),
                                                how='left', left_on='alpha-2', right_on='state')['income-2015']
statesmerge['change'] = statesmerge.merge(income.groupby(by="state")[['state','change']].median(),
                                          how='left', left_on='alpha-2', right_on='state')['change']

In [10]:
statesmerge.head()


Out[10]:
geometry name alpha-2 medianincome change
0 POLYGON ((-87.35930 35.00118, -85.60667 34.984... Alabama AL 38721.5 2.779114
1 MULTIPOLYGON (((-131.60202 55.11798, -131.5691... Alaska AK 62561.5 14.758367
2 POLYGON ((-109.04250 37.00026, -109.04798 31.3... Arizona AZ 43810.0 NaN
3 POLYGON ((-94.47384 36.50186, -90.15254 36.496... Arkansas AR 37890.0 10.897394
4 POLYGON ((-123.23326 42.00619, -120.00186 41.9... California CA 53341.0 6.716596

In [11]:
statesmerge['medianincome'].quantile(0.25)


Out[11]:
43969.375

In [12]:
colormap = branca.colormap.LinearColormap(
    vmin=statesmerge['change'].quantile(0.0), 
    vmax=statesmerge['change'].quantile(1), 
    colors=['red','orange','lightblue','green','darkgreen'],
    caption="State Level Median County Household Income (%)",
)

In [13]:
m = folium.Map(location=[35.3, -97.6], zoom_start=4)

popup = GeoJsonPopup(
    fields=['name','change'],
    aliases=['State',"% Change"],
    localize=True,
    labels=True,
    style="background-color: yellow;",
)

tooltip = GeoJsonTooltip(
    fields=["name", "medianincome", "change"],
    aliases=["State:", "2015 Median Income(USD):", "Median % Change:"],
    localize=True,
    sticky=False,
    labels=True,
    style="""
        background-color: #F0EFEF;
        border: 2px solid black;
        border-radius: 3px;
        box-shadow: 3px;
    """,
    max_width=800,
)


g = folium.GeoJson(
    statesmerge,
    style_function=lambda x: {
        "fillColor": colormap(x["properties"]["change"])
        if x["properties"]["change"] is not None
        else "transparent",
        "color": "black",
        "fillOpacity": 0.4,
    },
    tooltip=tooltip,
    popup=popup
).add_to(m)

colormap.add_to(m)

m


Out[13]: