MathGroup Archive 2008

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: fit plane to xz axis of data

  • To: mathgroup at smc.vnet.net
  • Subject: [mg89554] Re: fit plane to xz axis of data
  • From: Ray Koopman <koopman at sfu.ca>
  • Date: Thu, 12 Jun 2008 06:30:09 -0400 (EDT)
  • References: <200806110720.DAA15072@smc.vnet.net> <g2qhcd$8jc$1@smc.vnet.net>

On Jun 11, 11:57 pm, "Szabolcs Horv=E1t" <szhor... at gmail.com> wrote:
> On Wed, Jun 11, 2008 at 10:20, will parr <willpower... at hotmail.com> wrote:=

> > Dear Math Forum,
>
> > I am having problems fitting a plane to some data. I am using the follow=
ing procedure to fit the plane to my data (data is pasted at the bottom of t=
his message):
>
> > In[2]:= plane = Fit[data, {1, x, y}, {x, y}]
>
> > Out[2]= 3.28723- 0.189001 x - 0.0874557 y
>
> > Then the following to display the points and plane:
>
> > Show[ListPointPlot3D[data, Boxed -> False, Axes -> True,
> >  AxesEdge -> {{-1, -1}, {-1, -1}, {-1, -1}},
> >  AxesLabel -> {"x", "y", "z"}],
> >  Plot3D[plane, {x, Min[data[[All, 1]]], Max[data[[All, 1]]]}, {y,
> >   Min[data[[All, 2]]], Max[data[[All, 2]]]},
> >  PlotStyle -> Directive[Green, Opacity[0.5]],
> >  Mesh -> None]]
>
> > This works fine at fitting the plane in the xy axis, but I want to fit t=
he plane to the xz axis. Does anyone know how this is done?
>
> You just need to permute the coordinates:
>
> Replace[data, {x_, y_, z_} :> {x, z, y}, 1]
>
> Or, if necessary, you can do an "isotropic" fitting (that prefers no
> axis) by calculating the distances from the plane.  The original
> fitting attempt showed that the plane will not pass through {0,0,0} so
> we can use the equation a x + b y + c z == 1.  The distance-squared of=

> point {x,y,z} from this plane is (a x + b y + c z - 1)^2/(a^2 + b^2 +
> c^2), so the fitting can be done like this:
>
> In[2]:= planei =
>  a x + b y + c z /.
>   Last@NMinimize[
>     Expand@Total[
>       Function[{x, y, z}, (a x + b y + c z - 1)^2] @@@ data]/(
>     a^2 + b^2 + c^2), {a, b, c}]
>
> Out[2]= 0.100048 x + 0.0136288 y + 0.0112116 z
>
> In[3]:= plane = Fit[data, {1, x, y}, {x, y}]
>
> Out[3]= 3.28723- 0.189001 x - 0.0874557 y
>
> In[4]:= plane2 =
>  Fit[Replace[data, {x_, y_, z_} -> {x, z, y}, 1], {1, x, z}, {x, z}]
>
> Out[4]= 8.12817- 0.817828 x - 0.225109 z
>
> In[5]:= {{xa, xb}, {ya, yb}, {za, zb}} = {Min[#], Max[#]} & /@
>   Transpose[data]
>
> Out[5]= {{7.08299, 11.4614}, {-5.66284, 4.59986}, {-1.83404,
>   4.49073}}
>
> In[6]:= Show[
>  ContourPlot3D[planei == 1, {x, xa, xb}, {y, ya, yb}, {z, za, zb},
>   ContourStyle -> Directive[Blue, Opacity[.5]], Mesh -> None],
>  Plot3D[plane, {x, xa, xb}, {y, ya, yb},
>   PlotStyle -> Directive[Green, Opacity[0.5]], Mesh -> None],
>  ContourPlot3D[plane2 == y, {x, xa, xb}, {y, ya, yb}, {z, za, zb},
>   ContourStyle -> Directive[Red, Opacity[.5]], Mesh -> None],
>  ListPointPlot3D[data, PlotStyle -> Black],
>  PlotRange -> All, AxesLabel -> {"x", "y", "z"}
>  ]
>
> Your points don't seem to lie on a plane, so the three approaches give
> give different results.

The following will find the best-fitting (i.e., least-squares) plane:

  m = Mean[data]; {u,w,v] = SingularValueDecomposition[#-m&/@data];

v is a rotation matrix. Tr[w,List] (i.e., the diagonal elements of w)
gives the norms of the projections of the points onto the new axes.
They are in decreasing order, so

  ({x,y,z}-m).v[[All,3]] == 0

gives the equation which the best-fitting plane satisfies.


  • Prev by Date: Re: Re: Re: Re: Show and 6.0
  • Next by Date: Re: Don't understand replacement rule for some functions
  • Previous by thread: Re: fit plane to xz axis of data
  • Next by thread: Re: fit plane to xz axis of data