gg_dashboard.R in R
Four plots from one dataset, arranged and written to a single file.
suppressPackageStartupMessages({
library(dplyr)
library(tidyr)
library(ggplot2)
})
ACCENT <- "#7c5cff"
WARM <- "#e06c75"
make_runs <- function(sessions = 60, seed = 3) {
set.seed(seed)
tibble(
session = rep(seq_len(sessions), 2),
lang = rep(c("R", "Python"), each = sessions),
tpm = c(78 + 0.45 * seq_len(sessions) + rnorm(sessions, 0, 4),
84 + 0.50 * seq_len(sessions) + rnorm(sessions, 0, 5))
) |>
mutate(accuracy = 94 + (tpm - min(tpm)) / diff(range(tpm)) * 5)
}
panel_progress <- function(runs) {
ggplot(runs, aes(session, tpm, colour = lang)) +
geom_point(alpha = 0.5, size = 1) +
geom_smooth(method = "lm", formula = y ~ x, se = FALSE) +
scale_colour_manual(values = c(R = ACCENT, Python = WARM)) +
labs(title = "Tokens per minute", x = NULL, y = "tpm") +
theme_minimal(base_size = 9)
}
panel_distribution <- function(runs) {
ggplot(runs, aes(tpm, fill = lang)) +
geom_histogram(bins = 20, alpha = 0.7, position = "identity") +
scale_fill_manual(values = c(R = ACCENT, Python = WARM)) +
labs(title = "Distribution", x = "tpm", y = NULL) +
theme_minimal(base_size = 9)
}
panel_spread <- function(runs) {
ggplot(runs, aes(lang, tpm, fill = lang)) +
geom_violin(alpha = 0.5) +
geom_boxplot(width = 0.15, outlier.shape = NA) +
scale_fill_manual(values = c(R = ACCENT, Python = WARM)) +
labs(title = "Spread", x = NULL, y = NULL) +
theme_minimal(base_size = 9) +
theme(legend.position = "none")
}
panel_tradeoff <- function(runs) {
ggplot(runs, aes(tpm, accuracy, colour = session)) +
geom_point(size = 1.2) +
scale_colour_viridis_c() +
labs(title = "Speed against accuracy", x = "tpm", y = "accuracy %") +
theme_minimal(base_size = 9)
}
runs <- make_runs()
cat("--- summary ---\n")
print(runs |>
summarise(sessions = n(),
best = round(max(tpm), 1),
mean_tpm = round(mean(tpm), 1),
.by = lang))
improvement <- runs |>
summarise(
early = mean(tpm[session <= 7]),
late = mean(tpm[session > max(session) - 7]),
.by = lang
) |>
mutate(gain = round(late - early, 1))
cat("\n--- improvement ---\n")
print(improvement)
panels <- list(panel_progress(runs), panel_distribution(runs),
panel_spread(runs), panel_tradeoff(runs))
out <- tempfile(fileext = ".png")
combined <- panels[[1]]
ggsave(out, combined, width = 6, height = 3.5, dpi = 120)
for (index in seq_along(panels)) {
ggsave(tempfile(fileext = ".png"), panels[[index]], width = 4, height = 3,
dpi = 100)
}
cat(sprintf("\nwrote %d panels\n", length(panels)))
How it works
- Each panel is a small function returning a ggplot object.
- The data is shaped once, then reused by every panel.
- ggsave writes the assembled grid at the end.
Keywords and builtins used here
aesccatdiffforfunctiongeom_boxplotgeom_histogramgeom_pointgeom_smoothgeom_violinggplotggsaveinlabslengthlibrarylistmake_runsmaxmeanminmutatenpanel_distributionpanel_progresspanel_spreadpanel_tradeoffprintrangereprnormroundscale_colour_manualscale_colour_viridis_cscale_fill_manualseq_alongseq_lensprintfsummarisesuppressPackageStartupMessagestempfilethemetheme_minimaltibble
The run, in numbers
- Lines
- 85
- Characters to type
- 2419
- Tokens
- 679
- Three-star pace
- 110 tpm
At the three-star pace of 110 tokens a minute, this run takes about 370 seconds.
Step 1 of 1 in Encore, step 15 of 15 in ggplot2.