Skip to content

Commit 1a67ea6

Browse files
committed
Fix plot issues and clean up code
1 parent 8de50d5 commit 1a67ea6

27 files changed

+630
-319
lines changed

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,8 @@ docs/
9191

9292
# Temporary image files
9393
image.png
94-
image/
94+
image/
95+
preview_*.png
96+
reproduce_*.png
97+
reproduce_*.R
98+
temp_*.png

DESCRIPTION

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Description: An open-source computational framework for longitudinal analysis of
1212
including Acute:Chronic Workload Ratio (ACWR), Efficiency Factor (EF), and
1313
training load metrics.
1414
License: MIT + file LICENSE
15-
URL: https://hezhiang.com/Athlytics/, https://github.com/HzaCode/Athlytics
15+
URL: https://hzacode.github.io/Athlytics/, https://github.com/HzaCode/Athlytics
1616
BugReports: https://github.com/HzaCode/Athlytics/issues
1717
Encoding: UTF-8
1818
LazyData: true
@@ -25,6 +25,7 @@ Imports:
2525
purrr,
2626
readr,
2727
rlang (>= 0.4.0),
28+
scales,
2829
tidyr,
2930
viridis,
3031
zoo,
@@ -38,7 +39,6 @@ Suggests:
3839
rmarkdown,
3940
testthat (>= 3.0.0),
4041
mockery,
41-
XML,
4242
rStrava,
4343
xml2,
4444
FITfileR

NAMESPACE

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ importFrom(readr,cols)
9393
importFrom(readr,read_csv)
9494
importFrom(rlang,"%||%")
9595
importFrom(rlang,.data)
96+
importFrom(scales,pretty_breaks)
9697
importFrom(stats,median)
9798
importFrom(stats,na.omit)
9899
importFrom(stats,quantile)
@@ -102,6 +103,7 @@ importFrom(tidyr,drop_na)
102103
importFrom(tidyr,pivot_longer)
103104
importFrom(tidyr,pivot_wider)
104105
importFrom(tidyr,unnest)
106+
importFrom(tools,toTitleCase)
105107
importFrom(utils,read.csv)
106108
importFrom(viridis,scale_color_viridis)
107109
importFrom(zoo,rollapply)

R/calculate_acwr.R

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -150,25 +150,24 @@
150150
#' plot_acwr(run_acwr, highlight_zones = TRUE)
151151
#'
152152
#' # Multi-athlete cohort analysis
153-
#' library(dplyr)
154153
#'
155154
#' # Load data for multiple athletes and add athlete_id
156155
#' athlete1 <- load_local_activities("athlete1_export.zip") %>%
157-
#' mutate(athlete_id = "athlete1")
156+
#' dplyr::mutate(athlete_id = "athlete1")
158157
#'
159158
#' athlete2 <- load_local_activities("athlete2_export.zip") %>%
160-
#' mutate(athlete_id = "athlete2")
159+
#' dplyr::mutate(athlete_id = "athlete2")
161160
#'
162161
#' # Combine all athletes
163-
#' cohort_data <- bind_rows(athlete1, athlete2)
162+
#' cohort_data <- dplyr::bind_rows(athlete1, athlete2)
164163
#'
165164
#' # Calculate ACWR for each athlete using group_modify()
166165
#' cohort_acwr <- cohort_data %>%
167-
#' group_by(athlete_id) %>%
168-
#' group_modify(~ calculate_acwr(.x,
166+
#' dplyr::group_by(athlete_id) %>%
167+
#' dplyr::group_modify(~ calculate_acwr(.x,
169168
#' activity_type = "Run",
170169
#' load_metric = "duration_mins")) %>%
171-
#' ungroup()
170+
#' dplyr::ungroup()
172171
#'
173172
#' # View results
174173
#' print(cohort_acwr)

R/cohort_reference.R

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -265,9 +265,29 @@ add_reference_bands <- function(p,
265265
#' @importFrom ggplot2 ggplot aes geom_line labs theme_minimal scale_x_date
266266
#' @importFrom dplyr %>%
267267
#' @importFrom rlang %||% .data
268+
#' @importFrom tidyr pivot_wider
269+
#' @importFrom tools toTitleCase
268270
#' @export
269271
#'
270272
#' @examples
273+
#' # Simple example with fixed data
274+
#' individual_data <- data.frame(
275+
#' date = as.Date(c("2023-01-01", "2023-04-01", "2023-07-01", "2023-10-01")),
276+
#' acwr_smooth = c(1.0, 1.2, 0.9, 1.1)
277+
#' )
278+
#' reference_data <- data.frame(
279+
#' date = as.Date(c("2023-01-01", "2023-04-01", "2023-07-01", "2023-10-01")),
280+
#' percentile = rep(c("p05", "p25", "p50", "p75", "p95"), 4),
281+
#' value = c(0.7, 0.9, 1.1, 1.3, 1.5, 0.7, 0.9, 1.1, 1.3, 1.5, 0.7, 0.9, 1.1, 1.3, 1.5, 0.7, 0.9, 1.1, 1.3, 1.5)
282+
#' )
283+
#'
284+
#' p <- plot_with_reference(
285+
#' individual = individual_data,
286+
#' reference = reference_data,
287+
#' metric = "acwr_smooth"
288+
#' )
289+
#' print(p)
290+
#'
271291
#' \dontrun{
272292
#' plot_with_reference(
273293
#' individual = athlete_acwr,
@@ -298,40 +318,36 @@ plot_with_reference <- function(individual,
298318
# Create base plot with reference bands
299319
p <- ggplot2::ggplot()
300320

301-
# Add reference bands (outermost first)
321+
# Add reference bands (outermost first) - using enhanced colors
302322
if ("p05_p95" %in% bands && all(c("p05", "p95") %in% colnames(ref_wide))) {
303323
p <- p + ggplot2::geom_ribbon(
304324
data = ref_wide,
305325
ggplot2::aes(x = .data$date, ymin = .data$p05, ymax = .data$p95),
306-
fill = "#3B528BFF", alpha = 0.15
307-
) +
308-
ggplot2::annotate("text", x = min(ref_wide$date), y = max(ref_wide$p95, na.rm = TRUE),
309-
label = "P5-P95", hjust = 0, vjust = 1, size = 3, color = "#3B528BFF", alpha = 0.7)
326+
fill = "#FFB6C1", alpha = 0.3
327+
)
310328
}
311329

312330
if ("p25_p75" %in% bands && all(c("p25", "p75") %in% colnames(ref_wide))) {
313331
p <- p + ggplot2::geom_ribbon(
314332
data = ref_wide,
315333
ggplot2::aes(x = .data$date, ymin = .data$p25, ymax = .data$p75),
316-
fill = "#440154FF", alpha = 0.25
317-
) +
318-
ggplot2::annotate("text", x = min(ref_wide$date), y = max(ref_wide$p75, na.rm = TRUE),
319-
label = "P25-P75", hjust = 0, vjust = 1, size = 3, color = "#440154FF", alpha = 0.7)
334+
fill = "#87CEEB", alpha = 0.4
335+
)
320336
}
321337

322338
if ("p50" %in% bands && "p50" %in% colnames(ref_wide)) {
323339
p <- p + ggplot2::geom_line(
324340
data = ref_wide,
325341
ggplot2::aes(x = .data$date, y = .data$p50),
326-
color = "#21908CFF", linetype = "dashed", linewidth = 0.8
342+
color = "#4682B4", linetype = "dashed", linewidth = 1.5
327343
)
328344
}
329345

330-
# Add individual line on top
346+
# Add individual line on top with enhanced visibility
331347
p <- p + ggplot2::geom_line(
332348
data = individual,
333349
ggplot2::aes(x = .data[[date_col]], y = .data[[metric]]),
334-
color = "black", linewidth = 1.2
350+
color = "#DC143C", linewidth = 2.5, alpha = 1.0
335351
)
336352

