# Scatter Chart Examples

> Complete scatter and bubble layouts for relationships, clusters, and prioritization.

Source: https://www.honestui.com/docs/charts/scatter-chart/blocks

These examples combine the plot with headings and summaries. The values are sample data. Open the Code tab and update numeric fields, labels, scales, summaries, and the equivalent table together.

## Language learning outcomes [#language-learning-outcomes]

Use this grouped scatter plot to compare the relationship between two measures across cohorts. Replace `practice`, `fluency`, `plan`, and `cohort`, then update the axis formats and correlation summary. Do not imply causation from the visual relationship alone.

### Language learning outcomes

```tsx
"use client";

import { ScatterChart, type ChartConfig } from "honestui/charts";

// Scenario: Language learning outcomes
const chartData = [
  { cohort: "Jan 08", plan: "guided", practice: 91, fluency: 82 },
  { cohort: "Jan 15", plan: "guided", practice: 98, fluency: 88 },
  { cohort: "Jan 22", plan: "guided", practice: 84, fluency: 79 },
  { cohort: "Jan 29", plan: "guided", practice: 101, fluency: 92 },
  { cohort: "Feb 05", plan: "guided", practice: 94, fluency: 84 },
  { cohort: "Jan 08", plan: "selfPaced", practice: 64, fluency: 51 },
  { cohort: "Jan 15", plan: "selfPaced", practice: 71, fluency: 57 },
  { cohort: "Jan 22", plan: "selfPaced", practice: 79, fluency: 61 },
  { cohort: "Jan 29", plan: "selfPaced", practice: 74, fluency: 54 },
  { cohort: "Feb 05", plan: "selfPaced", practice: 81, fluency: 64 },
];

const chartConfig = {
  practice: { label: "Practice frequency" },
  fluency: { label: "Week-8 fluency" },
  guided: { label: "Guided", colors: { light: ["#0d9488"], dark: ["#2dd4bf"] } },
  selfPaced: { label: "Self-paced", colors: { light: ["#d97706"], dark: ["#fbbf24"] } },
} satisfies ChartConfig;

export function RetentionScatterChart() {
  return (
    <div className="flex h-full w-full flex-col p-4">
      <div className="flex items-start justify-between gap-5">
        <div>
          <p className="text-primary text-base font-medium tracking-tight sm:text-lg">
            Practice frequency vs fluency
          </p>
          <p className="text-muted-foreground mt-0.5 text-xs">Monthly learner cohorts</p>
        </div>
        <div className="grid shrink-0 grid-cols-2 gap-4 text-right sm:gap-6">
          <div>
            <p className="text-muted-foreground text-[10px] tracking-wide uppercase">Correlation</p>
            <p className="text-primary text-lg font-semibold tabular-nums">+0.74</p>
          </div>
          <div>
            <p className="text-muted-foreground text-[10px] tracking-wide uppercase">Cohorts</p>
            <p className="text-primary text-lg font-semibold tabular-nums">10</p>
          </div>
        </div>
      </div>

      <ScatterChart
        data={chartData}
        config={chartConfig}
        xDataKey="practice"
        yDataKey="fluency"
        groupDataKey="plan"
        pointNameDataKey="cohort"
        className="mt-2 min-h-0 w-full flex-1"
        ariaLabel="Practice frequency and eight-week fluency by plan and weekly cohort"
      >
        <ScatterChart.Grid />
        <ScatterChart.XAxis min={45} max={100} hideDots tickFormatter={(value) => `${value}%`} />
        <ScatterChart.YAxis min={35} max={90} hideDots tickFormatter={(value) => `${value}%`} />
        <ScatterChart.Legend align="right" isClickable />
        <ScatterChart.Tooltip
          variant="frosted-glass"
          xValueFormatter={(value) => `${value}%`}
          yValueFormatter={(value) => `${value}%`}
        />
        <ScatterChart.Scatter dataKey="selfPaced" symbol="diamond" symbolSize={11} isClickable />
        <ScatterChart.Scatter dataKey="guided" symbolSize={12} isClickable />
      </ScatterChart>
    </div>
  );
}

```

## National park comparison [#national-park-comparison]

Use bubble area to encode a third measure only when the exact value is also available in text or a table. Replace the funding, growth, acreage, and park-name fields, then update all units and the accessible label.

### National park comparison

