1

Since this question is maybe overloaded and contains too much unnecessary details, I tried to reformulate it into a more condensed and comprehensive form.

The problem is that I want to access the quiver plot coordinates (x,y,u,v) in an own piece of code, in quiver/after arrow/.code, oder alternatively in quiver/before arrow/.code. The following example does not make sense completely, since one could easily just change u and v vales. However, the problem is exactly the same as in my other question.

In the code, I have added a comment where I try to access the coordinates and where different non-working possibilites are commented out.

\documentclass[]{standalone} 
\usepackage{tikz,pgfplots}
\usetikzlibrary{calc} \pgfplotsset{compat=newest}

\begin{document}
  \begin{tikzpicture}
    \begin{axis}[axis equal image,enlargelimits=false,clip=false]
      % Reference plot
      \addplot[
               quiver={
                       u=x,v=y,
                      },
               ->,
               samples=5,domain=0:1
              ] {x*x};

              % own plot
      \addplot[
               quiver={
                       u=x,v=y,
                       % draw some other (e.g. orthogonal) arrows here!
                       after arrow/.code={
                                          \draw[blue,dashed,->] (0.5,0.25) -- ($ (0.5,0.25) + (0.25,-0.5)$);
                                          \draw[blue,dashed,->] (1,1) -- ($ (1,1) + (1,-1)$);
        %
        %
        % Things which are not working
        %
        %
                                          %\draw[blue,dashed,->] (x,y) -- ($ (x,y) + (v,-u)$);
                                          %\draw[blue,dashed,->] (\x,\y) -- ($ (\x,\y) + (\v,-\u)$);
                                          %\draw[blue,dashed,->] (\pgfplots@current@point@x,\pgfplots@current@point@y) -- ($ (\pgfplots@current@point@x,\pgfplots@current@point@y) + (\pgfplots@quiver@v,-\pgfplots@quiver@u)$);
                                         };
                      },
               draw=none,
               samples=5,domain=0:1
              ] {x*x};

   \end{axis}
  \end{tikzpicture} 

\end{document}
crateane
  • 2,217

1 Answers1

2

Currently the design of quiver is very inflexible. By the time the arrows are drawn, (x,y) coordinates are stored in \pgf@x and \pgf@y and (u,v) coordinates are translated to absolute coordinate. You do not have much choice.

Perhaps you can plot the same function twice with different quiver.

\documentclass[border=9,tikz]{standalone} 
\usepackage{pgfplots}\pgfplotsset{compat=newest}

\begin{document}
  \begin{tikzpicture}
    \begin{axis}[axis equal]
      % Reference plot
      \addplot[
               quiver={u=x,v=y},
               ->,
               samples=10,domain=0:1
              ] {x*x};

              % own plot
      \addplot[
               quiver={u=y,v=-x},
               ->,blue,
               samples=10,domain=0:1
              ] {x*x};

   \end{axis}
  \end{tikzpicture} 
\end{document}

A fragile way to access relative coordinate of (u,v)

\documentclass[border=9,tikz]{standalone} 
\usepackage{pgfplots}\pgfplotsset{compat=newest}

\begin{document}

\makeatletter
\def\pgfplotsplothandlerquiver@vis@path#1{%
    % remember (x,y) in a robust way
    #1%
    \pgfmathsetmacro\pgfplots@quiver@x{\pgf@x}%
    \pgfmathsetmacro\pgfplots@quiver@y{\pgf@y}%
    % calculate (u,v) in relative coordinate
    \pgfplotsaxisvisphasetransformcoordinate\pgfplots@quiver@u\pgfplots@quiver@v\pgfplots@quiver@w%
    \pgfplotsqpointxy{\pgfplots@quiver@u}{\pgfplots@quiver@v}%
    \pgfmathsetmacro\pgfplots@quiver@u{\pgf@x-\pgfplots@quiver@x}%
    \pgfmathsetmacro\pgfplots@quiver@v{\pgf@y-\pgfplots@quiver@y}%
    % move to (x,y) and start drawing
    {%
        \pgftransformshift{\pgfpoint{\pgfplots@quiver@x}{\pgfplots@quiver@y}}%
        \pgfpathmoveto{\pgfpointorigin}%
        \pgfpathlineto{\pgfpoint\pgfplots@quiver@u\pgfplots@quiver@v}%
    }%
}%

  \begin{tikzpicture}
    \begin{axis}[axis equal]
      \addplot[
               quiver={u=x,v=y,
                 after arrow/.code={
                   \relax{% always protect the shift
                     \pgftransformshift{\pgfpoint{\pgfplots@quiver@x}{\pgfplots@quiver@y}}%
                     \node[below right]{\tiny$(u,v)=(\pgfplots@quiver@u,\pgfplots@quiver@v)$};
                   }
                 }
               },
               ->,
               samples=10,domain=-1:1
              ] {x*x};
   \end{axis}
  \end{tikzpicture}
\end{document}

# OK...

The following code modify the internal procedure so that \pgfplots@quiver@x is the canvas x-coordinate and \pgfplots@quiver@u is the canvas, relative u-coordinate.

