The decisions of when and how to upload this data are entirely obfuscated to the end user, but as you'll see below, Android appears to upload a GPS location every 60 seconds. That's plenty of data to work with.

Google Takeout is a Google service that allows users to export any personal Google data. We'll use Takeout to download our raw location history as a one-time snapshot. Since Latitude was retired, no API exists to access location history in real-time.

The data will be in a json format, which works great for us. Download it in your favorite compression type.

When Google has finished creating your archive, you'll get an email notification and a link to download.

Download and unzip the file, and you should be looking at a LocationHistory.json file. Working with location data in Pandas. Pandas is an incredibly powerful tool that simplifies working with complex datatypes and performing statistical analysis in the style of R. Chris Albon has great primers on using Pandas here under the "Data Wrangling" section.

If you use Anaconda to manage your Python packages, I recommend creating a virtual environment with anaconda to install the dependencies. Copying the lines below the instruction into the terminal creates the environment, requirements.txt, etc.

withopen('data/LocationHistory/2018/LocationHistory.json','r')aslocation_file:raw=json.loads(location_file.read())# use location_data as an abbreviation for location datalocation_data=pd.DataFrame(raw['locations'])delraw#free up some memory# convert to typical unitslocation_data['latitudeE7']=location_data['latitudeE7']/float(1e7)location_data['longitudeE7']=location_data['longitudeE7']/float(1e7)# convert timestampMs to secondslocation_data['timestampMs']=location_data['timestampMs'].map(lambdax:float(x)/1000)location_data['datetime']=location_data.timestampMs.map(datetime.datetime.fromtimestamp)# Rename fields based on the conversionslocation_data.rename(columns={'latitudeE7':'latitude','longitudeE7':'longitude','timestampMs':'timestamp'},inplace=True)# Ignore locations with accuracy estimates over 1000mlocation_data=location_data[location_data.accuracy<1000]location_data.reset_index(drop=True,inplace=True)

First up, you'll need to download shapefile data for the part of the world you're interested in plotting. I wanted to focus on my current home of Seattle, which like many cities provides city shapefile map data for free. It's even broken into city neighborhoods! The US Census Bureau provides a ton of national shapefiles here. Your city likely provides this kind of data too. Tom MacWright has GIS with Python, Shapely, and Fiona overview for more detail on Python mapping with these tools

Next, we'll need to import the Shapefile data we downloaded from the data.seattle.gov link above

The first step is to pare down your location history to only contain points within the map's borders.

In [7]:

# set up a map dataframedf_map=pd.DataFrame({'poly':[Polygon(hood_points)forhood_pointsinm.seattle],'name':[hood['S_HOOD']forhoodinm.seattle_info]})# Convert our latitude and longitude into Basemap cartesian map coordinatesmapped_points=[Point(m(mapped_x,mapped_y))formapped_x,mapped_yinzip(location_data['longitude'],location_data['latitude'])]all_points=MultiPoint(mapped_points)# Use prep to optimize polygons for faster computationhood_polygons=(MultiPolygon(list(df_map['poly'].values)))prepared_polygons=prep(hood_polygons)# Filter out the points that do not fall within the map we're makingcity_points_filter=filter(prepared_polygons.contains,all_points)city_points_list=list(city_points_filter)