我正在制作一个特殊的 tick 命令。如果没有*
,则 tick 显示在左侧。有了*
,它应该出现在右侧。*
应该设置一些宏来更改 tick 的行为。但是,发生的事情是,所有 tick 都出现在右侧。(如果最近的ytick
调用没有*
,它们将出现在左侧。我知道这个问题与扩展有关。我想我需要做的是完全扩展每个 ytick 调用。
\documentclass{article}
\RequirePackage{tikz}
\usetikzlibrary{calc}
\RequirePackage{pgfplots}
\RequirePackage{pgffor}
\pgfplotsset{compat=newest}
\newcommand{\ticksign}{-}
\newcommand{\tickside}{0}
\newcommand{\tickanchor}{east}
\newcommand{\ticklength}{2pt}
\NewDocumentCommand{\ytick}{ s m O{#2} }{%
\IfBooleanTF{#1}{
\gdef\ticksign{}
\gdef\tickside{1}
\gdef\tickanchor{west}
}{
\gdef\ticksign{-}
\gdef\tickside{0}
\gdef\tickanchor{east}
}
\coordinate (tick) at ({rel axis cs: \tickside , 0} |- {axis cs: 0, #2}) ;
\draw[gray] (tick) -- + (\ticksign \ticklength , 0pt);
\node[anchor=\tickanchor ] at ($ (tick) + (\ticksign \ticklength , 0pt) $) {#3} ;
}
\begin{document}
\begin{tikzpicture}
\begin{axis}[hide axis,clip=false]
\addplot table[header=false,x expr=\coordindex, y index=0] {
1
2
3
2
1
};
\ytick{1}[one] % should be on left side
\ytick{3}[three] % should be on left side
\ytick*{2}[two]
\end{axis}
\end{tikzpicture}
\end{document}
答案1
我建议使用辅助宏来获取转发的参数而不是将它们存储在宏中:
\documentclass{article}
\RequirePackage{tikz}
\usetikzlibrary{calc}
\RequirePackage{pgfplots}
\RequirePackage{pgffor}
\pgfplotsset{compat=newest}
\newcommand{\ticklength}{2pt}
\makeatletter
\newcommand\ytick@[5]
{%
\coordinate (tick) at ({rel axis cs: #2 , 0} |- {axis cs: 0 , #4});
\draw[gray] (tick) -- +(#1\ticklength , 0pt);
\node[anchor=#3] at ($ (tick) + (#1\ticklength , 0pt) $) {#5};
}
\NewDocumentCommand{\ytick}{ s m O{#2} }
{%
\IfBooleanTF{#1}
{\ytick@{}{1}{west}}
{\ytick@{-}{0}{east}}
{#2}{#3}%
}
\makeatother
\begin{document}
\begin{tikzpicture}
\begin{axis}[hide axis,clip=false]
\addplot table[header=false,x expr=\coordindex, y index=0] {
1
2
3
2
1
};
\ytick{1}[one] % should be on left side
\ytick{3}[three] % should be on left side
\ytick*{2}[two]
\end{axis}
\end{tikzpicture}
\end{document}
答案2
恕我直言Skillmon 的回答为该问题提供了最佳、最有效的解决方案。我的回答只是对 Skillmon 的回答的一个补充,用于说明宏扩展的技巧,尽管这些技巧在这里并不是真正需要的(Skillmon 的回答已证明这一点)。
为了在学习扩展时获得乐趣,你可以嵌套如下内容\expandafter\Exchange\expandafter{...}{...}
:
\documentclass{article}
\RequirePackage{tikz}
\usetikzlibrary{calc}
\RequirePackage{pgfplots}
\RequirePackage{pgffor}
\pgfplotsset{compat=newest}
\newcommand\Exchange[2]{#2#1}
\newcommand\PassFirstToSecond[2]{#2{#1}}
\newcommand{\ticksign}{-}
\newcommand{\tickside}{0}
\newcommand{\tickanchor}{east}
\newcommand{\ticklength}{2pt}
\NewDocumentCommand{\ytick}{ s m O{#2} }{%
\IfBooleanTF{#1}{
\gdef\ticksign{}
\gdef\tickside{1}
\gdef\tickanchor{west}
}{
\gdef\ticksign{-}
\gdef\tickside{0}
\gdef\tickanchor{east}
}
\expandafter\expandafter\expandafter\PassFirstToSecond
\expandafter\expandafter\expandafter{%
\expandafter\Exchange\expandafter{%
\tickside}{rel axis cs: } , 0}{\coordinate (tick) at (} |- {axis cs: 0, #2}) ;
\expandafter\Exchange\expandafter{\ticklength}%
{\expandafter\Exchange\expandafter{\ticksign}{\draw[gray] (tick) -- + (}} , 0pt);
\expandafter\Exchange\expandafter{\ticklength}%
{\expandafter\Exchange\expandafter{\ticksign}%
{\expandafter\Exchange\expandafter{\tickanchor}{\node[anchor=} ] at ($ (tick) + (} } , 0pt) $) {#3} ;
}
\begin{document}
\begin{tikzpicture}
\begin{axis}[hide axis,clip=false]
\addplot table[header=false,x expr=\coordindex, y index=0] {
1
2
3
2
1
};
\ytick{1}[one] % should be on left side
\ytick{3}[three] % should be on left side
\ytick*{2}[two]
\end{axis}
\end{tikzpicture}
\end{document}
如果使用 TeX 引擎,\expanded
您可以结合\expanded
使用\noexpand
:
\documentclass{article}
\RequirePackage{tikz}
\usetikzlibrary{calc}
\RequirePackage{pgfplots}
\RequirePackage{pgffor}
\pgfplotsset{compat=newest}
\newcommand{\ticksign}{-}
\newcommand{\tickside}{0}
\newcommand{\tickanchor}{east}
\newcommand{\ticklength}{2pt}
\NewDocumentCommand{\ytick}{ s m O{#2} }{%
\IfBooleanTF{#1}{
\gdef\ticksign{}
\gdef\tickside{1}
\gdef\tickanchor{west}
}{
\gdef\ticksign{-}
\gdef\tickside{0}
\gdef\tickanchor{east}
}
\expanded{%
\noexpand\coordinate (tick) at ({rel axis cs: \tickside , 0} |- {axis cs: 0, #2}) ;
\noexpand\draw[gray] (tick) -- + (\ticksign \ticklength , 0pt);
\noexpand\node[anchor=\tickanchor ] at ($ (tick) + (\ticksign \ticklength , 0pt) $) {#3} ;
}%
}
\begin{document}
\begin{tikzpicture}
\begin{axis}[hide axis,clip=false]
\addplot table[header=false,x expr=\coordindex, y index=0] {
1
2
3
2
1
};
\ytick{1}[one] % should be on left side
\ytick{3}[three] % should be on left side
\ytick*{2}[two]
\end{axis}
\end{tikzpicture}
\end{document}