Skip to content

Instantly share code, notes, and snippets.

@marcusvolz marcusvolz/plot_calendar.R

Last active Jul 26, 2020
Embed
What would you like to do?
Visualise exercise activity data as a GitHub style calendar heat map
# Plot activity calendar
# Required packages
# devtools::install_github("marcusvolz/ggart")
# devtools::install_github("AtherEnergy/ggTimeSeries")
# Load packages
library(ggart)
library(ggthemes)
library(ggTimeSeries)
library(lubridate)
library(strava)
library(tidyverse)
library(viridis)
# Process the data
# data <- process_data(<gpx file path>)
# Summarise data
summary <- data %>%
mutate(time = lubridate::date(data$time),
year = strftime(data$time, format = "%Y"),
date_without_month = strftime(data$time, format = "%j"),
month = strftime(data$time, format = "%m"),
day_of_month = strftime(data$time, format = "%d"),
year_month = strftime(data$time, format = "%Y-%m")) %>%
group_by(time, year, date_without_month, month, day_of_month, year_month) %>%
summarise(total_dist = sum(dist_to_prev), total_time = sum(time_diff_to_prev)) %>%
mutate(speed = (total_dist) / (total_time /60^2)) %>%
mutate(pace = (total_time / 60) / (total_dist)) %>%
mutate(type = "day") %>%
ungroup %>%
mutate(id = as.numeric(row.names(.)))
# Generate plot data
time_min <- "2011-12-31"
time_max <- today()
max_dist <- 30
daily_data <- summary %>%
group_by(time) %>%
summarise(dist = sum(total_dist)) %>%
ungroup() %>%
mutate(time = lubridate::date(time)) %>%
filter(complete.cases(.), time > time_min, time < time_max) %>%
mutate(dist_scaled = ifelse(dist > max_dist, max_dist, dist))
# Create plot
p <- ggplot_calendar_heatmap(daily_data, "time", "dist_scaled",
dayBorderSize = 0.5, dayBorderColour = "white",
monthBorderSize = 0.75, monthBorderColour = "transparent",
monthBorderLineEnd = "round") +
xlab(NULL) +
ylab(NULL) +
scale_fill_continuous(name = "km", low = "#DAE580", high = "#236327", na.value = "#EFEDE0") +
facet_wrap(~Year, ncol = 1) +
theme_tufte() +
theme(strip.text = element_text(), axis.ticks = element_blank(), legend.position = "bottom")
# Save plot
ggsave("calendar001.png", p, width = 30, height = 30, units = "cm", dpi = 300)
@daviddiviny

This comment has been minimized.

Copy link

daviddiviny commented Dec 29, 2017

May I suggest using lubridate::date instead of as.Date to avoid converting dates to UTC. For example, an activity at 7am in AEDT is converted to the previous day on the calendar.

@marcusvolz

This comment has been minimized.

Copy link
Owner Author

marcusvolz commented Jan 17, 2018

Thanks David - that looks better

@narfel

This comment has been minimized.

Copy link

narfel commented Jan 29, 2020

Just for completeness: I needed to add library(gtools) for mixedsort() to #Load packages

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.