2

Box Plot Chart

PreviousNext

A statistical chart component for visualizing data distributions through quartiles, medians, and outlier detection.

"use client"

import { BoxPlotChart } from "@/components/ui/charts"

const data = [
  {
    label: "January",
    values: [20, 25, 30, 35, 40, 45, 50, 52, 55, 60, 65, 70, 75, 80],
    color: "#2563eb",
  },
  {
    label: "February",
    values: [15, 22, 28, 32, 38, 42, 48, 55, 58, 62, 68, 72, 78, 85, 90],
    color: "#3b82f6",
  },
  {
    label: "March",
    values: [10, 18, 25, 30, 35, 40, 42, 45, 48, 52, 55, 60],
    color: "#60a5fa",
  },
  {
    label: "April",
    values: [25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75],
    color: "#93c5fd",
  },
  {
    label: "May",
    values: [18, 22, 28, 35, 42, 48, 52, 58, 62, 68, 72, 78],
    color: "#2563eb",
  },
]

export function BoxPlotChartDemo() {
  return (
    <BoxPlotChart
      data={data}
      showGrid
      showTooltip
      showOutliers
      aspectRatio={2}
    />
  )
}

About

The Box Plot Chart (also known as box and whisker plot) displays the distribution of data through quartiles. It shows:

  • Median (Q2) - The middle value
  • Quartiles (Q1, Q3) - The box represents the interquartile range (IQR)
  • Whiskers - Extend to min/max values or 1.5×IQR
  • Outliers - Points beyond the whiskers

Installation

pnpm dlx shadcn@latest add https://ui.simplifying.ai/r/box-plot-chart.json

Usage

import { BoxPlotChart } from "@/components/ui/charts"
 
const data = [
  { label: "January", values: [20, 25, 30, 35, 40, 45, 50, 55, 60] },
  { label: "February", values: [15, 22, 28, 35, 42, 48, 55, 62, 70] },
]
 
export function MyChart() {
  return <BoxPlotChart data={data} />
}

Examples

Default

The default box plot displays vertical boxes with grid lines, tooltips, and outlier detection using the IQR method.

"use client"

import { BoxPlotChart } from "@/components/ui/charts"

const data = [
  {
    label: "January",
    values: [20, 25, 30, 35, 40, 45, 50, 52, 55, 60, 65, 70, 75, 80],
    color: "#2563eb",
  },
  {
    label: "February",
    values: [15, 22, 28, 32, 38, 42, 48, 55, 58, 62, 68, 72, 78, 85, 90],
    color: "#3b82f6",
  },
  {
    label: "March",
    values: [10, 18, 25, 30, 35, 40, 42, 45, 48, 52, 55, 60],
    color: "#60a5fa",
  },
  {
    label: "April",
    values: [25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75],
    color: "#93c5fd",
  },
  {
    label: "May",
    values: [18, 22, 28, 35, 42, 48, 52, 58, 62, 68, 72, 78],
    color: "#2563eb",
  },
]

export function BoxPlotChartDemo() {
  return (
    <BoxPlotChart
      data={data}
      showGrid
      showTooltip
      showOutliers
      aspectRatio={2}
    />
  )
}

Horizontal

Use orientation="horizontal" for horizontal box plots. Useful when you have many categories or long labels.

"use client"

import { BoxPlotChart } from "@/components/ui/charts"

const data = [
  {
    label: "Product A",
    values: [42, 48, 52, 55, 58, 62, 65, 68, 72, 75, 78, 82],
    color: "#2563eb",
  },
  {
    label: "Product B",
    values: [35, 40, 45, 50, 55, 58, 62, 68, 72, 78, 85],
    color: "#3b82f6",
  },
  {
    label: "Product C",
    values: [28, 32, 38, 42, 48, 52, 55, 60, 65, 70],
    color: "#60a5fa",
  },
  {
    label: "Product D",
    values: [50, 55, 60, 65, 70, 75, 78, 82, 85, 88, 92],
    color: "#93c5fd",
  },
]

export function BoxPlotChartHorizontalDemo() {
  return (
    <BoxPlotChart
      data={data}
      orientation="horizontal"
      showGrid
      showTooltip
      aspectRatio={1.5}
    />
  )
}
<BoxPlotChart data={data} orientation="horizontal" />

