Skip to content

Create Strava heatmaps locally using Folium library in Python.

Notifications You must be signed in to change notification settings

roboes/strava-local-heatmap-tool

Repository files navigation

Strava Local Heatmap Tool

Description

This repository aims to be a multi feature tool for locally manipulating Strava's bulk export archive file. The main features are:

  • Unzip compressed (.gz) activities files.
  • Remove leading first line blank spaces of .tcx activities files for properly importing it (feature not yet available directly in the sweatpy package, see here).
  • Import multiple .fit/.gpx/.tcx activities files at once (without the need of conversion) and create local highly customizable heatmaps with different colors by activity type with the use of the folium library.
  • Increment your Strava activities metadata by adding country, state, city, postal code, latitude, longitude geolocation information for each activity given the start recorded point (first non-missing latitude/longitude).

Additionally, it is possible to apply a series of filters to select the desired activities before performing the heatmap, such as activities that started inside a bounding box (within 4 corner latitude/longitude points) or activities realized in specific countries or states.

Although similar projects already exist (see here), some of the features implemented in this project were partial or non-existent.

Output

Munich Heatmap (rides in orange; runs in blue)

Heatmap Munich

Vienna Heatmap (rides in orange; runs in blue)

Heatmap Vienna

Map interaction (option to navigate through the map, click in a line and get an activity summary pop-up)

Heatmap Pop-up

Usage

Bulk export your Strava data

Strava's bulk export process documentation can be found here.

Note: Please keep in mind that Strava's bulk export is language sensitive, i.e. the activities column labels will depend on users' defined language preferences. This project assumes that your bulk export was realized in English (US). To change the language, log in to Strava and on the bottom right-hand corner of any page, select English (US) from the drop-down menu (more on this here).

