我想让箭筒图更美观一些,所以我对箭头进行了更美观的表示,使其具有 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@x
x 坐标会导致
! 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
在其他问题(这里和这里)的帮助下,我终于实现了我的目标。在我看来,这样的箭筒图确实漂亮得多!
以及重现它的代码
\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}