\documentclass[border=9,tikz]{standalone} 
\usepackage{pgfplots}\pgfplotsset{compat=newest}

\begin{document}

\makeatletter
\def\pgfplotsplothandlerquiver@vis@path#1{%
    % remember (x,y) in a robust way
    #1%
    \pgfmathsetmacro\pgfplots@quiver@x{\pgf@x}%
    \pgfmathsetmacro\pgfplots@quiver@y{\pgf@y}%
    % calculate (u,v) in relative coordinate
    \pgfplotsaxisvisphasetransformcoordinate\pgfplots@quiver@u\pgfplots@quiver@v\pgfplots@quiver@w%
    \pgfmathsetmacro\pgfplots@quiver@u{\pgfplots@quiver@u-\pgfplots@quiver@x}%
    \pgfmathsetmacro\pgfplots@quiver@v{\pgfplots@quiver@v-\pgfplots@quiver@y}%
    % move to (x,y) and start drawing
    {%
        \pgftransformshift{\pgfpoint{\pgfplots@quiver@x}{\pgfplots@quiver@y}}%
        \pgfpathmoveto{\pgfpointorigin}%
        \pgfpathlineto{\pgfplotsqpointxy\pgfplots@quiver@u\pgfplots@quiver@v}%
    }%
}%

  \begin{tikzpicture}
    \begin{axis}[axis equal]
      \addplot[
               quiver={u=x,v=y,
                 after arrow/.code={
                   \relax{% always protect the shift
                     \pgftransformshift{\pgfpoint{\pgfplots@quiver@x}{\pgfplots@quiver@y}}%
                     \node[below right]{$(u,v)=(\pgfplots@quiver@u,\pgfplots@quiver@v)$};
                   }
                 }
               },
               ->,
               samples=10,domain=0:1
              ] {x*x};
   \end{axis}
  \end{tikzpicture} 
\end{document}

[![][2]][2]

Disclaimer

Currently before arrow and after arrow is not used elsewhere in the package. The fact that (u,v) is in absolute coordinate might be changed in the future.

Symbol 1
  • 36,855
  • Thanks a lot for your effort. I've tried to explain in the question that this example is only for a simple demonstration of my problem (see the linked question). The problem is that I want to do sthg else than drawing an arrow, and therefore I need the coordinates. Is it somehow possible to acces \pgf@x in before arrow/.code or after arrow/.code or somehow else? – crateane Apr 22 '17 at 17:30
  • Maybe I could use normal plot and not quiver, to access x and y for every sample of a table? – crateane Apr 22 '17 at 17:31
  • I am currently playing with \pgfplotsplothandlerquiver@vis and \pgfplotsplothandlerquiver@vis@path. But they are really tough. I guess you can subtract x from u (It is \pgfplotsplothandlersurveypoint@quiver that makes u-v absolute. Maybe you can modify it)... And yes, because quiver is merely a kind of point-meta. – Symbol 1 Apr 22 '17 at 17:34
  • If it's easier for normal addplot, I could mis-use the z coordinate to store the rotation angle I need for the arrows, and use the point-meta value for the scaling and coloring of my arrows... I'll try to look into that. – crateane Apr 22 '17 at 17:37
  • @Faekynn Please see my edit. – Symbol 1 Apr 22 '17 at 17:57
  • It's working so far! :) I will try to transfer this to my other example... – crateane Apr 22 '17 at 19:48
  • Unfortunately, it seems not to work if i have negative coordinates. e.g. with domain=-1:1 the arrow at the point (1,1) certainly is not 45degree anymore. And a second thing: point meta isn't working any more... Do you have any idea why? I didnt see that you altered something for meta... – crateane Apr 23 '17 at 14:26
  • 1
    @Faekynn I guess I know the reason. Originally the drawing code is \pgfpathmoveto{\pgfpoint{x}{y}}\pgfpathlineto{\pgfplotspointxy{u}{v}} and notice that \pgfpoint and \pgfplotspointxy are using different transformation. – Symbol 1 Apr 23 '17 at 15:13
  • 1
    @Faekynn I fixed the code. If there is still some bug please tell me. – Symbol 1 Apr 23 '17 at 15:20
  • Thanks for the quick fix! You probably skipped my other point: point meta isn't working any more. Simple test case: adding the option point meta={x},and in the node text \color{red}{\pgfplotspointmetatransformed} But since I did not ask anything about meta in this question, I can also ask a new one... – crateane Apr 23 '17 at 15:57
  • It seems strange to me, because the original \pgfplotsplothandlerquiver@vis@path doesn't do anything with meta values as well... – crateane Apr 23 '17 at 15:58
  • @Faekynn Probably better to ask a new question. So other potential answerers can play with an MWE. – Symbol 1 Apr 23 '17 at 16:45
  • I thought so, too. See https://tex.stackexchange.com/questions/366266/customizing-the-quiver-plot-including-point-meta-values if you are also still interested ;) – crateane Apr 23 '17 at 17:10