请考虑这个MWE:
\begin{document}
\begin{tikzpicture}
\begin{axis}[%
/pgf/number format/1000 sep={}, % do not delimit per thousand
xmin=19,
xmax=22.5,
xlabel={angle in degree},
xtick pos=left, % bottom ticks
grid=none,
% FIXME: "extra x ticks" should be calculated from xstart, xinc, xend
% xstart=4500; xinc=-250; xend=4000;
% The x tick values below are calculated by: x=4250; asind(1500/x)
extra x ticks={22.02431, 20.66731, 19.47122}, % FIX ME
every extra x tick/.style={
xtick pos=right, % top ticks
xticklabel pos=right, % top tick labels
xticklabel={
\pgfmathparse{1500/sin(\tick)}
\pgfmathprintnumber{\pgfmathresult} m/s
},
xticklabel style={
/pgf/number format/.cd,fixed,fixed zerofill,precision=0,/tikz/.cd,
},
},
]
\addplot[red,samples at={19,19.1,...,23}] {x};
\end{axis}
\end{tikzpicture}
\end{document}
我绘制了依赖于变量的数据(这里是线性函数) ,变量是角度。现在我想在顶部添加第二个 x 轴。Pgfplots 不能很好地支持这一点,正如这里在其他几个问题中讨论的那样。我采用了定义并将它们放置在顶部的x
方法。extra x ticks
我想在那里绘制一个速度,它通过公式与角度相关联v=asind(1500/angle)
。我知道想要将速度以 250 的增量放在顶部轴上,例如 4500、4250 和 4000。标有 的行FIX ME
定义了我的问题:我想应用该公式来计算与速度相对应的 x 轴位置。角度值extra x ticks
被接受xticklabel
并转换回速度。这是由于两个轴的非线性关系而需要的。一个小问题是 PGF 的精度有限(4251
而不是4250
)。我试过了/pgf/fpu=true
......
希望我清楚地表达了我的问题。
答案1
以下是基于克劳迪奥,在这里。我们必须使用宏进行一些操作才能使其工作,但我们可以定义一个新命令来执行处理并为刻度和标签设置宏。pgfplots
也不喜欢在图中标签定义中使用宏(我不记得为什么)所以我们必须使用构造\edef
。这解决了精度问题,因为我们不必进行任何计算来设置标签。
的语法与所有for 循环\deflistticks
相同:,其中和之间的差值设置增量。您还可以使用所有坐标的明确列表。pgf
start element,second element,...,end element
start element
second element
该\deflisttick
宏通过定义两个全局宏(\gdef
)\extraticks
和来工作\listlabels
。这些全局宏将分别包含我们要设置的刻度和标签列表。我们要做的第一件事是找到输入列表中的项目数(#1
是输入)。然后我们循环遍历列表并对传入的值进行计算;请注意,pgf
默认情况下以度为单位进行操作。然后我们填充列表。如果元素是列表中的最后一个,我们不会添加逗号。
\documentclass{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.12}
\newcommand{\deflisttick}[1]{
\gdef\extraticks{}
\gdef\listlabels{}
\foreach \x[count=\xi] in {#1}{\global\let\maxitems\xi}
\foreach \x[count=\xi] in {#1}{
\pgfmathsetmacro{\xy}{asin(1500/\x)}
\ifnum\xi=\maxitems
\xdef\extraticks{\extraticks \xy}
\xdef\listlabels{\listlabels \x\ m/s}
\else
\xdef\extraticks{\extraticks \xy,}
\xdef\listlabels{\listlabels \x\ m/s,}
\fi
}
}
\deflisttick{4000,4250,...,4500}
\edef\temp{%
\noexpand\pgfplotsset{%
extra x tick labels list/.style={xticklabels={\listlabels}}
}%
}
\temp
\begin{document}
\begin{tikzpicture}
\begin{axis}[%
/pgf/number format/1000 sep={}, % do not delimit per thousand
xmin=19,
xmax=22.5,
xlabel={angle in degree},
xtick pos=left, % bottom ticks
grid=none,
% FIXME: "extra x ticks" should be calculated from xstart, xinc, xend
% xstart=4500; xinc=-250; xend=4000;
% The x tick values below are calculated by: x=4250; asind(1500/x)
% extra x ticks={22.02431, 20.66731, 19.47122}, % FIX ME
extra x ticks={\extraticks},
every extra x tick/.style={
xtick pos=right, % top ticks
xticklabel pos=right, % top tick labels
extra x tick labels list,
},
]
\addplot[red,samples at={19,19.1,...,23}] {x};
\end{axis}
\end{tikzpicture}
\end{document}