A timeline visualization that displays events and milestones along a temporal axis. Events are represented as points or markers with accompanying labels, making it easy to understand the sequence and timing of events. This plot type excels at showing chronological progressions and is particularly effective for communicating project phases, historical events, or any time-ordered sequence of occurrences.

# anyplot.ai
# timeline-basic: Event Timeline
# Library: makie 0.21.9 | Julia 1.11.9
# Quality: 88/100 | Created: 2026-09-09
using CairoMakie
using Dates
using Colors
using Random
Random.seed!(42)
# --- Theme tokens -----------------------------------------------------------
const THEME = get(ENV, "ANYPLOT_THEME", "light")
const PAGE_BG = THEME == "light" ? colorant"#FAF8F1" : colorant"#1A1A17"
const INK = THEME == "light" ? colorant"#1A1A17" : colorant"#F0EFE8"
const INK_SOFT = THEME == "light" ? colorant"#4A4A44" : colorant"#B8B7B0"
const IMPRINT_PALETTE = [
colorant"#009E73", colorant"#C475FD", colorant"#4467A3", colorant"#BD8233",
colorant"#2ABCCD",
]
# --- Data ---------------------------------------------------------------
milestones = [
(Date(2024, 1, 15), "Kickoff & Planning", "Planning"),
(Date(2024, 2, 20), "Requirements Signed Off", "Planning"),
(Date(2024, 3, 10), "Architecture Design", "Design"),
(Date(2024, 4, 5), "UI Prototype Approved", "Design"),
(Date(2024, 5, 18), "Core API Complete", "Build"),
(Date(2024, 6, 22), "Database Migration", "Build"),
(Date(2024, 7, 30), "Feature Freeze", "Build"),
(Date(2024, 9, 2), "Beta Release", "Testing"),
(Date(2024, 10, 14), "Security Audit Passed", "Testing"),
(Date(2024, 11, 25), "General Availability", "Launch"),
]
categories = ["Planning", "Design", "Build", "Testing", "Launch"]
category_colors = Dict(
"Planning" => IMPRINT_PALETTE[1],
"Design" => IMPRINT_PALETTE[2],
"Build" => IMPRINT_PALETTE[3],
"Testing" => IMPRINT_PALETTE[4],
"Launch" => IMPRINT_PALETTE[5],
)
dates = [m[1] for m in milestones]
event_names = [m[2] for m in milestones]
event_cats = [m[3] for m in milestones]
day_numbers = Float64.(Dates.value.(dates .- dates[1]))
event_colors = [category_colors[c] for c in event_cats]
# --- Plot -----------------------------------------------------------------
title_str = "timeline-basic · julia · makie · anyplot.ai"
fig = Figure(
resolution = (1600, 900),
fontsize = 14,
backgroundcolor = PAGE_BG,
)
ax = Axis(
fig[1, 1];
title = title_str,
titlesize = 27,
titlecolor = INK,
backgroundcolor = PAGE_BG,
xlabel = "2024",
xlabelsize = 14,
xlabelcolor = INK,
xticksvisible = false,
xticklabelsvisible = false,
leftspinevisible = false,
rightspinevisible = false,
topspinevisible = false,
bottomspinecolor = INK_SOFT,
yticksvisible = false,
yticklabelsvisible = false,
xgridvisible = false,
ygridvisible = false,
)
hidespines!(ax, :l, :r, :t)
ylims!(ax, -1.6, 1.6)
# Baseline axis
hlines!(ax, [0]; color = INK_SOFT, linewidth = 2)
# Stems + alternating labels above/below to prevent overlap
for (i, day) in enumerate(day_numbers)
above = isodd(i)
stem_top = above ? 0.9 : -0.9
label_y = above ? 1.1 : -1.1
lines!(ax, [day, day], [0.0, stem_top]; color = event_colors[i], linewidth = 2)
label = event_names[i] * "\n" * Dates.format(dates[i], "u d")
text!(
ax, day, label_y;
text = label,
color = INK,
fontsize = 13,
align = (:center, above ? :bottom : :top),
lineheight = 1.3,
)
end
scatter!(
ax, day_numbers, zeros(length(day_numbers));
color = event_colors, markersize = 20, strokewidth = 2, strokecolor = PAGE_BG,
)
# Legend for categories
legend_elements = [
MarkerElement(color = category_colors[c], marker = :circle, markersize = 16)
for c in categories
]
Legend(
fig[2, 1], legend_elements, categories;
orientation = :horizontal,
framevisible = false,
labelcolor = INK_SOFT,
labelsize = 12,
tellwidth = false,
tellheight = true,
)
rowsize!(fig.layout, 2, Relative(0.08))
hideydecorations!(ax)
# --- Save -------------------------------------------------------------------
save("plot-$(THEME).png", fig; px_per_unit = 2)
Runnable source as JSON, for any HTTP client: https://api.anyplot.ai/specs/timeline-basic/makie/code. Any spec id and library id listed in llms-full.txt fit the same URL shape; every URL below is complete and callable.
{
"spec_id": "timeline-basic",
"language": "julia",
"library": "makie",
"page": "https://anyplot.ai/timeline-basic/julia/makie",
"hub": "https://anyplot.ai/timeline-basic",
"code_json": "https://api.anyplot.ai/specs/timeline-basic/makie/code",
"spec_json": "https://api.anyplot.ai/specs/timeline-basic",
"render_light_png": "https://storage.googleapis.com/anyplot-images/plots/timeline-basic/julia/makie/plot-light.png",
"render_dark_png": "https://storage.googleapis.com/anyplot-images/plots/timeline-basic/julia/makie/plot-dark.png",
"quality_score": 88.0,
"license": "MIT",
"guide": "https://anyplot.ai/llms.txt"
}Part of Event Timeline on anyplot.ai.