Skip to content

Instantly share code, notes, and snippets.

@PatrickStotz
Last active January 19, 2025 10:46
Show Gist options
  • Save PatrickStotz/05fbbc6c2db6c118249f834c2799a22b to your computer and use it in GitHub Desktop.
Save PatrickStotz/05fbbc6c2db6c118249f834c2799a22b to your computer and use it in GitHub Desktop.
Plotting daily step count as a radial chart in R/ggplot
####### Package management #######
## install and load needs, if not yet present
# install.packages("needs")
# library(needs)
## packages used in this markdown document
## install these packages from github
# devtools::install_github("mrkaye97/fitbitr")
# devtools::install_github("AllanCameron/geomtextpath")
needs(tidyverse, viridis, fitbitr, geomtextpath)
####### get the data #######
# downloading step count for 2024 from the fitbit API with the fitbitr package
# see here for setup instructions https://github.com/mrkaye97/fitbitr
steps = get_steps("2024-01-01", "2024-12-31")
####### data preparation #######
# column charts in R/ggplot don't support gradual filling
# we turn the data into segments with 100 steps each and later plot them as tiles
steps_tiled = map2_dfr(steps$date, steps$steps, function(date, steps){
date = date
segments_count = round(steps / 100)
df = tibble(date = date, segment = seq(0, segments_count))
return(df)
})
# preparing a grid for vertical grid lines
grid_x = tibble(
x = seq(ymd("2024-01-01"), ymd("2024-12-31"), "month"),
xend = seq(ymd("2024-01-01"), ymd("2024-12-31"), "month"),
y = rep(0, 12),
yend = rep(285, 12), # manually setting max. value after checking my max. step coutn
mid = seq(ymd("2024-01-15"), ymd("2024-12-15"), "month"),) %>%
add_row(x = ymd("2024-12-31"), y = 0, xend = ymd("2024-12-31"), yend = 285, mid = NA) %>%
print()
# preparing label text
labels = tibble(x = rep(ymd("2023-12-01"), 5),
y = c(50, 100, 150, 200, 250),
label = c("5,000", "10,000", "15,000", "20,000", "25,000 steps a day"))
# preparing colors
col_white = "#F4F4F3"
col_grey = "#DBDBDA"
col_black = "#0f0f0f"
####### generating plot #######
ggplot(steps_tiled) +
# vertical grid lines
geom_segment(data = grid_x, aes(x = x, y = y, xend = xend, yend = yend),
linetype = "dashed", colour = col_grey,linewidth = 0.35) +
# horizontal grid lines
geom_hline(yintercept = c(100, 200), colour = col_grey, linewidth = 0.275) +
geom_hline(yintercept = c(50, 150, 250), colour = col_grey, linewidth = 0.125) +
# curved y-axis labels
geom_labelpath(data = labels, aes(x = x, y = y, label = label),
size = rel(2.95), hjust = 1, vjust = 1.2, colour = col_white, family = "Monaco",
fill = col_black, linewidth = 0, label.padding = 0) +
# tiles with a column look
geom_tile(aes(x = date, y = segment, fill = segment, color = segment), linewidth = 0.05) +
scale_fill_viridis_c(option = "B", begin = 0.09) +
scale_color_viridis_c(option = "B", begin = 0.09) +
# thin outlines for each pseudo-column with decreasing line width towards the center
geom_linerange(aes(x = c(date - 0.5), ymin = segment - 0.5, ymax = segment + 0.5, linewidth = segment), colour = col_black) +
geom_linerange(aes(x = c(date + 0.5), ymin = segment - 0.5, ymax = segment + 0.5, linewidth = segment), colour = col_black) +
scale_linewidth_continuous(range = c(0.0001, 0.25)) +
# labels for each month, positioned in the middle of the month sectors
scale_x_date(breaks = grid_x$mid, date_labels = "%b", limits = c(ymd("2023-12-01"), NA)) +
# turning the plot into a semi-circle polar plot
# adding inner radius simply for the look and setting start/end so we
# have one additional sector for y-axis labels
coord_radial(inner.radius = 0.125, start = -31/365 * pi, end = pi * 365.5/365, expand = F) +
# caption
labs(caption = "All my steps in 2024", x = "", y = "") +
# style, style, style
theme_minimal(base_family = "Gloucester MT Extra Condensed", base_size = 18) %+replace%
theme(
plot.caption = element_text(hjust = 0.5, vjust = 5, colour = col_white, size = rel(3.2)),
plot.background = element_rect(fill = col_black, size = 0),
plot.margin = margin(0, 0, 0, 0, unit = "cm"),
axis.text.x = element_text(face = "italic", colour = col_white, size = rel(1.55)),
axis.title.y = element_blank(),
axis.text.y = element_blank(),
panel.background = element_rect(fill = col_black, size = 0),
panel.grid = element_blank(),
legend.position = "none")
ggsave("steps_2024.png", width = 5, height = 8.55, scale = 1.5, dpi = 600)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment