7

So I have the vector field ${x^2+2*x*y,y^2+2*x*y} and I would like to plot 'streams.' quiver from pgfplots does produce arrows (which I normalise) but I think that streams would make things easier to understand. Here is a StreamPlot that mathematica creates.

Plot of vector field in mathematica

enter image description here

I would like to be able to make something like this with pgfplots to be able to maintain style consistency. Perhaps if I could extract the points that produce the curves then that could be plotted with pgfplots.

10
  • 1
    Welcome to TeX.SX. I think quiver plots in PGFPlots always produce straight arrows in in the above image the arrows aren't all straight. But I think your last suggestion should work, i.e. storing the points of the curves in a file that than is used by PGFPlots. I think you will "program" a solution to store the points in the file, so as a hint: You have to introduce empty lines so that the PGFPlots "jumps" to the start of the new curve instead of "drawing" to the start point of a new curve. Commented Nov 15, 2016 at 17:29
  • @StefanPinnow Thanks for the answer. I was merely throwing out possibilities but I do not know how to extract points, either from Mathematica or elsewhere, if you could advise on that issue.
    – user110503
    Commented Nov 15, 2016 at 17:56
  • 1
    I never used Mathematica, but googling found e.g. reference.wolfram.com/language/ref/Export.html or reference.wolfram.com/language/tutorial/…. Hopefully that helps. Good luck! Commented Nov 15, 2016 at 18:02
  • @StefanPinnow Thanks. I managed to get the extracted points and they are in a text file but I'm not sure how to plot them smoothly from the text file, if you know the answer to that. (I haven't used pgfplots before).
    – user110503
    Commented Nov 16, 2016 at 17:33
  • 1
    Take a look at MaTeX. The documentation (in the latest version) even has a section on style consistency.
    – Szabolcs
    Commented Nov 20, 2016 at 12:31

1 Answer 1

5

I used this: https://mathematica.stackexchange.com/questions/19859/plot-extract-data-to-a-file initially. The first element in the plot dynamicalStream was an empty string plus an object GraphicsComplex. I extracted the points from the plot with points = dynamicalStream[[1]][[2]][[1]]. It may be different for someone else. The Line objects from this GraphicsComplex object were extracted with (and I apologise for the way I did this, there are probably better methods)

lines = dynamicalStream[[1]][[2]][[2]][[2]][[3]][[2 ;; Length[ dynamicalStream[[1]][[2]][[2]][[2]][[3]]]] ].

I'd say this is unlikely to be useful, so either you find a more general method or do what I did which is manually find the correct part of the list to extract from.

I then created a list where each element is itself a list of points for each line. This was done with pointstable = Table[points[[#[[1]][[i]]]], {i, 1, Length[#[[1]]]}] & /@ lines. The inner list was created by going through each element in the Line object (this is a position of a point in the points list) and extracting the correct point. Thus you make a list of points corresponding to the Line. This is then mapped over each Line object in lines so the final list is of the described form.

I then saved each list in a separate text file: Export["line" <> IntegerString[#2] <> ".txt", #,"Table"] &~MapIndexed~pointstable as described in the link.

I plotted with:

\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
\usetikzlibrary{decorations.markings}
\tikzset{->-/.style={decoration={
  markings,
  mark=at position #1 with {\arrow{>}}},postaction={decorate}}}
  \tikzset{-<-/.style={decoration={
  markings,
  mark=at position #1 with {\arrow{<}}},postaction={decorate}}}

\begin{document}
    \begin{tikzpicture}[scale=1.5]
        \begin{axis}[axis lines=none]
            \foreach \i in {1,2,3,4,...,107}{
                \addplot[black,->-=0.5] table[]{line\i.txt};
            }
        \end{axis}
    \end{tikzpicture}
\end{document}

The result

After looking at that link properly, an easier way to do it would be:

points  = Cases[dynamicalStream, GraphicsComplex[data__] :> data, -3, 1][[1]]
lines = Cases[dynamicalStream, Line[data__] :> data, -3];
pointstable = Table[points[[#[[i]]]], {i, 1, Length[#]}] & /@ lines
3
  • That looks good. Even better it would be, if you could also add the output of PGFPlots to your answer, because we don't have your TXT files. (And just for your information: Maybe you have seen that I have edited your answer already. Instead of always writing <code>foo\</code> you can use the shortcut `foo`.) Commented Nov 16, 2016 at 20:37
  • @StefanPinnow Sorry I'm not exactly sure what want me to add.
    – user110503
    Commented Nov 16, 2016 at 21:39
  • You should move the resulting image of LaTeX/PGFPlots to the answer instead of the question ;) Commented Nov 16, 2016 at 22:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .