Skip to content

Instantly share code, notes, and snippets.

@tyleha
Last active November 12, 2017 17:23
Show Gist options
  • Save tyleha/c5ea21e2a4879fcc4151 to your computer and use it in GitHub Desktop.
Save tyleha/c5ea21e2a4879fcc4151 to your computer and use it in GitHub Desktop.
Choropleth of Location history
# 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')
@hamdikavak
Copy link

I think line 71 should have been ax.text not qax.text

@hamdikavak
Copy link

line 66 fails as jenks_labels is not introduced yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment