# How to plot Error Bars in a 3D scatter plot

This is a simple problem which is proving difficult to solve. I want to plot error bars on points in a 3D scatter graph. I plot error bars on points within a 2D scatter by:

ErrorListPlot[{{{x1_,y1_},ErrorBar[x1_err,y1_err]},{x2_,y2_},ErrorBar[x2err_,y2err_]}}]


I can plot 3D point data by:

ListPointPlot3D[{{x1_,y1_,z1_},{x2_,y2_,z2_}}]


However, the ErrorBar function doesn't seem to work in 3D (have tried ErrorBar3D and variations of).

Any suggestions much appreciated!

• Hello and welcome to Mathematica.SE. When you write a post, you can use many things like code-blocks, links, section titles, etc. Please look through the documention here to see how you use it. More important, please read our FAQ to understand how voting, asking good questions and all this works. Commented Sep 23, 2012 at 20:01
• Do you want bars or ellipsoids? Commented Sep 23, 2012 at 20:09
• Be sure to check out the variety of visualization functions in Mathematica, beyond ListPointPlot: wolfram.com/mathematica/new-in-8/statistical-visualization
– amr
Commented Sep 23, 2012 at 21:35

In my opinion 3D data plots are very, very confusing and you need to provide the user a multitude of visual cues to improve his/her interpretation. As a first draft I'd suggest something like:

t[x_, y_, z_, dx_, dy_, dz_] :=
GeometricTransformation[Sphere[{0, 0, 0}, 1],
AffineTransform[{DiagonalMatrix[{dx, dy, dz}], {x, y, z}}]];

