ボックスプロットライブラリ比較

3つのアプローチでデータの分布・中央値・外れ値を可視化し、実装方法とスタイルを比較

📊 使用しているサンプルデータ

4つの部門の月次売上データの分布(最小値・第1四分位・中央値・第3四分位・最大値・外れ値)を使用しています。

[
  {
    "group": "営業部",
    "min": 820,
    "q1": 950,
    "median": 1100,
    "q3": 1280,
    "max": 1450,
    "outliers": [
      620,
      1680
    ]
  },
  {
    "group": "マーケティング部",
    "min": 600,
    "q1": 780,
    "median": 920,
    "q3": 1050,
    "max": 1200,
    "outliers": [
      380,
      1420
    ]
  },
  {
    "group": "カスタマーサクセス部",
    "min": 700,
    "q1": 860,
    "median": 980,
    "q3": 1120,
    "max": 1300,
    "outliers": [
      500
    ]
  },
  {
    "group": "パートナー部",
    "min": 900,
    "q1": 1050,
    "median": 1200,
    "q3": 1380,
    "max": 1550,
    "outliers": [
      1800
    ]
  }
]

1. Nivo(@nivo/boxplot)

@nivo/boxplotパッケージでボックスプロットをネイティブサポート。生データを渡すと四分位数・中央値・外れ値を自動計算して描画。ホバー時のツールチップや色のカスタマイズも充実しており、最も手軽に高品質なボックスプロットを実装できる。

✓ 専用パッケージ✓ 美しいデザイン✓ 外れ値対応
特徴: D3.jsベースの高品質な実装。アニメーションやツールチップが標準装備で、デザイン性の高いダッシュボードに最適。
tsx
'use client';
import { ResponsiveBoxPlot } from '@nivo/boxplot';

const data = [
  { group: '営業部', subGroup: '月次売上', n: 50, mean: 1100,
    extrema: [820, 1450], quantiles: [0.1, 0.25, 0.5, 0.75, 0.9],
    values: [820, 950, 1100, 1280, 1450] },
  { group: 'マーケ部', subGroup: '月次売上', n: 50, mean: 900,
    extrema: [600, 1200], quantiles: [0.1, 0.25, 0.5, 0.75, 0.9],
    values: [600, 780, 920, 1050, 1200] },
];

export function NivoBoxPlot() {
  return (
    <div style={{ height: 300 }}>
      <ResponsiveBoxPlot
        data={data as any}
        groupBy="group"
        subGroupBy="subGroup"
        value="value"
        quantiles={[0.1, 0.25, 0.5, 0.75, 0.9]}
        margin={{ top: 20, right: 20, bottom: 60, left: 70 }}
        padding={0.3}
        colorBy="group"
        colors={{ scheme: 'category10' }}
        borderRadius={2}
        borderWidth={1.5}
        medianWidth={2}
        whiskerEndSize={0.6}
      />
    </div>
  );
}

🤖 AIプロンプトテンプレート

React + Tailwind CSSで、Nivo(@nivo/boxplot)を使ったボックスプロットを実装してください。

- 使用ライブラリ: @nivo/boxplot の ResponsiveBoxPlot コンポーネント
- サンプルデータ: 部門別の月次売上分布(最小値・第1四分位・中央値・第3四分位・最大値・外れ値)を用意すること
- インタラクティブ: ホバー時にツールチップで統計値を表示すること
- 外れ値: 外れ値を個別の点として表示すること
- レスポンシブ: 親要素の幅に応じてチャートサイズが変わるよう対応すること
- スタイリング: colorBy="group" で各ボックスに識別しやすい色を設定すること

⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。

2. D3.js(カスタム実装)

D3.jsのd3-arrayで四分位数・中央値を計算し、SVG描画をReactで制御するカスタム実装。ウィスカーの長さ・外れ値の判定基準・スタイルまで完全にコントロール可能。実装コストは高いが、独自の統計表現や複雑なインタラクションが必要な場合に最適。

