# How can I get better control over StreamPlot?

I'm having some difficulties with the command StreamPlot in Mathematica 7.0. Here's the basic plots I'm doing :

StreamPlot[{x, -y}, {x, -2, 2}, {y, -2, 2}, Axes -> True,
AxesOrigin -> {0, 0}, FrameTicks -> None,
StreamPoints -> 12, StreamScale -> 0.15, PerformanceGoal -> "Quality"]

StreamPlot[{y, x}, {x, -2, 2}, {y, -2, 2}, Axes -> True,
AxesOrigin -> {0, 0}, FrameTicks -> None, StreamPoints -> 12,
StreamScale -> 0.15, PerformanceGoal -> "Quality"]


Here's the output, which I find ugly :

• How can I define the number of arrows heads to be drawn on each curve? Currently, there are too many arrows on the curves. I would prefer a maximum of two (or maybe three) arrows per stream curve.

• How can I make the output perfectly symetric? Look for example at the second picture, which is terrible.

• How can I remove the straight stream lines?

-
Which straight lines are you referring to, the axes (black) or the streams (blue)? –  rcollyer Jun 20 '13 at 14:51
The straight lines (curves) are the straight streams (blue), of course. They are useless. I could remove them by double-clicking on the output graphics, but I would prefer a better method, from the input instead. –  Cham Jun 20 '13 at 14:53
I think you'll have to define StreamPoints explicitly to get rid of the straight lines. This could also be the solution to your symmetry problem. FWIW, this is perfectly symmetric by default on Mathematica 9. –  Corey Kelly Jun 20 '13 at 15:24
Another problem you may encounter is that Mathematica tries to avoid streamlines getting too close to each other, which will mean it may not draw lines for all your StreamPoints if they are too close to each other. This is addressed in the question How to get StreamPlot to draw many hundreds of streamlines? –  Jens Jun 20 '13 at 17:13

To make it more symmetric, you can manually specify StreamPoints.

To get rid of straight line, you can delete corresponding start points in StreamPoints.

To reduce the segmentation, you can manually specify StreamScale.

points = DeleteCases[
Tuples[Range[-2, 2, 1/2], 2],
pt_ /;
Not[FreeQ[pt, -2 | 0 | 2]] ||
Abs[pt[[1]]] == Abs[pt[[2]]]
];

StreamPlot[{y, x}, {x, -2, 2}, {y, -2, 2},
StreamPoints -> {points, Automatic},
StreamScale -> {
{0.4, 0.01}, (* or use Full to completely prevent segmentation *)
All, 0.02, Automatic}
]


A possible finer tuning would be to generating points according to the specific field we want to plot.

Edit: Another set of start points

For the first plot:

points = With[{d = .1},
Join[#, -#] &[
{#, -2 + d} & /@
DeleteCases[Range[-2, 2, 1/5],
x_ /; Not[FreeQ[x, -2 | 0 | 2]]]
]];


For the second plot:

points = With[{d = .1},
Join[#, Reverse /@ #] &@
Join[#, -#] &@
({-2 + d, #} & /@ DeleteCases[Range[0, 2, 1/4], 2])
];


-
Your second plot is still asymmetric. –  Corey Kelly Jun 20 '13 at 15:30
@CoreyKelly Hope we can call it symmetric now! :D –  Silvia Jun 20 '13 at 15:42
Also try this point list: points = DeleteCases[Tuples[Range[-2, 2, 1/2], 2], pt_ /; Not[FreeQ[pt, -2 | 2]] || Not[FreeQ[pt, 0]] && Total[Abs[pt]] != 1/2 || Abs[pt[[1]]] == Abs[pt[[2]]]] –  shrx Jun 20 '13 at 16:14
@shrx Better on the 2nd plot! But it introduces straight lines into 1st plot. So to do it better, adaptive start points sampling are necessary. –  Silvia Jun 20 '13 at 16:26