Message Boards Message Boards

9 Replies
8 Total Likes
View groups...
Share this post:

ListVectorPlot3D -- Why isn't this working?

Posted 10 years ago

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;

POSTED BY: David Keith
9 Replies
Posted 10 years ago

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

enter image description here

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

enter image description here

Show[vG, cG]

enter image description here


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."];
   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 bodeF

Notebook attached.

POSTED BY: Udo Krause

Dear David,

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

Is it true that you want something like this:

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

enter image description here

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]

enter image description here

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

Cheers, Marco

POSTED BY: Marco Thiel
Posted 10 years ago

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

POSTED BY: David Keith
Posted 10 years ago

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.

enter image description here

POSTED BY: David Keith
Posted 10 years ago

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

POSTED BY: David Keith
Posted 10 years ago

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:

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

enter image description here

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.

POSTED BY: David Keith

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.


enter image description here

Cheers, M.

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

POSTED BY: Marco Thiel

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}
POSTED BY: Udo Krause
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
or Discard

Group Abstract Group Abstract