✓ 完全カスタマイズ✓ 統計計算内蔵✓ 高い表現力
40060080010001200140016001800営業部マーケ部CSS部パートナー部
特徴: SVG要素を直接制御するため、アニメーションや独自インタラクションを自由に実装できる。統計計算もd3-arrayのd3.quantile()で正確に行える。
tsx
'use client';
// D3.js カスタム SVG ボックスプロット
const data = [
  { group: '営業部', min: 820, q1: 950, median: 1100, q3: 1280, max: 1450, outliers: [620, 1680] },
  { group: 'マーケ部', min: 600, q1: 780, median: 920, q3: 1050, max: 1200, outliers: [380, 1420] },
];

export function D3BoxPlot() {
  const viewBoxWidth = 400, viewBoxHeight = 300;
  const margin = { top: 20, right: 20, bottom: 60, left: 60 };
  const width = viewBoxWidth - margin.left - margin.right;
  const height = viewBoxHeight - margin.top - margin.bottom;
  const yMin = 200, yMax = 2000;
  const yScale = (v: number) => ((yMax - v) / (yMax - yMin)) * height;
  const bandWidth = width / data.length;
  const boxW = bandWidth * 0.4;
  const cx = (i: number) => i * bandWidth + bandWidth / 2;
  const colors = ['#3b82f6', '#10b981'];

  return (
    <svg viewBox={`0 0 ${viewBoxWidth} ${viewBoxHeight}`} className="w-full h-full">
      <g transform={`translate(${margin.left}, ${margin.top})`}>
        {data.map((d, i) => (
          <g key={d.group}>
            <line x1={cx(i)} x2={cx(i)} y1={yScale(d.max)} y2={yScale(d.min)} stroke={colors[i]} strokeWidth={1.5} />
            <rect x={cx(i) - boxW / 2} y={yScale(d.q3)} width={boxW}
              height={yScale(d.q1) - yScale(d.q3)} fill={colors[i]} fillOpacity={0.25}
              stroke={colors[i]} strokeWidth={1.5} rx={2} />
            <line x1={cx(i) - boxW / 2} x2={cx(i) + boxW / 2}
              y1={yScale(d.median)} y2={yScale(d.median)} stroke={colors[i]} strokeWidth={2.5} />
            {d.outliers.map((o, j) => (
              <circle key={j} cx={cx(i)} cy={yScale(o)} r={4} fill="none" stroke={colors[i]} strokeWidth={1.5} />
            ))}
            <text x={cx(i)} y={height + 20} textAnchor="middle" fontSize={11} fill="#6b7280">{d.group}</text>
          </g>
        ))}
      </g>
    </svg>
  );
}

🤖 AIプロンプトテンプレート

React + Tailwind CSSで、D3.js(カスタム実装)を使ったボックスプロットを実装してください。

- 使用ライブラリ: d3-array の quantile 関数でIQR・中央値を計算し、SVG描画をReactで制御するカスタム実装
- サンプルデータ: 部門別の月次売上分布(最小値・第1四分位・中央値・第3四分位・最大値・外れ値)を用意すること
- インタラクティブ: ホバー時にツールチップで統計値を表示すること
- 外れ値: 外れ値を個別の丸点として描画すること
- レスポンシブ: viewBox を使って親要素の幅に応じてチャートサイズが変わるよう対応すること
- スタイリング: 各ボックスに識別しやすい色を設定し、IQRボックスは半透明で塗りつぶすこと

⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。

3. Chart.js(カスタム実装)

chartjs-chart-boxplotプラグインを使用することでChart.jsでもボックスプロットを実現。事前に計算済みの統計値(min・q1・median・q3・max)を渡すだけで描画できる。Canvas描画のため大量のデータポイントや外れ値が多い場合でもパフォーマンスが安定。

✓ Canvas描画✓ プラグイン対応✓ 高パフォーマンス
特徴: Canvas APIによる高パフォーマンス描画。既存のChart.jsプロジェクトへの追加が容易で、事前計算済みの統計値をそのまま渡せる。
tsx
'use client';
import { Chart } from 'react-chartjs-2';
import { Chart as ChartJS, CategoryScale, LinearScale, Tooltip, Legend } from 'chart.js';
import { BoxPlotController, BoxAndWiskers } from '@sgratzl/chartjs-chart-boxplot';

