Last active
November 12, 2017 17:23
-
-
Save tyleha/c5ea21e2a4879fcc4151 to your computer and use it in GitHub Desktop.
Choropleth of Location history
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Check out the full post at http://beneathdata.com/how-to/visualizing-my-location-history/ | |
# to utilize the code below | |
# We'll only use a handful of distinct colors for our choropleth. So pick where | |
# you want your cutoffs to occur. Leave zero and ~infinity alone. | |
breaks = [0.] + [4., 24., 64., 135.] + [1e20] | |
def self_categorize(entry, breaks): | |
for i in range(len(breaks)-1): | |
if entry > breaks[i] and entry <= breaks[i+1]: | |
return i | |
return -1 | |
df_map['jenks_bins'] = df_map.hood_hours.apply(self_categorize, args=(breaks,)) | |
labels = ['Never been\nhere']+["> %d hours"%(perc) for perc in breaks[:-1]] | |
# Or, you could always use Natural_Breaks to calculate your breaks for you: | |
# from pysal.esda.mapclassify import Natural_Breaks | |
# breaks = Natural_Breaks(df_map[df_map['hood_hours'] > 0].hood_hours, initial=300, k=3) | |
# df_map['jenks_bins'] = -1 #default value if no data exists for this bin | |
# df_map['jenks_bins'][df_map.hood_count > 0] = breaks.yb | |
# | |
# jenks_labels = ['Never been here', "> 0 hours"]+["> %d hours"%(perc) for perc in breaks.bins[:-1]] | |
def custom_colorbar(cmap, ncolors, labels, **kwargs): | |
"""Create a custom, discretized colorbar with correctly formatted/aligned labels. | |
cmap: the matplotlib colormap object you plan on using for your graph | |
ncolors: (int) the number of discrete colors available | |
labels: the list of labels for the colorbar. Should be the same length as ncolors. | |
""" | |
from matplotlib.colors import BoundaryNorm | |
from matplotlib.cm import ScalarMappable | |
norm = BoundaryNorm(range(0, ncolors), cmap.N) | |
mappable = ScalarMappable(cmap=cmap, norm=norm) | |
mappable.set_array([]) | |
mappable.set_clim(-0.5, ncolors+0.5) | |
colorbar = plt.colorbar(mappable, **kwargs) | |
colorbar.set_ticks(np.linspace(0, ncolors, ncolors+1)+0.5) | |
colorbar.set_ticklabels(range(0, ncolors)) | |
colorbar.set_ticklabels(labels) | |
return colorbar | |
figwidth = 14 | |
fig = plt.figure(figsize=(figwidth, figwidth*h/w)) | |
ax = fig.add_subplot(111, axisbg='w', frame_on=False) | |
cmap = plt.get_cmap('Blues') | |
# draw neighborhoods with grey outlines | |
df_map['patches'] = df_map['poly'].map(lambda x: PolygonPatch(x, ec='#111111', lw=.8, alpha=1., zorder=4)) | |
pc = PatchCollection(df_map['patches'], match_original=True) | |
# apply our custom color values onto the patch collection | |
cmap_list = [cmap(val) for val in (df_map.jenks_bins.values - df_map.jenks_bins.values.min())/( | |
df_map.jenks_bins.values.max()-float(df_map.jenks_bins.values.min()))] | |
pc.set_facecolor(cmap_list) | |
ax.add_collection(pc) | |
#Draw a map scale | |
m.drawmapscale(coords[0] + 0.08, coords[1] + -0.01, | |
coords[0], coords[1], 10., | |
fontsize=16, barstyle='fancy', labelstyle='simple', | |
fillcolor1='w', fillcolor2='#555555', fontcolor='#555555', | |
zorder=5, ax=ax,) | |
# ncolors+1 because we're using a "zero-th" color | |
cbar = custom_colorbar(cmap, ncolors=len(jenks_labels)+1, labels=jenks_labels, shrink=0.5) | |
cbar.ax.tick_params(labelsize=16) | |
fig.suptitle("Time Spent in Seattle Neighborhoods", fontdict={'size':24, 'fontweight':'bold'}, y=0.92) | |
ax.set_title("Using location data collected from my Android phone via Google Takeout", fontsize=14, y=0.98) | |
qax.text(1.35, 0.04, "Collected from 2012-2014 on Android 4.2-4.4\nGeographic data provided by data.seattle.gov", | |
ha='right', color='#555555', style='italic', transform=ax.transAxes) | |
ax.text(1.35, 0.01, "BeneathData.com", color='#555555', fontsize=16, ha='right', transform=ax.transAxes) | |
plt.savefig('chloropleth.png', dpi=100, frameon=False, bbox_inches='tight', pad_inches=0.5, facecolor='#F2F2F2') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
line 66 fails as
jenks_labels
is not introduced yet.