Scatter Chart
What is a Scatter Chart?
ApexCharts renders scatter charts as individual data points plotted across two numeric axes, with no connecting lines between them. Each point encodes two values: an x-coordinate and a y-coordinate. The resulting pattern of points reveals whether a relationship exists between the two variables, how tight or loose that relationship is, and whether any clusters or outliers are present. Scatter charts are the right choice when both axes are numeric and you care about the shape of the distribution, not a sequence or ranking.
Data Format
Scatter series data can be expressed in two formats. Both are fully supported and can be mixed across series.
Array format uses a nested array [x, y] for each point:
series: [{
name: 'Sample A',
data: [
[16.4, 5.4],
[21.7, 2.0],
[25.4, 3.0],
[19.0, 7.2],
[10.9, 0.0]
]
}]
Object format uses { x, y } for each point. This form is easier to read when your data comes from an API that already structures records as objects:
series: [{
name: 'Sample A',
data: [
{ x: 16.4, y: 5.4 },
{ x: 21.7, y: 2.0 },
{ x: 25.4, y: 3.0 },
{ x: 19.0, y: 7.2 },
{ x: 10.9, y: 0.0 }
]
}]
Both formats produce identical output. Choose whichever fits the shape of your source data.
For more details on series construction, see the Working with data page.
Minimal Working Example
The only required configuration change from a default chart is setting chart.type to 'scatter'. ApexCharts infers a numeric x-axis automatically, so no xaxis.type override is needed unless you want datetime values (covered below).
const options = {
chart: {
type: 'scatter',
height: 400
},
series: [
{
name: 'Group A',
data: [
[10.2, 34.1],
[15.8, 28.5],
[22.4, 41.0],
[18.1, 37.9],
[27.6, 22.3],
[12.0, 30.7],
[9.5, 45.2]
]
},
{
name: 'Group B',
data: [
[30.1, 10.4],
[35.7, 18.9],
[28.3, 25.0],
[40.0, 12.6],
[33.5, 20.1],
[38.9, 15.8],
[25.4, 30.2]
]
}
],
xaxis: {
tickAmount: 10,
title: { text: 'Temperature (°C)' }
},
yaxis: {
title: { text: 'Humidity (%)' }
}
}
const chart = new ApexCharts(document.querySelector('#chart'), options)
chart.render()
The two series are drawn in different colors automatically. Tooltips show the exact x and y values for each point on hover.
Scatter vs Line vs Bubble
Choosing the right chart type depends on what your data contains and what question you are answering.
| Situation | Best type |
|---|---|
| Two numeric variables, no implied sequence | Scatter |
| Values measured over time or ordered categories | Line |
| Two numeric variables plus a third magnitude (e.g. market size) | Bubble |
| Comparing counts or totals across categories | Column / Bar |
The key distinction between scatter and line is that scatter treats x as a numeric coordinate, while line treats x as an ordered position (category or time). If you connect scatter points with a line, the result is a line chart. Use scatter when the positions of individual points matter, not the slope between them.
The key distinction between scatter and bubble is the z value. Bubble series accept { x, y, z } where z controls marker size, encoding a third dimension. Scatter has no third dimension. Adding a third variable to a scatter chart requires color coding or shape encoding instead.
The Jitter Feature
Dense scatter data often produces overplotting: many points land at nearly the same coordinate, stacking on top of each other and hiding the true density of the distribution. ApexCharts provides a jitter option under plotOptions.scatter to spread overlapping points by a small random offset. The tooltip always shows the original, unmodified value, so jitter is purely a display aid.
Fixing overplotting in a standard scatter chart
Enable jitter and set the maximum offset in x and y axis units:
const options = {
chart: {
type: 'scatter',
height: 400
},
series: [{
name: 'Measurements',
data: [
{ x: 5.0, y: 20.0 },
{ x: 5.0, y: 20.1 },
{ x: 5.0, y: 19.9 },
{ x: 5.1, y: 20.0 },
{ x: 10.0, y: 35.5 },
{ x: 10.0, y: 35.4 },
{ x: 10.0, y: 35.6 },
{ x: 15.0, y: 28.0 },
{ x: 15.0, y: 27.9 }
]
}],
plotOptions: {
scatter: {
jitter: {
enabled: true,
x: 0.3, // maximum ± horizontal offset in x-axis units
y: 0.5 // maximum ± vertical offset in y-axis units
}
}
}
}
Keep the offset values small relative to your axis range. A value of 0.3 on an axis that spans 0 to 100 produces a subtle spread. A value of 5 on the same axis produces a wide fan that may mislead readers about actual data positions.
Strip plots with jitter
A strip plot is a one-dimensional scatter where each x value is a category and the y values scatter within that band. This makes it easy to see the full distribution within each group without aggregating into a box or bar. To create a strip plot, format each data point as { x: 'CategoryName', y: value }:
const options = {
chart: {
type: 'scatter',
height: 400
},
series: [{
name: 'Test scores',
data: [
{ x: 'Group A', y: [72, 85, 91, 68, 77, 89, 83, 75] },
{ x: 'Group B', y: [55, 60, 71, 58, 64, 52, 67, 70] },
{ x: 'Group C', y: [90, 95, 88, 92, 97, 85, 93, 91] }
]
}],
plotOptions: {
scatter: {
jitter: {
enabled: true,
x: 0.4,
distributed: true, // colour each band differently within a single series
maxPoints: 200 // per-band cap; values beyond this are stride-thinned
}
}
},
xaxis: {
type: 'category'
}
}
In this format, each object in data represents one band. The y property is an array of all values within that band, and jitter spreads them horizontally so overlapping points become visible. Setting distributed: true assigns a distinct color to each band even though they all belong to the same series.
The full plotOptions.scatter reference is at plotOptions.scatter.
Datetime Scatter Charts
When your x values are timestamps, set xaxis.type to 'datetime'. Pass x as a JavaScript timestamp (milliseconds since epoch). ApexCharts formats the axis ticks and tooltip labels as dates automatically.
const options = {
chart: {
type: 'scatter',
height: 400
},
series: [
{
name: 'Session A',
data: [
{ x: new Date('2024-01-05').getTime(), y: 42 },
{ x: new Date('2024-01-12').getTime(), y: 58 },
{ x: new Date('2024-01-19').getTime(), y: 35 },
{ x: new Date('2024-02-03').getTime(), y: 71 },
{ x: new Date('2024-02-17').getTime(), y: 49 }
]
},
{
name: 'Session B',
data: [
{ x: new Date('2024-01-08').getTime(), y: 20 },
{ x: new Date('2024-01-15').getTime(), y: 33 },
{ x: new Date('2024-02-01').getTime(), y: 55 },
{ x: new Date('2024-02-22').getTime(), y: 28 },
{ x: new Date('2024-03-01').getTime(), y: 61 }
]
}
],
xaxis: {
type: 'datetime',
title: { text: 'Date' }
},
yaxis: {
title: { text: 'Response time (ms)' }
}
}
const chart = new ApexCharts(document.querySelector('#chart'), options)
chart.render()
Datetime scatter is particularly useful for event logs or experiment results where observations arrive at irregular intervals. Because scatter does not connect points with lines, the chart makes no implied claim about what happened between recorded measurements.
Using Scatter in a Combo Chart
Scatter series can be layered with line series in a combo chart. A common pattern is to plot raw observations as scatter and a fitted trend line on top. To do this, specify type inside each series object:
const options = {
chart: {
type: 'line', // fallback type for series that don't declare their own
height: 400
},
series: [
{
type: 'scatter',
name: 'Observations',
data: [
[5, 12], [10, 22], [15, 30], [20, 45], [25, 52], [30, 61]
]
},
{
type: 'line',
name: 'Trend',
data: [
[5, 10], [10, 20], [15, 30], [20, 40], [25, 50], [30, 60]
]
}
]
}
See Mixed Charts for more combination examples.
Customizing Markers
Since scatter charts are entirely made of markers, the markers option is central to their appearance. You can control size, shape, stroke, fill, and hover behavior:
markers: {
size: 7, // marker radius in pixels
shape: 'circle', // 'circle' | 'square' | 'star' | 'plus' | 'cross'
strokeWidth: 1,
strokeColors: '#fff',
fillOpacity: 0.9,
hover: {
sizeOffset: 2 // extra radius on hover, giving the user visual feedback
}
}
Larger size values help when data is sparse and points need to be easy to click. Smaller values are better when you have hundreds of points and want to reduce visual clutter.
More Examples
See the full collection of scatter chart demos at scatter chart demos.