Skip to content

Instantly share code, notes, and snippets.

@mcanouil
Last active June 18, 2026 15:13
Show Gist options
  • Select an option

  • Save mcanouil/d149ba403b63d356dbcabcc07f476bc1 to your computer and use it in GitHub Desktop.

Select an option

Save mcanouil/d149ba403b63d356dbcabcc07f476bc1 to your computer and use it in GitHub Desktop.
#import "@preview/gribouille:0.3.0": *
#set page("a4", margin: 2.5cm)
// === Data management: reproduce `creations` ===
#let challenges = csv("bakeoff-challenges.csv", row-type: dictionary)
// grepl patterns -> ingredient names (French labels match the R script).
#let ingredients = (
chocolat: regex("[Cc]hocolat"),
framboise: regex("[Rr]aspberr"),
orange: regex("[Oo]range"),
)
// Distinct series in order of first appearance.
#let series-list = ()
#for row in challenges {
let s = int(row.series)
if s not in series-list { series-list.push(s) }
}
// pivot_longer(signature, showstopper) + grepl + sum, grouped by series.
#let counts = (:)
#for s in series-list {
counts.insert(str(s), (chocolat: 0, framboise: 0, orange: 0))
}
#for row in challenges {
let s = str(int(row.series))
for col in ("signature", "showstopper") {
let value = row.at(col)
for (ingredient, pattern) in ingredients {
if value.contains(pattern) {
counts.at(s).at(ingredient) += 1
}
}
}
}
// pivot_longer(-series) + rank(-value, ties="min") within series + mary_berry.
#let creations = ()
#for s in series-list {
let row-counts = counts.at(str(s))
for (ingredient, value) in row-counts {
let rank = 1
for (_, other) in row-counts {
if other > value { rank += 1 }
}
creations.push((
series: s,
ingredient: ingredient,
value: value,
rank: rank,
mary-berry: if s < 8 { "oui" } else { "non" },
))
}
}
// === Plot: reproduce the ggplot from bakeoff ===
#let couleurs-accessibles = (
chocolat: rgb("#5F1C34"),
orange: rgb("#DCA113"),
framboise: rgb("#d33b66"),
mary: rgb("#F2CAE4"),
)
#let my-plot = plot(
data: creations,
mapping: aes(
x: "series",
y: "value",
colour: "ingredient",
fill: "ingredient",
shape: "ingredient",
),
layers: (
geom-rect(
data: ((xmin: 0.5, xmax: 7.5, ymin: 0, ymax: 32),),
mapping: aes(xmin: "xmin", xmax: "xmax", ymin: "ymin", ymax: "ymax"),
inherit-aes: false,
fill: couleurs-accessibles.mary,
alpha: 0.3,
),
geom-line(),
geom-vline(xintercept: 7.5, stroke: 0.2pt, colour: rgb("#ca3e8c")),
geom-typst(
data: ((x: 7.5, y: 31, label: "*Les années Mary Berry*"),),
mapping: aes(x: "x", y: "y", label: "label"),
inherit-aes: false,
anchor: "east",
colour: rgb("#3f4a57"),
),
geom-point(size: 8pt, colour: rgb("#3f4a57")),
),
scales: (
scale-shape-manual(
values: ("diamond", "triangle", "circle"),
limits: ("chocolat", "framboise", "orange"),
),
scale-fill-manual(
values: (couleurs-accessibles.chocolat, couleurs-accessibles.framboise, couleurs-accessibles.orange),
limits: ("chocolat", "framboise", "orange"),
),
scale-colour-manual(
values: (couleurs-accessibles.chocolat, couleurs-accessibles.framboise, couleurs-accessibles.orange),
limits: ("chocolat", "framboise", "orange"),
),
scale-x-continuous(breaks: range(1, 11), expand: (0pt, 12pt)),
scale-y-continuous(limits: (0, 31), expand: (0pt, 0pt)),
),
guides: guides(default: guide-legend(position: "bottom")),
labs: labs(
title: "Le chocolat demeure l'ingrédient le plus utilisé, même s'il s'est fait brièvement doubler par les oranges en Saison 8",
subtitle: "Le nombre de créations incluant du chocolat était bien plus élevé pendant que Mary Berry était dans le jury. On anticipe d'avoir besoin de deux fois plus de chocolat la saison prochaine si elle revient.",
x: "Saison",
y: "Nombre de créations",
),
theme: theme-minimal(
ink: rgb("#3f4a57"),
legend-title: element-blank(),
text: element-text(font: "Inclusive Sans", size: 12pt, colour: rgb("#3f4a57")),
plot-title: element-text(
font: "Inclusive Sans",
weight: "bold",
size: 19.2pt,
colour: rgb("#071526"),
margin: margin(top: 12pt, bottom: 18pt),
),
plot-subtitle: element-text(
font: "Inclusive Sans",
size: 14.4pt,
colour: rgb("#3f4a57"),
margin: margin(top: 12pt, bottom: 24pt),
),
plot-background: element-rect(
fill: rgb("#f8f8f8"),
inset: margin(top: 24pt, right: 24pt, bottom: 24pt, left: 24pt),
),
axis-title: element-text(size: 12pt),
axis-text: element-text(size: 12pt),
legend-text: element-text(size: 12pt),
),
width: 16cm,
height: 20cm,
)
#show heading.where(level: 1): set text(size: 20pt)
= Bien plus qu'un beau graphique : Creativité et accessibilité avec ggplot2
_By Cara Thompson._
Date: The 17th of June, 2026
Original version: #link("https://www.cararthompson.com/talks/rencontresr-2026-beau-graphique/")[www.cararthompson.com/talks/rencontresr-2026-beau-graphique]
== Typst Version with Gribouille
#align(center)[
#my-plot
]
#place(dx: 68%, dy: 5pt)[
Typst code by #link("https://mickael.canouil.fr")[Mickaël Canouil].
]
@mcanouil

mcanouil commented Jun 18, 2026

Copy link
Copy Markdown
Author
A data visualisation page titled "Bien plus qu un beau graphique : Creativité et accessibilité avec ggplot2" by Cara Thompson, dated 17 June 2026, with a note crediting Typst code to Mickaël Canouil. The chart headline reads "Le chocolat demeure l ingrédient le plus utilisé, même s il s est fait brièvement doubler par les oranges en Saison 8", followed by a short paragraph noting that chocolate creations were far more numerous when Mary Berry was on the judging panel. The line chart plots the number of creations ("Nombre de créations") across 10 seasons ("Saison") for three ingredients: chocolat (dark red diamonds), framboise (pink triangles), and orange (gold circles). A shaded pink background region labelled "Les années Mary Berry" covers seasons 1 to 7. Chocolate counts peak at 30 in season 2 and remain consistently the highest series throughout; raspberry and orange counts are lower and more variable, with orange briefly surpassing chocolate in season 8.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment