From GPX to Heatmap

18 October, 2019

Hi :)
with this tutorial we’ll see how to convert GPX to a Heatmap using Python and some libraries.


From Strava GPX to an Heatmap

Download all your tracks from Strava

As reported in Strava’s Bulk export page:

  • Log into the account on from which you wish to bulk export data.
  • Hover over your name in the upper right-hand corner of the Strava page. Choose “Settings,” then find the “My Account” tab from the menu listed on the Left.
  • Select “Get Started” under “Download or Delete Your Account.”
  • Select “Request your archive” on the next page.
  • You will receive an email with a link to download your data (this may take a few hours.) For this reason, it’s important that you have access to the email account attached to your Strava profile.

Once you’ve downloaded the archive you should have a folder called “activities” and a csv “activities.csv”

Data elaboration

For the following elaboration, python and some libraries, as pandas , geopandas , togeojsontiles and matplotlib will be used

import os
import pandas as pd
import geopandas as gpd
import togeojsontiles
import matplotlib.pyplot as plt

Selection data of interest

os.chdir('YOUR PATH') # Move to the Strava directory
activities = pd.read_csv('./activities.csv')

Now you can visualize the top rows of activities with activities.head()

tabella data

If the abbreviation for the month of your activities is in a language different from english, you’ll have to set the local one

import locale
locale.setlocale(locale.LC_ALL, 'it_IT')

Now we have to convert the ‘Date of the activity’ (‘Data dell’attività’ in Italian) to a datatime format

activities['Data dell’attività'] = pd.to_datetime(activities['Data dell’attività'], errors='coerce', format='%d %b %Y, %H:%M:%S')

Set the data-frame you’re looking at and add other filter if you’re interested in

start_date = pd.to_datetime('10 giu 2018, 14:00:00', errors='coerce', format = '%d %b %Y, %H:%M:%S')
end_date = pd.to_datetime('20 lug 2018, 14:00:00', errors='coerce', format = '%d %b %Y, %H:%M:%S')

selected = activities[(activities['Data dell’attività'] > start_date) & (activities['Data dell’attività'] < end_date) & (activities['Tipo attività'] == 'Ciclismo')]

Convert the gpx to geojson

The new geojson files will be created in a new folder ‘geojson’

rows = len(selected.index)
indice = selected.index

newpath = './geojson/'
if not os.path.exists(newpath):

for i in range(rows):
    filename = './'+selected.loc[indice[i],'Nome del file']
    activity = filename.partition('s/')[-1].rpartition('.')[0] # Isolated activities name
    jsonname = './geojson/'+activity+'.geojson' #
    togeojsontiles.gpx_to_geojson(file_gpx=filename, file_geojson=jsonname)

List geojson files to open

list_gj = []
for (dirpath, dirnames, filenames) in os.walk('./geojson/'):

Managing projections

original = dict(ellps='WGS84', datum='WGS84', proj='longlat')
target = dict(ellps='WGS84', datum='WGS84', proj='utm', zone=32, units='km', no_defs=True) # edit zone if needed


fig, ax = plt.subplots(1, figsize=(12, 12))

for i in range(len(list_gj)):
    giro = gpd.read_file(list_gj[i])
    giro_series = gpd.GeoSeries(giro['geometry']) = original
    track = giro_series.to_crs(crs=target).plot(ax=ax, alpha=0.5) # You can change colors, trasparency, etc. here

I hope this tutorial can be useful.

Happy heatmapping ;)