Each row is one candidate box from a detector, sorted top-to-bottom by descending confidence — its bar length is that confidence score. Rows never move once drawn; sliders only recolor rows and redraw arcs, so you can watch the same 90 candidates get filtered differently as thresholds change.
An arc on the right connects two rows whose boxes overlap (IoU) past the current threshold. When the greedy loop keeps a row, every arc from it to a lower row means "this suppressed that" — those arcs light up in red and the lower row turns red too. Arcs that never get walked (because one endpoint was already suppressed by someone else first) stay faint.
IoU(A, B) = area(A ∩ B) / area(A ∪ B)
pool = { b : score(b) ≥ confT }, sorted by score desc → row order
kept = []
while pool not empty:
best = pool.pop_front() → top remaining row, turns teal
kept.append(best)
for b in pool: if IoU(best,b) ≥ iouT: remove b, arc→red → row turns red
- Confidence threshold — rows below it never enter the pool; they sink to the grey strip at the bottom.
- IoU threshold — how much two boxes' rectangles must overlap before an arc becomes an active suppression edge. Low values prune aggressively; high values let near-duplicate rows both survive.
- Row/bar length is confidence; arc curvature is purely cosmetic (bigger vertical gap → wider arc) and carries no numeric meaning.
This is the same greedy algorithm every modern detector (YOLO, Faster R-CNN, SSD…) runs as its last step — just drawn as a suppression graph instead of boxes on an image, so the *order of decisions* is as visible as the *geometry* they act on.