Skip to content

Instantly share code, notes, and snippets.

@friendly
Created March 2, 2026 03:02
Show Gist options
  • Select an option

  • Save friendly/ca2eb17bde75b17e5e34b0f11ba823fe to your computer and use it in GitHub Desktop.

Select an option

Save friendly/ca2eb17bde75b17e5e34b0f11ba823fe to your computer and use it in GitHub Desktop.
R Birthday card generated by Claude Sonnet 4.6
# Happy Birthday, R!
# R 1.0.0 was first released on February 29, 2000
# Celebrating 26 years of statistical computing!
out_file <- "r_birthday_cake.png"
png(out_file, width = 800, height = 660, bg = "#FFF0F5")
par(mar = c(0.3, 0.3, 0.3, 0.3), bg = "#FFF0F5")
plot(0, 0, type = "n", xlim = c(0, 10), ylim = c(0, 10),
axes = FALSE, xlab = "", ylab = "")
rect(-1, -1, 11, 11, col = "#FFF0F5", border = NA)
# ---- Helper: teardrop flame ----
draw_flame <- function(cx, base_y) {
t <- seq(0, 2 * pi, length.out = 120)
polygon(cx + 0.15 * sin(t),
base_y + 0.32 * (1 - cos(t)) / 2,
col = "#FFD93D", border = "#FFA500", lwd = 1)
polygon(cx + 0.09 * sin(t),
base_y + 0.02 + 0.20 * (1 - cos(t)) / 2,
col = "#FF8C00", border = NA)
polygon(cx + 0.04 * sin(t),
base_y + 0.05 + 0.10 * (1 - cos(t)) / 2,
col = "#FFFACD", border = NA)
}
# ---- Confetti scatter (top & bottom strips) ----
set.seed(2000)
confetti_cols <- c("#FF6B6B", "#FFD93D", "#6BCB77", "#4D96FF", "#C77DFF", "#FF9F43")
for (i in 1:90) {
x <- runif(1, 0.1, 9.9)
y <- ifelse(runif(1) > 0.5, runif(1, 0, 1.3), runif(1, 8.1, 9.9))
col <- sample(confetti_cols, 1)
points(x, y, pch = sample(c(15, 17, 18), 1),
cex = runif(1, 0.5, 1.6),
col = adjustcolor(col, alpha.f = 0.75))
}
# ---- Title text ----
text(5, 9.55, "Happy Birthday, R!",
cex = 2.7, col = "#C0392B", font = 2, adj = 0.5)
text(5, 9.07, "February 29, 2000 \u2014 26 Years of Statistical Computing",
cex = 0.92, col = "#7F8C8D", font = 3, adj = 0.5)
# ---- Cake plate (ellipse) ----
t_e <- seq(0, 2 * pi, length.out = 200)
polygon(5 + 3.7 * cos(t_e), 2.12 + 0.28 * sin(t_e),
col = "#C8B89A", border = "#A8987A", lwd = 2)
# ---- Bottom cake layer ----
rect(1.65, 2.12, 8.35, 4.3, col = "#FADADD", border = "#E8A0A8", lwd = 2)
# 3-D right-side face
polygon(c(8.35, 8.65, 8.65, 8.35), c(2.12, 1.88, 4.05, 4.3),
col = "#ECC0C5", border = "#E8A0A8", lwd = 1)
# White frosting bar + drips (bottom layer)
rect(1.65, 4.3, 8.35, 4.58, col = "white", border = NA)
t_d <- seq(pi, 2 * pi, length.out = 30)
for (dx in seq(2.05, 8.1, by = 0.52)) {
polygon(c(dx - 0.18, dx + 0.18 * cos(t_d), dx + 0.18),
c(4.3, 4.3 + 0.28 * sin(t_d), 4.3),
col = "white", border = NA)
}
# ---- Top cake layer ----
rect(2.3, 4.58, 7.7, 6.3, col = "#FFB3C1", border = "#F08090", lwd = 2)
# 3-D right-side face
polygon(c(7.7, 8.0, 8.0, 7.7), c(4.58, 4.33, 6.05, 6.3),
col = "#F09098", border = "#F08090", lwd = 1)
# White frosting bar + drips (top layer)
rect(2.3, 6.3, 7.7, 6.52, col = "white", border = NA)
for (dx in seq(2.62, 7.38, by = 0.52)) {
polygon(c(dx - 0.16, dx + 0.16 * cos(t_d), dx + 0.16),
c(6.3, 6.3 + 0.24 * sin(t_d), 6.3),
col = "white", border = NA)
}
# ---- Sprinkles ----
set.seed(2000)
# Bottom layer
for (i in 1:55) {
x <- runif(1, 1.85, 8.15); y <- runif(1, 2.25, 4.2)
a <- runif(1, 0, pi); col <- sample(confetti_cols, 1)
segments(x - 0.17 * cos(a), y - 0.17 * sin(a),
x + 0.17 * cos(a), y + 0.17 * sin(a),
col = col, lwd = 2.5)
}
# Top layer
for (i in 1:38) {
x <- runif(1, 2.45, 7.55); y <- runif(1, 4.68, 6.22)
a <- runif(1, 0, pi); col <- sample(confetti_cols, 1)
segments(x - 0.15 * cos(a), y - 0.15 * sin(a),
x + 0.15 * cos(a), y + 0.15 * sin(a),
col = col, lwd = 2.5)
}
# ---- "R" on the cake ----
text(5, 5.42, "R", cex = 5.8, col = "#1F4E79", font = 2)
# ---- Candles ----
cx_vals <- seq(3.0, 7.0, length.out = 6)
c_fill <- c("#FF6B6B", "#FFD93D", "#6BCB77", "#4D96FF", "#C77DFF", "#FF9F43")
c_border <- c("#CC3333", "#CCB000", "#339944", "#0033CC", "#7733BB", "#CC7700")
for (i in seq_along(cx_vals)) {
cx <- cx_vals[i]
rect(cx - 0.14, 6.52, cx + 0.14, 7.58,
col = c_fill[i], border = c_border[i], lwd = 1.5)
# highlight
rect(cx - 0.09, 6.63, cx - 0.02, 7.47,
col = adjustcolor("white", alpha.f = 0.35), border = NA)
# wick
segments(cx, 7.58, cx, 7.72, col = "#222222", lwd = 2)
draw_flame(cx, 7.72)
}
# ---- "26 years" badge ----
symbols(8.6, 7.65, circles = 0.72, inches = FALSE, add = TRUE,
bg = "#C0392B", fg = "#8B0000", lwd = 2)
text(8.6, 7.78, "26", cex = 1.3, col = "white", font = 2)
text(8.6, 7.53, "years", cex = 0.72, col = "white", font = 2)
# ---- Footer ----
text(5, 0.65,
"S \u2192 S-PLUS \u2192 R \u2014 the world\u2019s favourite stats language",
cex = 0.82, col = "#95A5A6", font = 3, adj = 0.5)
dev.off()
cat(sprintf("Saved: %s\n", out_file))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment