I have a streamplot like this

elField1P[q1_, {x1_, y1_}][x_, y_] := Module[{r1t},
r1t = {x - x1, y - y1};
q1 Normalize[r1t]/Norm[r1t]];

startingPoints = CirclePoints[{-1, 0}, 0.1, 20]~Join~CirclePoints[{1, 0}, 0.1, 18][[{4, 6}]];

g = StreamPlot[elField1P[2, {-1, 0}][x, y] + elField1P[-1, {1, 0}][x, y], {x, -2, 2}, {y, -1.2, 1.2}, AspectRatio -> Automatic, StreamPoints -> {startingPoints, Automatic, Scaled[1]}, StreamStyle -> {Red, "Line"}, StreamScale -> None, PerformanceGoal -> "Quality", PlotRangePadding -> None,ImageSize -> 600, Epilog -> Point[startingPoints]] ;

(* Add arrows in the middle of field lines *)
gf = Normal[g] /. Line[x_] :> {Arrowheads[{{0.02, 0.5}}], Arrow[x]}

Which ouput this plot


Now I would like to extract the position of the arrows in the plot and I don't know how to do it. This command

arrows = Cases[gf, Arrow[__], 7]

gives a list of the arrows in the form

{Arrow[{{x1, y1},{x2, y2},...}],...}

but it doesn't tell me where the tips of the arrows are. I could use the information in two ways: - position and rotation of the arrow tip or - starting and ending point (they have to be very close if the field is not straight in that region) of the straight segment the arrow lies on.

How can I do that?


You can use the function LineScaledCoordinate from the "GraphUtilities`" package as follows:

tips = Cases[gf, Arrow[x_, ___] :> LineScaledCoordinate[x, .5], All];
Show[gf, Graphics[{Blue, PointSize[Large], Point @ tips}]]

enter image description here

Note: Using StreamStyle -> {Red, Arrowheads[{{0.02, .5}}],"Arrow"} in defining g you get the desired output without having to pos-process.

  • $\begingroup$ That's good, this gives me the position of the tips but what about the orientation? Is there a way to find also the point before? I need to plot those arrow tips using small straight segments like (startingPoint)-(endPoint), or, (point) and rotation. $\endgroup$ – Emmet Jun 28 at 6:56
  • $\begingroup$ @Emmet, You can use LineScaledCoordinate[x, #]&/@{.5-delta,.5,.5+delta} for small delta to get three points (before the tip, at the tip and after the tip) $\endgroup$ – kglr Jun 28 at 7:04
  • $\begingroup$ I tried tips = Cases[gf, Arrow[x_, ___] :> LineScaledCoordinate[x, #] & /@ {.5 - delta, .5, .5 + delta}, All] but it gives me an empty list. $\endgroup$ – Emmet Jun 28 at 7:14
  • $\begingroup$ @Emmet, try delta =.05; tips = Cases[gf, Arrow[x_, ___] :> (LineScaledCoordinate[x, #] & /@ {.5 - delta, .5, .5 + delta}), All]? $\endgroup$ – kglr Jun 28 at 7:17
  • $\begingroup$ Now it works, thank you very much. $\endgroup$ – Emmet Jun 28 at 7:25

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.