更新:pgfmathsetmacro
与实际函数结合使用时,内部tikzpicture
似乎是问题所在。一些空白可以通过使用\relax
内部来规避,但这会在 tikzpicture 中\pgfmathsetmacro
产生随机性。@
我制作了一个算法pgfmath
,打算在动画中使用(见下文)。出于某种原因,只有当我使用此算法时才会产生向右的奇怪偏移(在序言qnorm
中\pgfmathdeclarefunction
)。为什么会发生这种情况?
我相信这是不言而喻的,上图中动画 tikzpicture 的对齐方式完全是错误的。
要了解发生了什么,请尝试将值设置为:
\pgfmathsetmacro\static{10}
和
\pgfmathsetmacro\qqq{14}
我根本无法解释为什么计算值会产生与内部直接设置的近似值相反的行为\pgfmathsetmacro
。
\documentclass{article}
\usepackage{pgfplots}
\usepackage{tikz}
\usepackage{animate}
\usepackage{geometry}
\usepackage{hyperref}
\usepackage{hypcap}
\pgfplotsset{compat=newest}
\usepgfplotslibrary{fillbetween}
\usetikzlibrary{intersections}
\usetikzlibrary{shadows}
\pgfmathdeclarefunction{normal}{2}{%
\pgfmathparse{1/(#2*sqrt(2*pi))*exp(-((x-#1)^2)/(2*#2^2))}%
}
%
\makeatletter
\pgfmathdeclarefunction{qnorm}{4}{%
\begingroup
\pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}
\pgfmathparse{#1}
\edef\p{\pgfmathresult}
\pgfmathparse{#2}
\edef\mu{\pgfmathresult}
\pgfmathparse{#3}
\edef\sigma{\pgfmathresult}
%
\pgfmathparse{\sigma < 0 ? 1 : 0}
\edef\sigma@neg{\pgfmathresult}
\pgfmathparse{\sigma == 0 ? 1 : 0}
\edef\sigma@zero{\pgfmathresult}
%
\pgfmathparse{\p - .5}
\edef\q{\pgfmathresult}
%
\pgfmathparse{abs(\q) <= .425 ? 1 : 0}
\edef\q@i{\pgfmathresult}
%
\pgfmathparse{
\q@i ?
.180625 - \q * \q
:
sqrt(-ln(min(\p,(1-\p))))
}
\edef\r@{\pgfmathresult}
%
\pgfmathparse{\q@i ?
\r@
:
(\r@ <= 5 ?
\r@ - 1.6 %
:
\r@ - 5
)}
\edef\r{\pgfmathresult}
\pgfmathparse{\q@i ?
(\q * (((((((\r * 2509.0809287301226727 +
33430.575583588128105) * \r + 67265.770927008700853) * \r +
45921.953931549871457) * \r + 13731.693765509461125) * \r +
1971.5909503065514427) * \r + 133.14166789178437745) * \r +
3.387132872796366608)
/ (((((((\r * 5226.495278852854561 +
28729.085735721942674) * \r + 39307.89580009271061) * \r +
21213.794301586595867) * \r + 5394.1960214247511077) * \r +
687.1870074920579083) * \r + 42.313330701600911252) * \r + 1.))
: ( \r@ <= 5 ?
((((((((\r * 7.7454501427834140764e-4 + %
.0227238449892691845833) * \r + .24178072517745061177) * %
\r + 1.27045825245236838258) * \r + %
3.64784832476320460504) * \r + 5.7694972214606914055) * %
\r + 4.6303378461565452959) * \r + %
1.42343711074968357734) %
/ (((((((\r * %
1.05075007164441684324e-9 + 5.475938084995344946e-4) * %
\r + .0151986665636164571966) * \r + %
.14810397642748007459) * \r + .68976733498510000455) * %
\r + 1.6763848301838038494) * \r + %
2.05319162663775882187) * \r + 1)) %
:
((((((((\r * 2.01033439929228813265e-7 +
2.71155556874348757815e-5) * \r +
.0012426609473880784386) * \r + .026532189526576123093) *
\r + .29656057182850489123) * \r +
1.7848265399172913358) * \r + 5.4637849111641143699) *
\r + 6.6579046435011037772)
/ (((((((\r *
2.04426310338993978564e-15 + 1.4215117583164458887e-7)*
\r + 1.8463183175100546818e-5) * \r +
7.868691311456132591e-4) * \r + .0148753612908506148525)
* \r + .13692988092273580531) * \r +
.59983220655588793769) * \r + 1.))
)
}
\edef\val{\pgfmathresult}
\pgfmathparse{\q@i ? \val :
(\q > 0 ? \val : -\val)} %
\edef\@tmp{\pgfmathresult}
\pgfmathparse{\p > 1 ? sqrt(-1) :
(\p < 0 ? sqrt(-1) :
\sigma@neg ? sqrt(-1) : %
(\sigma@zero ? \mu : %
(#4 ? \mu+\sigma*\@tmp :
\mu-\sigma*\@tmp) %
)
)
}
\pgfmath@smuggleone\pgfmathresult
\endgroup
}
\makeatother
\begin{document}
\newcommand*\samplesize{7}\relax
\let\mean\relax\newcommand\mean{9}\relax
\let\sd\relax\newcommand\sd{3}\relax
\let\lowertail\relax\newcommand\lowertail{0}\relax
\begin{figure}[ht]
\capstart
\begin{center}
\begin{animateinline}[controls]{15}
\multiframe{15}{ik=1+2}{
\begin{tikzpicture}
\begin{axis}[
hide y axis,
axis lines*=center,
axis on top,
no markers,
domain=4:20,
samples=4*\samplesize-7,
xlabel=\empty,
ylabel=\empty,
every axis x label/.style={at=(current axis.right of origin),anchor=west},
every axis y label/.style={at=(current axis.above origin),anchor=south},
width=.8\linewidth,
height=.3\linewidth,
xmin = 4, xmax=20,
xtick=, ytick=\empty,
enlargelimits=false,
clip=false
]
\pgfmathsetmacro\result{1/((\ik/25+.65)^2+(ln(\ik/25+.65)^2+1.5))/1.2}
\pgfmathsetmacro\static{qnorm(0.05,\mean,\sd,\lowertail)}
\pgfmathsetmacro\qqq{qnorm(\result,\mean,\sd,\lowertail)}
\pgfmathsetmacro\colorq{(.1+.2*\ik/180)*100}
\pgfmathsetmacro\colorr{(.3+.55*\ik/180)*100}
\pgfmathsetmacro\colort{(.9-.8*\ik/180)*100}
\pgfmathsetmacro\colors{(.85-.55*\ik/180)*100}
\node at (axis cs:5,0.2) {};
\node at (axis cs:10.25,0.025) {\ifnum\ik>75{\textcolor{red}{waarschijnlijk een effect! $\rightarrow$}}\else{waarschijnlijk geen effect}\fi};
\node at (axis cs:\qqq,{1/(\sd*sqrt(2*pi))*exp(-((\qqq-\mean)^2)/(2*\sd^2))+.02}) {\ifnum\ik<75$\downarrow$\else\textcolor{red}{$\downarrow$}\fi};
\path[name path=line] (axis cs:\static,0) -- (axis cs:\static,\pgfkeysvalueof{/pgfplots/ymax}*1.1);
\addplot [name path=normaal,very thick,cyan!85!black!50] {normal(\mean,\sd)};
\path[name path=axis] (axis cs:\pgfkeysvalueof{/pgfplots/xmin},0) -- (axis cs:\pgfkeysvalueof{/pgfplots/xmax},0);
\addplot[cyan!\colort!red!\colorq,draw=cyan!\colors!red!\colorr,thick] fill between[of=normaal and axis,soft clip={domain=\qqq:\pgfkeysvalueof{/pgfplots/xmax}}];
\node at (axis cs:{\mean+1.65*\sd},{.055-.003*\sd^.5-.0015*\sd^2}) [pin=45:$\alpha$] {};
\node at (axis cs:{\mean*.85},{1/(\sd*sqrt(2*pi))-.015}) [pin=135:$H_0$] {};
\node at (axis cs:{4+\mean+1.65*\sd},{.08+.055-.003*\sd^.5-.0015*\sd^2}) [rectangle,draw=blue!60,fill=cyan!10] {\ifnum\ik<75$p=\result$\else\textcolor{red}{$p=\result$}\fi};
\path[name intersections={of=line and normaal, by={interp}}];
\draw[draw=red!80!black] (axis cs:\static,0) -- (interp);
\end{axis}
\end{tikzpicture}
}
\end{animateinline}
\caption{De verdeling die hoort bij een nulhypothese en een aantal mogelijke meetresultaten (weergegeven door het pijltje) - wanneer je meetresultaat erg afwijkt van de aanname waarbij er geen effect zou plaatsvinden, is er dus waarschijnlijk kans op een effect}\label{fig:p.waarde.anim}
\end{center}
\end{figure}
\end{document}
答案1
的定义中有很多未受保护的行尾\qnorm
;的参数中空格会被忽略\pgfmathparse
,但的其他地方不会被忽略\pgfmathdeclarefunction
。
\documentclass{article}
\usepackage{pgfplots}
\usepackage{tikz}
\usepackage{animate}
\usepackage{geometry}
\usepackage{hyperref}
\usepackage{hypcap}
\pgfplotsset{compat=newest}
\usepgfplotslibrary{fillbetween}
\usetikzlibrary{intersections}
\usetikzlibrary{shadows}
\pgfmathdeclarefunction{normal}{2}{%
\pgfmathparse{1/(#2*sqrt(2*pi))*exp(-((x-#1)^2)/(2*#2^2))}%
}
\makeatletter
\pgfmathdeclarefunction{qnorm}{4}{%
\begingroup
\pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}%
\pgfmathparse{#1}%
\edef\p{\pgfmathresult}%
\pgfmathparse{#2}%
\edef\mu{\pgfmathresult}%
\pgfmathparse{#3}%
\edef\sigma{\pgfmathresult}%
%
\pgfmathparse{\sigma < 0 ? 1 : 0}%
\edef\sigma@neg{\pgfmathresult}%
\pgfmathparse{\sigma == 0 ? 1 : 0}%
\edef\sigma@zero{\pgfmathresult}%
%
\pgfmathparse{\p - .5}%
\edef\q{\pgfmathresult}%
%
\pgfmathparse{abs(\q) <= .425 ? 1 : 0}%
\edef\q@i{\pgfmathresult}%
%
\pgfmathparse{
\q@i ?
.180625 - \q * \q
:
sqrt(-ln(min(\p,(1-\p))))
}%
\edef\r@{\pgfmathresult}%
%
\pgfmathparse{\q@i ?
\r@
:
(\r@ <= 5 ?
\r@ - 1.6 %
:
\r@ - 5
)}%
\edef\r{\pgfmathresult}%
\pgfmathparse{\q@i ?
(\q * (((((((\r * 2509.0809287301226727 +
33430.575583588128105) * \r + 67265.770927008700853) * \r +
45921.953931549871457) * \r + 13731.693765509461125) * \r +
1971.5909503065514427) * \r + 133.14166789178437745) * \r +
3.387132872796366608)
/ (((((((\r * 5226.495278852854561 +
28729.085735721942674) * \r + 39307.89580009271061) * \r +
21213.794301586595867) * \r + 5394.1960214247511077) * \r +
687.1870074920579083) * \r + 42.313330701600911252) * \r + 1.))
: ( \r@ <= 5 ?
((((((((\r * 7.7454501427834140764e-4 +
.0227238449892691845833) * \r + .24178072517745061177) *%
\r + 1.27045825245236838258) * \r +
3.64784832476320460504) * \r + 5.7694972214606914055) *
\r + 4.6303378461565452959) * \r +
1.42343711074968357734)
/ (((((((\r *
1.05075007164441684324e-9 + 5.475938084995344946e-4) *
\r + .0151986665636164571966) * \r +
.14810397642748007459) * \r + .68976733498510000455) *
\r + 1.6763848301838038494) * \r +
2.05319162663775882187) * \r + 1))
:
((((((((\r * 2.01033439929228813265e-7 +
2.71155556874348757815e-5) * \r +
.0012426609473880784386) * \r + .026532189526576123093) *
\r + .29656057182850489123) * \r +
1.7848265399172913358) * \r + 5.4637849111641143699) *
\r + 6.6579046435011037772)
/ (((((((\r *
2.04426310338993978564e-15 + 1.4215117583164458887e-7)*
\r + 1.8463183175100546818e-5) * \r +
7.868691311456132591e-4) * \r + .0148753612908506148525)
* \r + .13692988092273580531) * \r +
.59983220655588793769) * \r + 1.))
)
}%
\edef\val{\pgfmathresult}%
\pgfmathparse{\q@i ? \val :
(\q > 0 ? \val : -\val)}%
\edef\@tmp{\pgfmathresult}%
\pgfmathparse{\p > 1 ? sqrt(-1) :
(\p < 0 ? sqrt(-1) :
\sigma@neg ? sqrt(-1) :
(\sigma@zero ? \mu :
(#4 ? \mu+\sigma*\@tmp :
\mu-\sigma*\@tmp)
)
)
}%
\pgfmath@smuggleone\pgfmathresult
\endgroup
}
\makeatother
\begin{document}
\newcommand*\samplesize{7}\relax
\let\mean\relax\newcommand\mean{9}\relax
\let\sd\relax\newcommand\sd{3}\relax
\let\lowertail\relax\newcommand\lowertail{0}\relax
\begin{figure}[ht]
\capstart
\begin{center}
\begin{animateinline}[controls]{15}
\multiframe{15}{ik=1+2}{%
\begin{tikzpicture}
\begin{axis}[
hide y axis,
axis lines*=center,
axis on top,
no markers,
domain=4:20,
samples=4*\samplesize-7,
xlabel=\empty,
ylabel=\empty,
every axis x label/.style={at=(current axis.right of origin),anchor=west},
every axis y label/.style={at=(current axis.above origin),anchor=south},
width=.8\linewidth,
height=.3\linewidth,
xmin = 4, xmax=20,
xtick=, ytick=\empty,
enlargelimits=false,
clip=false
]
\pgfmathsetmacro\result{1/((\ik/25+.65)^2+(ln(\ik/25+.65)^2+1.5))/1.2}
\pgfmathsetmacro\static{qnorm(0.05,\mean,\sd,\lowertail)}
\pgfmathsetmacro\qqq{qnorm(\result,\mean,\sd,\lowertail)}
\pgfmathsetmacro\colorq{(.1+.2*\ik/180)*100}
\pgfmathsetmacro\colorr{(.3+.55*\ik/180)*100}
\pgfmathsetmacro\colort{(.9-.8*\ik/180)*100}
\pgfmathsetmacro\colors{(.85-.55*\ik/180)*100}
\node at (axis cs:5,0.2) {};
\node at (axis cs:10.25,0.025) {\ifnum\ik>75{\textcolor{red}{waarschijnlijk een effect! $\rightarrow$}}\else{waarschijnlijk geen effect}\fi};
\node at (axis cs:\qqq,{1/(\sd*sqrt(2*pi))*exp(-((\qqq-\mean)^2)/(2*\sd^2))+.02}) {\ifnum\ik<75$\downarrow$\else\textcolor{red}{$\downarrow$}\fi};
\path[name path=line] (axis cs:\static,0) -- (axis cs:\static,\pgfkeysvalueof{/pgfplots/ymax}*1.1);
\addplot [name path=normaal,very thick,cyan!85!black!50] {normal(\mean,\sd)};
\path[name path=axis] (axis cs:\pgfkeysvalueof{/pgfplots/xmin},0) -- (axis cs:\pgfkeysvalueof{/pgfplots/xmax},0);
\addplot[cyan!\colort!red!\colorq,draw=cyan!\colors!red!\colorr,thick] fill between[of=normaal and axis,soft clip={domain=\qqq:\pgfkeysvalueof{/pgfplots/xmax}}];
\node at (axis cs:{\mean+1.65*\sd},{.055-.003*\sd^.5-.0015*\sd^2}) [pin=45:$\alpha$] {};
\node at (axis cs:{\mean*.85},{1/(\sd*sqrt(2*pi))-.015}) [pin=135:$H_0$] {};
\node at (axis cs:{4+\mean+1.65*\sd},{.08+.055-.003*\sd^.5-.0015*\sd^2}) [rectangle,draw=blue!60,fill=cyan!10] {\ifnum\ik<75$p=\result$\else\textcolor{red}{$p=\result$}\fi};
\path[name intersections={of=line and normaal, by={interp}}];
\draw[draw=red!80!black] (axis cs:\static,0) -- (interp);
\end{axis}
\end{tikzpicture}%
}
\end{animateinline}
\caption{De verdeling die hoort bij een nulhypothese en een aantal mogelijke meetresultaten (weergegeven door het pijltje) - wanneer je meetresultaat erg afwijkt van de aanname waarbij er geen effect zou plaatsvinden, is er dus waarschijnlijk kans op een effect}\label{fig:p.waarde.anim}
\end{center}
\end{figure}
\end{document}