ListVectorPlot3D -- Why isn't this working?

Hello,
Any idea what I’m doing wrong here? The data nvf seems to match the structure wanted for an explicit list of vector field points, but nothing plots.

f[x_, y_] := Sin[x y]

normF = {D[f[x, y], x], D[f[x, y], y], -1} // Normalize;

nvecs = Table[{{x, y, f[x, y]}, Normalize[normF]}, {x, 0, 3, .5}, {y, 
    0, 3, .5}];

nvf = Flatten[nvecs, 1]; nvf // Dimensions;

ListVectorPlot3D[nvf]

You miss a dimension, having 3

In[64]:= Dimensions[nvf]
Out[64]= {49, 2, 3}

on the other hand, from the manual

vectors =  Table[{x, y, z}, {x, -1, 1, .1}, {y, -1, 1, .1}, {z, -1, 1, .1}]; ListVectorPlot3D[vectors]

works fine and has 4 dimensions

In[65]:= Dimensions[Table[{x, y, z}, {x, -1, 1, .1}, {y, -1, 1, .1}, {z, -1, 1, .1}]]
Out[65]= {21, 21, 21, 3}

Dear David,

are you sure that you need to flatten nvecs? If you do not flatten it, everything works fine and it then seems to have the right dimensions.

ListVectorPlot3D[nvecs]

Cheers,
M.

PS: Sorry I must have been typing when the first reply came in.

Thanks to you both. But I still find this peculiar. I think my nvf has the format specified in the second entry of the docs for ListVectorPlot3D, which is { {{x1,y1,y2},{vx1,vy1,vz1}}, . . . }, and has rank 3. – which is just a list of field points and vector values.

The unflattened nvecs does plot as you show, Marco, but I think all the field points should lie on the surface f[x,y] = Sin[x y]. Here I plot the field points of nvf on the surface:

Show[Plot3D[
  f[x, y], {x, 0, 3}, {y, 0, 3}], {PointSize[0.02], 
   Point[nvf[[All, 1]]]} // Graphics3D]

But the field points for the unflattened nvecs don’t lie on the surface where they were generated, but seem to be on a grid, as though Mathemetica were interpreting it as some array, which is like the first entry in the documentation for ListVectorPlot3D.

This post does not look like the preview. The image is not displayed, but seen only when clicked on.

Here is the image. The plot plots the surface on which the 3D points for the vector field are generated, and the points as extracted from the field list.

Dear David,

I think I understand better now what you mean. That behaviour is odd and has been discussed before:

http://forums.wolfram.com/mathgroup/archive/2009/Feb/msg00770.html

http://mathematica.stackexchange.com/questions/26519/making-a-listvectorplot3d-from-data-in-an-external-file

http://mathematica.stackexchange.com/questions/27921/problem-with-listvectorplot3d

Is it true that you want something like this:

Show[Graphics3D[{Thick, Arrow[{#[[1]], #[[1]] + #[[2]]}]} & /@ nvf], 
 ListPlot3D[nvf[[All, 1]]]]

I couldn’t make it work with ListVectorPlot3D. This, however, is similar and does work

    scalarField = x^2 - y^2 - z;
    vectorField = D[scalarField, {{x, y, z}}];
    data = Table[vectorField, {x, -2, 2}, {y, -2, 2}, {z, -2, 2}];

v = ListVectorPlot3D[data, DataRange -> {{-2, 2}, {-2, 2}, {-2, 2}}, 
  VectorPoints -> 25, VectorScale -> {0.1, Scaled[0.5]}, 
  RegionFunction -> Function[{x, y, z}, -0.1 <= scalarField <= 0.1]]

c = ContourPlot3D[
  scalarField == 0, {x, -2, 2}, {y, -2, 2}, {z, -2, 2}, Mesh -> None, 
  ContourStyle -> Opacity[0.5, Green]]

Show[v, c]

I know that this does not really answer the question of why ListVectorPlot3D does not do it.

Cheers,
Marco

Hi Marco,

That’s quite useful.

I had not noticed that ListVectorPlot and ListVectorPlot3D are trying to re-interpolate the field and generate a plot on a regular grid. When I noticed that, I tried the option VectorPoints → All, which is supposed to cause the vectors to be plotted only at the explicit points. That still did not work. I suppose that on a 2D manifold the interpolation algorithm is breaking down. This is too bad, since for a list plot I would really rather have a vector field plotted from an explicit list. I suppose I will make my own.

Best,
David

Here is some simple impl to draw the normal vector on a 2D function with rectangular support

Remove[bodeN]; (* bode normal *)
bodeN[fn_ (* function of two arguments *),
  {v1_, v10_, v11_} (* range of argument 1 *),
  {v2_, v20_, v21_} (* range of argument 2 *),
  l0_ (* length of normals *),
  p0_Integer: 20 (* plot points *)
  ] :=
 Module[{dv1, dv2, o, dfn1, dfn2, x, y, p, pp, pic0, pic1}, 
   (* Check fn *)
   If[FreeQ[fn[v1, v2], v1] || FreeQ[fn[v1, v2], v2], 
    Print["Function ", fn, " unabhaengig von ", v1, " und/oder ", 
     v2 "! Bye."];
    Return[$Failed]
    ];
   dv1 = (v11 - v10)/p0;
   dv2 = (v21 - v20)/p0;
   dfn1[x_, y_] := Evaluate[D[fn[x, y], x]];
   dfn2[x_, y_] := Evaluate[D[fn[x, y], y]];
   (* die Fusspunkte des Normalenfeldes - "in" der Flaeche *)
   p = Flatten[Table[{x, y, fn[x, y]}, {x, v10, v11, dv1}, {y, v20, v21, dv2}], 1];
   (* die Normalenrichtungen *)
   pp = (((l0/Sqrt[#.#]) & /@ #)*#) &[Flatten[Table[{dfn1[x, y], dfn2[x, y], -1}, 
       {x, v10, v11, dv1}, {y, v20, v21, dv2}], 1]];
   (* das l0 normierte Normalenrichtungsfeld mit Pfeilen *)
   pic1 = Graphics3D[{Arrowheads[.01], Arrow /@ Transpose[{p, p + pp}]}, DisplayFunction -> Identity];
   (* die Flaeche z = fn[v1, v2] selbst *)
   pic0 = Plot3D[fn[v1, v2], {v1, v10, v11}, {v2, v20, v21}, DisplayFunction -> Identity, PlotPoints->p0];
   (* Anzeige *)
   Show[{pic0, pic1}, DisplayFunction -> $DisplayFunction]
   ] /; l0 != 0 && v10 < v11 && v20 < v21 && AtomQ[v1] && 
   AtomQ[v2] && ! StringMatchQ[ToString[v1], ToString[v2]]

originating back from 2001; at that times there was a function ListPlotVectorField3D[] which has seemingly gone. bodeN gives Output like

Notebook attached.

Does the following work for you?

f1[x_, y_] := Sin[x y]
vecF = Normalize[{D[f1[x, y], x], D[f1[x, y], y], -1}];
scalarR = f1[x, y] - z;
vecData = Table[vecF, {x, 0, 3, 0.5}, {y, 0, 3, 0.5}, {z, -1, 1, 0.5}];

For this, I created a regularly spaced array of vectors in 3D. The iteration on z is for that purpose. The scalar region function, scalarR, is used as the rule for RegionFunction. BTW, it seems like you have a redundant Normalize in your original code, so I left it out.

vG = ListVectorPlot3D[vecData, DataRange -> {{0, 3}, {0, 3}, {-1, 1}}, 
  VectorPoints -> 20, 
  RegionFunction -> Function[{x, y, z}, -0.2 <= scalarR <= 0.2]]

cG = ContourPlot3D[scalarR == 0, {x, 0, 3}, {y, 0, 3}, {z, -1, 1}, 
  Mesh -> None, ContourStyle -> Opacity[0.5, Green]]

Show[vG, cG]