# Visualize eigenvectors at specified points?

I am very new to Mathematica and I got stuck about visualizing eigenvectors 2D and 3D. I want to visualize my largest eigenvector field of tensor data(15x15). I wrote this code for instance :

points = {{0, 0}, {1, 0}, {2, 0}, {0, 1}, {1, 1}, {2, 1}, {0, 2}, {1,
2}, {2, 2}};

ListVectorPlot[{{{0, 0}, {1, 1}}, {{1, 0}, {1, 0}}, {{2, 0}, {0,
1}}, {{0, 1}, {1, -1}}, {{1, 1}, {1, 1}}, {{2, 1}, {-1, 1}}, {{0,
2}, {0, 1}}, {{1, 2}, {-1, 0}}, {{2, 2}, {0, -1}}}, VectorPoints -> points, FrameLabel -> {x, y}, PerformanceGoal -> "Quality", Epilog -> {Red, PointSize[Medium], Point[points]}]


But my vectors don't begin from the specified point. ListVectorPlot function locate the vector in the middle of the point. Do you think I have to use another function like Arrow and Graphics?

In addition,I want to plot my second eigenvectors from the same point. For example, I have a matrix and its eigenvectors are {{1,1},{-6,5}} or {{4,5},{-1,3}}. At the end I have to multiply these vectors with their eigenvalues({{2,4}}) and visualize like that. How can I do that at specified points at an order and different lenghts of vectors(multiply with eigenvalues)?

Below you can find a basic example data,

datax = {{{{3, 4}, {4, 3}}, {{3, 4}, {4, 3}}, {{3, 4}, {4,
3}}}, {{{3, 6}, {6, 3}}, {{3, 6}, {6, 3}}, {{3, 6}, {6,
3}}}, {{{3, 5}, {4, 3}}, {{3, 5}, {4, 3}}, {{3, 5}, {4, 3}}}};
dataxv = Table[Eigenvectors[datax[[z, t]]], {z, 1, 3}, {t, 1, 3}];
dataxva = Table[Eigenvalues[datax[[z, t]]], {z, 1, 3}, {t, 1, 3}];


• @eolin For the second part of your question, can you give example data too? Just click on edit on the left side below your question and insert it. – halirutan Oct 29 '12 at 0:02
• Regarding the positioning of the arrows, see this question. – Simon Woods Oct 29 '12 at 8:25
• @halirutan Thank you for your interest. I have done a bit what I have asked as a second question but I couldn't do it exactly. – cesm Oct 29 '12 at 8:39
• @SimonWoods Thank you very much. As for me, It is a confusing problem that VectorPlot has. – cesm Oct 29 '12 at 8:41

## Solution

You could use Graphics, Arrow and s which is a scaling factor and write

