Summary
Add an annotation API for adding callout text, reference lines, and arrows to plots — matching matplotlib's ax.annotate(), ax.axhline(), and ax.axvline().
Motivation
Performance plots often need annotations: marking the SLA threshold with a horizontal line, labeling the fastest implementation directly on the chart, or drawing an arrow to a regression point. Without annotations, these must be added in post-processing.
Proposed API
// Horizontal/vertical reference lines (in data coordinates)
figure.axhline(100.0) // y = 100 ns SLA threshold
.color(sepia::Color{255, 60, 60})
.style(sepia::LineStyle::Dashed)
.label("SLA limit");
figure.axvline(512.0) // x = 512 (input size boundary)
.color(sepia::Color{120, 120, 120});
// Text annotation at a data coordinate
figure.annotate("peak throughput", /*x=*/3.5, /*y=*/142.0)
.font_size(10)
.color(sepia::Color{40, 40, 40})
.offset_px(5, -8); // pixel offset from anchor point
// Arrow annotation (from label position to data point)
figure.annotate("bottleneck", /*label_x=*/2.0, /*label_y=*/50.0)
.arrow_to(/*data_x=*/3.5, /*data_y=*/120.0)
.color(sepia::Color{200, 60, 60});
Implementation Notes
axhline / axvline: Store a y (or x) value + style. During render(), draw a full-width line at the transformed coordinate using existing draw_line(). Add to legend if .label() is set.
annotate (text only): Transform data coords to pixel coords, call text_renderer.draw_text() at (px + offset_x, py + offset_y).
annotate with arrow: Draw the text, then a line from the text anchor to the data point. Arrow head = small filled triangle using fill_rect approximation or two short lines.
- Annotations stored as a separate
std::vector<AnnotationEntry> in Figure, rendered last (on top of data).
Acceptance Criteria
Summary
Add an annotation API for adding callout text, reference lines, and arrows to plots — matching matplotlib's
ax.annotate(),ax.axhline(), andax.axvline().Motivation
Performance plots often need annotations: marking the SLA threshold with a horizontal line, labeling the fastest implementation directly on the chart, or drawing an arrow to a regression point. Without annotations, these must be added in post-processing.
Proposed API
Implementation Notes
axhline/axvline: Store a y (or x) value + style. Duringrender(), draw a full-width line at the transformed coordinate using existingdraw_line(). Add to legend if.label()is set.annotate(text only): Transform data coords to pixel coords, calltext_renderer.draw_text()at(px + offset_x, py + offset_y).annotatewith arrow: Draw the text, then a line from the text anchor to the data point. Arrow head = small filled triangle usingfill_rectapproximation or two short lines.std::vector<AnnotationEntry>inFigure, rendered last (on top of data).Acceptance Criteria
axhline()andaxvline()draw correctly across the full plot areaaxhline/axvlineentries appear in legend when.label()is setannotate()places text at correct data-space coordinatesexamples/annotations.cppshowing an SLA line + labeled peak