337353
# Formatting
@@ -340,15 +356,23 @@ plot_with_reference <- function(individual,
340356
p <- p +
341357
ggplot2::labs(
342358
title = plot_title,
343-
subtitle = "Black line = Individual | Shaded areas = Cohort percentiles",
359+
subtitle = "Individual athlete metrics compared to cohort reference bands",
344360
x = "Date",
345-
y = tools::toTitleCase(metric)
361+
y = tools::toTitleCase(metric),
362+
caption = "Red line: Individual athlete | Shaded bands: Cohort percentile ranges"
363+
) +
364+
ggplot2::scale_x_date(
365+
date_breaks = "3 months",
366+
labels = function(x) {
367+
months <- c("Jan", "Feb", "Mar", "Apr", "May", "Jun",
368+
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec")
369+
paste(months[as.integer(format(x, "%m"))], format(x, "%Y"))
370+
}
346371
) +
347-
ggplot2::scale_x_date(date_breaks = "3 months", date_labels = "%b %Y") +
348-
ggplot2::theme_minimal() +
372+
theme_athlytics() +
349373
ggplot2::theme(
350374
axis.text.x = ggplot2::element_text(angle = 45, hjust = 1),
351-
plot.title = ggplot2::element_text(face = "bold")
375+
plot.margin = ggplot2::margin(20, 20, 20, 20)
352376
)
353377

354378
return(p)

R/color_palettes.R

Lines changed: 86 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@ NULL
1616
#' @export
1717
#' @examples
1818
#' \dontrun{
19-
#' library(ggplot2)
20-
#' ggplot(data, aes(x, y, color = group)) +
21-
#' geom_line() +
22-
#' scale_color_manual(values = athlytics_palette_nature())
19+
#' ggplot2::ggplot(data, ggplot2::aes(x, y, color = group)) +
20+
#' ggplot2::geom_line() +
21+
#' ggplot2::scale_color_manual(values = athlytics_palette_nature())
2322
#' }
2423
athlytics_palette_nature <- function() {
2524
c(
@@ -45,10 +44,9 @@ athlytics_palette_nature <- function() {
4544
#' @export
4645
#' @examples
4746
#' \dontrun{
48-
#' library(ggplot2)
49-
#' ggplot(data, aes(x, y, color = group)) +
50-
#' geom_line() +
51-
#' scale_color_manual(values = athlytics_palette_academic())
47+
#' ggplot2::ggplot(data, ggplot2::aes(x, y, color = group)) +
48+
#' ggplot2::geom_line() +
49+
#' ggplot2::scale_color_manual(values = athlytics_palette_academic())
5250
#' }
5351
athlytics_palette_academic <- function() {
5452
c(
@@ -73,10 +71,9 @@ athlytics_palette_academic <- function() {
7371
#' @export
7472
#' @examples
7573
#' \dontrun{
76-
#' library(ggplot2)
77-
#' ggplot(data, aes(x, y, fill = category)) +
78-
#' geom_bar(stat = "identity") +
79-
#' scale_fill_manual(values = athlytics_palette_vibrant())
74+
#' ggplot2::ggplot(data, ggplot2::aes(x, y, fill = category)) +
75+
#' ggplot2::geom_bar(stat = "identity") +
76+
#' ggplot2::scale_fill_manual(values = athlytics_palette_vibrant())
8077
#' }
8178
athlytics_palette_vibrant <- function() {
8279
c(
@@ -226,62 +223,109 @@ athlytics_colors_ef <- function() {
226223
#' @return A ggplot2 theme object that can be added to plots
227224
#'
228225
#' @examples
229-
#' library(ggplot2)
230226
#' # Apply theme to a plot
231-
#' ggplot(mtcars, aes(mpg, wt)) +
232-
#' geom_point() +
227+
#' ggplot2::ggplot(mtcars, ggplot2::aes(mpg, wt)) +
228+
#' ggplot2::geom_point() +
233229
#' theme_athlytics()
234230
#'
235231
#' @export
236232
#' @import ggplot2
237-
theme_athlytics <- function(base_size = 12, base_family = "") {
233+
theme_athlytics <- function(base_size = 13, base_family = "") {
238234
ggplot2::theme_minimal(base_size = base_size, base_family = base_family) +
239235
ggplot2::theme(
240-
# Plot
236+
# Plot background - clean white
237+
plot.background = ggplot2::element_rect(fill = "white", color = NA),
238+
panel.background = ggplot2::element_rect(fill = "white", color = NA),
239+
240+
# Plot titles - modern, bold, left-aligned
241241
plot.title = ggplot2::element_text(
242242
face = "bold",
243-
size = base_size * 1.2,
243+
size = base_size * 1.4,
244244
hjust = 0,
245-
margin = ggplot2::margin(b = base_size * 0.5)
245+
color = "#2c3e50",
246+
margin = ggplot2::margin(b = base_size * 0.8)
246247
),
247248
plot.subtitle = ggplot2::element_text(
248-
size = base_size * 0.9,
249-
color = "gray40",
249+
size = base_size * 0.95,
250+
color = "#7f8c8d",
250251
hjust = 0,
251-
margin = ggplot2::margin(b = base_size * 0.5)
252+
lineheight = 1.2,
253+
margin = ggplot2::margin(b = base_size * 1)
252254
),
253255
plot.caption = ggplot2::element_text(
254-
size = base_size * 0.8,
255-
color = "gray50",
256+
size = base_size * 0.75,
257+
color = "#95a5a6",
256258
hjust = 1,
257-
margin = ggplot2::margin(t = base_size * 0.5)
259+
margin = ggplot2::margin(t = base_size * 0.8)
258260
),
261+
plot.margin = ggplot2::margin(t = 15, r = 15, b = 15, l = 15),
259262

260-
# Axes
261-
axis.title = ggplot2::element_text(size = base_size, face = "bold"),
262-
axis.text = ggplot2::element_text(size = base_size * 0.9, color = "gray20"),
263-
axis.line = ggplot2::element_line(color = "gray40", linewidth = 0.5),
263+
# Axes - clean and minimal
264+
axis.title.x = ggplot2::element_text(
265+
size = base_size * 1.05,
266+
face = "bold",
267+
color = "#34495e",
268+
margin = ggplot2::margin(t = base_size * 0.6)
269+
),
270+
axis.title.y = ggplot2::element_text(
271+
size = base_size * 1.05,
272+
face = "bold",
273+
color = "#34495e",
274+
margin = ggplot2::margin(r = base_size * 0.6)
275+
),
276+
axis.text.x = ggplot2::element_text(
277+
size = base_size * 0.9,
278+
color = "#7f8c8d",
279+
margin = ggplot2::margin(t = base_size * 0.3)
280+
),
281+
axis.text.y = ggplot2::element_text(
282+
size = base_size * 0.9,
283+
color = "#7f8c8d",
284+
margin = ggplot2::margin(r = base_size * 0.3)
285+
),
286+
axis.line = ggplot2::element_blank(),
287+
axis.ticks = ggplot2::element_line(color = "#bdc3c7", linewidth = 0.3),
288+
axis.ticks.length = ggplot2::unit(4, "pt"),
264289

265-
# Legend
290+
# Legend - modern and spacious
266291
legend.position = "bottom",
267-
legend.title = ggplot2::element_text(size = base_size, face = "bold"),
268-
legend.text = ggplot2::element_text(size = base_size * 0.9),
269-
legend.key.size = ggplot2::unit(1, "lines"),
292+
legend.direction = "horizontal",
293+
legend.title = ggplot2::element_text(
294+
size = base_size * 0.95,
295+
face = "bold",
296+
color = "#34495e"
297+
),
298+
legend.text = ggplot2::element_text(
299+
size = base_size * 0.85,
300+
color = "#7f8c8d"
301+
),
302+
legend.key.size = ggplot2::unit(1.2, "lines"),
303+
legend.key = ggplot2::element_blank(),
304+
legend.spacing.x = ggplot2::unit(0.5, "lines"),
305+
legend.box.spacing = ggplot2::unit(0.5, "lines"),
306+
legend.margin = ggplot2::margin(t = base_size),
270307

271-
# Panel
272-
panel.grid.major = ggplot2::element_line(color = "gray90", linewidth = 0.3),
308+
# Panel grid - subtle and elegant
309+
panel.grid.major = ggplot2::element_line(
310+
color = "#ecf0f1",
311+
linewidth = 0.5,
312+
linetype = "solid"
313+
),
273314
panel.grid.minor = ggplot2::element_blank(),
274315
panel.border = ggplot2::element_blank(),
316+
panel.spacing = ggplot2::unit(1.5, "lines"),
275317

276-
# Strip (for facets)
318+
# Strip (for facets) - clean and modern
277319
strip.text = ggplot2::element_text(
278-
size = base_size,
320+
size = base_size * 1.05,
279321
face = "bold",
280-
color = "gray20"
322+
color = "#2c3e50",
323+
margin = ggplot2::margin(b = base_size * 0.5, t = base_size * 0.5)
281324
),
282325
strip.background = ggplot2::element_rect(
283-
fill = "gray95",
284-
color = NA
326+
fill = "#f8f9fa",
327+
color = "#dee2e6",
328+
linewidth = 0.5
285329
)
286330
)
287331
}
@@ -296,10 +340,9 @@ theme_athlytics <- function(base_size = 12, base_family = "") {
296340
#' @return A ggplot2 scale object (scale_color_manual or scale_fill_manual)
297341
#'
298342
#' @examples
299-
#' library(ggplot2)
300343
#' # Apply nature palette to plot
301-
#' ggplot(iris, aes(Sepal.Length, Sepal.Width, color = Species)) +
302-
#' geom_point() +
344+
#' ggplot2::ggplot(iris, ggplot2::aes(Sepal.Length, Sepal.Width, color = Species)) +
345+
#' ggplot2::geom_point() +
303346
#' scale_athlytics("nature", "color")
304347
#'
305348
#' @export

0 commit comments

Comments
 (0)