Multiple Colors

Assign different colors to each box by adding a color property to your data points.

"use client"

import { BoxPlotChart } from "@/components/ui/charts"

const data = [
  {
    label: "Q1",
    values: [45, 52, 58, 62, 68, 72, 75, 78, 82, 85, 88, 92],
    color: "#2563eb",
  },
  {
    label: "Q2",
    values: [55, 60, 65, 70, 75, 80, 85, 88, 92, 95, 98],
    color: "#3b82f6",
  },
  {
    label: "Q3",
    values: [62, 68, 72, 78, 82, 85, 88, 92, 95, 100, 105],
    color: "#60a5fa",
  },
  {
    label: "Q4",
    values: [70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120],
    color: "#93c5fd",
  },
]

export function BoxPlotChartMultiDemo() {
  return (
    <BoxPlotChart
      data={data}
      showGrid
      showTooltip
      showOutliers
      aspectRatio={2}
    />
  )
}
const data = [
  { label: "Q1", values: [...], color: "#93c5fd" },
  { label: "Q2", values: [...], color: "#3b82f6" },
  { label: "Q3", values: [...], color: "#2563eb" },
  { label: "Q4", values: [...], color: "#1d4ed8" },
]
 
<BoxPlotChart data={data} />

Comparison / Interactive

Create interactive charts with state-controlled data. Toggle between different datasets to compare distributions.

Control: Baseline
Experiment: +40% avg
"use client"

import * as React from "react"

import { BoxPlotChart } from "@/components/ui/charts"

const controlData = [
  {
    label: "Week 1",
    values: [42, 45, 48, 52, 55, 58, 60, 62, 65, 68],
    color: "#2563eb",
  },
  {
    label: "Week 2",
    values: [44, 48, 52, 55, 58, 62, 65, 68, 70, 72],
    color: "#2563eb",
  },
  {
    label: "Week 3",
    values: [46, 50, 54, 58, 62, 65, 68, 70, 72, 75],
    color: "#2563eb",
  },
  {
    label: "Week 4",
    values: [48, 52, 56, 60, 64, 68, 70, 72, 75, 78],
    color: "#2563eb",
  },
]

const experimentData = [
  {
    label: "Week 1",
    values: [52, 58, 62, 68, 72, 75, 78, 82, 85, 88],
    color: "#60a5fa",
  },
  {
    label: "Week 2",
    values: [58, 65, 70, 75, 80, 85, 88, 92, 95, 98],
    color: "#60a5fa",
  },
  {
    label: "Week 3",
    values: [65, 72, 78, 82, 88, 92, 95, 100, 105, 108],
    color: "#60a5fa",
  },
  {
    label: "Week 4",
    values: [72, 80, 85, 90, 95, 100, 105, 110, 115, 120],
    color: "#60a5fa",
  },
]

export function BoxPlotChartComparisonDemo() {
  const [activeGroup, setActiveGroup] = React.useState<
    "control" | "experiment"
  >("control")

  const data = activeGroup === "control" ? controlData : experimentData

  return (
    <div className="w-full">
      {/* Toggle buttons */}
      <div className="mb-4 flex gap-2">
        <button
          className={`rounded-lg px-4 py-2 text-sm font-medium transition-colors ${
            activeGroup === "control"
              ? "bg-[#2563eb] text-white"
              : "bg-muted text-muted-foreground hover:bg-muted/80"
          }`}
          onClick={() => setActiveGroup("control")}
        >
          Control Group
        </button>
        <button
          className={`rounded-lg px-4 py-2 text-sm font-medium transition-colors ${
            activeGroup === "experiment"
              ? "bg-[#60a5fa] text-white"
              : "bg-muted text-muted-foreground hover:bg-muted/80"
          }`}
          onClick={() => setActiveGroup("experiment")}
        >
          Experiment Group
        </button>
      </div>

      <BoxPlotChart
        data={data}
        showGrid
        showTooltip
        showOutliers
        aspectRatio={2}
      />

      {/* Summary */}
      <div className="mt-4 flex justify-center gap-8 text-sm">
        <div className="flex items-center gap-2">
          <div className="size-3 rounded-sm bg-[#2563eb]" />
          <span className="text-muted-foreground">Control: Baseline</span>
        </div>
        <div className="flex items-center gap-2">
          <div className="size-3 rounded-sm bg-[#60a5fa]" />
          <span className="text-muted-foreground">Experiment: +40% avg</span>
        </div>
      </div>
    </div>
  )
}