arrows = {{{0, 0}, {1, 1}}, {{1, 0}, {1, 0}}, {{2, 0}, {0, 1}}, {{0,
1}, {1, -1}}, {{1, 1}, {1, 1}}, {{2, 1}, {-1, 1}}, {{0, 2}, {0,
1}}, {{1, 2}, {-1, 0}}, {{2, 2}, {0, -1}}};
s = 0.3;
Graphics[{Arrow[{#1, #1 + s*Normalize[#2]}] & @@@ arrows, Red,
PointSize[0.03], Point[#1] & @@@ arrows}, Frame -> True] ## Explanation

arrows is a list where every element has the form {p, v} where p is the starting point and v is the vector to draw. The Mathematica function Arrow needs a starting point and an end point to draw something. We have the starting points explicitly, but the end-points need to be calculated. This calculation is simple: when we want to start at a point p and go along a vector v we just need to add them and we get the endpoint.

Let's further say, we want that all arrows have a constant length s than we could in a first step make v of normal length (meaning having length 1) and then we multiply v with s:

s*Normalize[v]


Therefore, if we want to define a Function taking p and v as parameter and which draws an arrow, it would look like

f = Function[{p,v}, Arrow[{p, p + s*Normalize[v]}]]


Now we want to use this function and apply it as easy as possible to your list of points and vectors l which has the structure

l = {{p1, v1}, {p2, v2}, {p3, v3}}


If possible, we want to transform this in one step into

{f[p1, v1], f[p2, v2], f[p3, v3]}


Here, Apply is very handy. The operators @@ and @@@ are infix forms for apply at level 0 and apply at level 1 respectively. What this function does is, it replaces the Head of and expression with something else. Example

Blub @@ Boing[1, 2, 3]

(* Out= Blub[1, 2, 3] *)


The Head Boing was replaced by Blub. If you now consider, that {1,2,3} is nothing more than List[1,2,3] you see what happens when you do

Plus @@ {1, 2, 3}

(* Out= 6 *)


With your parameter list, we need this replacement of the head inside the list, therefore we have to use @@@

Boing @@@ l

(* Out= {Boing[p1, v1], Boing[p2, v2], Boing[p3, v3]} *)


If we now use f instead of Boing everything is like we want it to be:

s = 0.3;
arrows = {{{0, 0}, {1, 1}}, {{1, 0}, {1, 0}}, {{2, 0}, {0, 1}}, {{0,
1}, {1, -1}}, {{1, 1}, {1, 1}}, {{2, 1}, {-1, 1}}, {{0, 2}, {0,
1}}, {{1, 2}, {-1, 0}}, {{2, 2}, {0, -1}}};
f = Function[{p, v}, Arrow[{p, p + s*Normalize[v]}]];

f @@@ arrows

(*
{Arrow[{{0, 0}, {0.212132, 0.212132}}], Arrow[{{1, 0}, {1.3, 0.}}],
Arrow[{{2, 0}, {2., 0.3}}], ...
*)


The last thing which need explanation is, that we don't really need to define f. We can just use it by writing the code where you need it.

Function[{p, v}, Arrow[{p, p + s*Normalize[v]}]] @@@ arrows


For the Function construct there is a shorter form where you don't give the parameters names like p and v. Just write the expression and refer to the first parameter as #1 and to the second as #2 and append an & at the end:

Arrow[{#1, #1 + s*Normalize[#2]}] & @@@ arrows


Now you should be prepared to understand the first code block in every detail.

## Update to your second question

You datax is a matrix of matrices having the following form

datax = {{{{3, 4}, {4, 3}}, {{3, 4}, {4, 3}}, {{3, 4}, {4, 3}}}, {{{3,
6}, {6, 3}}, {{3, 6}, {6, 3}}, {{3, 6}, {6, 3}}}, {{{3, 5}, {4,
3}}, {{3, 5}, {4, 3}}, {{3, 5}, {4, 3}}}};
MatrixForm[MapIndexed[Tooltip[MatrixForm[#1], #2] &, datax, {2}]] I assume you want to plot the eigenvectors of the matrix in the upper left corner at position {1,1}, the vectors of the matrix right of it at position {1,2} and so on. (Run with the mouse over the entries if you evaluate the upper code. You'll see the positions).

Since I explained the first solution in detail, I will go a bit further now. Let's say we want a function, which

• takes a matrix mat and a point point
• calculates the Eigensystem of this matrix
• plots the normalized eigenvectors scaled by its eigenvalue as Arrow
• Shows the expression as Tooltip if you run with the mouse over it

Note, that I even Normalize the list of eigenvectors {e1,e2,..} so that their values are never bigger than 1 but the length-relation is kept alive. With this, the length of the arrows never exceeds 1:

drawSystem[mat_, point_] := Module[{evec, eval},
{eval, evec} = Eigensystem[mat];
{
Tooltip[Arrow[{point, point + #1*#2}],
Row[{#1, MatrixForm[#2]}]] & @@@
Transpose[{Normalize[eval], Normalize /@ evec}],
Red, PointSize[0.02], Point[point]
}
]


Now, you could use Table in the same way you you already did (but we will not):

Table[drawSystem[datax[[z, t]], {z, t}], {z, 1, 3}, {t, 1, 3}]


instead let me introduce you to MapIndexed. MapIndexed applies a function to each element of a list (or a matrix, or a tensor in general) and gives as second parameter the position. Look at the following example:

MapIndexed[f, {{a, b}, {c, d}}, {2}]

(* {{f[a, {1, 1}], f[b, {1, 2}]}, {f[c, {2, 1}], f[d, {2, 2}]}} *)


This is exactly what we need for our situation. f is the drawing function and the matrix {{{a, b}, {c, d}} is the matrix of matrices datax:

Graphics[MapIndexed[drawSystem, datax, {2}], Frame -> True] • Outstanding answer! – Dr. belisarius Oct 28 '12 at 23:54
• @belisarius Thanks. I was afraid, that the code itself was useless to the OP. I started to explain it and it got longer and longer.. – halirutan Oct 29 '12 at 0:03
• Oh well ... the OP posted the question and went away. So let's hope he returns to check this one! – Dr. belisarius Oct 29 '12 at 0:10
• @halirutan Thank you again, I want 's' to change at every point, how can I do that? I created a list for s and tried to apply it at every point but I couldn't succeed it. – cesm Oct 29 '12 at 22:02