ChartJS.register(CategoryScale, LinearScale, Tooltip, Legend, BoxPlotController, BoxAndWiskers);

const data = {
  labels: ['営業部', 'マーケ部', 'CSS部', 'パートナー部'],
  datasets: [{
    label: '月次売上分布',
    data: [
      { min: 820, q1: 950, median: 1100, q3: 1280, max: 1450, outliers: [620, 1680] },
      { min: 600, q1: 780, median: 920, q3: 1050, max: 1200, outliers: [380, 1420] },
      { min: 700, q1: 860, median: 980, q3: 1120, max: 1300, outliers: [500] },
      { min: 900, q1: 1050, median: 1200, q3: 1380, max: 1550, outliers: [1800] },
    ],
    backgroundColor: ['rgba(59,130,246,0.3)', 'rgba(16,185,129,0.3)', 'rgba(245,158,11,0.3)', 'rgba(139,92,246,0.3)'],
    borderColor: ['#3b82f6', '#10b981', '#f59e0b', '#8b5cf6'],
    borderWidth: 1.5,
  }],
};

export function ChartJSBoxPlot() {
  return (
    <Chart type={"boxplot" as any} data={data as any}
      options={{ responsive: true, maintainAspectRatio: false }} />
  );
}

🤖 AIプロンプトテンプレート

React + Tailwind CSSで、Chart.js(カスタム実装)を使ったボックスプロットを実装してください。

- 使用ライブラリ: chart.js と @sgratzl/chartjs-chart-boxplot の BoxPlotController・BoxAndWiskers、react-chartjs-2 の Chart コンポーネント
- サンプルデータ: 部門別の月次売上分布(min・q1・median・q3・max・outliers)を事前計算して渡すこと
- インタラクティブ: Chart.js 標準のツールチップでホバー時に統計値を表示すること
- 外れ値: outliers 配列を渡して外れ値を点として描画すること
- レスポンシブ: responsive: true・maintainAspectRatio: false を設定すること
- スタイリング: backgroundColor・borderColor に各グループの識別しやすい色を設定すること

⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。

ライブラリ比較

アプローチレンダリングボックスプロット対応自動統計計算おすすめ用途
NivoSVG◎ 専用パッケージデザイン重視のダッシュボード
D3.js カスタムSVG◎ 完全カスタム複雑な統計可視化
Chart.js カスタムCanvas◯ プラグイン△ 事前計算必要大量データ・高パフォーマンス

選択のポイント

  • Nivo: @nivo/boxplotが最もバランスが良く、生データを渡すだけで統計計算から描画まで自動処理。本番環境への導入に最もおすすめ。
  • D3.js: 独自の統計処理や高度なカスタマイズが必要な研究・分析ツールに最適。実装コストは最も高い。
  • Chart.js: 既にChart.jsを使用しているプロジェクトへの追加が容易。統計値を事前に計算して渡す必要があるが、Canvas描画で大量データでも安定動作。

典型的な使用例

  • 📊成績・スコア分布:テスト結果や評価スコアのばらつきと中央値をグループ間で比較
  • 💰売上分布の比較:部門・地域・製品カテゴリー別の売上分布とばらつきを分析
  • 🔬実験データの分析:複数条件下での測定値の分布と外れ値を統計的に可視化
  • 👥パフォーマンス評価:チーム・個人のKPI分布を比較して改善ポイントを特定

⚠️使用時の注意点

  • ボックスプロットはデータの分布を示すため、最低でも各グループ10件以上のデータがあると意味のある可視化になる
  • 外れ値の定義(一般的にはIQR×1.5を超える値)をドキュメントや凡例で明示する
  • 中央値と平均値は異なる概念であることをユーザーに伝えるラベル設計にする
  • データ件数が少ない場合は散布図や個別のデータポイント表示の方が適している場合がある