#1731·visx

Whisker calculation (min/max) in box plot not considering actual datapoints if there are outliers

Author: titzstCreated Jul 13, 2023Updated Sep 16, 2026

The current implementation of calculating the whiskers of a box plot only considers the actual datapoints for the calculation if there are no outliers. This leads to incorrect chart representations.

Example: The following histogram shows a dataset of 1,000 points with a minimum value of 4.1 and a maximum value of 10.73.

image

When shown using the current implementation of the box plot stats calculation, this leads to the following box plot.

image

The "maximum" whisker clearly extends beyond the maximum dataset value of 10.73, which should not be the case as it suggests to the user that there is data in the dataset which is not actually there. Also, the two whiskers are the exact same length, which can theoretically happen for a dataset, but is rather an edge case in reality.

From my perspective, the issue lies in packages/visx-stats/src/util/computeStats.ts where the following code only sets max and min to values that actually exist in the dataset when there are no outliers.

  let min = firstQuartile - 1.5 * IQR;
  let max = thirdQuartile + 1.5 * IQR;

  const outliers = points.filter((p) => p < min || p > max);
  if (outliers.length === 0) {
    min = Math.min(...points);
    max = Math.max(...points);
  }

In contrast to this, the values should be set independent of outliers to the largest datapoint from the dataset that's smaller than the maximum calculated from using the IQRs for the upper whisker and vice versa for the lower whisker. This can lead to different length of whiskers, which is perfectly fine. See here for more details: https://www.nature.com/articles/nmeth.2813

So something along these lines should work:

  let min = firstQuartile - 1.5 * IQR;
  let max = thirdQuartile + 1.5 * IQR;

  const nonOutliers = points.filter((p) => p >= min && p <= max);
  min = Math.min(...nonOutliers);
  max = Math.max(...nonOutliers);

Note that this will not make sense if there is too little data. But box plots in general only make sense when there is a minimum of 5 points. If there are less points, they typically fall back to showing individual points.