In essence, the process is as follows:

  1. Log in to Strava.
  2. Open the Account Download and Deletion. Then press Request Your Archive button (Important: Don't press anything else on that page, particularly not the Request Account Deletion button).
  3. Wait until Strava notifies you that your archive is ready via email. Download the archive file and unzip it to Downloads/Strava folder (or alternatively set a different working directory in the strava-local-heatmap-tool.py code).

Python dependencies

python -m pip install folium geopy pandas plotnine python-dateutil sweat

Functions

activities_import

activities_import()

Description

Parameters

  • None.

activities_filter

activities_filter(activities_df=activities, activity_type=None, activity_state=None, bounding_box={'latitude_top_right': None, 'longitude_top_right': None, 'latitude_top_left': None, 'longitude_top_left': None, 'latitude_bottom_left': None, 'longitude_bottom_left': None, 'latitude_bottom_right': None, 'longitude_bottom_right': None})

Description

  • Filter Strava activities DataFrame.

Parameters

  • activities_df: Strava activities DataFrame. Imported from activities_import() function.
  • activity_type: str list. If None, no activity type filter will be applied.
  • activity_state: str list. If None, no state location filter will be applied.
  • bounding_box: dict. If None, no bounding box will be applied.

Examples of bounding_box:

# Munich
bounding_box={
'latitude_top_right': 48.2316, 'longitude_top_right': 11.7170, # Top right boundary
'latitude_top_left': 48.2261, 'longitude_top_left': 11.4521, # Top left boundary
'latitude_bottom_left': 48.0851, 'longitude_bottom_left': 11.4022, # Bottom left boundary
'latitude_bottom_right': 48.0696, 'longitude_bottom_right': 11.7688 # Bottom right boundary
}
# Greater Munich
bounding_box={
'latitude_top_right': 48.4032, 'longitude_top_right': 11.8255, # Top right boundary
'latitude_top_left': 48.3924, 'longitude_top_left': 11.3082, # Top left boundary
'latitude_bottom_left': 47.9008, 'longitude_bottom_left': 11.0703, # Bottom left boundary
'latitude_bottom_right': 47.8609, 'longitude_bottom_right': 12.1105, # Bottom right boundary
}
# Southern Bavaria
bounding_box={
'latitude_top_right': 47.7900, 'longitude_top_right': 12.2692, # Top right boundary
'latitude_top_left': 47.7948, 'longitude_top_left': 10.9203, # Top left boundary
'latitude_bottom_left': 47.4023, 'longitude_bottom_left': 10.9779, # Bottom left boundary
'latitude_bottom_right': 47.4391, 'longitude_bottom_right': 12.3187, # Bottom right boundary
}

heatmap

heatmap(activities_df=activities, activities_coordinates_df=activities_coordinates, activity_colors={'Hike': '#00AD43', 'Ride': '#FF5800', 'Run': '#00A6FC'}, map_tile='dark_all', map_zoom_start=12, line_weight=1.0, line_opacity=0.6, line_smooth_factor=1.0)

Description

  • Create Heatmap based on inputted activities DataFrame.

Parameters

  • activities_df: Strava activities DataFrame, default: activities. Imported from activities_import() function.
  • activities_coordinates_df: Strava activities coordinates DataFrame, default: activities_coordinates. Imported from activities_import() function.
  • activity_colors: dict, default: {'Hike': '#00AD43', 'Ride': '#FF5800', 'Run': '#00A6FC'}. Depending on how many distinct activity_type are contained in the activities DataFrame, more dictionaries objects need to be added.
  • map_tile: str, options: 'dark_all', 'dark_nolabels', 'light_all', 'light_nolabels', 'terrain_background', 'toner_lite' and 'ocean_basemap', default: 'dark_all'.
  • map_zoom_start: int, default: 12. Initial zoom level for the map (for more details, check zoom_start parameter for folium.folium.Map documentation).
  • line_weight: float, default: 1.0. Stroke width in pixels (for more details, check weight parameter for folium.vector_layers.PolyLine).
  • line_opacity: float, default: 0.6. Stroke opacity (for more details, check opacity parameter for folium.vector_layers.PolyLine).
  • line_smooth_factor: float, default: 1.0. How much to simplify the polyline on each zoom level. More means better performance and smoother look, and less means more accurate representation (for more details, check smooth_factor parameter for folium.vector_layers.PolyLine).

copy_activities

copy_activities(activities_files=activities['filename'])

Description

  • Copies a given .fit/.gpx/.tcx list of files to 'output\activities' folder.

Parameters

  • activities_files: list, default: activities['filename'].

Save map as a high definition .png file and print it on canvas

Unfortunately Folium does not natively export a rendered map to .png.

A workaround is to open the rendered .html Folium map in Chrome, then open Chrome's Inspector, changing the width and high dimensions to 3500 x 3500 px, setting the zoom to 22% and the DPR to 3.0. Then capture a full size screenshot.

The canvas.xcf is a Gimp template for printing a canvas in 30 x 30 cm. Its design is similar to this Reddit discussion:

Heatmap Munich

The statistics shown in the lower right corner are printed once the heatmap function is executed.

Documentation

Strava API v3: Definition of activities variables.

See also

Similar projects

These repositories have a similar or additional purpose to this project:

Strava local heatmap browser: Code to reproduce the Strava Global Heatmap with local .gpx files (Python).

Visualization of activities from Garmin Connect: Code for processing activities with .gpx files from Garmin Connect (Python).

Create artistic visualisations with your Strava exercise data: Code for creating artistic visualizations with your Strava exercise data (Python; a R version is available here).

strava-offline: Tool to keep a local mirror of Strava activities for further analysis/processing.

dérive - Generate a heatmap from GPS tracks: Generate heatmap by drag and dropping one or more .gpx/.tcx/.fit/.igc/.skiz file(s) (JavaScript, HTML).

Articles

Data Science For Cycling - How to Visualize GPX Strava Routes With Python and Folium (GitHub).

Build Interactive GPS activity maps from GPX files using Folium (GitHub).

External links

StatsHunters: Connect your Strava account and show all your sport activities and added photos on one map.

Recommended settings:

  • Receive monthly statistics by email
  • Hide my data in club heatmaps

Cultureplot Custom Strava Heatmap Generator: Connect to Strava to see your activity heatmap. Includes the possibility to filter the activities (by date, time and type) and to customize the map (map type, background color, line color (also by activity), thickness and opacity).

About

Create Strava heatmaps locally using Folium library in Python.

Resources

Stars

Watchers

Forks

Languages