Build Your Own Strava Activity Map & Heatmap (No Premium Required)
by The Debunker in Outside > Sports
603 Views, 11 Favorites, 0 Comments
Build Your Own Strava Activity Map & Heatmap (No Premium Required)
Strava locks one of its most interesting features — viewing all your activities on a single map or heatmap — behind a premium subscription.
But here’s the thing:
your activity data already contains everything you need.
In this project, I’ll show you how to:
- Combine all your Strava activities into a single route map
- Generate a true heatmap showing where you spend the most time
- (Bonus) Create sport-specific heatmaps (cycling, walking, hiking, etc.)
All using:
- free tools
- your exported data
- no premium subscription
How It Works
Each Strava activity file (GPX) contains thousands of GPS points.
We:
- Combine GPX files to visualize routes
- Extract GPS coordinates
- Plot them into a heatmap
- Optionally filter by activity type
This turns raw GPS data into meaningful visual maps.
Supplies
Strava account
Computer
Internet connection
Strava data export (GPX files)
Google account (for Google Colab)
Request Your Strava Data
Log into Strava on desktop.
Go to:
Settings → My Account
Scroll down to:
Download or Delete Your Account
Click:
Get Started → Request Your Archive
Important:
You can only request your archive once per week.
Download and Extract Your Files
When your email arrives:
- Download the ZIP file
- Extract it into a folder
- Locate your activity files
- You should see .gpx files
- move all of the gpx files into thier own folder
Create Your Route Map
Go to:
👉 https://gpx-zone.com/combiner
Upload your GPX files.
Choose a map style you like and generate the map.
This creates a combined route map showing every path you’ve taken.
What this shows:
- exact trails
- repeated routes
- your real movement paths
Open Google Colab
Install Required Libraries
Paste this into the first cell:
!pip install gpxpy folium
Run it.
Upload Your GPX Files
Click "+Code"
Paste:
from google.colab import files
uploaded = files.upload()
Run and upload your GPX files.
Extract GPS Points + Detect Activity Type
Click "+Code"
Now we extract GPS data AND categorize activities.
Paste this:
import gpxpy
all_points = []
activity_points = {
"cycling": [],
"walking": [],
"running": [],
"other": []
}
for filename in uploaded.keys():
with open(filename, 'r') as gpx_file:
gpx = gpxpy.parse(gpx_file)
# Detect activity type from filename
name = filename.lower()
if "ride" in name or "cycling" in name or "bike" in name:
category = "cycling"
elif "walk" in name or "hike" in name:
category = "walking"
elif "run" in name:
category = "running"
else:
category = "other"
for track in gpx.tracks:
for segment in track.segments:
for point in segment.points:
coord = [point.latitude, point.longitude]
all_points.append(coord)
activity_points[category].append(coord)
print(f"Total points: {len(all_points)}")
print(f"Cycling points: {len(activity_points['cycling'])}")
print(f"Walking points: {len(activity_points['walking'])}")
print(f"Running points: {len(activity_points['running'])}")
What this does:
- extracts GPS coordinates
- groups them by activity type
- prepares data for multiple heatmaps
Create the Main Heatmap
Click "+Code"
Paste:
import folium
from folium.plugins import HeatMap
center = all_points[0]
m = folium.Map(
location=center,
zoom_start=13,
tiles="CartoDB dark_matter"
)
HeatMap(all_points, radius=8, blur=10).add_to(m)
m
What this shows:
- overall activity density
- your most-used areas
Save Your Maps
Click "+Code"
Save any map:
m.save("heatmap.html")
Click "+Code"
Download:
files.download("heatmap.html")
Create Sport-Specific Heatmaps (Bonus)
One of the coolest parts of this project is that Strava GPX files often include the activity type directly inside the file.
That means instead of guessing based on the filename, we can read the actual GPX data and separate points into categories like:
- cycling
- walking
- hiking
- running
This makes it possible to create separate heatmaps for different sports and compare where each activity tends to happen.
For example:
- cycling may cluster on roads or bike paths
- hiking may cluster on trails
- walking may stay around neighborhoods, parks, or attractions
Before creating the maps, I used this code to extract GPS points and sort them by activity type:
import gpxpy
all_points = []
activity_points = {
"cycling": [],
"walking": [],
"hiking": [],
"running": [],
"other": []
}
for filename in uploaded.keys():
with open(filename, "r", encoding="utf-8") as gpx_file:
gpx = gpxpy.parse(gpx_file)
category = "other"
for track in gpx.tracks:
track_type = (track.type or "").lower().strip()
track_name = (track.name or "").lower().strip()
if track_type == "cycling":
category = "cycling"
elif track_type == "walking":
category = "walking"
elif track_type == "hiking":
category = "hiking"
elif track_type == "running":
category = "running"
else:
# Fallback if <type> is missing
if "ride" in track_name or "bike" in track_name or "cycling" in track_name:
category = "cycling"
elif "walk" in track_name:
category = "walking"
elif "hike" in track_name:
category = "hiking"
elif "run" in track_name:
category = "running"
for segment in track.segments:
for point in segment.points:
coord = [point.latitude, point.longitude]
all_points.append(coord)
activity_points[category].append(coord)
print(f"Total points: {len(all_points)}")
print(f"Cycling points: {len(activity_points['cycling'])}")
print(f"Walking points: {len(activity_points['walking'])}")
print(f"Hiking points: {len(activity_points['hiking'])}")
print(f"Running points: {len(activity_points['running'])}")
print(f"Other points: {len(activity_points['other'])}")
To make the next steps more reliable, I also used a helper function that prevents errors if one category is empty:
def make_heatmap(points, center_point, title="Heatmap"):
if not points:
print(f"No points found for {title}")
return None
m = folium.Map(location=center_point, zoom_start=13, tiles="CartoDB dark_matter")
HeatMap(points, radius=8, blur=10).add_to(m)
return m
Cycling heatmap
m_cycle = make_heatmap(activity_points["cycling"], center, "Cycling")
m_cycle
Walking heatmap
m_walk = make_heatmap(activity_points["walking"], center, "Walking")
m_walk
Hiking heatmap
m_hike = make_heatmap(activity_points["hiking"], center, "Hiking")
m_hike
Running heatmap
m_run = make_heatmap(activity_points["running"], center, "Running")
m_run
Compare Your Results
Route Map
- exact paths
Heatmap
- activity density
What You Can Learn
This is where the project becomes meaningful.
You might notice:
- areas you visit repeatedly
- differences between walking and cycling
- unexpected hotspots
- unused areas
Troubleshooting
Map background not loading
Use:
tiles="CartoDB dark_matter"
instead of default tiles.
No data showing
- make sure GPX files contain tracks
- try different activities
Activity detection wrong
- depends on filename
- rename files if needed
Improvements
separate maps by date
weekday vs weekend maps
yearly maps
print as wall art