Labeled and interactive maps in Python
Setup
# Load libraries
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.style.use('ggplot')
#plt.style.use('fivethirtyeight')
import seaborn as sns
#sns.set_style('darkgrid')
#sns.set_style('whitegrid')
#sns.set_style('white')
import geopandas as gpd
import plotly.express as px
import pyproj
# Import a .zip file containing spatial files and data
#! wget http://www2.census.gov/geo/tiger/GENZ2015/shp/cb_2015_us_county_20m.zip
#! unzip cb_2015_us_county_20m.zip
Import data
c = gpd.read_file("http://www2.census.gov/geo/tiger/GENZ2015/shp/cb_2015_us_county_20m.zip")
#c = gpd.read_file("cb_2015_us_county_20m.shp")
c = c.loc[c['GEOID'].isin(['26161','26093','26049','26091','26075','26125','26163','26099','26115','26065'])]
c['awl'] = c['AWATER']/c['ALAND']
c
c.plot('awl');
fig, ax = plt.subplots(figsize=(6,4))
c.plot(column="awl", scheme='NaturalBreaks', k=5, cmap='coolwarm', legend=True, ax=ax, legend_kwds={'bbox_to_anchor':(1.45, 0.37)})
plt.title('Spatial distribution of awl \n ')
plt.tight_layout()
#ax.axis("off")
#plt.savefig('myMap.png',dpi=150, bbox_inches='tight')
plt.show()
Labeled static map
c['coords'] = c['geometry'].apply(lambda x: x.representative_point().coords[:])
c['coords'] = [coords[0] for coords in c['coords']]
fig, ax = plt.subplots(figsize=(6,4))
c.plot(column="awl", scheme='NaturalBreaks', k=5, cmap='coolwarm', legend=True, ax=ax, legend_kwds={'bbox_to_anchor':(1.45, 0.37)})
texts =[ax.text(row.coords[0], row.coords[1], s=row["NAME"], horizontalalignment='center') for idx, row in c.iterrows()]
plt.title('Spatial distribution of awl \n ')
plt.tight_layout()
#ax.axis("off")
#plt.savefig('myMap.png',dpi=150, bbox_inches='tight')
plt.show()
fig, ax = plt.subplots(figsize=(6,4))
c.plot(column="awl", scheme='NaturalBreaks', k=5, cmap='coolwarm', legend=True, ax=ax, legend_kwds={'bbox_to_anchor':(1.45, 0.37)})
texts =[ax.text(row.coords[0], row.coords[1], s=row["NAME"], horizontalalignment='center', bbox={'facecolor': 'white', 'alpha':0.8, 'pad': 2, 'edgecolor':'none'}) for idx, row in c.iterrows()]
plt.title('Spatial distribution of awl \n ')
plt.tight_layout()
#ax.axis("off")
#plt.savefig('myMap.png',dpi=150, bbox_inches='tight')
plt.show()
Add selected labels
# Replace/elimante the following names
c['NameSelected'] = c['NAME']
c['NameSelected'] = c['NameSelected'].str.replace('Livingston','')
c['NameSelected'] = c['NameSelected'].str.replace('Jackson','')
c['NameSelected'] = c['NameSelected'].str.replace('Genesee','')
c['NameSelected'] = c['NameSelected'].str.replace('Oakland','')
c
fig, ax = plt.subplots(figsize=(6,4))
c.plot(column="awl", scheme='NaturalBreaks', k=5, cmap='coolwarm', legend=True, ax=ax, legend_kwds={'bbox_to_anchor':(1.45, 0.37)})
texts =[ax.text(row.coords[0], row.coords[1], s=row["NameSelected"], horizontalalignment='center', bbox={'facecolor': 'white', 'alpha':0.8, 'pad': 2, 'edgecolor':'none'}) for idx, row in c.iterrows()]
plt.title('Spatial distribution of awl \n ')
plt.tight_layout()
#ax.axis("off")
#plt.savefig('myMap.png',dpi=150, bbox_inches='tight')
plt.show()
# Create dataframe of selected regions
selected_regions = ['Livingston', 'Jackson', 'Genesee', 'Oakland']
c_selected = c.loc[c['NAME'].isin(selected_regions)]
c_selected = c_selected[['GEOID', 'NAME']]
c_selected['Selected_Name'] = c_selected['NAME']
c_selected.drop('NAME', axis = 1, inplace = True)
c_selected
c = c.merge(c_selected, on='GEOID', how='left')
c['Selected_Name'] = c['Selected_Name'].fillna('')
c
fig, ax = plt.subplots(figsize=(6,4))
c.plot(column="awl", scheme='NaturalBreaks', k=5, cmap='coolwarm', legend=True, ax=ax, legend_kwds={'bbox_to_anchor':(1.45, 0.37)})
texts =[ax.text(row.coords[0], row.coords[1], s=row["Selected_Name"], horizontalalignment='center', bbox={'facecolor': 'white', 'alpha':0.8, 'pad': 2, 'edgecolor':'none'}) for idx, row in c.iterrows()]
plt.title('Spatial distribution of awl \n ')
plt.tight_layout()
#ax.axis("off")
#plt.savefig('myMap.png',dpi=150, bbox_inches='tight')
plt.show()
Add repelling labels
# Install the adjustText package
#!pip install https://github.com/Phlya/adjustText/archive/master.zip
# Ref: https://github.com/Phlya/adjustText/blob/master/docs/source/Examples.ipynb
from adjustText import adjust_text
c.reset_index(level=0, inplace=True)
c
fig, ax = plt.subplots(figsize=(6,4))
c.plot(column="awl", scheme='NaturalBreaks', k=5, cmap='coolwarm', legend=True, ax=ax, legend_kwds={'bbox_to_anchor':(1.45, 0.37)})
texts =[ax.text(row.coords[0], row.coords[1], s=row["NAME"], horizontalalignment='center', bbox={'facecolor': 'white', 'alpha':0.8, 'pad': 2, 'edgecolor':'none'}) for idx, row in c.iterrows()]
adjust_text(texts, ax=ax)
plt.title('Spatial distribution of awl \n ')
plt.tight_layout()
#ax.axis("off")
#plt.savefig('myMap.png',dpi=150, bbox_inches='tight')
plt.show()
fig, ax = plt.subplots(figsize=(6,4))
c.plot(column="awl", scheme='NaturalBreaks', k=5, cmap='coolwarm', legend=True, ax=ax, legend_kwds={'bbox_to_anchor':(1.45, 0.37)})
texts =[ax.text(row.coords[0], row.coords[1], s=row["NAME"], bbox={'facecolor': 'white', 'alpha':0.8, 'pad': 2, 'edgecolor':'none'}) for idx, row in c.iterrows()]
adjust_text(texts, ax=ax)
plt.title('Spatial distribution of awl \n ')
plt.tight_layout()
#ax.axis("off")
#plt.savefig('myMap.png',dpi=150, bbox_inches='tight')
plt.show()
Interactive maps
Using plotly
fig = px.choropleth(c, geojson=c.geometry, locations=c.index, color="awl")
fig.update_geos(fitbounds="locations", visible=False)
fig.show()
c.set_index("NAME", inplace=True)
fig = px.choropleth(c, geojson=c.geometry, locations=c.index, projection="mercator", color="awl")
fig.update_geos(fitbounds="locations", visible=False)
fig.show()
Using leaflet (via Geopandas)
c.explore()
c.explore(column='awl')
c.explore(
column='awl',
tooltip=['NAME', 'AWATER', 'ALAND'],
scheme='naturalbreaks',
cmap='Spectral',
legend=True,
tiles='Stamen Terrain',
style_kwds =dict(color="gray", weight=0.5),
legend_kwds=dict(colorbar=False)
)