Adding Error Bars to Plotly.js Scatter Plots for Scientific Data
Add error bars to Plotly.js scatter plots using the error_y property with array data for symmetric errors or plus/minus arrays for asymmetric uncertainties. Includes worked example, styling options, performance limits, and verification steps.
22 Feb 2026, 07:55 UTC

Quick answer
Use the error_y property on a scatter trace with type: 'data' and an array of symmetric error values, or plus/minus arrays for asymmetric errors. Plotly.js 1.42+ also supports error_expressions for computed statistics without pre-calculating arrays.
Worked example: symmetric error bars from measured data
The following snippet creates a scatter plot with three data points and per-point symmetric error bars. Run this in a browser page that loads Plotly.js (via CDN or npm) and has a <div id="myDiv"></div> container.
<script src="https://cdn.plot.ly/plotly-2.32.0.min.js"></script>
<div id="myDiv" style="width:600px;height:400px;"></div>
<script>
const trace = {
x: [1, 2, 3],
y: [2, 4, 3],
type: 'scatter',
mode: 'markers',
marker: { size: 10, color: '#1f77b4' },
error_y: {
type: 'data', // use explicit values, not a percentage or constant
array: [0.5, 1.0, 0.8], // symmetric ±error for each point
visible: true,
color: '#d62728', // error bar line color
thickness: 2, // line width in pixels
width: 6 // cross-bar width in pixels
}
};
Plotly.newPlot('myDiv', [trace], {
title: 'Measured values with symmetric uncertainty',
xaxis: { title: 'Condition' },
yaxis: { title: 'Response (units)', range: [0, 6] }
});
</script>Each point receives a vertical error bar extending ± the corresponding value in array. The color, thickness, and width properties style the error bars independently from the markers.
Asymmetric errors and computed statistics
When upper and lower uncertainties differ, supply plus and minus arrays instead of array:
error_y: {
type: 'data',
plus: [0.6, 1.2, 0.9],
minus: [0.4, 0.8, 0.7],
visible: true
}Starting with Plotly.js 1.42.0, you can avoid pre-computing arrays by using error_expressions. The expression receives the trace's y values and returns an array of errors. Example using a 5% relative error:
error_y: {
type: 'data',
error_expressions: ['0.05 * y'],
visible: true
}The expression language supports basic arithmetic and the variables x, y, z (for 3D), and color. This is useful when errors derive from a known formula rather than per-point measurements.
Styling and visibility control
Error bars inherit the trace's visible state but have their own error_y.visible toggle. Set it to false to hide bars without removing the data. You can also control them at runtime via Plotly.restyle:
// Hide error bars after plot creation
Plotly.restyle('myDiv', { 'error_y.visible': false });
// Update error values dynamically
Plotly.restyle('myDiv', { 'error_y.array': [0.3, 0.6, 0.4] });Styling properties (color, thickness, width) accept single values or arrays for per-bar customization.
Performance limits and common mistakes
Large datasets
Error bars add SVG/Canvas elements per point. Beyond ~10,000 markers, rendering time grows noticeably. Mitigations:
- Use
scattergl(WebGL) trace type instead ofscatterfor >5k points. - Downsample or bin data before plotting.
- Offload error computation to a Web Worker and update via
Plotly.extendTracesorPlotly.restylein batches.
Version compatibility
error_expressions requires Plotly.js ≥ 1.42.0 (released 2019). Check at runtime:
console.log(Plotly.version); // e.g., "2.32.0"
if (parseFloat(Plotly.version) < 1.42) {
// fall back to pre-computed arrays
}CDN URLs without a pinned version may serve newer releases that change defaults; pin to a specific version in production.
Misaligned arrays
The array, plus, and minus arrays must match the length of x/y. Mismatched lengths silently truncate or produce no error bars. Validate before plotting:
function validateErrorArrays(trace) {
const n = trace.x.length;
const ey = trace.error_y;
if (!ey) return true;
const check = (arr) => Array.isArray(arr) && arr.length === n;
if (ey.array && !check(ey.array)) throw new Error('error_y.array length mismatch');
if (ey.plus && !check(ey.plus)) throw new Error('error_y.plus length mismatch');
if (ey.minus && !check(ey.minus)) throw new Error('error_y.minus length mismatch');
return true;
}Logarithmic axes
On log-scaled axes, symmetric linear errors appear asymmetric visually. Plotly does not automatically convert errors for log scales. Compute log-space errors upstream or use asymmetric plus/minus that reflect the transformed uncertainty.
Verification checklist
- Render test: Open the page and confirm vertical bars appear at each marker with the expected length.
- Visibility toggle: In the browser console, run
Plotly.restyle('myDiv', { 'error_y.visible': false })and verify bars disappear; settrueto restore. - Version check: Run
console.log(Plotly.version)and confirm ≥ 1.42.0 if usingerror_expressions. - Asymmetric test: Replace
arraywithplus/minusarrays of different values and confirm upper/lower extents differ. - Dynamic update: Call
Plotly.restyle('myDiv', { 'error_y.array': [newValues] })and verify bars resize without a full re-plot.
When to consider alternatives
If you need horizontal error bars, use error_x with the same property structure. For box plots or violin plots that show distribution statistics directly, those trace types compute quartiles and whiskers internally and may replace manual error bars. For real-time streaming with high-frequency error updates, consider scattergl with Plotly.extendTraces and a Web Worker to keep the main thread responsive.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.