28
$\begingroup$

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!

$\endgroup$
3
  • 1
    $\begingroup$ 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. $\endgroup$
    – halirutan
    Commented Sep 23, 2012 at 20:01
  • $\begingroup$ Do you want bars or ellipsoids? $\endgroup$ Commented Sep 23, 2012 at 20:09
  • $\begingroup$ Be sure to check out the variety of visualization functions in Mathematica, beyond ListPointPlot: wolfram.com/mathematica/new-in-8/statistical-visualization $\endgroup$
    – amr
    Commented Sep 23, 2012 at 21:35

5 Answers 5

31
$\begingroup$

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]

Mathematica graphics

Compare that to this one:

Mathematica graphics

Which would you use?

$\endgroup$
29
$\begingroup$

Yet another way:

enter image description here

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]
$\endgroup$
5
  • $\begingroup$ Very nice solution +1 $\endgroup$ Commented Oct 3, 2012 at 8:29
  • $\begingroup$ Wow! The things that can be done. Very nice, indeed. $\endgroup$
    – Edmund
    Commented Apr 16, 2015 at 23:03
  • $\begingroup$ @Edmund How would you adapt this to be suitable for more recent version of Mathematica? I think ErrorBar is obsolete now. Thanks. $\endgroup$
    – John Doe
    Commented Feb 17, 2023 at 12:40
  • 1
    $\begingroup$ @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! $\endgroup$
    – kirma
    Commented Feb 17, 2023 at 13:55
  • $\begingroup$ Modified a working directional light in the answer. $\endgroup$
    – kirma
    Commented Feb 17, 2023 at 14:17
14
$\begingroup$

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]

Mathematica graphics

$\endgroup$
7
$\begingroup$

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]

Output showing ErrorBar3D

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

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]]]

graph

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.