- Charts
- Line Chart
- Bar Chart
- Area Chart
- Scatter Chart
- Pie Chart
- Donut Chart
- Dot Plot Chart
- Lollipop Chart
- Dumbbell Chart
- Slope Chart
- Range Chart
- Histogram Chart
- Box Plot Chart
- Violin Chart
- Polar Chart
- Parallel Coordinates
- SPLOM Chart
- Parcats Chart
- Candlestick Chart
- OHLC Chart
- Waterfall Chart
- Funnel Chart
- Heatmap Chart
- Contour Chart
- Density Chart
- Ternary Chart
- Radar Chart
- Treemap Chart
- Sunburst Chart
- Sankey Chart
- Gauge Chart
- Bullet Chart
- Icicle Chart
- Network Graph
- Dendrogram
- Choropleth Chart
"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.
"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
| Prop | Type | Default | Description |
|---|---|---|---|
data | BoxPlotDataPoint[] | required | Array of data points with labels and values |
color | string | "#2563eb" | Default fill color for boxes |
className | string | - | Additional CSS classes |
showGrid | boolean | true | Show grid lines |
showTooltip | boolean | true | Enable tooltip on hover |
showOutliers | boolean | true | Display outlier points |
orientation | "vertical" | "horizontal" | "vertical" | Box orientation |
boxWidth | number | 0.6 | Width of boxes relative to category spacing (0-1) |
whiskerType | "minmax" | "iqr" | "iqr" | Whisker calculation method |
aspectRatio | number | 2 | Width 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