Outliers Detection

The IQR method automatically detects and displays outliers as individual points. Outliers are values that fall below Q1 - 1.5×IQR or above Q3 + 1.5×IQR.

Outliers are detected using IQR method (1.5 × IQR from quartiles)

"use client"

import { BoxPlotChart } from "@/components/ui/charts"

// Data with intentional outliers
const data = [
  {
    label: "Dataset A",
    values: [
      5,
      10, // outliers below
      35,
      38,
      42,
      45,
      48,
      52,
      55,
      58,
      62,
      65,
      68,
      95,
      100, // outliers above
    ],
    color: "#2563eb",
  },
  {
    label: "Dataset B",
    values: [40, 45, 48, 52, 55, 58, 62, 65, 68, 72, 75, 78, 82],
    color: "#3b82f6",
  },
  {
    label: "Dataset C",
    values: [
      15, // outlier below
      50,
      55,
      58,
      62,
      65,
      68,
      72,
      75,
      78,
      82,
      85,
      120,
      125, // outliers above
    ],
    color: "#60a5fa",
  },
]

export function BoxPlotChartOutliersDemo() {
  return (
    <div className="w-full">
      <BoxPlotChart
        data={data}
        showGrid
        showTooltip
        showOutliers
        whiskerType="iqr"
        aspectRatio={2}
      />
      <p className="text-muted-foreground mt-3 text-center text-xs">
        Outliers are detected using IQR method (1.5 × IQR from quartiles)
      </p>
    </div>
  )
}
<BoxPlotChart data={data} showOutliers whiskerType="iqr" />

API Reference

PropTypeDefaultDescription
dataBoxPlotDataPoint[]requiredArray of data points with labels and values
colorstring"#2563eb"Default fill color for boxes
classNamestring-Additional CSS classes
showGridbooleantrueShow grid lines
showTooltipbooleantrueEnable tooltip on hover
showOutliersbooleantrueDisplay outlier points
orientation"vertical" | "horizontal""vertical"Box orientation
boxWidthnumber0.6Width of boxes relative to category spacing (0-1)
whiskerType"minmax" | "iqr""iqr"Whisker calculation method
aspectRationumber2Width to height ratio
valueFormatter(value: number) => string-Format displayed values

Data Types

// Raw data with values array
interface BoxPlotDataPoint {
  label: string // Category name
  values: number[] // Array of numeric values
  color?: string // Optional: custom color for this box
}
 
// Pre-computed statistics (alternative)
interface BoxPlotStats {
  label: string
  min: number
  q1: number
  median: number
  q3: number
  max: number
  outliers: number[]
  color?: string
}

Whisker Types

  • "iqr" (default) - Whiskers extend to 1.5×IQR from quartiles. Values beyond are shown as outliers.
  • "minmax" - Whiskers extend to the minimum and maximum values. No outliers shown.

Customization

Custom Colors Per Box

const data = [
  { label: "Success", values: [...], color: "#22c55e" },
  { label: "Warning", values: [...], color: "#eab308" },
  { label: "Error", values: [...], color: "#ef4444" },
]
 
<BoxPlotChart data={data} />

Pre-computed Statistics

If you've already computed the statistics, you can pass them directly:

const stats = [
  {
    label: "Dataset A",
    min: 10,
    q1: 25,
    median: 50,
    q3: 75,
    max: 90,
    outliers: [2, 98],
  },
]
 
<BoxPlotChart data={stats} />

Notes

  • Box plots are ideal for comparing distributions across multiple groups or categories
  • The IQR (Interquartile Range) method is the standard approach for detecting outliers in statistical analysis
  • Use horizontal orientation when dealing with many categories or long labels
  • The component automatically calculates quartiles, median, and outliers from raw data arrays
  • Pre-computed statistics can be passed directly if you've already performed the calculations
  • Box width can be adjusted to improve readability when comparing multiple categories