通过公式计算 xtick 位置来模拟 plotxx (或 plotyy)

通过公式计算 xtick 位置来模拟 plotxx (或 plotyy)

请考虑这个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相同:,其中和之间的差值设置增量。您还可以使用所有坐标的明确列表。pgfstart element,second element,...,end elementstart elementsecond 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}

在此处输入图片描述

相关内容