Skip to content

Box mark ^0.4.2

The box mark summarizes one-dimensional distributions as boxplots. It is a composite mark consisting of a rule to represent the extreme values (not including outliers), a bar to represent the interquartile range (trimmed to the data), a tick to represent the median value, and a dot to represent any outliers. The group transform is used to group and aggregate data.

For example, the boxplot below shows A.A. Michelson’s experimental measurements of the speed of light. (Speed is in km/sec minus 299,000.)

6507007508008509009501,0001,050↑ Speed12345ExptFork
js
Plot.plot({
  y: {
    grid: true,
    inset: 6
  },
  marks: [
    Plot.boxY(morley, {x: "Expt", y: "Speed"})
  ]
})

boxY produces vertical boxplots; for horizontal boxplots, use boxX and swap x and y.

12345Expt6507007508008509009501,0001,050Speed →Fork
js
Plot.plot({
  x: {
    grid: true,
    inset: 6
  },
  marks: [
    Plot.boxX(morley, {x: "Speed", y: "Expt"})
  ]
})

As shorthand, you can pass an array of numbers for a single boxplot.

01234567Fork
js
Plot.boxX([0, 3, 4.4, 4.5, 4.6, 5, 7]).plot()

Since the box mark uses the group transform, the secondary dimension must be ordinal. To group quantitative values, bin manually, say with Math.floor; see #1330.

Fork
js
Plot.plot({
  marginLeft: 60,
  y: {
    grid: true,
    label: "Price"
  },
  x: {
    interval: 0.5,
    label: "Carats",
    labelAnchor: "right",
    tickFormat: (x) => x.toFixed(1)
  },
  marks: [
    Plot.ruleY([0]),
    Plot.boxY(diamonds, {x: (d) => Math.floor(d.carat * 2) / 2, y: "price"})
  ]
})

This chart is slightly easier to construct with faceting using the interval scale option on the fx scale. (This technique cannot be used with the x scale above because the scale interval transform is applied after the box mark applies the group transform.)

Fork
js
Plot.plot({
  marginLeft: 60,
  y: {
    grid: true,
    label: "Price"
  },
  fx: {
    interval: 0.5,
    label: "Carats",
    labelAnchor: "right",
    tickFormat: (x) => x.toFixed(1)
  },
  marks: [
    Plot.ruleY([0]),
    Plot.boxY(diamonds, {fx: "carat", y: "price"})
  ]
})

Box options

The box mark is a composite mark consisting of four marks:

  • a rule representing the extreme values (not including outliers)
  • a bar representing the interquartile range (trimmed to the data)
  • a tick representing the median value, and
  • a dot representing outliers, if any

The given options are passed through to these underlying marks, with the exception of the following options:

  • fill - the fill color of the bar; defaults to #ccc
  • fillOpacity - the fill opacity of the bar; defaults to 1
  • stroke - the stroke color of the rule, tick, and dot; defaults to currentColor
  • strokeOpacity - the stroke opacity of the rule, tick, and dot; defaults to 1
  • strokeWidth - the stroke width of the tick; defaults to 1

boxX(data, options)

js
Plot.boxX(simpsons.map((d) => d.imdb_rating))

Returns a horizontal box mark. If the x option is not specified, it defaults to the identity function, as when data is an array of numbers. If the y option is not specified, it defaults to null; if the y option is specified, it should represent an ordinal (discrete) value.

boxY(data, options)

js
Plot.boxY(simpsons.map((d) => d.imdb_rating))

Returns a vertical box mark. If the y option is not specified, it defaults to the identity function, as when data is an array of numbers. If the x option is not specified, it defaults to null; if the x option is specified, it should represent an ordinal (discrete) value.