```tsx
"use client";

import { ScatterChart, type ChartConfig } from "honestui/charts";

// Scenario: National park comparison
const chartData = [
  { company: "Acadia", valuation: 1.33, growth: 93, revenue: 47 },
  { company: "Olympic", valuation: 3.11, growth: 75, revenue: 107 },
  { company: "Zion", valuation: 4.55, growth: 58, revenue: 171 },
  { company: "Everglades", valuation: 6.33, growth: 49, revenue: 240 },
  { company: "Denali", valuation: 8.21, growth: 39, revenue: 339 },
  { company: "Yosemite", valuation: 10.1, growth: 31, revenue: 466 },
  { company: "Badlands", valuation: 3.77, growth: 85, revenue: 131 },
  { company: "Arches", valuation: 6.99, growth: 68, revenue: 274 },
];

const chartConfig = {
  valuation: { label: "Annual funding" },
  growth: { label: "Visitor growth" },
  revenue: { label: "Acreage" },
  market: {
    label: "Parks",
    colors: {
      light: ["#ccfbf1", "#0f766e"],
      dark: ["#134e4a", "#5eead4"],
    },
  },
} satisfies ChartConfig;

export function MarketMapScatterChart() {
  return (
    <div className="flex h-full w-full flex-col p-4">
      <div className="flex items-baseline justify-between gap-4">
        <div>
          <p className="text-primary text-base font-medium tracking-tight sm:text-lg">National parks</p>
          <p className="text-muted-foreground mt-0.5 text-xs">Bubble area represents acreage</p>
        </div>
        <p className="text-muted-foreground text-xs">2026 season</p>
      </div>

      <ScatterChart
        data={chartData}
        config={chartConfig}
        xDataKey="valuation"
        yDataKey="growth"
        pointNameDataKey="company"
        className="mt-2 min-h-0 w-full flex-1"
        ariaLabel="Park funding and visitor growth with acreage represented by bubble area"
      >
        <ScatterChart.Grid />
        <ScatterChart.XAxis hideDots tickFormatter={(value) => `$${value}b`} />
        <ScatterChart.YAxis hideDots tickFormatter={(value) => `${value}%`} />
        <ScatterChart.Tooltip
          xValueFormatter={(value) => `$${value.toFixed(1)}b`}
          yValueFormatter={(value) => `${value}%`}
          sizeValueFormatter={(value) => `$${value}m`}
        />
        <ScatterChart.Scatter
          dataKey="market"
          variant="bubble"
          sizeDataKey="revenue"
          minSize={14}
          maxSize={58}
          isClickable
        />
      </ScatterChart>
    </div>
  );
}

```

## Emergency preparedness plan [#emergency-preparedness-plan]

Use labeled quadrants to support a documented prioritization model. Replace cost, readiness gain, feasibility, and project name, then confirm that the split points match the real decision rules. Provide equivalent filters or a table if selecting points affects the workflow.

### Emergency preparedness plan

```tsx
"use client";

import { ScatterChart, type ChartConfig } from "honestui/charts";

// Scenario: Emergency preparedness plan
const chartData = [
  { project: "Backup generators", effort: 31, impact: 99, confidence: 102 },
  { project: "Flood barriers", effort: 80, impact: 95, confidence: 84 },
  { project: "Radio network", effort: 43, impact: 81, confidence: 93 },
  { project: "Shelter supplies", effort: 71, impact: 75, confidence: 79 },
  { project: "Evacuation signs", effort: 48, impact: 61, confidence: 72 },
  { project: "Volunteer training", effort: 85, impact: 41, confidence: 64 },
  { project: "Water storage", effort: 27, impact: 47, confidence: 98 },
  { project: "Siren replacement", effort: 92, impact: 24, confidence: 105 },
];

const chartConfig = {
  effort: { label: "Cost" },
  impact: { label: "Readiness gain" },
  confidence: { label: "Feasibility" },
  roadmap: {
    label: "Preparedness",
    colors: {
      light: ["#fef3c7", "#d97706"],
      dark: ["#78350f", "#fbbf24"],
    },
  },
} satisfies ChartConfig;

export function PriorityScatterChart() {
  return (
    <div className="flex h-full w-full flex-col p-4">
      <div className="flex items-start justify-between gap-4">
        <div>
          <p className="text-primary text-base font-medium tracking-tight sm:text-lg">
            Emergency readiness
          </p>
          <p className="text-muted-foreground mt-0.5 text-xs">
            Bubble area represents confidence
          </p>
        </div>
        <span className="border-border bg-muted/40 text-primary rounded-md border px-2.5 py-1.5 text-xs font-medium">
          8 candidates
        </span>
      </div>

      <ScatterChart
        data={chartData}
        config={chartConfig}
        xDataKey="effort"
        yDataKey="impact"
        pointNameDataKey="project"
        className="mt-2 min-h-0 w-full flex-1"
        ariaLabel="Preparedness projects by cost, readiness gain, and feasibility"
      >
        <ScatterChart.XAxis min={0} max={100} hideDots />
        <ScatterChart.YAxis min={0} max={100} hideDots />
        <ScatterChart.Quadrants
          xSplit={50}
          ySplit={50}
          labels={{
            topLeft: "Do now",
            topRight: "Plan",
            bottomLeft: "Opportunistic",
            bottomRight: "Defer",
          }}
        />
        <ScatterChart.Tooltip sizeValueFormatter={(value) => `${value}%`} />
        <ScatterChart.Scatter
          dataKey="roadmap"
          variant="bubble"
          sizeDataKey="confidence"
          minSize={11}
          maxSize={28}
          isClickable
        />
      </ScatterChart>
    </div>
  );
}

```
