自定义箭头图/访问变量 x、y、u、v

自定义箭头图/访问变量 x、y、u、v

我想让箭筒图更美观一些,所以我对箭头进行了更美观的表示,使其具有 3D 外观。箭头的阴影取自来自另一个问题在这个网站上。并且这个问题是宏的由来\arrowthreeD

目前,我正在努力确定箭头的位置。其他一切都很好:箭头缩放得很好,通过颜色图着色也很好。另外,据我所知,箭头的放置是在轴 cs 内完成的。(它们被放置在0..1000 的1,\pgfplotspointmetatransformed/200位置\pgfplotspointmetatransformed。因此,它们被相应地放置在 y 值的 0 到 5 之间。

但是,在代码中注释的位置,我没有方法访问箭头最初放置的坐标 (x,y)。在 pgfplots 代码中,我发现了一些关于 的信息\pgfplots@current@point@[xyz]。但我无法访问存储在那里的值... 同样,我不知道如何访问 u 和 v(箭筒箭头尺寸),以通过 atan() 或类似程序计算角度。

因此,我的问题可能是:我如何访问

  • \pgfplots@current@point@x
  • \pgfplots@current@point@y
  • \pgfplots@quiver@u
  • \pgfplots@quiver@v

如果我尝试使用它们,它们就无法被评估(之后我会收到一些错误\pgfplots。例如,使用\pgfplots@current@point@xx 坐标会导致

! Undefined control sequence.

<argument> \pgfplots

@current@point@x,\pgfplotspointmetatransformed /200

l.95 \end{axis}

?

\documentclass[]{standalone} 
\usepackage{tikz,pgfplots,pgfplotstable,filecontents}
\usepgfplotslibrary{colormaps}
\usetikzlibrary{calc}
\pgfplotsset{compat=1.13}

\newcommand*{\arrowheadthreeD}[4]{%
  \colorlet{beamcolor}{#1!75!black}
  \colorlet{innercolor}{#1!50}
  \foreach \i in {1, 0.975, ..., 0} {
    \pgfmathsetmacro{\shade}{\i*\i*100}
    \pgfmathsetmacro{\startangle}{90-\i*30}
    \pgfmathsetmacro{\endangle}{90+\i*30}
    \fill[beamcolor!\shade!innercolor,shift={#2},rotate=#3,line width=0,line cap=butt,]%,
      (0,0) -- (\startangle:0.2599) arc (\startangle:\endangle:0.2599)--cycle;
  }
  \fill[beamcolor,shift={#2},rotate=#3,line width=0,line cap=butt] (60:0.26) arc (60:120:0.26) -- ($(120:0.26)!0.06*#4!(0,0.0)$) arc (120:60:{0.26-0.015*#4}) -- cycle;
}

\newcommand*{\arrowthreeD}[4]{
  \begin{scope}[shift={([rotate = -#4]#2)}]
    \begin{scope}[,,transform canvas={rotate=#4},scale=#3,]
      \fill [left color=#1!75!black,right color=#1!75!black,middle color=#1!50,join=round,line cap=round,draw=none] (0.05,0) -- (0.05,-0.175) arc (360:180:0.05 and 0.05) -- (-0.05,0)--cycle;
      \arrowheadthreeD{#1}{(0,0.25)}{180}{#3};
    \end{scope}
  \end{scope}
} 


\begin{filecontents}{quiver.txt}
x y u v
1 0.5 1.4 1.4
2 0.1 0 1.5
0.1 2 1 0
0.2 0.75 0.5 0
1 1 0.1 0.1
\end{filecontents}

\begin{document}
\thispagestyle{empty} 
  \begin{tikzpicture}
    \begin{axis}[
        width= 5cm,
        ymin=0, 
        ymax=6,
        xmin=0,
        xmax=3,
        axis equal image,
        clip=false,
        grid=both,
        colormap/hot2,
        ]





      \addplot[
               point meta={sqrt{\thisrow{u}*\thisrow{u}+\thisrow{v}*\thisrow{v}}},
               point meta min=0,
               quiver={u=\thisrow{u},
                       v=\thisrow{v},
                       every arrow/.append style={
                         line width=1pt,
                         draw=none,
                         },
                       after arrow/.code={
                         \arrowthreeD{mapped color}{1,\pgfplotspointmetatransformed/200}{sqrt{\pgfplotspointmetatransformed}/25}{90}
                         %%%%%
                         %%%%%
                         % Explanation: arguments are 
                         %   color 
                         %   coordinates (should be (x,y))
                         %   scaling value
                         %   angle (should be computed from atan(u,v) or similar)
                         %%%%%
                         %%%%%
                       },  
                       },
               ] table {quiver.txt};

      \addplot[
               point meta={sqrt{\thisrow{u}*\thisrow{u}+\thisrow{v}*\thisrow{v}}},
               quiver={u=\thisrow{u},
                       v=\thisrow{v},
                       every arrow/.append style={
                         line width=2pt*\pgfplotspointmetatransformed/1500,
                         ->,
                         },
                       },
               ] table {quiver.txt};
   \end{axis}
  \end{tikzpicture} 

\end{document}

当然还有当前结果的图片:(新箭头的定位非常任意) 在此处输入图片描述

答案1

在其他问题(这里和这里)的帮助下,我终于实现了我的目标。在我看来,这样的箭筒图确实漂亮得多!

首先是一个例子pgfplots manual 在此处输入图片描述

我的“改进”版本 在此处输入图片描述

以及重现它的代码

\documentclass[border=9,tikz]{standalone} 
\usepackage{pgfplots,filecontents}\pgfplotsset{compat=newest}
\usetikzlibrary{arrows.meta,calc}


\newcommand*{\arrowheadthreeD}[4]{%
  \colorlet{beamcolor}{#1!75!black}
  \colorlet{innercolor}{#1!50}
  \foreach \i in {1, 0.9, ..., 0} {
    \pgfmathsetmacro{\shade}{\i*\i*100}
    \pgfmathsetmacro{\startangle}{90-\i*30}
    \pgfmathsetmacro{\endangle}{90+\i*30}
    \fill[beamcolor!\shade!innercolor,shift={#2},rotate=#3,line width=0,line cap=butt,]%,
      (0,0) -- (\startangle:0.259) arc (\startangle:\endangle:0.259)--cycle;
  }
%  \pgfmathparse{#4}
  \fill[beamcolor,shift={#2},rotate=#3,line width=0,line cap=butt] (60:0.26) arc (60:120:0.26) -- ($(120:0.26)!0.06*1!(0,0.0)$) arc (120:60:{0.26-0.015*1}) -- cycle; % statt *1 *#4???
      %\draw[blue,thick,shift={#2},rotate=#3] (0,0) -- (0,0.25);
}

\newcommand*{\arrowthreeD}[4]{
  %\begin{scope}[shift={([rotate = -#4]#2)}]
    %\begin{scope}[,,transform canvas={rotate=#4},scale=#3,]
    \begin{scope}[scale=#3,]
      \fill [left color=#1!75!black,right color=#1!75!black,middle color=#1!50,join=round,line cap=round,line width=0,draw=none,shading angle=#4+90,,shift={(0,0.25)},rotate=180] (0,0.25) -- (0.05,0.25) -- (0.05,0.175+0.25) arc (0:180:0.05 and 0.05) -- (-0.05,0.25)--cycle;
     % \fill [left color=#1!75!black,right color=#1!75!black,middle color=#1!50,draw=none,shading angle=#4-90] (0,0) -- (0.05,0) -- (0.05,-0.175) -- (-0.05,-0.175) -- (-0.05,0)--cycle;

      \arrowheadthreeD{#1}{(0,0.25)}{180}{#3};
    \end{scope}
  %\end{scope}
} 


\begin{document}

\makeatletter
\def\pgfplotsplothandlerquiver@vis@path#1{%
    % remember (x,y) in a robust way
    #1%
    \pgfmathsetmacro\pgfplots@quiver@x{\pgf@x}\global\let\pgfplots@quiver@x\pgfplots@quiver@x%
    \pgfmathsetmacro\pgfplots@quiver@y{\pgf@y}\global\let\pgfplots@quiver@y\pgfplots@quiver@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}%
    \pgfmathparse{atan2(\pgfplots@quiver@v,\pgfplots@quiver@u)-90}
    \pgfmathsetmacro\pgfplots@quiver@a{\pgfmathresult}\global\let\pgfplots@quiver@a\pgfplots@quiver@a%
    % 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 image,enlargelimits=false,view={0}{90},domain=-2:2,,xmin=-2.1,xmax=2.1,ymin=-2.1,ymax=2.1]
\addplot3[contour gnuplot={number=9,
labels=false},thick]
{exp(0-x^2-y^2)*x};
            \addplot3[
                colormap/hot2,
           % point meta=x,
           % quiver={
           %     u=x,v=y,
            point meta={sqrt{exp(0-x^2-y^2)*(1-2*x^2)*exp(0-x^2-y^2)*(1-2*x^2)+exp(0-x^2-y^2)*(-2*x*y)*exp(0-x^2-y^2)*(-2*x*y)}},
            quiver={u={exp(0-x^2-y^2)*(1-2*x^2)},
                    v={exp(0-x^2-y^2)*(-2*x*y)},
                every arrow/.append style={%
                    draw=none,%-{Latex[scale length={max(0.1,\pgfplotspointmetatransformed/1000)}]},mapped color
                },
                after arrow/.code={
                    \relax{% always protect the shift
                        \pgftransformshift{\pgfpoint{\pgfplots@quiver@x}{\pgfplots@quiver@y}}%
                        %\node[below right]{\tiny\color{mapped color!50!black}\pgfplotspointmetatransformed};
                        \pgftransformrotate{\pgfplots@quiver@a}%
                        \arrowthreeD{mapped color}{0,0}{sqrt{\pgfplotspointmetatransformed}/62}{\pgfplots@quiver@a}
                    }
                }
            },
            samples=15,
           ] {exp(0-x^2-y^2)*x};
    \end{axis}
\end{tikzpicture}
\end{document}

相关内容