1
$\begingroup$

Related: How to plot vectors in Mathematica

I am not interested in vector fields and field plots. I'd like to pass a $(2 \times n)$ or $(3 \times n)$ matrix into a function (or 2 different functions) and have it plot the columns as vectors, whose tails are at the origin and whose heads are at the coordinate of the columns.

I'll answer my own question below and share my hard work, but if anyone can tell me a built in function that does this, I'd appreciate that.

$\endgroup$
1
$\begingroup$

As shown in How to plot vectors in Mathematica, the desired graphics primitive is Arrow with a list of two vectors, one the origin and one the head of the vector.

If A is your matrix, this expression builds the list of Arrow primitives.

In[1]:=  A=Array[a,{2,3}];
         Map[Arrow, Transpose[{0 A, A}, {2, 3, 1}]]

Out[2]:= {Arrow[{{0, 0}, {a[1, 1], a[2, 1]}}],
          Arrow[{{0, 0}, {a[1, 2], a[2, 2]}}],
          Arrow[{{0, 0}, {a[1, 3], a[2, 3]}}]}

Now you can write functions that will plot these primitives.

vPlot[A_] := Graphics[Map[Arrow, Transpose[{0 A, A}, {2, 3, 1}]]]
vPlot3D[A_] := Graphics3D[Map[Arrow, Transpose[{0 A, A}, {2, 3, 1}]]]

This isn't very satisfying, since there are no axes and the plot is squished. The following will plot with axes and make the graph square, and let you pass in your own Graphics options, even overriding the ones specified.

vPlot[A_, opts___]   := Graphics[Map[Arrow, Transpose[{0 A, A}, {2, 3, 1}]],
                          opts,
                          Axes -> True,
                          AspectRatio -> 1,
                          PlotRange -> {{-1.1 Max[Abs[A]], 1.1 Max[Abs[A]]},
                                        {-1.1 Max[Abs[A]], 1.1 Max[Abs[A]]}}]
vPlot3D[A_, opts___] := Graphics3D[Map[Arrow, Transpose[{0 A, A}, {2, 3, 1}]],
                          opts,
                          Axes -> True,
                          AspectRatio -> 1,
                          PlotRange -> {{-1.1 Max[Abs[A]], 1.1 Max[Abs[A]]},
                                        {-1.1 Max[Abs[A]], 1.1 Max[Abs[A]]},
                                        {-1.1 Max[Abs[A]], 1.1 Max[Abs[A]]}}]

Finally, we can overcast the same function to plot 2D or 3D depending on whether it's passed a matrix with 2D or 3D vectors as columns.

vecPlot[A_, opts___] :=
  Module[{a, aa, body},
    a = 1.1 Max[Abs[A]];
    aa = {-a, a};
    body = Sequence[Map[Arrow, Transpose[{0 A, A}, {2, 3, 1}]], 
             opts,
             AspectRatio -> 1,
             Axes -> True];
    vPlot::dims = "The matrix with dimensions `1` does not contain 2D or 3D columns.";
    Switch[Dimensions[A],
      {2, _}, Graphics[body, PlotRange -> {aa, aa}],
      {3, _}, Graphics3D[body, PlotRange -> {aa, aa, aa}, AxesLabel -> {"x", "y", "z"}],
      _, Message[vPlot::dims, Dimensions[A]]
    ]
  ]

Screenshot of vecPlot in action Error message

$\endgroup$
  • $\begingroup$ How I'd have done it: Arrow[{ConstantArray[0, Length[#]], #}] & /@ Transpose[{{1, -1/2, -1/2}, {0, Sqrt[3]/2, -Sqrt[3]/2}}] $\endgroup$ – J. M. is away Jul 6 '16 at 1:58
0
$\begingroup$

Maybe something like this.

arrow[mat__] := Module[{dim}, dim = Dimensions[mat][[2]]; 
                Map[Arrow[{ConstantArray[0, dim], #}] &, mat]]

a = RandomReal[{-1, 1}, {10, 3}]
Graphics3D[arrow[a], PlotRange -> {{-1, 1}, {-1, 1}, {-1, 1}}]

a = RandomReal[{-1, 1}, {10, 2}]
Graphics[arrow[a], PlotRange -> {{-1, 1}, {-1, 1}}]

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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