---
url: https://chartbuddy.io/embed/docs/chart-types/scatter.md
---
# Scatter / bubble

Points positioned by two metrics, optionally sized and grouped. A bubble is a scatter with a larger default marker.

## Identity

| | |
|---|---|
| `chartType` | `scatter` · `bubble` |
| Option bag | `scatter` |
| `seriesData` layout | `pointRows` – row 0 names metrics; later rows are points |
| Min grid | 2 rows × 3 columns |
| Orientation | Linear X/Y – not category band remap like bars |
| Sample | [Scatter](/samples/scatter) |

***

## Minimal `chartData`

```js
{
  chartType: 'scatter', // or 'bubble'
  seriesData: [
    ['', 'Metric X', 'Metric Y', 'Size', 'Group'],
    ['A', 10, 15, 8, 'G1'],
    ['B', 14, 11, 12, 'G1'],
    ['C', 8, 20, 6, 'G2'],
  ],
  title: { visible: true, text: 'Scatter' },
  subtitle: { visible: false, text: '' },
}
```

***

## `seriesData`

Scatter does **not** use bar/line transpose. Layout is `pointRows`:

```js
[
  ['', 'Metric X', 'Metric Y', 'Size', 'Group'],
  ['Point 1', 10, 15, 8, 'A'],
  ['Point 2', 14, 11, 12, 'A'],
]
```

| Column (typical) | Role |
|---|---|
| 0 | Point label |
| 1 | X metric |
| 2 | Y metric |
| 3 | Optional size |
| 4 | Optional group |

Minimum: header + one point, with at least X and Y columns.

Shared layout rules: [chartData schema · seriesData](/api/chart-data#seriesdata-layouts).

***

## Option bag: `scatter`

| Field | Default (new charts) | Role |
|---|---|---|
| `diameter` | `10` for `scatter`; **larger (~`45`) for `bubble`** | Marker diameter (px) |
| `shape` | `'circle'` | Default marker shape |
| `shapes` | `[]` | Optional per-series shape list |
| `seriesStrokes` / widths / dash | `[]` | Per-series stroke chrome |
| `overrides` | `{}` | Indexed style patches |

```js
{
  chartType: 'bubble',
  seriesData: [/* … */],
  // diameter already seeded larger; override only if needed:
  scatter: { diameter: 36, shape: 'circle' },
}
```

`getChartData()` returns `chartType: 'scatter'` with the larger diameter already set.

***

## Axes & scales

| Role | Behaviour |
|---|---|
| Domain | **Linear X** (runtime forces linear; not a category band) |
| Primary range | Linear Y |

Format both linear sides. Ignore category `fitMechanism` / date wrap unless you intentionally treat labels as categories (you usually do not).

Details: [Axes · by chart type](/axes/by-chart-type) · [Domain axis](/axes/domain).

***

## Type-specific behaviour

* Size / group columns are optional but common for bubble-style decks.
* Palette / grouping still ties into legend colors.
* Prefer editor + `getChartData()` for per-point overrides.

***

## Pitfalls

* Using `isDataTransposed: true` series-rows layout meant for bars
* Putting options in `pie` / `bar` on a scatter
* Expecting category wrap/rotate behaviour from band axes
* Expecting `getChartData()` to keep `chartType: 'bubble'` — it returns `scatter` with the larger diameter

***

## Related

* [chartData schema](/api/chart-data) · [Axes](/axes/)
* Sample: [Scatter](/samples/scatter)
