Box plot

박스 플롯

Summarizes a distribution’s center and spread with five numbers: min, Q1, median, Q3, max.

Also known as: Box-and-whisker plot상자 수염 그림
···
html
<div class="viz">
  <svg id="svg"></svg>
</div>
css
:root{--viz-4:#e8a23a;--viz-5:#4098d7}
body{display:block}
.viz{position:relative;width:100%;height:100%}
svg{display:block;width:100%;height:100%;overflow:visible}
.axis{stroke:var(--line);stroke-width:1}
.tick{fill:var(--muted);font-weight:600}
.minor{display:none}
@media (min-width:460px){.minor{display:inline}}
.wk{stroke-width:1.4}
.med{stroke-width:2.4}
js
var svg = document.getElementById('svg');
var NS = 'http://www.w3.org/2000/svg';
function se(t){ return document.createElementNS(NS,t); }
function sa(e,o){ for (var k in o) e.setAttribute(k,o[k]); }
function R(a,b){ return a + Math.random()*(b-a); }

var GROUPS = ['A','B','C','D'];
var COLORS = ['var(--accent)','var(--viz-4)','var(--accent-3)','var(--viz-5)'];

function genStats(){
  var median = R(35,68);
  var iqr = R(10,26);
  var q1 = Math.max(2, median-iqr/2);
  var q3 = Math.min(98, median+iqr/2);
  var lo = Math.max(0, q1-R(5,16));
  var hi = Math.min(100, q3+R(5,16));
  return { lo:lo, q1:q1, med:median, q3:q3, hi:hi };
}
var cur = GROUPS.map(genStats);
var W=300, H=200;

function measure(){
  var r = svg.getBoundingClientRect();
  W = Math.max(r.width,10); H = Math.max(r.height,10);
  sa(svg,{ viewBox: '0 0 ' + W + ' ' + H });
}

function draw(){
  svg.innerHTML = '';
  var padL=24, padR=10, padT=14, padB=20;
  var pw=W-padL-padR, ph=H-padT-padB;
  var n=GROUPS.length;
  var fs = Math.max(8, Math.min(12, W/72));
  var gap = pw*0.12/n;
  var bw = Math.min(38,(pw-gap*(n-1))/n);
  var totalW = bw*n+gap*(n-1);
  var startX = padL+(pw-totalW)/2;
  function Y(v){ return padT+ph-(v/100)*ph; }

  var base = se('line');
  sa(base,{x1:padL,y1:H-padB,x2:W-padR,y2:H-padB,class:'axis'});
  svg.appendChild(base);

  cur.forEach(function(s,i){
    var x = startX+i*(bw+gap);
    var cx = x+bw/2;
    var color = COLORS[i];
    var wk = se('line');
    sa(wk,{x1:cx,y1:Y(s.lo),x2:cx,y2:Y(s.hi),class:'wk',stroke:color});
    svg.appendChild(wk);
    [s.lo,s.hi].forEach(function(v){
      var cap = se('line');
      sa(cap,{x1:cx-bw*0.22,y1:Y(v),x2:cx+bw*0.22,y2:Y(v),class:'wk',stroke:color});
      svg.appendChild(cap);
    });
    var box = se('rect');
    sa(box,{x:x,y:Y(s.q3),width:bw,height:Math.max(Y(s.q1)-Y(s.q3),1),rx:2,fill:color,'fill-opacity':0.22,stroke:color,'stroke-width':1.6});
    svg.appendChild(box);
    var med = se('line');
    sa(med,{x1:x,y1:Y(s.med),x2:x+bw,y2:Y(s.med),class:'med',stroke:color});
    svg.appendChild(med);
    var cat = se('text');
    sa(cat,{x:cx,y:H-padB+14,'text-anchor':'middle',class:'tick','font-size':fs-1});
    cat.textContent = GROUPS[i];
    svg.appendChild(cat);
  });
}

function animate(target){
  var from = cur;
  var t0 = performance.now();
  function step(t){
    var p = Math.min(1,(t-t0)/750);
    var e = 1-Math.pow(1-p,3);
    cur = from.map(function(s,i){
      var to = target[i];
      var m = {};
      ['lo','q1','med','q3','hi'].forEach(function(k){ m[k] = s[k]+(to[k]-s[k])*e; });
      return m;
    });
    draw();
    if (p<1) requestAnimationFrame(step); else cur = target;
  }
  requestAnimationFrame(step);
}

new ResizeObserver(function(){ measure(); draw(); }).observe(svg);
measure();
draw();
setInterval(function(){ animate(GROUPS.map(genStats)); }, 3700);

The box's top and bottom edges are Q1 and Q3 — the middle 50% of the data. The line inside is the median; the whiskers extending up and down cover the rest of the range, excluding outliers. Where a single histogram gets crowded fast, box plots line groups up side by side cleanly.

The biggest trap: the same box can hide very different distributions. A single-peaked distribution and a bimodal one can produce nearly identical five-number summaries. If the actual shape matters, pair it with a violin plot or a jittered strip plot.

With only two groups, showing the raw values directly is often clearer — this chart earns its keep once there are four or more groups to compare at once.

When to use

Use it to compare several groups’ distributions — center, spread, outliers — lined up in one row.