Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: StreamPlot or streamlines in 3D?

1,221 views
Skip to first unread message

Heike Gramberg

unread,
Mar 19, 2011, 6:23:30 AM3/19/11
to

It's only a start, but maybe you could mimic streams by using the graphics
directive Arrowheads[] to plot several arrow heads along your trajectories.
For example, by doing something like

pts = Table[{Cos[t], Sin[t], t/10}, {t, 0, 10 Pi, Pi/50}];
Graphics3D[{Arrowheads[Table[{0.03, i}, {i, 0, 1, 1/60}]], Orange,
Thick, Arrow[pts]}]

which sort of looks like a streamline in StreamPlot. You can also use ArrowHeads[] to change the appearance of the heads, by supplying a graphics object to each of the arrowhead specifications in the table, e.g.


pts = Table[{Cos[t], Sin[t], t/10}, {t, 0, 10 Pi, Pi/50}];
Graphics3D[{Arrowheads[
Table[{0.03, i,
Graphics3D[{Hue[i], Cone[{{0, 0, 0}, {1, 0, 0}}, 0.3]}]}, {i, 0,
1, 1/60}]], Gray, Thick, Arrow[pts]}]


Heike.

On 17 Mar 2011, at 11:35, Istv=E1n Zachar wrote:

> Dear Group,
>
> I'm plotting some trajectories in 3D, and I would like to present
> results as StremPlot does in 2D. Is there an established method how to
> generate StreamPlot-like streams and arrows, or I have to work my way
> from scratch, and extend it to 3D? It would be nice to have some ready-
> made algorithms on stream segmentation, placement, interpolation and
> styling. A Stream[...] object seems to be a natural extension to
> Point, Line and Arrow primitives...
> Note, that I do NOT generate a vectorfield in 3D, but a set of points
> for each trajectory, which I want to present as arrows, though not as
> general arrows, as those simply point to the fixed points of the ODE
> system, which are displayed as a point in the corner sorrunded with a
> multitude of arrowheads - pretty crowded. See the picture below (three
> views of the solutions of a 4D ODE on a 3D simplex).
>
> http://img708.imageshack.us/i/simplex3d.png/
>
> Any help/idea is appreciated
>
> Istvan
>

István Zachar

unread,
Mar 21, 2011, 7:14:38 AM3/21/11
to
Thanks for the reply Heike,
but it does not solve my problem. Consider this:

