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)

Activity Maps Cover.png
Screenshot 2026-04-14 092157.png
Screenshot 2026-04-14 113722.png

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:

  1. Combine all your Strava activities into a single route map
  2. Generate a true heatmap showing where you spend the most time
  3. (Bonus) Create sport-specific heatmaps (cycling, walking, hiking, etc.)

All using:

  1. free tools
  2. your exported data
  3. no premium subscription

How It Works

Each Strava activity file (GPX) contains thousands of GPS points.

We:

  1. Combine GPX files to visualize routes
  2. Extract GPS coordinates
  3. Plot them into a heatmap
  4. 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

Click Settings.png
my account.png
download get started.png

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

Screenshot 2026-04-14 083247.png
Screenshot 2026-04-14 090900.png
Screenshot 2026-04-14 090937.png
Screenshot 2026-04-14 090949.png
Screenshot 2026-04-14 091300.png

When your email arrives:

  1. Download the ZIP file
  2. Extract it into a folder
  3. Locate your activity files
  4. You should see .gpx files
  5. move all of the gpx files into thier own folder


Create Your Route Map

Screenshot 2026-04-14 091837.png
Screenshot 2026-04-14 093913.png
Screenshot 2026-04-14 092039.png
Screenshot 2026-04-14 092120.png

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:

  1. exact trails
  2. repeated routes
  3. your real movement paths


Open Google Colab

Screenshot 2026-04-14 092353.png

Go to:

👉 https://colab.research.google.com

Click:

New Notebook

Install Required Libraries

Screenshot 2026-04-14 092413.png
Screenshot 2026-04-14 092438.png

Paste this into the first cell:

!pip install gpxpy folium

Run it.

Upload Your GPX Files

Screenshot 2026-04-14 092636.png

Click "+Code"

Paste:

from google.colab import files

uploaded = files.upload()


Run and upload your GPX files.

Extract GPS Points + Detect Activity Type

Screenshot 2026-04-14 092557.png
Screenshot 2026-04-14 092813.png

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:

  1. extracts GPS coordinates
  2. groups them by activity type
  3. prepares data for multiple heatmaps


Create the Main Heatmap

Screenshot 2026-04-14 093418.png
Screenshot 2026-04-14 113708.png
Screenshot 2026-04-14 113932.png

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:

  1. overall activity density
  2. your most-used areas



Save Your Maps

Screenshot 2026-04-14 113826.png
Screenshot 2026-04-14 125858.png

Click "+Code"

Save any map:

m.save("heatmap.html")


Click "+Code"

Download:

files.download("heatmap.html")

Create Sport-Specific Heatmaps (Bonus)

Screenshot 2026-04-14 130848.png
Screenshot 2026-04-14 130858.png

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:

  1. cycling
  2. walking
  3. hiking
  4. running

This makes it possible to create separate heatmaps for different sports and compare where each activity tends to happen.

For example:

  1. cycling may cluster on roads or bike paths
  2. hiking may cluster on trails
  3. 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

6 activity map.png

Route Map

  1. exact paths

Heatmap

  1. activity density


What You Can Learn

This is where the project becomes meaningful.

You might notice:

  1. areas you visit repeatedly
  2. differences between walking and cycling
  3. unexpected hotspots
  4. unused areas


Troubleshooting

Map background not loading

Use:

tiles="CartoDB dark_matter"

instead of default tiles.


No data showing

  1. make sure GPX files contain tracks
  2. try different activities

Activity detection wrong

  1. depends on filename
  2. rename files if needed


Improvements

Screenshot 2026-04-14 113916.png
Screenshot 2026-04-14 092127.png
Screenshot 2026-04-14 092228.png

separate maps by date

weekday vs weekend maps

yearly maps

print as wall art