Plotly error bars: error_y in px and graph_objects (tested)

In plotly express pass a column name: px.scatter(df, x="x", y="y", error_y="sd") (add error_y_minus= for asymmetric bars). In graph_objects pass a dict: go.Scatter(..., error_y=dict(type="data", array=sd)). Plotly does not aggregate, so compute the mean and sd per group first.

1. Every way to add error bars

b1.py prints the error_y object each call produces:

import pandas as pd, plotly, plotly.express as px, plotly.graph_objects as go
print("plotly", plotly.__version__)
df = pd.DataFrame({"x": ["a", "b", "c"], "y": [4.0, 6.0, 5.0],
                   "sd": [0.5, 1.0, 0.8], "lo": [0.2, 0.4, 0.3]})

fig = px.scatter(df, x="x", y="y", error_y="sd")                 # symmetric
print("px symmetric:", fig.data[0].error_y.to_plotly_json())

fig = px.bar(df, x="x", y="y", error_y="sd", error_y_minus="lo") # asymmetric
print("px asymmetric:", fig.data[0].error_y.to_plotly_json())

fig = go.Figure(go.Scatter(x=df.x, y=df.y, mode="markers",
                           error_y=dict(type="data", array=df.sd)))
print("go data:", fig.data[0].error_y.to_plotly_json())

fig = go.Figure(go.Bar(x=df.x, y=df.y, error_y=dict(type="percent", value=10)))
print("go percent:", fig.data[0].error_y.to_plotly_json())

try:
    px.scatter(df, x="x", y="y", error_y="std")
except ValueError as ex:
    print("ValueError:", str(ex).splitlines()[0])
try:
    px.scatter(df, x="x", y="y", error_y=[0.1, 0.2])
except ValueError as ex:
    print("ValueError:", str(ex).splitlines()[0])

Output (plotly 7.1.0, pandas 3.1.0, Python 3.13.5):

plotly 7.1.0
px symmetric: {'array': array([0.5, 1. , 0.8])}
px asymmetric: {'array': array([0.5, 1. , 0.8]), 'arrayminus': array([0.2, 0.4, 0.3])}
go data: {'array': array([0.5, 1. , 0.8]), 'type': 'data'}
go percent: {'type': 'percent', 'value': 10}
ValueError: Value of 'error_y' is not the name of a column in 'data_frame'. Expected one of ['x', 'y', 'sd', 'lo'] but received: std
ValueError: All arguments should have the same length. The length of argument `error_y` is 2, whereas the length of previously-processed arguments ['x', 'y'] is 3

2. Error bars from raw rows: aggregate first

b2.py:

import pandas as pd, plotly.express as px
raw = pd.DataFrame({"group": ["a"] * 4 + ["b"] * 4,
                    "value": [3, 5, 4, 6, 7, 9, 8, 10]})
# px does not aggregate: compute mean and spread per group first
stats = raw.groupby("group", as_index=False)["value"].agg(mean="mean", sd="std", n="count")
stats["se"] = stats["sd"] / stats["n"] ** 0.5
print(stats.round(3).to_string(index=False))
fig = px.bar(stats, x="group", y="mean", error_y="sd")
print("bars:", fig.data[0].y.tolist(), "error_y:", fig.data[0].error_y.array.round(3).tolist())

fig = px.bar(raw, x="group", y="value")  # raw rows, no error bars
print("raw rows -> traces:", len(fig.data), "bar segments:", len(fig.data[0].y))
group  mean    sd  n    se
    a   4.5 1.291  4 0.645
    b   8.5 1.291  4 0.645
bars: [4.5, 8.5] error_y: [1.291, 1.291]
raw rows -> traces: 1 bar segments: 8

Frequently asked questions

How do I add error bars in plotly express?

Pass a column name (or same-length array) as error_y, e.g. px.bar(df, x="x", y="y", error_y="sd"); error_y_minus makes them asymmetric.

How do I add error bars with plotly graph_objects?

Use error_y=dict(type="data", array=values) on the trace, or dict(type="percent", value=10) for percentage bars.

Why does plotly not show error bars for my raw data?

Plotly does not compute them. Group your data, compute std or standard error, and pass that column to error_y.

Written with AI assistance. Measured on 2026-10-23 with plotly 7.1.0, pandas 3.1.0 and Python 3.13.5 on Linux. Scripts ran verbatim and the output was pasted unedited. PlainTables is our extension; Plotly is free.