# 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. – halirutan Sep 23 '12 at 20:01
Do you want bars or ellipsoids? – belisarius has settled Sep 23 '12 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 Sep 23 '12 at 21:35

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. – Sjoerd C. de Vries Sep 23 '12 at 20:18

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?

-

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]


-

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, {0, 0, 0}}}, ImageSize -> 800]
`
-
Very nice solution +1 – Markus Roellig Oct 3 '12 at 8:29
Wow! The things that can be done. Very nice, indeed. – Edmund Apr 16 at 23:03