data = {{10, 10, 10, 2, 2, 2}, {20, 25, 20, 2, 2, 4}, {20, 10, 30, 4, 2, 1},
{20, 30, 40, 1, 2, 3}, {30, 30, 30, 2, 1, 1}};
Graphics3D[{Line[{{#1, #2, 0}, {#1, #2, #3}}], Red,
Tube[{{#1 - #4, #2, #3}, {#1 + #4, #2, #3}}],
Tube[{{#1, #2 - #5, #3}, {#1, #2 + #5, #3}}],
Tube[{{#1, #2, #3 - #6}, {#1, #2, #3 + #6}}], {Blue,
PointSize[0.04], Point[{#1, #2, #3}]}, {Opacity[0.4],
t[#1, #2, #3, #4, #5, #6]}} & @@@ data, Axes -> True,
FaceGrids -> All]


Compare that to this one:

Which would you use?

Yet another way:

In this plot, data points are represented in a 3D space, whereas errors are represented on the (x,y), (x,z), and (y,z) planes as textures using ErrorListPlot.

Here the code:

Needs["ErrorBarPlots"]

data = {{.5, .5, .5, .2, .2, .2}, {-.4, -.1, .2, .2, .2, .3}, {.2, \
.1, .3, .1, .2, .1}, {-.2, .3, .4, .1, .2, .3}, {.3, -.3, -.3, .2, \
.1, .1}};

xyzSpace = Graphics3D[{
{Lighter[Green], Sphere[{#1, #2, #3}, .03]},
{Dashed, Black, Thickness[.003],
Line[{{#1, #2, -1}, {#1, #2, #3}}]},
{Dashed, Black, Thickness[.003],
Line[{{#1, 1, #3}, {#1, #2, #3}}]},
{Dashed, Black, Thickness[.003],
Line[{{-1, #2, #3}, {#1, #2, #3}}]}
} & @@@ data, PlotRange -> {{-1, 1}, {-1, 1}, {-1, 1}},
BoxRatios -> 1, AxesLabel -> {x, y, z}];

xyPlane =
ErrorListPlot[
{{#1, #2}, ErrorBar[#4, #5]} & @@@ data,
PlotRange -> {{-1, 1}, {-1, 1}}, AspectRatio -> 1, Axes -> None,
PlotStyle -> {Darker[Green], Thickness[.01], PointSize[.03]},
ImageSize -> 400];

xzPlane =
ErrorListPlot[
{{#1, #3}, ErrorBar[#4, #6]} & @@@ data,
PlotRange -> {{-1, 1}, {-1, 1}}, AspectRatio -> 1, Axes -> None,
PlotStyle -> {Darker[Green], Thickness[.01], PointSize[.03]},
ImageSize -> 800];

yzPlane =
ErrorListPlot[
{{#2, #3}, ErrorBar[#5, #6]} & @@@ data,
PlotRange -> {{-1, 1}, {-1, 1}}, AspectRatio -> 1, Axes -> None,
PlotStyle -> {Darker[Green], Thickness[.01], PointSize[.03]},
ImageSize -> 800];

xyTex = Graphics3D[{EdgeForm[{Thin, Black}], {Texture[xyPlane],
Polygon[{{-1, -1, -1}, {1, -1, -1}, {1, 1, -1}, {-1, 1, -1}},
VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}}]}},
Boxed -> False];

xzTex = Graphics3D[{EdgeForm[{Thin, Black}], {Texture[xzPlane],
Polygon[{{-1, 1, -1}, {1, 1, -1}, {1, 1, 1}, {-1, 1, 1}},
VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}}]}},
Boxed -> False];

yzTex = Graphics3D[{EdgeForm[{Thin, Black}], {Texture[yzPlane],
Polygon[{{-1, -1, -1}, {-1, 1, -1}, {-1, 1, 1}, {-1, -1, 1}},
VertexTextureCoordinates -> {{0, 0}, {1, 0}, {1, 1}, {0, 1}}]}},
Boxed -> False];

Show[xyzSpace, xyTex, xzTex, yzTex, Axes -> True,
Lighting -> {{"Directional", White, {2, -3, 4}}}, ImageSize -> 800]

• Very nice solution +1 Commented Oct 3, 2012 at 8:29
• Wow! The things that can be done. Very nice, indeed. Commented Apr 16, 2015 at 23:03
• @Edmund How would you adapt this to be suitable for more recent version of Mathematica? I think ErrorBar is obsolete now. Thanks. Commented Feb 17, 2023 at 12:40
• @JohnDoe Intriguingly enough, if you see a black cube, the problem is related to the lighting direction! change Lighting -> {{"Directional", White, {0, 0, 0}}} to Lighting -> {{"Directional", White, {2, -3, 4}}} or something similar and it should work! Commented Feb 17, 2023 at 13:55
• Modified a working directional light in the answer. Commented Feb 17, 2023 at 14:17

Another way:

data = RandomInteger[{3, 7}, {5, 3}];
ErrorBar3D[point_, error_] := {Blue,
Scale[Sphere[point], RandomReal[{.1, .3}, 3], point], Dashed,
Line /@ Partition[ Riffle[(# + point) & /@ (IdentityMatrix[3] (
rs[[All, 1]] - point)), {point}, {2, -1, 2}], 2]}
rs = ({Min@# - 1, Max@# + 1} & /@ Transpose@data);
Show[{Graphics3D[ErrorBar3D[#, RandomReal[{.1, .4}]] & /@ data],
ContourPlot3D[{x == rs[[1, 1]], y == rs[[2, 1]], z == rs[[3, 1]]},
Evaluate[Sequence @@ (({{x, Sequence @@ #[[1]]},
{y, Sequence @@ #[[2]]},
{z, Sequence @@ #[[3]]}}) &@rs)],
Mesh -> None,
ContourStyle -> Directive[Orange, Opacity[0.3], Specularity[White, 30]]]},
Boxed -> True, PlotRange -> rs, Axes -> True]


It doesn't look like there's a built-in way to do it. Here's a custom approach:

data = {{1, 4, 2}, {2, 2, 1}, {1, 1, 3}, {3, 1, 3}, {1, 2, 1}};
ErrorBar3D[point_, error_] :=
Line[{point - {0, 0, error}, point + {0, 0, error}}];

Show[{
ListPointPlot3D[data],
Graphics3D[ErrorBar3D[#, RandomReal[{.1, .4}]] & /@ data]
}, Boxed -> False]


• Hmmm, without drop-down shadows you don't have a clue about the points' locations. Could be anywhere. Commented Sep 23, 2012 at 20:18

Using built-in functions:

data = Around @@@ Transpose[Partition[#, 3, 3]] & /@
{{10, 10, 10, 2, 2, 2}, {20, 25, 20, 2, 2, 4}, {20, 10, 30, 4, 2, 1}, {20, 30, 40, 1, 2, 3}, {30, 30, 30, 2, 1, 1}};

ListPointPlot3D[data, IntervalMarkers -> "Tubes", PlotRange -> All,
Filling -> Bottom, FillingStyle -> Directive[Red, Thickness[0.005]]]
`