如果使用 tikz“数学”库,beamer 和 pgfplots 不起作用

如果使用 tikz“数学”库,beamer 和 pgfplots 不起作用

提供的代码这里gcd()(至少在 1.18 中不再需要解决问题pgfplots)执行以下操作:

  • 如果使用的类是article,则有效,
  • 如果使用的类是,则不起作用beamer

事实上,以下 MCE 的编译:

\documentclass{beamer}
\usepackage{pgfplots}
\pgfplotsset{compat=1.18}

% Load math library, for \tikzmath
\usetikzlibrary{math}

\pgfplotsset{
  % Typeset fractions of pi at regular intervals on x axis
  x axis in pi/.style={
    % Make sure the x axis is in radians
    trig format plots=rad,
    % Set tick distance from style argument
    xtick distance={pi/#1},
    % Set label style: calculate reduced fraction of pi
    xticklabel={
      \tikzmath{
        % Calculate this tick's multiple of pi/#1
        int \numorig, \gcd, \num, \denom, \absnum;
        \numorig = round(\tick*#1/pi);
        % Calculate reduced fraction for \numorig/#1
        \gcd = gcd(\numorig,#1);
        \num = \numorig / \gcd;
        \absnum = abs(\num);
        \denom = #1 / \gcd;
        % Build label text
        if \num < 0 then {
          let \sign = -;
        } else {
          let \sign =;
        };
        if \absnum == 1 then {
          let \numpi = \pi;
        } else {
          let \numpi = \absnum\pi;
        };
        if \denom == 1 then {
          if \num == 0 then {
            { \strut$0$ };
          } else {
            { \strut$\sign\numpi$ };
          };
        } else {
          { \strut$\sign\frac{\numpi}{\denom}$ };
          % Other style with all pi symbols same and aligned:
          % { \strut$\sign\frac{\absnum}{\denom}\pi$ };
        };
      }
    },
  },
}

\begin{document}
\begin{frame}
  \begin{tikzpicture}
    \begin{axis}[
      x axis in pi=2, % tick distance as fraction of pi
      ]
      \addplot {sin(x)};
    \end{axis}
\end{tikzpicture}
\end{frame}
\end{document}

失败并出现错误:

(./test-beamer.nav)
! Missing \endcsname inserted.
<to be read again> 
                   \protect 
l.62 \end{frame}
                
?

请注意,将该fragile选项添加到frame环境中并没有帮助。

你明白发生了什么事吗?

答案1

问题在于库处理变量名的方式math;本质上,对于变量\gcd,它会尝试在构造内部使用它\csname

您的问题可以归结为以下 MWE:

\RequirePackage{amsmath}
\RequirePackage{tikz}
\usetikzlibrary{math}
\tikzmath{\gcd = 1;}
\stop

区别在于 LaTeX 对\gcd(\meaning以 开头) 的标准定义和(以 开头)macro中的定义,因此我们可以进一步降低 MWE:amsmath\meaning\protected

\RequirePackage{tikz}
% make \gcd \protected, but don't alter it otherwise
\protected\expandafter\def\expandafter\gcd\expandafter{\gcd}
\usetikzlibrary{math}
\tikzmath{\gcd = 1;}
\stop

现在,math-parser 不明白这是一个变量,但认为它是一个关键字的一部分,将所有内容抓取到下一个空格(或者它这样做了吗?这里不确定),并尝试构建该关键字的名称,但结果却\csname严重失败。

因此,您不能分配给已经\protected在库中定义的变量math(好吧,如果您使用let关键字,那么您可以,这样\tikzmath{let \gcd=;}可以,之后您可以使用名称\gcd)!

如果你改变该变量的名称(例如,改为\mygcd),一切都会再次正常工作:

\documentclass{beamer}
\usepackage{pgfplots}
\pgfplotsset{compat=1.18}

% Load math library, for \tikzmath
\usetikzlibrary{math}

\pgfplotsset{
  % Typeset fractions of pi at regular intervals on x axis
  x axis in pi/.style={
    % Make sure the x axis is in radians
    trig format plots=rad,
    % Set tick distance from style argument
    xtick distance={pi/#1},
    % Set label style: calculate reduced fraction of pi
    xticklabel={
      \tikzmath{
        % Calculate this tick's multiple of pi/#1
        int \numorig, \gcd, \num, \denom, \absnum;
        \numorig = round(\tick*#1/pi);
        % Calculate reduced fraction for \numorig/#1
        \mygcd = gcd(\numorig,#1);
        \num = \numorig / \mygcd;
        \absnum = abs(\num);
        \denom = #1 / \mygcd;
        % Build label text
        if \num < 0 then {
          let \sign = -;
        } else {
          let \sign =;
        };
        if \absnum == 1 then {
          let \numpi = \pi;
        } else {
          let \numpi = \absnum\pi;
        };
        if \denom == 1 then {
          if \num == 0 then {
            { \strut$0$ };
          } else {
            { \strut$\sign\numpi$ };
          };
        } else {
          { \strut$\sign\frac{\numpi}{\denom}$ };
          % Other style with all pi symbols same and aligned:
          % { \strut$\sign\frac{\absnum}{\denom}\pi$ };
        };
      }
    },
  },
}

\begin{document}
\begin{frame}
  \begin{tikzpicture}
    \begin{axis}[
      x axis in pi=2, % tick distance as fraction of pi
      ]
      \addplot {sin(x)};
    \end{axis}
\end{tikzpicture}
\end{frame}
\end{document}

相关内容