Activity Rings Progress Chart in Makie.jl (Julia)

The same plot in 14 other libraries — Python: Altair, Bokeh, lets-plot, Matplotlib, Plotly, plotnine, Pygal, Seaborn; R: ggplot2; JavaScript: Chart.js, D3.js, Apache ECharts, Highcharts, MUI X Charts. Compare all 15 side by side: Activity Rings Progress Chart in Python, R, Julia and JavaScript.

An activity rings chart displays goal completion for several metrics at once using concentric radial progress arcs, in the style popularized by fitness trackers. Each ring is a partial arc with rounded end caps that starts at the top (12 o'clock) and sweeps clockwise in proportion to how close the metric is to its goal, with a distinct color per metric and a faint background track showing the full circle. It is instantly recognizable and ideal for at-a-glance comparison of progress across a small set of related goals, filling the general radial-progress gap that needle gauges (`gauge-basic`) and polar bars (`polar-bar`) do not cover.

Activity Rings Progress Chart rendered with Makie.jl

Renders

Julia source (Makie.jl)

# anyplot.ai
# gauge-activity-rings: Activity Rings Progress Chart
# Library: makie 0.22.10 | Julia 1.11.9
# Quality: 89/100 | Created: 2026-06-14

using CairoMakie
using Colors
using Statistics

# 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 INK_MUTED = THEME == "light" ? colorant"#6B6A63" : colorant"#A8A79F"

const IMPRINT_PALETTE = [
    colorant"#009E73",  # 1 — brand green (first series, always)
    colorant"#C475FD",  # 2 — lavender
    colorant"#4467A3",  # 3 — blue
    colorant"#BD8233",  # 4 — ochre
    colorant"#AE3030",  # 5 — matte red
    colorant"#2ABCCD",  # 6 — cyan
    colorant"#954477",  # 7 — rose
    colorant"#99B314",  # 8 — lime
]

# Data — daily fitness tracker: Move, Exercise, Stand
const metrics     = ["Move",  "Exercise", "Stand"]
const val_current = [420,      25,          9]
const val_goal    = [600,      30,         12]
const val_unit    = ["kcal",  "min",       "hr"]
const ring_radii  = [0.68,    0.50,        0.32]
const ring_colors = IMPRINT_PALETTE[1:3]

const fractions = val_current ./ val_goal     # [0.70, 0.833, 0.75]
const avg_pct   = round(Int, mean(fractions) * 100)   # 76

# Figure — square canvas → 2400 × 2400 output
fig = Figure(
    size            = (1200, 1200),
    fontsize        = 14,
    backgroundcolor = PAGE_BG,
)

ax = Axis(
    fig[1, 1];
    title              = "gauge-activity-rings · julia · makie · anyplot.ai",
    titlesize          = 20,
    titlecolor         = INK,
    backgroundcolor    = PAGE_BG,
    aspect             = DataAspect(),
    topspinevisible    = false,
    rightspinevisible  = false,
    leftspinevisible   = false,
    bottomspinevisible = false,
    xgridvisible       = false,
    ygridvisible       = false,
    xticksvisible      = false,
    yticksvisible      = false,
    xticklabelsvisible = false,
    yticklabelsvisible = false,
)

limits!(ax, -1.10, 1.10, -1.10, 1.10)

# Ring drawing parameters
const N_PTS = 360
const LW    = 46   # device px → ×2 = 92 output px on 2400-px canvas

# Draw rings outer → inner
for (r, frac, col) in zip(ring_radii, fractions, ring_colors)
    # Faint background track — full circle; higher opacity in dark for contrast
    bg_alpha = THEME == "dark" ? 0.22f0 : 0.12f0
    θ_bg = range(0.0, 2π, length = N_PTS + 1)
    lines!(ax, r .* cos.(θ_bg), r .* sin.(θ_bg);
           linewidth = LW, color = (col, bg_alpha))

    # Progress arc — starts at 12 o'clock (π/2), sweeps clockwise
    sweep = min(frac, 1.0) * 2π
    n_arc = max(4, round(Int, frac * N_PTS))
    θ_arc = range(π / 2, π / 2 - sweep; length = n_arc)
    x_arc = r .* cos.(θ_arc)
    y_arc = r .* sin.(θ_arc)
    lines!(ax, x_arc, y_arc; linewidth = LW, color = col)

    # Circular end caps that match the line width for a rounded look
    scatter!(ax, [x_arc[1]],   [y_arc[1]];   color = col, markersize = LW, strokewidth = 0)
    scatter!(ax, [x_arc[end]], [y_arc[end]]; color = col, markersize = LW, strokewidth = 0)
end

# Center summary text
text!(ax, 0.0, 0.10;
      text     = "$(avg_pct)%",
      fontsize = 60,
      color    = INK,
      align    = (:center, :center))
text!(ax, 0.0, -0.12;
      text     = "COMPLETE",
      fontsize = 18,
      color    = INK_MUTED,
      align    = (:center, :center))

# Bottom legend strip — color dot + metric name + value/goal
const x_pos = [-0.52, 0.0, 0.52]
const y_lbl = -0.84
const y_val = -0.97

for (i, (name, cur, goal, unit, col)) in
        enumerate(zip(metrics, val_current, val_goal, val_unit, ring_colors))
    xc = x_pos[i]
    scatter!(ax, [xc - 0.14], [(y_lbl + y_val) / 2];
             color = col, markersize = 22, strokewidth = 0)
    text!(ax, xc - 0.04, y_lbl;
          text = name, fontsize = 16, color = INK, align = (:left, :baseline))
    text!(ax, xc - 0.04, y_val;
          text = "$(cur) / $(goal) $(unit)", fontsize = 13, color = INK_SOFT,
          align = (:left, :baseline))
end

# Save — px_per_unit = 2 doubles the resolution to 2400 × 2400
save("plot-$(THEME).png", fig; px_per_unit = 2)

Retrieve this implementation

Runnable source as JSON, for any HTTP client: https://api.anyplot.ai/specs/gauge-activity-rings/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": "gauge-activity-rings",
  "language": "julia",
  "library": "makie",
  "page": "https://anyplot.ai/gauge-activity-rings/julia/makie",
  "hub": "https://anyplot.ai/gauge-activity-rings",
  "code_json": "https://api.anyplot.ai/specs/gauge-activity-rings/makie/code",
  "spec_json": "https://api.anyplot.ai/specs/gauge-activity-rings",
  "render_light_png": "https://storage.googleapis.com/anyplot-images/plots/gauge-activity-rings/julia/makie/plot-light.png",
  "render_dark_png": "https://storage.googleapis.com/anyplot-images/plots/gauge-activity-rings/julia/makie/plot-dark.png",
  "quality_score": 89.0,
  "license": "MIT",
  "guide": "https://anyplot.ai/llms.txt"
}

Part of Activity Rings Progress Chart on anyplot.ai.

Other implementations