startPts = RandomReal[{0, 1}, {20, 3}];
arrows = Arrow[{#, {1, 1, 1}}] & /@ startPts;
Graphics3D[{arrows}]

Note that since every trajectory points to the same fixpoint, there is
a clump of arrowheads. Also note, that there may be NO internal points
in a trajectory, to allow segmented arrows, like in your example. Thus
what I need are two things:
1. An algorithm that SEGMENTS unsegmented lines to create
midpoints (this I guess is the easier one);
2. An algorithm that calculates the POSITIONS where these
midpoints should lie to yield an esthetic result where no two arrows
(streamlines) terminate at the exact same point.
All the rest is finetuning and styling, but that is not important
here.
And as I've already said it, both the two algorithms exist, though are
not accessible being the internal routines of StreamPlot.
Can StreamPlot be reverse engineered? Or is there a developer's
package dealing with streamlines, that preceded the built-in
StreamPlot function?
I fail to see why the whole paradigm was not transferred to 3D already
by Wolfram. Is there an inherent snag preventing the extension?
Even if it cannot be extended to 3D it would be nice to use the
streamlines in a more customizable way in 2D (i.e. to know the above
algorithms).

Istv=E1n

On Mar 19, 11:23 am, Heike Gramberg <heike.gramb...@gmail.com> wrote:
> It's only a start, but maybe you could mimic streams by using the graphic=
s
> directive Arrowheads[] to plot several arrow heads along your trajectorie=


s.
> For example, by doing something like
>
> pts = Table[{Cos[t], Sin[t], t/10}, {t, 0, 10 Pi, Pi/50}];
> Graphics3D[{Arrowheads[Table[{0.03, i}, {i, 0, 1, 1/60}]], Orange,
> Thick, Arrow[pts]}]
>

> which sort of looks like a streamline in StreamPlot. You can also use Arr=
owHeads[] to change the appearance of the heads, by supplying a graphics ob=


ject to each of the arrowhead specifications in the table, e.g.
>
> pts = Table[{Cos[t], Sin[t], t/10}, {t, 0, 10 Pi, Pi/50}];
> Graphics3D[{Arrowheads[
> Table[{0.03, i,

> Graphics3D[{Hue[i], Cone[{{0, 0, 0}, {1, 0, 0}}, 0.3]}]}, {i, =

Heike Gramberg

unread,
Mar 23, 2011, 3:59:52 AM3/23/11
to
Arrowheads[] positions arrowheads along the arrow independently of the shape and number of internal points. If you supply a list of positions, it will plot a sequence of arrow heads, one at each of the positions in the list. So in your example, if you would do something like

startPts = RandomReal[{0, 1}, {20, 3}];
arrows = Arrow[{#, {1, 1, 1}}] & /@ startPts;

Graphics3D[{Arrowheads[Table[{0.02, i}, {i, 0, 1, 1/10}],
Appearance -> "Projected"], arrows}]

you would get 11 equally spaces arrowheads along each of the arrows. In the section Scope > Multiple Arrowheads in the documentation for Arrowheads there are more examples.

If you want more control over the arrows (say you want small gaps between the arrows, or want to fit a curve through the points), you could interpolate your points with respect to the (approximated) arc length along the line as such

Options[interpArcl] = Options[Interpolation];
interpArcl[plist_, opts : OptionsPattern[]] :=
With[{arclengths =
Prepend[Accumulate[Norm /@ Differences[plist]], 0]},
Interpolation[Transpose[{arclengthList[plist], plist}], opts]]

Then you can use something like this to plot segmented arrows along your sreamline

Options[stream3D2] = Options[ParametricPlot3D];
stream3D2[f_, {min_, max_}, ds_, gap_, opts : OptionsPattern[]] :=
Module[{segments, t},
segments =
Table[Rescale[
t, {0, 1}, {min + i ds, Min[min + (i + 1) ds - gap, max]}], {i,
0, Ceiling[(max - min)/ds] - 1}];
ParametricPlot3D[Unevaluated[f /@ segments], {t, 0, 1}, {opts}] /.
a_Line :> Arrow[a]]

This would plot arrows with spacing ds and a gaps of length gap along between arc lengths min and max along your curve f[s]. So for example:

pts = {{-1, -1, -1}, {1, 1, 1}, {-1, 0, 1}};
f = interpArcl[pts, InterpolationOrder -> 1];
stream3D2[f, f[[1, 1]], 0.3, 0.05,
PlotStyle -> {Thick, Red, Arrowheads[0.025]}]

Since stream3D2 uses ParametricPlot3D you can use the option RegionFunction if you want your arrow to skip over parts of your domain, e.g. in

pts = {{-1, -1, -1}, {1, 1, 1}, {-1, 0, 1}};
f = interpArcl[pts, InterpolationOrder -> 1];
stream3D2[f, f[[1, 1]], 0.3, 0.05,
PlotStyle -> {Thick, Red, Arrowheads[0.025]},
RegionFunction -> Function[{x, y, z}, Norm[{x, y, z}] > 0.2]]

the streamline "avoids" the sphere centred at the origin with radius 0.2.

Heike.

> Istv==E1n


>
>
>
> On Mar 19, 11:23 am, Heike Gramberg <heike.gramb...@gmail.com> wrote:

>> It's only a start, but maybe you could mimic streams by using the graphics
>> directive Arrowheads[] to plot several arrow heads along your trajectories.


>> For example, by doing something like
>>
>> pts = Table[{Cos[t], Sin[t], t/10}, {t, 0, 10 Pi, Pi/50}];
>> Graphics3D[{Arrowheads[Table[{0.03, i}, {i, 0, 1, 1/60}]], Orange,
>> Thick, Arrow[pts]}]
>>

>> which sort of looks like a streamline in StreamPlot. You can also use ArrowHeads[] to change the appearance of the heads, by supplying a graphics object to each of the arrowhead specifications in the table, e.g.


>>
>> pts = Table[{Cos[t], Sin[t], t/10}, {t, 0, 10 Pi, Pi/50}];
>> Graphics3D[{Arrowheads[
>> Table[{0.03, i,

>> Graphics3D[{Hue[i], Cone[{{0, 0, 0}, {1, 0, 0}}, 0.3]}]}, {i, 0,

István Zachar

unread,
Mar 29, 2011, 7:59:11 AM3/29/11
to
Dear Heike and All,

even if I correct arclengthList[plist] to arclengths in your
interpArcl function, the ParametericPlot3D fails to plot the
InterpolatingFunction object. It hangs Mathematica and forces me to
kill the whole thing form under Taskmanager. I narrowed down the
problem to the Line -> Arrow replacement. Although even if I remove
it, the evaluation is a bit slow. Nevertheless, it is a good way to
start, thanks for the ideas!

However, my main concern here is that I DO NOT want to write this
algorithm at all, as it is my experience that whenever I reverse-
engineere or produce from scratch something that I KNOW exists in
Mathematica, the next release will contain it surely as a built-in
algorithm, with better integration and optimized routines. This
happened to me with many of the post-6 functions, and especially the
graphing abilities... I'm sure many of you know this feeling of
futility.

So what I would like to hear is the opinion or advise from a
developer, whether it will be included in any future release, or
whether it is present in any form in a developer's package at present.
It is a huge undertaking to extend, develop and polish streamline
functionality, so I naturally would like to avoid such work it if
there are existing solutions. If not, I can write it of course, but
will be rather irritated if it turns out that the thing exists. And we
all know that the thing exists, though masked behind StreamPlot.

Istvan

On Mar 23, 8:59 am, Heike Gramberg <heike.gramb...@gmail.com> wrote:
> Arrowheads[] positions arrowheads along the arrow independently of the sh=
ape and number of internal points. If you supply a list of positions, it=
will plot a sequence of arrow heads, one at each of the positions in the l=


ist. So in your example, if you would do something like
>
> startPts = RandomReal[{0, 1}, {20, 3}];
> arrows = Arrow[{#, {1, 1, 1}}] & /@ startPts;
> Graphics3D[{Arrowheads[Table[{0.02, i}, {i, 0, 1, 1/10}],
> Appearance -> "Projected"], arrows}]
>

> you would get 11 equally spaces arrowheads along each of the arrows. In t=
he section Scope > Multiple Arrowheads in the documentation for Arrowheads =
there are more examples.
>
> If you want more control over the arrows (say you want small gaps between=
the arrows, or want to fit a curve through the points), you could interpol=
ate your points with respect to the (approximated) arc length along the lin=


e as such
>
> Options[interpArcl] = Options[Interpolation];
> interpArcl[plist_, opts : OptionsPattern[]] :=
> With[{arclengths =
> Prepend[Accumulate[Norm /@ Differences[plist]], 0]},
> Interpolation[Transpose[{arclengthList[plist], plist}], opts]]
>

> Then you can use something like this to plot segmented arrows along your =


sreamline
>
> Options[stream3D2] = Options[ParametricPlot3D];
> stream3D2[f_, {min_, max_}, ds_, gap_, opts : OptionsPattern[]] :=
> Module[{segments, t},
> segments =
> Table[Rescale[

> t, {0, 1}, {min + i ds, Min[min + (i + 1) ds - gap, max]}], {i=


,
> 0, Ceiling[(max - min)/ds] - 1}];
> ParametricPlot3D[Unevaluated[f /@ segments], {t, 0, 1}, {opts}] /.
> a_Line :> Arrow[a]]
>

> This would plot arrows with spacing ds and a gaps of length gap along bet=


ween arc lengths min and max along your curve f[s]. So for example:
>
> pts = {{-1, -1, -1}, {1, 1, 1}, {-1, 0, 1}};
> f = interpArcl[pts, InterpolationOrder -> 1];
> stream3D2[f, f[[1, 1]], 0.3, 0.05,
> PlotStyle -> {Thick, Red, Arrowheads[0.025]}]
>

> Since stream3D2 uses ParametricPlot3D you can use the option RegionFuncti=

> >> It's only a start, but maybe you could mimic streams by using the grap=
hics
> >> directive Arrowheads[] to plot several arrow heads along your trajecto=


ries.
> >> For example, by doing something like
>
> >> pts = Table[{Cos[t], Sin[t], t/10}, {t, 0, 10 Pi, Pi/50}];
> >> Graphics3D[{Arrowheads[Table[{0.03, i}, {i, 0, 1, 1/60}]], Orange,
> >> Thick, Arrow[pts]}]
>

> >> which sort of looks like a streamline in StreamPlot. You can also use =
ArrowHeads[] to change the appearance of the heads, by supplying a graphics=


object to each of the arrowhead specifications in the table, e.g.
>
> >> pts = Table[{Cos[t], Sin[t], t/10}, {t, 0, 10 Pi, Pi/50}];
> >> Graphics3D[{Arrowheads[
> >> Table[{0.03, i,

> >> Graphics3D[{Hue[i], Cone[{{0, 0, 0}, {1, 0, 0}}, 0.3]}]}, {i, =


0,
> >> 1, 1/60}]], Gray, Thick, Arrow[pts]}]
>
> >> Heike.
>
> >> On 17 Mar 2011, at 11:35, Istv=E1n Zachar wrote:
>
> >>> Dear Group,
>
> >>> I'm plotting some trajectories in 3D, and I would like to present

> >>> results as StremPlot does in 2D. Is there an established method how t=


o
> >>> generate StreamPlot-like streams and arrows, or I have to work my way

> >>> from scratch, and extend it to 3D? It would be nice to have some read=


y-
> >>> made algorithms on stream segmentation, placement, interpolation and
> >>> styling. A Stream[...] object seems to be a natural extension to
> >>> Point, Line and Arrow primitives...
> >>> Note, that I do NOT generate a vectorfield in 3D, but a set of points
> >>> for each trajectory, which I want to present as arrows, though not as
> >>> general arrows, as those simply point to the fixed points of the ODE
> >>> system, which are displayed as a point in the corner sorrunded with a

> >>> multitude of arrowheads - pretty crowded. See the picture below (thre=

0 new messages